diff --git a/modulo4/iwfs-cookenu/.gitignore b/modulo4/iwfs-cookenu/.gitignore new file mode 100644 index 0000000..8ece3ba --- /dev/null +++ b/modulo4/iwfs-cookenu/.gitignore @@ -0,0 +1,4 @@ +node_modules +package-lock.json +build +.env \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/package.json b/modulo4/iwfs-cookenu/package.json new file mode 100644 index 0000000..3ea298b --- /dev/null +++ b/modulo4/iwfs-cookenu/package.json @@ -0,0 +1,34 @@ +{ + "name": "iwfs-cookenu", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "dev": "ts-node-dev ./src/index.ts", + "start": "tsc && node ./build/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/bcryptjs": "^2.4.2", + "@types/cors": "^2.8.12", + "@types/express": "^4.17.13", + "@types/knex": "^0.16.1", + "@types/uuid": "^8.3.4", + "ts-node-dev": "^1.1.8", + "typescript": "^4.5.5" + }, + "dependencies": { + "@types/jsonwebtoken": "^8.5.8", + "bcryptjs": "^2.4.3", + "cors": "^2.8.5", + "dotenv": "^16.0.0", + "express": "^4.17.3", + "jsonwebtoken": "^8.5.1", + "knex": "^1.0.3", + "mysql": "^2.18.1", + "uuid": "^8.3.2" + } +} diff --git a/modulo4/iwfs-cookenu/request.rest b/modulo4/iwfs-cookenu/request.rest new file mode 100644 index 0000000..c36af82 --- /dev/null +++ b/modulo4/iwfs-cookenu/request.rest @@ -0,0 +1,28 @@ +POST http://localhost:3003/login +Content-Type: application/json +Authorization: "3a297fc1-910e-4fc1-a8b1-5fcc01da752b" + +{ + + "email": "igor@gmail.com", + "password": "igorigor123" +} +### + +GET http://localhost:3003/user/profile +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjNhMjk3ZmMxLTkxMGUtNGZjMS1hOGIxLTVmY2MwMWRhNzUyYiIsImlhdCI6MTY0NjE0MjQwNiwiZXhwIjoxNjQ2MzE1MjA2fQ.49cL29yj9iWoi1CgLgoM-18SHSo7OuSSdI5FwNx7PoU + +### +POST http://localhost:3003/recipe +Content-Type: application/json +Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjNhMjk3ZmMxLTkxMGUtNGZjMS1hOGIxLTVmY2MwMWRhNzUyYiIsImlhdCI6MTY0NjI1ODk3NSwiZXhwIjoxNjQ2NDMxNzc1fQ.bQiculocWEhoeB3guk3CaXx8vxPBMfv6y-30KipSnpM + +{ + "title": "Arroz", + "description": "AAAAAAAAAAAAAAAAAAAAAAAA" +} + + +### +GET http://localhost:3003/recipe \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/app.ts b/modulo4/iwfs-cookenu/src/app.ts new file mode 100644 index 0000000..3d052e2 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/app.ts @@ -0,0 +1,22 @@ +import express, { Express } from "express" +import cors from "cors" +import dotenv from "dotenv" +import { AddressInfo } from "net" + +dotenv.config(); + +const app: Express = express() +app.use(express.json()) +app.use(cors()) + +const server = app.listen(process.env.PORT || 3003, () => { +if (server) { +const address = server.address() as AddressInfo; +console.log(`Server is running in http://localhost:${address.port}`); +} else { +console.error(`Failure upon starting server.`); +} +}); + + +export default app \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/data/RecipieDataBase.ts b/modulo4/iwfs-cookenu/src/data/RecipieDataBase.ts new file mode 100644 index 0000000..e320ea7 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/data/RecipieDataBase.ts @@ -0,0 +1,34 @@ +import baseDataBase from "../entities/BaseDataBase"; +import { Recipie } from "../entities/Class"; + + +export class RecipieDataBase extends baseDataBase{ + + async createRecipie(recipie: Recipie):Promise{ + try{ + const recipies = await baseDataBase.connection('Receitas').insert({ + id: recipie.getId(), + criador_id: recipie.getCreator(), + titulo: recipie.getTitle(), + descricao: recipie.getDescription(), + data: recipie.getDate() + }) + return recipies[0] && Recipie.toUserModel(recipies[0]) + } catch(e:any){ + throw new Error(e.sqlMessage || e.message) + } + } + + async getRecipie(id:string){ + try{ + const recipie = await baseDataBase.connection('Receitas') + .select('id', 'titulo', 'descricao', 'data') + .where({id}) + return recipie[0] && Recipie.toUserModel(recipie[0]) + + } catch(e:any){ + throw new Error(e.sqlMessage || e.message) + } + } + +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/data/UserDataBase.ts b/modulo4/iwfs-cookenu/src/data/UserDataBase.ts new file mode 100644 index 0000000..ef2c367 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/data/UserDataBase.ts @@ -0,0 +1,59 @@ +import baseDataBase from "../entities/BaseDataBase"; +import { Recipie, User } from "../entities/Class"; + + +export class UserDataBase extends baseDataBase { + + async createUser(user: User) { + console.log(user) + await baseDataBase.connection('Cookenu').insert({ + id: user.getId(), + nome: user.getName(), + email: user.getEmail(), + password: user.getPassword() + }) + } + + + async findUserByEmail(email: string): Promise { + try { + const user = await baseDataBase.connection('Cookenu') + .select('*') + .where({ email }) + + return user[0] && User.toUserModel(user[0]) + } catch (e: any) { + throw new Error(e.sqlMessage || e.message) + } + } + + async getProfile(id: string): Promise { + try { + const profile = await baseDataBase.connection('Cookenu') + .select("id", "nome", "email") + .where({ id }) + + return profile[0] && User.toUserModel(profile[0]) + } catch (e: any) { + + throw new Error(e.sqlMessage || e.message) + } + } + + async getProfileById(id: string): Promise { + try { + const profileById = await baseDataBase.connection('Cookenu') + .select('id','nome', 'email') + .where({id}) + + return profileById[0] && User.toUserModel(profileById[0]) + } catch (e: any) { + + throw new Error(e.sqlMessage || e.message) + } + } + + +} + + diff --git a/modulo4/iwfs-cookenu/src/endpoints/createRecipes.ts b/modulo4/iwfs-cookenu/src/endpoints/createRecipes.ts new file mode 100644 index 0000000..4a30f78 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/createRecipes.ts @@ -0,0 +1,34 @@ + +import { Response, Request } from "express" +import { Authenticator } from "../services/Authenticator" +import { idGen } from "../services/idGen" +import { Recipie } from "../entities/Class" +import { RecipieDataBase } from "../data/RecipieDataBase" + +export async function createRecipie(req:Request, res:Response):Promise{ + try{ + const token = req.headers.authorization as string + const {title, description} = req.body + const idGenerator = new idGen() + const id = idGenerator.generate() + const data = new Date() + + if(!title || !description){ + res.status(422).send('Preencha todos os campos') + } + + const authenticator = new Authenticator() + const tokenIsCorrect = authenticator.getTokenData(token) + console.log(tokenIsCorrect) + if(!tokenIsCorrect){ + res.status(422).send('Token inválido') + } + const recipie: Recipie = new Recipie(id, tokenIsCorrect.id, title, description, data) + const recipieDataBase = new RecipieDataBase() + await recipieDataBase.createRecipie(recipie) + + res.status(201).send('Receita criada') + } catch(e:any){ + res.status(500).send(e.message) + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/endpoints/getProfile.ts b/modulo4/iwfs-cookenu/src/endpoints/getProfile.ts new file mode 100644 index 0000000..3de3d18 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/getProfile.ts @@ -0,0 +1,19 @@ +import { UserDataBase } from "../data/UserDataBase" +import { Response, Request } from "express" +import { Authenticator } from "../services/Authenticator" + +export async function getProfile(req: Request, res: Response): Promise{ + try { + const token = req.headers.authorization as string + + const authenticator = new Authenticator() + const tokenIsCorrect = authenticator.getTokenData(token) + + const userDatabase = new UserDataBase() + const user = await userDatabase.getProfile(tokenIsCorrect.id) + + res.status(200).send(user) + } catch (e: any) { + res.status(500).send(e.message) + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/endpoints/getProfileById.ts b/modulo4/iwfs-cookenu/src/endpoints/getProfileById.ts new file mode 100644 index 0000000..0b64e8b --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/getProfileById.ts @@ -0,0 +1,25 @@ +import { Request, Response } from 'express' +import { UserDataBase } from '../data/UserDataBase' +import { Authenticator } from '../services/Authenticator' + +export async function getProfileById (req:Request, res:Response):Promise{ + try{ + const id = req.params.id as string + + const token = req.headers.authorization as string + + const authenticador = new Authenticator() + const tokenIsCorrect = authenticador.getTokenData(token) + + const userDatabase = new UserDataBase() + const profile = await userDatabase.getProfileById(id) + + if(!profile){ + res.status(404).send('Usuário não existe') + } + + res.status(200).send(profile) + } catch(e: any){ + res.status(400).send(e.message) + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/endpoints/getRecipeById.ts b/modulo4/iwfs-cookenu/src/endpoints/getRecipeById.ts new file mode 100644 index 0000000..c8ed95a --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/getRecipeById.ts @@ -0,0 +1,26 @@ +import { Response, Request } from "express" +import { RecipieDataBase } from "../data/RecipieDataBase" +import { Authenticator } from "../services/Authenticator" + + +export async function getRecipeById(req:Request, res:Response):Promise{ + try{ + const id = req.params.id as string + + if(!id){ + res.status(401).send('Receita não encontrada') + } + const token = req.headers.authorization as string + + const authenticator = new Authenticator() + const tokenIsCorrect = authenticator.getTokenData(token) + + const recipe = new RecipieDataBase() + const getRecipe = await recipe.getRecipie(id) + + res.status(200).send(getRecipe) + } catch(e:any){ + res.status(500).send(e.message) + } +} + diff --git a/modulo4/iwfs-cookenu/src/endpoints/login.ts b/modulo4/iwfs-cookenu/src/endpoints/login.ts new file mode 100644 index 0000000..9311573 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/login.ts @@ -0,0 +1,42 @@ +import { Request, Response } from 'express' +import { UserDataBase } from '../data/UserDataBase' +import { Authenticator } from '../services/Authenticator' +import { HashManager } from '../services/HashManager' + + + + +export async function login(req: Request, res: Response) { + try { + const { email, password } = req.body + + + if (!email || !password) + res.status(422).send('Preencha os campos corretamente.') + + + const userDataBase = new UserDataBase() + + const user = await userDataBase.findUserByEmail(email) + + if (!user) { + res.status(409).send('O e-mail não está cadastrado') + } + + const hashManager = new HashManager() + const passwordIsCorrect = await hashManager.compare(password, user.getPassword()) + + if(!passwordIsCorrect){ + res.status(401).send('Senha ou e-mail incorretos') + } + const authenticator = new Authenticator() + const token = authenticator.generate({ id: user.getId()}) + + + res.status(200).send(token ? `Usuário logado com sucesso: ${token}` : '') + + } catch (e: any) { + res.status(400).send(e.message) + } +} + diff --git a/modulo4/iwfs-cookenu/src/endpoints/signup.ts b/modulo4/iwfs-cookenu/src/endpoints/signup.ts new file mode 100644 index 0000000..83dccd9 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/endpoints/signup.ts @@ -0,0 +1,49 @@ + +import { Request, Response } from 'express' +import { UserDataBase } from '../data/UserDataBase' +import { User } from '../entities/Class' +import { Authenticator } from '../services/Authenticator' +import { HashManager } from '../services/HashManager' +import { idGen } from '../services/idGen' + + + +export async function signup(req: Request, res: Response) { + try { + const { name, email, password } = req.body + const idGenerator = new idGen() + const id = idGenerator.generate() + + if (!name || !email || !password) + res.status(422).send('Preencha os campos corretamente.') + + if (password.length < 6) { + res.status(401).send('A senha deve ter 6 ou mais caracteres') + } + + const userDataBase = new UserDataBase() + + const user = await userDataBase.findUserByEmail(email) + + if (user) { + res.status(409).send('O e-mail já está cadastrado') + } + + const hashManager = new HashManager() + const hashPassword = await hashManager.hash(password) + + const newUser = new User(id, name, email, hashPassword) + + await userDataBase.createUser(newUser) + + const authenticator = new Authenticator() + const token = authenticator.generate({ id }) + + + res.status(200).send(token ? `Token de registro: ${token}` : '') + + } catch (e: any) { + res.status(400).send(e.message) + } +} + diff --git a/modulo4/iwfs-cookenu/src/entities/AuthenticationData.ts b/modulo4/iwfs-cookenu/src/entities/AuthenticationData.ts new file mode 100644 index 0000000..1cefdb2 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/entities/AuthenticationData.ts @@ -0,0 +1,5 @@ + interface AuthenticationData { + id: string, +} + +export default AuthenticationData \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/entities/BaseDataBase.ts b/modulo4/iwfs-cookenu/src/entities/BaseDataBase.ts new file mode 100644 index 0000000..39087e7 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/entities/BaseDataBase.ts @@ -0,0 +1,22 @@ +import knex, { Knex } from 'knex' +import dotenv from "dotenv" + +dotenv.config(); + + +export class baseDataBase { + getAllUsers() { + throw new Error("Method not implemented."); + } + protected static connection: Knex = knex({ + client: 'mysql', + connection:{ + host: process.env.DB_HOST, + user: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME, + }, + }) +} + +export default baseDataBase diff --git a/modulo4/iwfs-cookenu/src/entities/Class.ts b/modulo4/iwfs-cookenu/src/entities/Class.ts new file mode 100644 index 0000000..54ce737 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/entities/Class.ts @@ -0,0 +1,58 @@ + +export class User { + + constructor( + private id:string, + private name:string, + private email:string, + private password:string + ){} + + static toUserModel(data:any):User{ + return new User(data.id, data.name, data.email, data.password) + } + + + getId(){ + return this.id + } + getName(){ + return this.name + } + getEmail(){ + return this.email + } + getPassword(){ + return this.password + } +} + +export class Recipie { + constructor( + private id:string, + private criador_id:string, + private titulo:string, + private descricao:string, + private data: Date + + ){} + static toUserModel(data: any): Recipie { + return new Recipie(data.id, data.criador_id, data.titulo, data.descricao, data.data) + } + getId(){ + return this.id + } + getCreator(){ + return this.criador_id + } + getTitle(){ + return this.titulo + } + getDescription(){ + return this.descricao + } + + getDate(){ + return this.data + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/index.ts b/modulo4/iwfs-cookenu/src/index.ts new file mode 100644 index 0000000..7261f46 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/index.ts @@ -0,0 +1,23 @@ +import app from "./app" +import { createRecipie } from "./endpoints/createRecipes" +import { getProfile } from "./endpoints/getProfile" +import { getProfileById } from "./endpoints/getProfileById" +import { getRecipeById } from "./endpoints/getRecipeById" +import { login } from "./endpoints/login" +import { signup } from "./endpoints/signup" + + + + + +app.post('/login', login) +app.post('/signup', signup) +app.post('/recipe', createRecipie) + +app.get('/user/profile', getProfile) +app.get('/user/:id', getProfileById) +app.get('/recipe/:id', getRecipeById) + + + + diff --git a/modulo4/iwfs-cookenu/src/services/Authenticator.ts b/modulo4/iwfs-cookenu/src/services/Authenticator.ts new file mode 100644 index 0000000..7629a9d --- /dev/null +++ b/modulo4/iwfs-cookenu/src/services/Authenticator.ts @@ -0,0 +1,25 @@ +import * as jwt from 'jsonwebtoken' +import dotenv from 'dotenv' +import AuthenticationData from '../entities/AuthenticationData' + + +dotenv.config() + + + + +export class Authenticator { + generate(input: AuthenticationData):string { + const token = jwt.sign(input, process.env.JWT_KEY as string, { + + expiresIn: process.env.EXPIRES_IN + }) + return token + } + + + getTokenData(token:string):AuthenticationData{ + const data = jwt.verify(token, process.env.JWT_KEY as string) + return data as AuthenticationData + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/services/HashManager.ts b/modulo4/iwfs-cookenu/src/services/HashManager.ts new file mode 100644 index 0000000..47a69a5 --- /dev/null +++ b/modulo4/iwfs-cookenu/src/services/HashManager.ts @@ -0,0 +1,16 @@ +import * as bcrypt from 'bcryptjs' + + +export class HashManager{ + async hash(text:string):Promise { + const rounds = Number(process.env.COST) + const salt = await bcrypt.genSalt(rounds) + + return bcrypt.hash(text, salt) + } + + async compare(text:string, hash:string):Promise{ + return bcrypt.compare(text, hash) + } +} + \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/src/services/idGen.ts b/modulo4/iwfs-cookenu/src/services/idGen.ts new file mode 100644 index 0000000..7b08e2d --- /dev/null +++ b/modulo4/iwfs-cookenu/src/services/idGen.ts @@ -0,0 +1,7 @@ +import {v4} from 'uuid' + +export class idGen { + generate():string { + return v4() + } +} \ No newline at end of file diff --git a/modulo4/iwfs-cookenu/tsconfig.json b/modulo4/iwfs-cookenu/tsconfig.json new file mode 100644 index 0000000..40ff6fc --- /dev/null +++ b/modulo4/iwfs-cookenu/tsconfig.json @@ -0,0 +1,101 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Projects */ + // "incremental": true, /* Enable incremental compilation */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ + // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + "rootDir": "./src", /* Specify the root folder within your source files. */ + // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "resolveJsonModule": true, /* Enable importing .json files */ + // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ + "outDir": "./build", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ + // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ + // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +}