diff --git a/server/.gitignore b/server/.gitignore index c6bba59..a884d38 100644 --- a/server/.gitignore +++ b/server/.gitignore @@ -1,130 +1,3 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files .env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* +dist/ diff --git a/server/index.d.ts b/server/index.d.ts index 1046036..4bfb95d 100644 --- a/server/index.d.ts +++ b/server/index.d.ts @@ -9,6 +9,7 @@ type decodedUser = { type decodedAdmin = { id: number; email: string; + name: string; role: string; iat: number; exp: number; diff --git a/server/package-lock.json b/server/package-lock.json index e095213..f81f7de 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -23,13 +23,13 @@ "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.5", - "@types/node": "^20.10.0", + "@types/node": "^20.11.0", "dotenv": "^16.3.1", "nodemon": "^3.0.1", "prettier": "^3.1.1", "prisma": "^5.6.0", "ts-node": "^10.9.1", - "typescript": "^5.3.2" + "typescript": "^5.3.3" } }, "node_modules/@cspotcode/source-map-support": { @@ -233,9 +233,10 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.10.1", + "version": "20.11.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz", + "integrity": "sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ==", "dev": true, - "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } @@ -1833,9 +1834,10 @@ } }, "node_modules/typescript": { - "version": "5.3.2", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/server/package.json b/server/package.json index b4b3e3b..ab107c8 100644 --- a/server/package.json +++ b/server/package.json @@ -3,8 +3,8 @@ "version": "1.0.0", "description": "", "main": "index.js", + "types": "module", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", "format": "prettier --write \"**/*.{js,jsx,mjs,ts,tsx,mts,md}\"", "dev": "nodemon", "typecheck": "tsc --noEmit", @@ -30,12 +30,12 @@ "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.5", - "@types/node": "^20.10.0", + "@types/node": "^20.11.0", "dotenv": "^16.3.1", "nodemon": "^3.0.1", "prettier": "^3.1.1", "prisma": "^5.6.0", "ts-node": "^10.9.1", - "typescript": "^5.3.2" + "typescript": "^5.3.3" } } diff --git a/server/src/custom-types/admin-types.ts b/server/src/custom-types/admin-types.ts index 043e8a4..0a8198c 100644 --- a/server/src/custom-types/admin-types.ts +++ b/server/src/custom-types/admin-types.ts @@ -9,5 +9,6 @@ export type Admin = { export type adminPayload = { id: number; email: string; + name: string | null; role: string; }; diff --git a/server/src/index.ts b/server/src/index.ts index 0ebc01c..cf26418 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -18,7 +18,7 @@ app.use(cookieParser("my-secret")); app.use("/admin", adminRouter); app.use("/user", userRouter); -app.get("/ping", async (req: Request, res: Response) => { +app.get("/ping", async (_req: Request, res: Response) => { try { res.send("pong"); } catch (error) { diff --git a/server/src/routes/admin.ts b/server/src/routes/admin.ts index 97c5806..67935b0 100644 --- a/server/src/routes/admin.ts +++ b/server/src/routes/admin.ts @@ -8,9 +8,9 @@ import { CourseFromDB, CourseWithAdminId, } from "../custom-types/course-types"; -import z from "zod"; import { courseFromDBScheam, + courseIdSchema, createCourseSchema, signupSchema, } from "../zod/zod-types"; @@ -21,13 +21,11 @@ adminRouter.post("/signup", async (req: Request, res: Response) => { try { const parsedInput = signupSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: parsedInput.error.format() }); } else { const { email, password }: { email: string; password: string } = parsedInput.data; - const adminData: Admin | null = await prisma.admin.findFirst({ + const adminData: Admin | null = await prisma.admin.findUnique({ where: { email: email }, }); if (adminData) { @@ -56,9 +54,7 @@ adminRouter.post("/signin", async (req: Request, res: Response) => { try { const parsedInput = signupSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: parsedInput.error.format() }); } else { const { email, password }: { email: string; password: string } = parsedInput.data; @@ -81,19 +77,13 @@ adminRouter.post("/signin", async (req: Request, res: Response) => { const { id, email, + name, role, - }: { id: number; email: string; role: string } = adminData; - const adminPayload: adminPayload = { id, email, role }; + }: { id: number; email: string; name: string | null; role: string } = + adminData; + const adminPayload: adminPayload = { id, email, name, role }; const adminToken: string = generateAdminJWT(adminPayload); res.cookie("adminAccessToken", adminToken, { - domain: "localhost", - path: "/", - maxAge: 60 * 60 * 1000, - httpOnly: true, - secure: true, - sameSite: "strict", - }); - res.cookie("adminLoggedIn", true, { domain: "localhost", path: "/", maxAge: 60 * 60 * 1000, @@ -101,7 +91,7 @@ adminRouter.post("/signin", async (req: Request, res: Response) => { sameSite: "strict", }); } - return res.json({ message: "Logged in successfully" }); + return res.json({ message: "Signin in successfully" }); } } } catch (error) { @@ -124,7 +114,10 @@ adminRouter.get( }); await prisma.$disconnect(); res.json({ + id: adminData?.id, + email: adminData?.email, name: adminData?.name, + role: adminData?.role, }); } catch (error) { await prisma.$disconnect(); @@ -137,10 +130,9 @@ adminRouter.get( adminRouter.post( "/logout", authenticateAdminJWT, - async (req: Request, res: Response) => { + async (_req: Request, res: Response) => { try { res.clearCookie("adminAccessToken"); - res.clearCookie("adminLoggedIn"); res.json({ message: "Logged out successfully" }); } catch (error) { console.error(error); @@ -162,7 +154,6 @@ adminRouter.delete( }); await prisma.$disconnect(); res.clearCookie("adminAccessToken"); - res.clearCookie("adminLoggedIn"); res.json({ message: "Admin deleted successfully" }); } catch (error) { await prisma.$disconnect(); @@ -181,9 +172,7 @@ adminRouter.post( try { const parsedInput = createCourseSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: "zod" }); } else { const { title, description, published, imageUrl, price }: Course = parsedInput.data; @@ -217,9 +206,7 @@ adminRouter.put( try { const parsedInput = courseFromDBScheam.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: parsedInput.error.format() }); } else { const updatedCourse: CourseFromDB = parsedInput.data; const decodedAdmin: decodedAdmin = req.decodedAdmin; @@ -253,23 +240,29 @@ adminRouter.delete( async (req: Request, res: Response) => { try { const decodedAdmin: decodedAdmin = req.decodedAdmin; - const { courseId }: { courseId: number } = await req.body; - const currentCourse: CourseFromDB | null = await prisma.course.findFirst({ - where: { id: courseId }, - }); - if (!currentCourse) { - return res.status(404).json({ message: "Course does not exists" }); - } - if (currentCourse.adminId === decodedAdmin.id) { - await prisma.course.delete({ - where: { id: courseId }, - }); - await prisma.$disconnect(); - return res.json({ message: "Course deleted successfully" }); + const parsedInput = courseIdSchema.safeParse(req.body); + if (!parsedInput.success) { + return res.status(411).json({ message: parsedInput.error.format() }); } else { - return res - .status(403) - .json({ message: "The course does not belong to this admin." }); + const { courseId } = parsedInput.data; + const currentCourse: CourseFromDB | null = + await prisma.course.findUnique({ + where: { id: courseId }, + }); + if (!currentCourse) { + return res.status(404).json({ message: "Course does not exists" }); + } + if (currentCourse.adminId === decodedAdmin.id) { + await prisma.course.delete({ + where: { id: courseId }, + }); + await prisma.$disconnect(); + return res.json({ message: "Course deleted successfully" }); + } else { + return res + .status(403) + .json({ message: "The course does not belong to this admin." }); + } } } catch (error) { await prisma.$disconnect(); @@ -301,7 +294,7 @@ adminRouter.get( adminRouter.get( "/all-courses", authenticateAdminJWT, - async (req: Request, res: Response) => { + async (_req: Request, res: Response) => { try { const courses: CourseFromDB[] = await prisma.course.findMany(); await prisma.$disconnect(); diff --git a/server/src/routes/user.ts b/server/src/routes/user.ts index 4af8c91..1998f2b 100644 --- a/server/src/routes/user.ts +++ b/server/src/routes/user.ts @@ -3,26 +3,16 @@ import { prisma } from "../prismaClient"; import bcrypt from "bcrypt"; import { authenticateUserJWT, generateUserJWT } from "../jwt-auth/user-auth"; import { User, userPayload } from "../custom-types/user-types"; -import { Course, CourseFromDB } from "../custom-types/course-types"; +import { CourseFromDB } from "../custom-types/course-types"; import { purchaseCourseSchema, signupSchema } from "../zod/zod-types"; export const userRouter: Router = Router(); -// userRouter.get("/", async (req: Request, res: Response) => { -// try { -// res.status(200).send("

User api

"); -// } catch (error) { -// res.sendStatus(500); -// } -// }); - userRouter.post("/signup", async (req: Request, res: Response) => { try { const parsedInput = signupSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: "zod" }); } else { const { email, password }: { email: string; password: string } = parsedInput.data; @@ -56,9 +46,7 @@ userRouter.post("/signin", async (req: Request, res: Response) => { try { const parsedInput = signupSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: "zod" }); } else { const { email, password }: { email: string; password: string } = parsedInput.data; @@ -85,18 +73,9 @@ userRouter.post("/signin", async (req: Request, res: Response) => { domain: "localhost", path: "/", maxAge: 60 * 60 * 1000, - // httpOnly: true, secure: true, sameSite: "strict", }); - - // res.cookie("userLoggedIn", true, { - // domain: "localhost", - // path: "/", - // maxAge: 60 * 60 * 1000, - // secure: true, - // sameSite: "strict", - // }); } return res.json({ message: "Logged in successfully", email }); } @@ -128,7 +107,7 @@ userRouter.get( }, ); -userRouter.post("/logout", authenticateUserJWT, async (req, res) => { +userRouter.post("/logout", authenticateUserJWT, async (_req, res) => { try { res.clearCookie("userAccessToken"); res.clearCookie("userLoggedIn"); @@ -161,7 +140,7 @@ userRouter.delete("/delete", authenticateUserJWT, async (req, res) => { userRouter.get( "/all-courses", authenticateUserJWT, - async (req: Request, res: Response) => { + async (_req: Request, res: Response) => { try { const courseData: CourseFromDB[] = await prisma.course.findMany(); await prisma.$disconnect(); @@ -181,13 +160,11 @@ userRouter.post( try { const parsedInput = purchaseCourseSchema.safeParse(req.body); if (!parsedInput.success) { - return res - .status(411) - .json({ message: parsedInput.error.issues[0].message }); + return res.status(411).json({ message: "zod" }); } else { const { courseId }: { courseId: number } = parsedInput.data; const decodedUser: decodedUser = req.decodedUser; - const result = await prisma.userCourses.create({ + await prisma.userCourses.create({ data: { user: { connect: { id: decodedUser.id }, diff --git a/server/src/zod/zod-types.ts b/server/src/zod/zod-types.ts index 9adc06a..fcddd22 100644 --- a/server/src/zod/zod-types.ts +++ b/server/src/zod/zod-types.ts @@ -30,5 +30,9 @@ export const courseFromDBScheam = courseSchemaWithAdminId.extend({ }); export const purchaseCourseSchema = z.object({ - courseId: z.number().min(1, "Course ID can't be less than 1"), + courseId: z.number().min(1, "CourseId can't be less than 1"), +}); + +export const courseIdSchema = z.object({ + courseId: z.number().min(1, "CourseId can't be less than 1"), }); diff --git a/server/tsconfig.json b/server/tsconfig.json index cee82a3..906477c 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -1,109 +1,26 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "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": "ES2020" /* 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 legacy experimental 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. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - - /* Modules */ - "module": "NodeNext" /* Specify what module code is generated. */, - "rootDir": "./src" /* Specify the root folder within your source files. */, - "moduleResolution": "NodeNext" /* 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": ["src/@types", "./node_modules/@types"], /* 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. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "allowImportingTsExtensions": true /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */, - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ - // "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. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "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": "./dist/js" /* 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. */ - // "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. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "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, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when 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, /* Add 'undefined' to a type when accessed using an index. */ - // "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. */ + // Base Options + "esModuleInterop": true, + "skipLibCheck": true, + "target": "ES2022", + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + // Strictness + "strict": true, + "noUncheckedIndexedAccess": true, + // If transpiling with Typescript + "moduleResolution": "NodeNext", + "module": "NodeNext", + "outDir": "dist", + "sourceMap": true, + // And if you're building for a library + "declaration": true, + "lib": [ + "ES2022" + ], + "allowImportingTsExtensions": true } }