├── apps ├── express-typescript-mongo-apis │ ├── env.example │ ├── src │ │ ├── post │ │ │ ├── post.service.ts │ │ │ ├── post.interface.ts │ │ │ ├── post.dto.ts │ │ │ ├── post.model.ts │ │ │ └── post.controller.ts │ │ ├── user │ │ │ ├── user.service.ts │ │ │ ├── user.interface.ts │ │ │ ├── user.dto.ts │ │ │ ├── user.model.ts │ │ │ └── user.controller.ts │ │ ├── interfaces │ │ │ ├── token.interface.ts │ │ │ ├── controller.interface.ts │ │ │ └── req.user.ts │ │ ├── authentication │ │ │ ├── logIn.dto.ts │ │ │ ├── auth.service.ts │ │ │ └── auth.controller.ts │ │ ├── exceptions │ │ │ ├── auth.token.exception.ts │ │ │ ├── post.exception.ts │ │ │ ├── user.exception.ts │ │ │ ├── user.acces.exception.ts │ │ │ ├── wrong.credentials.exception.ts │ │ │ ├── auth.access-token.exception.ts │ │ │ ├── user.login.exception.ts │ │ │ ├── http.exception.ts │ │ │ └── user.register.exception.ts │ │ ├── server.ts │ │ ├── middleware │ │ │ ├── error.middleware.ts │ │ │ └── auth.middleware.ts │ │ └── app.ts │ ├── jest.config.js │ ├── nodemon.json │ ├── tsconfig.json │ └── package.json ├── nestjs-rest-api-auth │ ├── src │ │ ├── app │ │ │ ├── shared │ │ │ │ └── shared.module.ts │ │ │ ├── core │ │ │ │ ├── decorator │ │ │ │ │ ├── role-allowed.ts │ │ │ │ │ └── user.ts │ │ │ │ ├── middleware │ │ │ │ │ ├── log.middleware.ts │ │ │ │ │ ├── app-log.middleware.ts │ │ │ │ │ └── auth.middleware.ts │ │ │ │ ├── guard │ │ │ │ │ └── api-guard.ts │ │ │ │ └── filters │ │ │ │ │ └── index.ts │ │ │ ├── domain │ │ │ │ ├── authentication │ │ │ │ │ ├── local.auth.guard.ts │ │ │ │ │ ├── request-with.user.ts │ │ │ │ │ ├── jwt-authentication.guard.ts │ │ │ │ │ ├── local.strategy.ts │ │ │ │ │ ├── dto │ │ │ │ │ │ └── register.dto.ts │ │ │ │ │ ├── jwt.strategy.ts │ │ │ │ │ ├── auth.module.ts │ │ │ │ │ ├── auth.controller.ts │ │ │ │ │ └── auth.service.ts │ │ │ │ ├── user │ │ │ │ │ ├── user.controller.ts │ │ │ │ │ ├── user.module.ts │ │ │ │ │ ├── user.entity.ts │ │ │ │ │ ├── dto │ │ │ │ │ │ └── createUser.dto.ts │ │ │ │ │ └── user.service.ts │ │ │ │ ├── post │ │ │ │ │ └── post.module.ts │ │ │ │ └── domain.module.ts │ │ │ └── docs │ │ │ │ ├── swagger.interface.ts │ │ │ │ ├── swagger.config.ts │ │ │ │ └── swagger.ts │ │ ├── app.service.ts │ │ ├── app.controller.ts │ │ ├── app.module.ts │ │ ├── main.ts │ │ └── app.controller.spec.ts │ ├── .prettierrc │ ├── tsconfig.build.json │ ├── nest-cli.json │ ├── test │ │ ├── jest-e2e.json │ │ └── app.e2e-spec.ts │ ├── .gitignore │ ├── tsconfig.json │ └── .eslintrc.js ├── nestjs-baseline-rest-apis │ ├── src │ │ ├── app │ │ │ ├── shared │ │ │ │ └── shared.module.ts │ │ │ ├── domain │ │ │ │ ├── users │ │ │ │ │ ├── user.response.dto.ts │ │ │ │ │ ├── user.dao.service.ts │ │ │ │ │ ├── user.module.ts │ │ │ │ │ ├── user.entity.ts │ │ │ │ │ ├── user.dto.ts │ │ │ │ │ ├── user.service.ts │ │ │ │ │ └── user.controller.ts │ │ │ │ ├── auth │ │ │ │ │ ├── auth.service.ts │ │ │ │ │ └── auth.module.ts │ │ │ │ └── domain.module.ts │ │ │ ├── core │ │ │ │ ├── decorator │ │ │ │ │ ├── role-allowed.ts │ │ │ │ │ └── user.ts │ │ │ │ ├── middleware │ │ │ │ │ ├── log.middleware.ts │ │ │ │ │ ├── app-log.middleware.ts │ │ │ │ │ └── auth.middleware.ts │ │ │ │ ├── guard │ │ │ │ │ └── api-guard.ts │ │ │ │ └── filters │ │ │ │ │ └── index.ts │ │ │ └── docs │ │ │ │ ├── swagger.interface.ts │ │ │ │ ├── swagger.config.ts │ │ │ │ └── swagger.ts │ │ ├── app.service.ts │ │ ├── app.controller.ts │ │ ├── app.module.ts │ │ ├── main.ts │ │ └── app.controller.spec.ts │ ├── .prettierrc │ ├── tsconfig.build.json │ ├── nest-cli.json │ ├── test │ │ ├── jest-e2e.json │ │ └── app.e2e-spec.ts │ ├── .gitignore │ ├── tsconfig.json │ ├── .eslintrc.js │ └── package.json ├── nest-graphql-prisma │ ├── .prettierrc │ ├── nest-cli.json │ ├── prisma │ │ ├── dev.db │ │ ├── migrations │ │ │ ├── migration_lock.toml │ │ │ └── 20210731111431_init │ │ │ │ └── migration.sql │ │ └── schema.prisma │ ├── tsconfig.build.json │ ├── src │ │ ├── app.service.ts │ │ ├── main.ts │ │ ├── generate-typings.ts │ │ ├── app.controller.ts │ │ ├── posts │ │ │ ├── posts.module.ts │ │ │ ├── schema.graphql │ │ │ ├── posts.resolvers.ts │ │ │ └── posts.service.ts │ │ ├── app.module.ts │ │ ├── generate-typings.js │ │ ├── prisma.service.ts │ │ ├── app.controller.spec.ts │ │ └── graphql.ts │ ├── test │ │ ├── jest-e2e.json │ │ └── app.e2e-spec.ts │ ├── tsconfig.json │ ├── .gitignore │ ├── .eslintrc.js │ └── package.json ├── nestjs-graphql-typeorm │ ├── .prettierrc │ ├── nest-cli.json │ ├── src │ │ ├── modules │ │ │ ├── api │ │ │ │ ├── user │ │ │ │ │ ├── user.service.ts │ │ │ │ │ ├── user.controller.ts │ │ │ │ │ ├── user.module.ts │ │ │ │ │ ├── user.service.js │ │ │ │ │ └── user.module.js │ │ │ │ ├── league │ │ │ │ │ ├── league.graphql │ │ │ │ │ ├── league.module.ts │ │ │ │ │ ├── league.resolver.ts │ │ │ │ │ ├── league.service.ts │ │ │ │ │ └── league.module.js │ │ │ │ ├── pokemon │ │ │ │ │ ├── pokemon.module.ts │ │ │ │ │ ├── pokemon.graphql │ │ │ │ │ ├── pokemon.resolver.ts │ │ │ │ │ ├── pokemon.service.ts │ │ │ │ │ └── pokemon.module.js │ │ │ │ ├── api.module.ts │ │ │ │ └── api.module.js │ │ │ ├── ressources │ │ │ │ ├── pokemon.ressource.ts │ │ │ │ └── pokemon.ressource.js │ │ │ ├── entity │ │ │ │ ├── league.entity.ts │ │ │ │ ├── pokemon.entity.ts │ │ │ │ └── league.entity.js │ │ │ └── shared │ │ │ │ ├── logging.interceptor.ts │ │ │ │ └── logging.interceptor.js │ │ ├── main.ts │ │ ├── app.module.ts │ │ ├── graphql.schema.ts │ │ └── app.module.js │ ├── tsconfig.build.json │ ├── test │ │ ├── jest-e2e.json │ │ └── app.e2e-spec.ts │ ├── .env.example │ ├── schema.gpl │ ├── tsconfig.json │ ├── tslint.json │ ├── .gitignore │ └── package.json ├── express-typescript-apis │ ├── nodemon.json │ ├── src │ │ ├── router │ │ │ ├── auth.ts │ │ │ ├── index.ts │ │ │ └── users.ts │ │ ├── helpers │ │ │ └── index.ts │ │ ├── middleware │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── db │ │ │ └── users.ts │ │ └── controller │ │ │ ├── users.ts │ │ │ └── auth.ts │ ├── tsconfig.json │ └── package.json ├── express-trpc-apis │ ├── envtext.txt │ ├── src │ │ ├── database │ │ │ ├── config.ts │ │ │ └── connectionDB.ts │ │ ├── index.ts │ │ ├── Dockerfile │ │ ├── models │ │ │ └── todo.ts │ │ ├── trpc.ts │ │ ├── views │ │ │ └── index.html │ │ ├── package.json │ │ ├── app.ts │ │ ├── routes │ │ │ └── todos.ts │ │ └── README.md │ ├── Dockerfile │ ├── package.json │ └── README.md └── express-js-auth-apis │ ├── src │ ├── model │ │ └── user.js │ ├── static │ │ ├── index.html │ │ └── login.html │ └── index.js │ └── package.json ├── packages ├── app-http │ ├── src │ │ ├── http-client.decorator.ts │ │ ├── http-client.constants.ts │ │ ├── index.ts │ │ ├── http-client.provider.ts │ │ ├── http-client.interface.ts │ │ ├── http-client.service.ts │ │ └── http-client.module.ts │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json ├── app-database │ ├── src │ │ ├── index.ts │ │ ├── db.interface.ts │ │ └── db.module.ts │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json ├── app-email │ ├── src │ │ ├── index.ts │ │ ├── v1 │ │ │ ├── email.module.ts │ │ │ └── email.service.ts │ │ ├── email.interface.ts │ │ ├── email.service.ts │ │ └── email.module.ts │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json ├── app-logger │ ├── src │ │ ├── index.ts │ │ ├── logger.module.ts │ │ ├── loglevel.ts │ │ └── logger.service.ts │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json └── app-config │ ├── src │ ├── index.ts │ ├── config.module.ts │ ├── config.default.ts │ ├── config.interface.ts │ └── config.service.ts │ ├── tsconfig.json │ ├── jest.config.js │ └── package.json ├── .prettierrc ├── .eslintignore ├── commitlint.config.js ├── .husky ├── commit-msg ├── pre-commit └── prepare-commit-msg ├── pnpm-workspace.yaml ├── .gitignore ├── .prettierignore ├── jest.config.js ├── nx.json ├── README.md ├── docker-compose.yml ├── docker-utils ├── docker-entrypoint.sh └── entrypoint │ └── init.sh ├── .eslintrc └── package.json /apps/express-typescript-mongo-apis/env.example: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.decorator.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/post/post.service.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/user/user.service.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.response.dto.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": false, 3 | "trailingComma": "es5" 4 | } 5 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /**/build 3 | **/.next/ 4 | dist 5 | build 6 | ./**/.next -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ["@commitlint/config-conventional"] }; 2 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /packages/app-database/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./db.interface"; 2 | export * from "./db.module"; 3 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx --no-install commitlint --edit $1 -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "collection": "@nestjs/schematics", 3 | "sourceRoot": "src" 4 | } 5 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ext": ".ts,.js", 4 | "exec": "ts-node ./src/index.ts" 5 | } -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: "ts-jest", 3 | testEnvironment: "node", 4 | }; 5 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src"], 3 | "ext": ".ts,.js", 4 | "exec": "ts-node ./src/server.ts" 5 | } -------------------------------------------------------------------------------- /packages/app-email/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./email.interface"; 2 | export * from "./email.module"; 3 | export * from "./email.service"; 4 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/prisma/dev.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkssharma/nodejs-microservices-2023/HEAD/apps/nest-graphql-prisma/prisma/dev.db -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "language": "ts", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src" 5 | } 6 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | if [ "$NO_VERIFY_YOLO" ]; then exit 0; fi 5 | npm run lint && npm run prettier 6 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.dao.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | export class UserDaoService {} 4 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/user/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class UserService {} 5 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/envtext.txt: -------------------------------------------------------------------------------- 1 | PORT=3000 2 | MONGODB_CONNECTION_STRING=mongodb+srv://username:password@usercluster.bwa3z.mongodb.net/dotodb?retryWrites=true&w=majority -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | # all packages in direct subdirs of packages/ 3 | - "packages/*" 4 | # all packages in subdirs of components/ 5 | - "apps/*" 6 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/ressources/pokemon.ressource.ts: -------------------------------------------------------------------------------- 1 | export class CreatePokemonDto { 2 | name: string; 3 | type: string; 4 | pokedex: number; 5 | } 6 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/interfaces/token.interface.ts: -------------------------------------------------------------------------------- 1 | interface TokenData { 2 | token: string; 3 | expiresIn: number; 4 | } 5 | 6 | export default TokenData; 7 | -------------------------------------------------------------------------------- /packages/app-database/src/db.interface.ts: -------------------------------------------------------------------------------- 1 | import { ConnectionOptions } from "typeorm"; 2 | 3 | export interface DbConfig { 4 | entities: ConnectionOptions["entities"]; 5 | } 6 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.constants.ts: -------------------------------------------------------------------------------- 1 | export const HTTP_CLIENT_MODULE_OPTIONS = "HTTP_CLIENT_MODULE_OPTIONS"; 2 | export const HTTP_CLIENT_TOKEN = "HTTP_CLIENT_TOKEN"; 3 | -------------------------------------------------------------------------------- /packages/app-logger/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./logger.module"; 2 | export * from "./logger.service"; 3 | export * from "./logger.middleware"; 4 | export * from "./loglevel"; 5 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/post/post.interface.ts: -------------------------------------------------------------------------------- 1 | interface Post { 2 | authorId: string; 3 | content: string; 4 | title: string; 5 | } 6 | 7 | export default Post; 8 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts", "./src/graphql.schema.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/app-config/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./config.module"; 2 | export * from "./config.service"; 3 | export * from "./config.interface"; 4 | export * from "./config.default"; 5 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "sqlite" -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/decorator/role-allowed.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | 3 | export const RoleAllowed = (...roles: string[]) => SetMetadata('roles', roles); 4 | -------------------------------------------------------------------------------- /.husky/prepare-commit-msg: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | if [ "$NO_VERIFY" ] || [ "$NO_VERIFY_YOLO" ]; then exit 0; fi 5 | exec < /dev/tty && node_modules/.bin/cz --hook || true 6 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/decorator/role-allowed.ts: -------------------------------------------------------------------------------- 1 | import { SetMetadata } from '@nestjs/common'; 2 | 3 | export const RoleAllowed = (...roles: string[]) => SetMetadata('roles', roles); 4 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/interfaces/controller.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | 3 | interface Controller { 4 | path: string; 5 | router: Router; 6 | } 7 | 8 | export default Controller; 9 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/app-http/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./http-client.module"; 2 | export * from "./http-client.service"; 3 | export * from "./http-client.interface"; 4 | export * from "./http-client.provider"; 5 | export * from "./http-client.constants"; 6 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/interfaces/req.user.ts: -------------------------------------------------------------------------------- 1 | import User from "user/user.interface"; 2 | import { Request } from "express"; 3 | 4 | interface RequestWithUser extends Request { 5 | user: User; 6 | } 7 | 8 | export default RequestWithUser; 9 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/local.auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class LocalAuthGuard extends AuthGuard('local') {} 6 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule); 6 | await app.listen(3000); 7 | } 8 | bootstrap(); 9 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/test/jest-e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "moduleFileExtensions": ["js", "json", "ts"], 3 | "rootDir": ".", 4 | "testEnvironment": "node", 5 | "testRegex": ".e2e-spec.ts$", 6 | "transform": { 7 | "^.+\\.(t|j)s$": "ts-jest" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/request-with.user.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import User from '../user/user.entity'; 3 | 4 | interface RequestWithUser extends Request { 5 | user: User; 6 | } 7 | 8 | export default RequestWithUser; 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | .vercel 10 | .output 11 | /packages/**/build 12 | /packages/**/dist 13 | /apps/**/build 14 | /apps/**/dist 15 | /infra/**/build 16 | /infra/**/dist 17 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/jwt-authentication.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export default class JwtAuthenticationGuard extends AuthGuard('jwt') {} 6 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/docs/swagger.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Specifies configuration for the swagger UI (found at /api). 3 | */ 4 | export interface SwaggerConfig { 5 | title: string; 6 | description: string; 7 | version: string; 8 | tags: string[]; 9 | } 10 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/authentication/logIn.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString } from "class-validator"; 2 | 3 | class LogInDto { 4 | @IsString() 5 | public email: string; 6 | 7 | @IsString() 8 | public password: string; 9 | } 10 | 11 | export default LogInDto; 12 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/post/post.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString } from "class-validator"; 2 | 3 | class CreatePostDto { 4 | @IsString() 5 | public content: string; 6 | 7 | @IsString() 8 | public title: string; 9 | } 10 | 11 | export default CreatePostDto; 12 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/docs/swagger.interface.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Specifies configuration for the swagger UI (found at /api). 3 | */ 4 | export interface SwaggerConfig { 5 | title: string; 6 | description: string; 7 | version: string; 8 | tags: string[]; 9 | } 10 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/router/auth.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | import { login, register } from "../controller/auth"; 4 | 5 | export default (router: express.Router) => { 6 | router.post("/auth/register", register); 7 | router.post("/auth/login", login); 8 | }; 9 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/user/user.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller } from '@nestjs/common'; 2 | import { UserService } from './user.service'; 3 | 4 | @Controller('users') 5 | export class UserController { 6 | constructor(private readonly userService: UserService) {} 7 | } 8 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/post/post.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | @Module({ 4 | imports: [], 5 | providers: [], 6 | exports: [], 7 | controllers: [], 8 | }) 9 | export class PostModule {} 10 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/database/config.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config(); 3 | 4 | console.log(process.env.PORT); 5 | 6 | export const APP_PORT = parseInt(process.env.PORT || "") || 3000; 7 | export const MONGODB_URI = 8 | process.env.MONGODB_CONNECTION_STRING || "mongodb://localhost:27017"; 9 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/auth.token.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class AuthTokenMissing extends HttpException { 4 | constructor() { 5 | super(401, `auth token missing in cookies`); 6 | } 7 | } 8 | 9 | export default AuthTokenMissing; 10 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/router/index.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | import auth from "./auth"; 4 | import users from "./users"; 5 | 6 | const router = express.Router(); 7 | 8 | export default (): express.Router => { 9 | auth(router); 10 | users(router); 11 | return router; 12 | }; 13 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/post.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class PostNotFoundException extends HttpException { 4 | constructor(id: string) { 5 | super(404, `post not found for id ${id}`); 6 | } 7 | } 8 | 9 | export default PostNotFoundException; 10 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/user.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class UserNotFoundException extends HttpException { 4 | constructor(id: string) { 5 | super(404, `User with id ${id} not found`); 6 | } 7 | } 8 | 9 | export default UserNotFoundException; 10 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/index.ts: -------------------------------------------------------------------------------- 1 | import app from "./app"; 2 | import { dbConnect } from "./database/connectionDB"; 3 | import { APP_PORT } from "./database/config"; 4 | 5 | // console.log(process.env) 6 | dbConnect(); 7 | app.listen(APP_PORT as number); 8 | console.log("Server running on http://localhost:" + APP_PORT + "/"); 9 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/user/user.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Req, Res } from '@nestjs/common'; 2 | 3 | @Controller('users') 4 | export class UserController { 5 | @Get() 6 | async index(@Req() req, @Res() res) { 7 | res.send({ 8 | hello: 'world', 9 | }); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/user.acces.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class UnauthorizedException extends HttpException { 4 | constructor(id: string) { 5 | super(401, `User with id ${id} not found`); 6 | } 7 | } 8 | 9 | export default UnauthorizedException; 10 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/wrong.credentials.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class WrongCredentialsException extends HttpException { 4 | constructor() { 5 | super(401, "Wrong credentials provided"); 6 | } 7 | } 8 | 9 | export default WrongCredentialsException; 10 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/user/user.interface.ts: -------------------------------------------------------------------------------- 1 | interface User { 2 | _id: string; 3 | firstName: string; 4 | lastName: string; 5 | fullName: string; 6 | email: string; 7 | password: string; 8 | address?: { 9 | street: string; 10 | city: string; 11 | }; 12 | } 13 | 14 | export default User; 15 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/ressources/pokemon.ressource.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.__esModule = true; 3 | exports.CreatePokemonDto = void 0; 4 | var CreatePokemonDto = /** @class */ (function () { 5 | function CreatePokemonDto() {} 6 | return CreatePokemonDto; 7 | })(); 8 | exports.CreatePokemonDto = CreatePokemonDto; 9 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/.env.example: -------------------------------------------------------------------------------- 1 | # APP 2 | APP_ENV=dev 3 | APP_URL=http://127.0.0.1 4 | APP_PORT=3000 5 | NEW_RELIC_KEY= 6 | DATABASE_URL=postgres://api:development_pass@localhost:5432/test-api 7 | 8 | SWAGGER_USERNAME=hello 9 | SWAGGER_PASSWORD=hello 10 | LOG_LEVEL=http 11 | 12 | AUTH_TOKEN_EXPIRY=300 13 | AUTH_SECRET=XXXXXXXXX -------------------------------------------------------------------------------- /apps/express-typescript-apis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module":"NodeNext", 4 | "moduleResolution": "node", 5 | "baseUrl": "src", 6 | "outDir": "dist", 7 | "sourceMap": true, 8 | "noImplicitAny": true 9 | }, 10 | "include": ["src/**/*"], 11 | "exclude": ["dist","node_modules","tests"] 12 | } -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { UserController } from './user.controller'; 3 | import { UserService } from './user.service'; 4 | 5 | @Module({ 6 | controllers: [UserController], 7 | providers: [UserService], 8 | }) 9 | export class UserModule {} 10 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Custom 2 | /packages/*/build/** 3 | /packages/*/coverage/** 4 | /node_modules/** 5 | package-lock.json 6 | ./package.json 7 | tmp 8 | dist 9 | */dist 10 | ./**/.next 11 | 12 | *.yml 13 | *.json 14 | *.next 15 | /packages/**/build 16 | /packages/**/dist 17 | /apps/**/build 18 | /apps/**/dist 19 | /infra/**/build 20 | /infra/**/dist -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/auth.access-token.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class WrongAuthTokenPassedException extends HttpException { 4 | constructor() { 5 | super(404, `wrong auth token -passed in cookies`); 6 | } 7 | } 8 | 9 | export default WrongAuthTokenPassedException; 10 | -------------------------------------------------------------------------------- /apps/express-js-auth-apis/src/model/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const UserSchema = new mongoose.Schema({ 4 | username: { type: String, required: true, unique: true }, 5 | password: { type: String, required: true }, 6 | }); 7 | 8 | const model = mongoose.model("UserSchema", UserSchema); 9 | 10 | module.exports = model; 11 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/user.login.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class InavlidCredsPassedException extends HttpException { 4 | constructor(email: string) { 5 | super(404, `User with provided Creds doesn't exists`); 6 | } 7 | } 8 | 9 | export default InavlidCredsPassedException; 10 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/prisma/migrations/20210731111431_init/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "Post" ( 3 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 4 | "title" TEXT NOT NULL, 5 | "content" TEXT NOT NULL, 6 | "published" BOOLEAN NOT NULL DEFAULT false, 7 | "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP 8 | ); 9 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18 2 | 3 | WORKDIR /usr/src/app 4 | 5 | COPY package*.json ./ 6 | COPY tsconfig.json ./ 7 | 8 | COPY src ./src 9 | 10 | RUN npm install 11 | 12 | EXPOSE 3000 13 | 14 | 15 | COPY client ./trpc-client 16 | 17 | RUN npm install --prefix client 18 | 19 | 20 | RUN npm run build:all 21 | 22 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/http.exception.ts: -------------------------------------------------------------------------------- 1 | class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | constructor(status: number, message: string) { 5 | super(message); 6 | this.status = status; 7 | this.message = message; 8 | } 9 | } 10 | 11 | export default HttpException; 12 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/generate-typings.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLDefinitionsFactory } from '@nestjs/graphql'; 2 | import { join } from 'path'; 3 | const definitionsFactory = new GraphQLDefinitionsFactory(); 4 | definitionsFactory.generate({ 5 | typePaths: ['./src/**/*.graphql'], 6 | path: join(process.cwd(), 'src/graphql.ts'), 7 | outputAs: 'class', 8 | }); 9 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18 2 | 3 | WORKDIR /usr/src/app 4 | 5 | COPY package*.json ./ 6 | COPY tsconfig.json ./ 7 | 8 | COPY src ./src 9 | 10 | RUN npm install 11 | 12 | EXPOSE 3000 13 | 14 | 15 | COPY client ./trpc-client 16 | 17 | RUN npm install --prefix client 18 | 19 | 20 | RUN npm run build:all 21 | 22 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /packages/app-email/src/v1/email.module.ts: -------------------------------------------------------------------------------- 1 | import { ConfigModule } from "@dev/config"; 2 | import { Module } from "@nestjs/common"; 3 | import { EmailService } from "./email.service"; 4 | 5 | @Module({ 6 | imports: [ConfigModule], 7 | controllers: [], 8 | providers: [EmailService], 9 | exports: [EmailService], 10 | }) 11 | export class EmailModule {} 12 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/posts/posts.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PostResolvers } from './posts.resolvers'; 3 | import { PostService } from './posts.service'; 4 | import { PrismaService } from 'src/prisma.service'; 5 | 6 | @Module({ 7 | providers: [PostResolvers, PostService, PrismaService], 8 | }) 9 | export class PostModule {} 10 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/exceptions/user.register.exception.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "./http.exception"; 2 | 3 | class UserWithThatEmailAlreadyExistsException extends HttpException { 4 | constructor(email: string) { 5 | super(404, `User with provided email already exists`); 6 | } 7 | } 8 | 9 | export default UserWithThatEmailAlreadyExistsException; 10 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable, forwardRef } from '@nestjs/common'; 2 | import { UserService } from '../users/user.service'; 3 | 4 | @Injectable() 5 | export class AuthService { 6 | constructor( 7 | @Inject(forwardRef(() => UserService)) 8 | private readonly userService: UserService, 9 | ) {} 10 | } 11 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller('') 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get('health') 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { GraphQLModule } from '@nestjs/graphql'; 3 | import { PostModule } from './posts/posts.module'; 4 | 5 | @Module({ 6 | imports: [ 7 | PostModule, 8 | GraphQLModule.forRoot({ 9 | typePaths: ['./**/*.graphql'], 10 | }), 11 | ], 12 | }) 13 | export class AppModule {} 14 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller('') 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get('health') 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/decorator/user.ts: -------------------------------------------------------------------------------- 1 | import { createParamDecorator, ExecutionContext } from '@nestjs/common'; 2 | 3 | export const User = createParamDecorator( 4 | (data: string, ctx: ExecutionContext) => { 5 | const request = ctx.switchToHttp().getRequest(); 6 | const user = request.user; 7 | return data ? user?.[data] : user; 8 | }, 9 | ); 10 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/decorator/user.ts: -------------------------------------------------------------------------------- 1 | import { createParamDecorator, ExecutionContext } from '@nestjs/common'; 2 | 3 | export const User = createParamDecorator( 4 | (data: string, ctx: ExecutionContext) => { 5 | const request = ctx.switchToHttp().getRequest(); 6 | const user = request.user; 7 | return data ? user?.[data] : user; 8 | }, 9 | ); 10 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/docs/swagger.config.ts: -------------------------------------------------------------------------------- 1 | import { SwaggerConfig } from './swagger.interface'; 2 | 3 | /** 4 | * Configuration for the swagger UI (found at /api). 5 | * Change this to suit your app! 6 | */ 7 | export const SWAGGER_CONFIG: SwaggerConfig = { 8 | title: 'user service', 9 | description: ' api specs', 10 | version: '1.0', 11 | tags: [], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/docs/swagger.config.ts: -------------------------------------------------------------------------------- 1 | import { SwaggerConfig } from './swagger.interface'; 2 | 3 | /** 4 | * Configuration for the swagger UI (found at /api). 5 | * Change this to suit your app! 6 | */ 7 | export const SWAGGER_CONFIG: SwaggerConfig = { 8 | title: 'user service', 9 | description: ' api specs', 10 | version: '1.0', 11 | tags: [], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/middleware/log.middleware.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NestMiddleware } from '@nestjs/common'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | @Injectable() 5 | export class LoggerMiddleware implements NestMiddleware { 6 | use(req: Request, res: Response, next: NextFunction) { 7 | console.log('Request...'); 8 | next(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/middleware/log.middleware.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NestMiddleware } from '@nestjs/common'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | @Injectable() 5 | export class LoggerMiddleware implements NestMiddleware { 6 | use(req: Request, res: Response, next: NextFunction) { 7 | console.log('Request...'); 8 | next(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/league/league.graphql: -------------------------------------------------------------------------------- 1 | type League{ 2 | id: ID! 3 | name:String! 4 | pokemons: [Pokemon!] 5 | } 6 | 7 | type Query{ 8 | leagues: [League!] 9 | league(id: ID): League! 10 | } 11 | 12 | type Mutation { 13 | createLeague(name: String!): League 14 | updateLeague(id: ID, name: String!): League 15 | deleteLeague(id: ID): Deleted 16 | } 17 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { DomainModule } from './app/domain/domain.module'; 5 | 6 | @Module({ 7 | imports: [DomainModule], 8 | controllers: [AppController], 9 | providers: [AppService], 10 | }) 11 | export class AppModule {} 12 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/generate-typings.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | exports.__esModule = true; 3 | var graphql_1 = require('@nestjs/graphql'); 4 | var path_1 = require('path'); 5 | var definitionsFactory = new graphql_1.GraphQLDefinitionsFactory(); 6 | definitionsFactory.generate({ 7 | typePaths: ['./src/**/*.graphql'], 8 | path: path_1.join(process.cwd(), 'src/graphql.ts'), 9 | outputAs: 'class', 10 | }); 11 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { DomainModule } from './app/domain/domain.module'; 5 | 6 | @Module({ 7 | imports: [DomainModule], 8 | controllers: [AppController], 9 | providers: [AppService], 10 | }) 11 | export class AppModule {} 12 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/helpers/index.ts: -------------------------------------------------------------------------------- 1 | import crypto from "crypto"; 2 | 3 | const secret = process.env.PASSWORD_SECRET || ""; 4 | 5 | export const authentication = (salt: string, password: string): string => { 6 | return crypto 7 | .createHmac("sha256", [salt, password].join("/")) 8 | .update(secret) 9 | .digest("hex"); 10 | }; 11 | 12 | export const random = () => crypto.randomBytes(128).toString("base64"); 13 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/schema.gpl: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------- 2 | # !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!! 3 | # !!! DO NOT MODIFY THIS FILE BY YOURSELF !!! 4 | # ----------------------------------------------- 5 | 6 | type CreatePokemonDto { 7 | id: String! 8 | name: String! 9 | type: String! 10 | pokedex: Float! 11 | } 12 | 13 | type Query { 14 | pokemon: [CreatePokemonDto!]! 15 | } 16 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | 4 | module.exports = { 5 | testEnvironment: "node", 6 | restoreMocks: true, 7 | collectCoverageFrom: ["**/*.(t|j)s"], 8 | coverageDirectory: "../coverage", 9 | transform: { 10 | "^.+\\.ts$": "ts-jest", 11 | }, 12 | moduleFileExtensions: ["ts", "js", "json", "node"], 13 | }; 14 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/server.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import App from "./app"; 3 | import AuthenticationController from "./authentication/auth.controller"; 4 | import PostController from "./post/post.controller"; 5 | import UserController from "./user/user.controller"; 6 | 7 | const app = new App([ 8 | new AuthenticationController(), 9 | new PostController(), 10 | new UserController(), 11 | ]); 12 | 13 | app.listen(); 14 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/post/post.model.ts: -------------------------------------------------------------------------------- 1 | import * as mongoose from "mongoose"; 2 | import Post from "./post.interface"; 3 | 4 | const postSchema = new mongoose.Schema({ 5 | author: { 6 | ref: "User", 7 | type: mongoose.Schema.Types.ObjectId, 8 | }, 9 | content: String, 10 | title: String, 11 | }); 12 | 13 | const postModel = mongoose.model("Post", postSchema); 14 | 15 | export default postModel; 16 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/main.ts: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | import { NestFactory } from '@nestjs/core'; 4 | import { AppModule } from './app.module'; 5 | import { Logger } from '@nestjs/common'; 6 | 7 | async function bootstrap() { 8 | const app = await NestFactory.create(AppModule); 9 | await app.listen(process.env.PORT || 3000); 10 | Logger.log(`Server start ${process.env.PORT || 3000}`, 'Bootstap'); 11 | } 12 | 13 | bootstrap(); 14 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module, forwardRef } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import { AuthService } from './auth.service'; 4 | import { UserModule } from '../users/user.module'; 5 | 6 | @Module({ 7 | imports: [forwardRef(() => UserModule)], 8 | controllers: [], 9 | providers: [AuthService], 10 | exports: [AuthService], 11 | }) 12 | export class AuthModule {} 13 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/router/users.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | import { getAllAPIUsers, deleteUsers, updateUsers } from "../controller/users"; 4 | import { isAuthenticated } from "../middleware"; 5 | 6 | export default (router: express.Router) => { 7 | router.get("/users", isAuthenticated, getAllAPIUsers); 8 | router.delete("/users/:id", isAuthenticated, deleteUsers); 9 | router.patch("/users/:id", isAuthenticated, updateUsers); 10 | }; 11 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "nx/presets/npm.json", 3 | "$schema": "./node_modules/nx/schemas/nx-schema.json", 4 | "tasksRunnerOptions": { 5 | "default": { 6 | "runner": "nx/tasks-runners/default", 7 | "options": { 8 | "cacheableOperations": [ 9 | "lint", 10 | "test", 11 | "e2e" 12 | ] 13 | } 14 | } 15 | }, 16 | "targetDefaults": { 17 | "build": { 18 | "dependsOn": ["^build"] 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "sourceMap": true, 4 | "target": "es2017", 5 | "outDir": "./dist", 6 | "baseUrl": "./src", 7 | "moduleResolution": "nodenext", 8 | "alwaysStrict": true, 9 | "noImplicitAny": true, 10 | "experimentalDecorators": true, 11 | "emitDecoratorMetadata": true 12 | }, 13 | "include": [ 14 | "src/**/*.ts" 15 | ], 16 | "exclude": [ 17 | "node_modules" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## How To Use 2 | 3 | To clone and run this application, you'll need [Git](https://git-scm.com) and [Node.js](https://nodejs.org/en/download/) (which comes with [npm](http://npmjs.com)) installed on your computer. From your command line: 4 | 5 | ```bash 6 | # Clone this repository 7 | $ git clone git@github.com:tkssharma/nodejs-microservices-2023.git 8 | 9 | # Go into the repository 10 | $ cd nodejs-microservices-2023 11 | 12 | # Install dependencies 13 | $ pnpm i 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/league/league.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { LeagueResolver } from './league.resolver'; 3 | import { LeagueService } from './league.service'; 4 | import { TypeOrmModule } from '@nestjs/typeorm'; 5 | import { LeagueEntity } from '../../entity/league.entity'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([LeagueEntity])], 9 | providers: [LeagueResolver, LeagueService], 10 | }) 11 | export class LeagueModule {} 12 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "esModuleInterop": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "dist" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import User from './user.entity'; 4 | import { UserService } from './user.service'; 5 | import { UserController } from './user.controller'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([User])], 9 | providers: [UserService], 10 | exports: [UserService], 11 | controllers: [UserController], 12 | }) 13 | export class UserModule {} 14 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/prisma.service.ts: -------------------------------------------------------------------------------- 1 | import { INestApplication, Injectable, OnModuleInit } from '@nestjs/common'; 2 | import { PrismaClient } from '@prisma/client'; 3 | 4 | @Injectable() 5 | export class PrismaService extends PrismaClient implements OnModuleInit { 6 | async onModuleInit() { 7 | await this.$connect(); 8 | } 9 | 10 | async enableShutdownHooks(app: INestApplication) { 11 | this.$on('beforeExit', async () => { 12 | await app.close(); 13 | }); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/app-config/src/config.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { ConfigService } from "./config.service"; 3 | 4 | const configFactory = { 5 | provide: ConfigService, 6 | useFactory: () => { 7 | const config = new ConfigService(); 8 | config.loadFromEnv(); 9 | return config; 10 | }, 11 | }; 12 | 13 | @Module({ 14 | imports: [], 15 | controllers: [], 16 | providers: [configFactory], 17 | exports: [configFactory], 18 | }) 19 | export class ConfigModule {} 20 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/pokemon/pokemon.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PokemonService } from './pokemon.service'; 3 | import { TypeOrmModule } from '@nestjs/typeorm'; 4 | import { PokemonEntity } from '../../entity/pokemon.entity'; 5 | import { PokemonResolver } from './pokemon.resolver'; 6 | 7 | @Module({ 8 | imports: [TypeOrmModule.forFeature([PokemonEntity])], 9 | providers: [PokemonService, PokemonResolver], 10 | }) 11 | export class PokemonModule {} 12 | -------------------------------------------------------------------------------- /apps/express-js-auth-apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/expres-auth-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node src/index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "bcryptjs": "^2.4.3", 14 | "body-parser": "^1.20.2", 15 | "dotenv": "^16.0.3", 16 | "express": "^4.18.2", 17 | "jsonwebtoken": "^9.0.0", 18 | "mongoose": "^7.1.1" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/database/connectionDB.ts: -------------------------------------------------------------------------------- 1 | import { MONGODB_URI } from "./config"; 2 | import mongoose from "mongoose"; 3 | 4 | export const dbConnect = async () => { 5 | try { 6 | mongoose.set("strictQuery", false); 7 | const db = await mongoose.connect(MONGODB_URI); 8 | console.log("Database connected to ", db.connection.db.databaseName); 9 | } catch (error) { 10 | if (error instanceof Error) { 11 | console.error(error.message); 12 | process.exit(1); 13 | } 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | datasource db { 5 | provider = "sqlite" 6 | url = env("DATABASE_URL") 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | model Post { 14 | id Int @id @default(autoincrement()) 15 | title String 16 | content String 17 | published Boolean @default(false) 18 | createdAt DateTime @default(now()) 19 | } 20 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "jsRules": { 5 | "no-unused-expression": true 6 | }, 7 | "rules": { 8 | "quotemark": [true, "single"], 9 | "member-access": [false], 10 | "ordered-imports": [false], 11 | "max-line-length": [true, 150], 12 | "member-ordering": [false], 13 | "interface-name": [false], 14 | "arrow-parens": false, 15 | "object-literal-sort-keys": false 16 | }, 17 | "rulesDirectory": [] 18 | } 19 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/middleware/app-log.middleware.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Logger, NestMiddleware } from '@nestjs/common'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | @Injectable() 5 | export class AppLoggerMiddleware implements NestMiddleware { 6 | private logger = new Logger(`HTTP`); 7 | use(req: Request, res: Response, next: NextFunction) { 8 | this.logger.log( 9 | `Logging HTTP request ${req.method} ${req.url} ${res.statusCode}`, 10 | ); 11 | next(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/middleware/app-log.middleware.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Logger, NestMiddleware } from '@nestjs/common'; 2 | import { Request, Response, NextFunction } from 'express'; 3 | 4 | @Injectable() 5 | export class AppLoggerMiddleware implements NestMiddleware { 6 | private logger = new Logger(`HTTP`); 7 | use(req: Request, res: Response, next: NextFunction) { 8 | this.logger.log( 9 | `Logging HTTP request ${req.method} ${req.url} ${res.statusCode}`, 10 | ); 11 | next(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /packages/app-email/src/email.interface.ts: -------------------------------------------------------------------------------- 1 | import { ModuleMetadata } from "@nestjs/common"; 2 | import { FactoryProvider } from "@nestjs/common/interfaces/modules/provider.interface"; 3 | 4 | export const EMAIL_CONFIG_OPTIONS = "EMAIL_CONFIG_OPTIONS"; 5 | 6 | export interface EmailOptions { 7 | service: string; 8 | user: string; 9 | pass: string; 10 | } 11 | 12 | type EmailAsyncOptions = Pick & 13 | Pick, "useFactory" | "inject">; 14 | 15 | export default EmailAsyncOptions; 16 | -------------------------------------------------------------------------------- /packages/app-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ESNext"], 5 | "downlevelIteration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "declaration": true, 9 | "strict": true, 10 | "pretty": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "experimentalDecorators": true, 15 | "outDir": "./build", 16 | "rootDir": "./src" 17 | }, 18 | "exclude": ["node_modules", "build"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-email/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ESNext"], 5 | "downlevelIteration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "declaration": true, 9 | "strict": true, 10 | "pretty": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "experimentalDecorators": true, 15 | "outDir": "./build", 16 | "rootDir": "./src" 17 | }, 18 | "exclude": ["node_modules", "build"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-http/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ESNext"], 5 | "downlevelIteration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "declaration": true, 9 | "strict": true, 10 | "pretty": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "experimentalDecorators": true, 15 | "outDir": "./build", 16 | "rootDir": "./src" 17 | }, 18 | "exclude": ["node_modules", "build"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-logger/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ESNext"], 5 | "downlevelIteration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "declaration": true, 9 | "strict": true, 10 | "pretty": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "experimentalDecorators": true, 15 | "outDir": "./build", 16 | "rootDir": "./src" 17 | }, 18 | "exclude": ["node_modules", "build"] 19 | } 20 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | services: 3 | mongo: 4 | container_name: mongo 5 | image: mongo 6 | ports: 7 | - 27017:27017 8 | postgres-user: 9 | image: postgres 10 | environment: 11 | - POSTGRES_USER=api 12 | - POSTGRES_PASSWORD=development_pass 13 | - POSTGRES_MULTIPLE_DATABASES="test-api","test-api-testing" 14 | volumes: 15 | - ./docker-utils:/docker-entrypoint-initdb.d 16 | - test_api_data:/data/postgres 17 | ports: 18 | - 5432:5432 19 | volumes: 20 | test_api_data: {} -------------------------------------------------------------------------------- /packages/app-database/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "lib": ["ESNext"], 5 | "downlevelIteration": true, 6 | "importHelpers": true, 7 | "module": "commonjs", 8 | "declaration": true, 9 | "strict": true, 10 | "pretty": true, 11 | "noImplicitReturns": true, 12 | "noUnusedLocals": true, 13 | "noUnusedParameters": true, 14 | "experimentalDecorators": true, 15 | "outDir": "./build", 16 | "rootDir": "./src" 17 | }, 18 | "exclude": ["node_modules", "build"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/app-email/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | const base = require("../../jest.config.js"); 4 | 5 | module.exports = { 6 | ...base, 7 | rootDir: "./build", 8 | name: "drivers", 9 | displayName: "@cdc3/drivers", 10 | collectCoverage: true, 11 | verbose: true, 12 | coverageThreshold: { 13 | global: { 14 | statements: 5, 15 | branches: 5, 16 | functions: 5, 17 | lines: 5, 18 | }, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/app-http/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | const base = require("../../jest.config.js"); 4 | 5 | module.exports = { 6 | ...base, 7 | rootDir: "./build", 8 | name: "drivers", 9 | displayName: "@cdc3/drivers", 10 | collectCoverage: true, 11 | verbose: true, 12 | coverageThreshold: { 13 | global: { 14 | statements: 5, 15 | branches: 5, 16 | functions: 5, 17 | lines: 5, 18 | }, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/app-logger/src/logger.module.ts: -------------------------------------------------------------------------------- 1 | import { MiddlewareConsumer, Module, NestModule } from "@nestjs/common"; 2 | 3 | import { MyLoggerService } from "./logger.service"; 4 | import { LoggerMiddleware } from "./logger.middleware"; 5 | 6 | @Module({ 7 | imports: [], 8 | controllers: [], 9 | providers: [MyLoggerService], 10 | exports: [MyLoggerService], 11 | }) 12 | export class AppLoggerModule implements NestModule { 13 | public configure(consumer: MiddlewareConsumer) { 14 | consumer.apply(LoggerMiddleware).forRoutes("*"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/pokemon/pokemon.graphql: -------------------------------------------------------------------------------- 1 | type Pokemon{ 2 | id: String! 3 | name:String! 4 | pokedex: String! 5 | type: String! 6 | league: League! 7 | } 8 | type Query{ 9 | pokemons: [Pokemon!] 10 | pokemon(id: ID): Pokemon! 11 | } 12 | 13 | type Deleted{ 14 | delete: Boolean! 15 | } 16 | 17 | type Mutation { 18 | create(name: String!, type: String!, pokedex: String!): Pokemon 19 | update(id: ID!, name: String!, type: String!, pokedex: String!): Pokemon 20 | delete(id: ID!): Deleted 21 | } 22 | -------------------------------------------------------------------------------- /packages/app-config/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | const base = require("../../jest.config.js"); 4 | 5 | module.exports = { 6 | ...base, 7 | rootDir: "./build", 8 | name: "drivers", 9 | displayName: "@cdc3/drivers", 10 | collectCoverage: true, 11 | verbose: true, 12 | coverageThreshold: { 13 | global: { 14 | statements: 5, 15 | branches: 5, 16 | functions: 5, 17 | lines: 5, 18 | }, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/app-database/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | const base = require("../../jest.config.js"); 4 | 5 | module.exports = { 6 | ...base, 7 | rootDir: "./build", 8 | name: "drivers", 9 | displayName: "@cdc3/drivers", 10 | collectCoverage: true, 11 | verbose: true, 12 | coverageThreshold: { 13 | global: { 14 | statements: 5, 15 | branches: 5, 16 | functions: 5, 17 | lines: 5, 18 | }, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /packages/app-logger/jest.config.js: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | const base = require("../../jest.config.js"); 4 | 5 | module.exports = { 6 | ...base, 7 | rootDir: "./build", 8 | name: "drivers", 9 | displayName: "@cdc3/drivers", 10 | collectCoverage: true, 11 | verbose: true, 12 | coverageThreshold: { 13 | global: { 14 | statements: 5, 15 | branches: 5, 16 | functions: 5, 17 | lines: 5, 18 | }, 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/middleware/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import HttpException from "exceptions/http.exception"; 2 | import { NextFunction, Request, Response } from "express"; 3 | 4 | function errorMiddleware( 5 | error: HttpException, 6 | request: Request, 7 | response: Response, 8 | next: NextFunction 9 | ) { 10 | const status = error.status || 500; 11 | const message = error.message || "something wrong "; 12 | response.status(status).send({ 13 | message, 14 | status, 15 | }); 16 | } 17 | 18 | export default errorMiddleware; 19 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/entity/league.entity.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Entity, 3 | PrimaryGeneratedColumn, 4 | Column, 5 | BaseEntity, 6 | OneToMany, 7 | } from 'typeorm'; 8 | import { PokemonEntity } from './pokemon.entity'; 9 | 10 | @Entity('league') 11 | export class LeagueEntity extends BaseEntity { 12 | @PrimaryGeneratedColumn('uuid') id: string; 13 | 14 | @Column('varchar', { length: 500, unique: true }) 15 | name: string; 16 | 17 | @OneToMany((type) => PokemonEntity, (pokemon) => pokemon.league) 18 | pokemons: PokemonEntity[]; 19 | } 20 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | pnpm-debug.log* 10 | yarn-debug.log* 11 | yarn-error.log* 12 | lerna-debug.log* 13 | 14 | # OS 15 | .DS_Store 16 | 17 | # Tests 18 | /coverage 19 | /.nyc_output 20 | 21 | # IDEs and editors 22 | /.idea 23 | .project 24 | .classpath 25 | .c9/ 26 | *.launch 27 | .settings/ 28 | *.sublime-workspace 29 | 30 | # IDE - VSCode 31 | .vscode/* 32 | !.vscode/settings.json 33 | !.vscode/tasks.json 34 | !.vscode/launch.json 35 | !.vscode/extensions.json -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | .env 6 | 7 | # Logs 8 | logs 9 | *.log 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | lerna-debug.log* 14 | 15 | # OS 16 | .DS_Store 17 | 18 | # Tests 19 | /coverage 20 | /.nyc_output 21 | 22 | # IDEs and editors 23 | /.idea 24 | .project 25 | .classpath 26 | .c9/ 27 | *.launch 28 | .settings/ 29 | *.sublime-workspace 30 | 31 | # IDE - VSCode 32 | .vscode/* 33 | !.vscode/settings.json 34 | !.vscode/tasks.json 35 | !.vscode/launch.json 36 | !.vscode/extensions.json 37 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | 5 | # Logs 6 | logs 7 | *.log 8 | npm-debug.log* 9 | yarn-debug.log* 10 | yarn-error.log* 11 | lerna-debug.log* 12 | 13 | # OS 14 | .DS_Store 15 | 16 | # Tests 17 | /coverage 18 | /.nyc_output 19 | 20 | # IDEs and editors 21 | /.idea 22 | .project 23 | .classpath 24 | .c9/ 25 | *.launch 26 | .settings/ 27 | *.sublime-workspace 28 | 29 | # IDE - VSCode 30 | .vscode/* 31 | !.vscode/settings.json 32 | !.vscode/tasks.json 33 | !.vscode/launch.json 34 | !.vscode/extensions.json 35 | 36 | #guide 37 | 38 | /article -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/user/user.entity.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Column, 3 | Entity, 4 | JoinColumn, 5 | OneToMany, 6 | OneToOne, 7 | PrimaryGeneratedColumn, 8 | } from 'typeorm'; 9 | import { Exclude } from 'class-transformer'; 10 | 11 | @Entity({ name: 'users' }) 12 | class User { 13 | @PrimaryGeneratedColumn('uuid') 14 | public id: string; 15 | 16 | @Column({ unique: true }) 17 | public email: string; 18 | 19 | @Column() 20 | public name: string; 21 | 22 | @Column() 23 | @Exclude() 24 | public password: string; 25 | } 26 | 27 | export default User; 28 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/models/todo.ts: -------------------------------------------------------------------------------- 1 | import { getModelForClass, modelOptions, prop } from "@typegoose/typegoose"; 2 | 3 | @modelOptions({ 4 | schemaOptions: { 5 | timestamps: true, 6 | }, 7 | }) 8 | class Todo { 9 | /** 10 | * Decorator prop is for database modelation and the second one type data is for model in typescript 11 | */ 12 | @prop({ type: String }) 13 | title: string; 14 | 15 | @prop({ type: String }) 16 | description: string; 17 | 18 | @prop({ type: Boolean, default: false }) 19 | done: boolean; 20 | } 21 | 22 | export default getModelForClass(Todo); 23 | -------------------------------------------------------------------------------- /packages/app-config/src/config.default.ts: -------------------------------------------------------------------------------- 1 | import { ConfigData } from "./config.interface"; 2 | 3 | export const DEFAULT_CONFIG: ConfigData = { 4 | port: Number(process.env.PORT || 3001), 5 | env: "production", 6 | db: { 7 | url: process.env.DATABASE_URL!, 8 | }, 9 | swagger: { 10 | username: "", 11 | password: "", 12 | }, 13 | auth: { 14 | secret: "", 15 | expiry: "", 16 | }, 17 | logLevel: "", 18 | email: { 19 | service_name: "", 20 | username: "", 21 | password: "", 22 | }, 23 | externalApi: { 24 | apiUrl: "", 25 | apiKey: "", 26 | }, 27 | }; 28 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/local.strategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Strategy } from 'passport-local'; 3 | import { PassportStrategy } from '@nestjs/passport'; 4 | import { AuthenticationService } from './auth.service'; 5 | 6 | @Injectable() 7 | export class LocalStrategy extends PassportStrategy(Strategy) { 8 | constructor(private authService: AuthenticationService) { 9 | super({ 10 | usernameField: 'email', 11 | }); 12 | } 13 | async validate(email: string, password: string) { 14 | return this.authService.getAuthUser(email, password); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/posts/schema.graphql: -------------------------------------------------------------------------------- 1 | type Post { 2 | id: ID! 3 | title: String! 4 | content: String! 5 | published: Boolean! 6 | createdAt: String! 7 | } 8 | 9 | input NewPost { 10 | title: String! 11 | content: String! 12 | } 13 | 14 | input UpdatePost { 15 | id:ID! 16 | published: Boolean 17 | title: String 18 | content: String 19 | } 20 | 21 | type Query { 22 | posts: [Post!]! 23 | post(id: ID!): Post 24 | } 25 | 26 | type Mutation { 27 | createPost(input: NewPost): Post! 28 | updatePost(input: UpdatePost): Post 29 | deletePost(id: ID!): Post 30 | } -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/trpc.ts: -------------------------------------------------------------------------------- 1 | import { inferAsyncReturnType, initTRPC } from "@trpc/server"; 2 | import * as trpcExpressAdpater from "@trpc/server/adapters/express"; 3 | 4 | /** 5 | * Created for each request 6 | */ 7 | export const createContext = ({ 8 | req, 9 | res, 10 | }: trpcExpressAdpater.CreateExpressContextOptions) => ({}); //There is no context, add auth header here 11 | 12 | type Context = inferAsyncReturnType; 13 | 14 | const t = initTRPC.context().create(); 15 | 16 | export const router = t.router; 17 | export const middleware = t.middleware; 18 | export const publicProcedure = t.procedure; 19 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/main.ts: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | import { NestFactory } from '@nestjs/core'; 4 | import { AppModule } from './app.module'; 5 | import { createDocument } from './app/docs/swagger'; 6 | import { HttpExceptionFilter } from './app/core/filters'; 7 | import { MyLoggerService } from '@dev/logger'; 8 | async function bootstrap() { 9 | const app = await NestFactory.create(AppModule); 10 | app.useLogger(new MyLoggerService('context')); 11 | app.setGlobalPrefix('/api/v1'); 12 | app.useGlobalFilters(new HttpExceptionFilter()); 13 | createDocument(app); 14 | await app.listen(process.env.PORT || 3000); 15 | } 16 | bootstrap(); 17 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/main.ts: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | 3 | import { NestFactory } from '@nestjs/core'; 4 | import { AppModule } from './app.module'; 5 | import { createDocument } from './app/docs/swagger'; 6 | import { HttpExceptionFilter } from './app/core/filters'; 7 | import { MyLoggerService } from '@dev/logger'; 8 | async function bootstrap() { 9 | const app = await NestFactory.create(AppModule); 10 | app.useLogger(new MyLoggerService('context')); 11 | app.setGlobalPrefix('/api/v1'); 12 | app.useGlobalFilters(new HttpExceptionFilter()); 13 | createDocument(app); 14 | await app.listen(process.env.PORT || 3000); 15 | } 16 | bootstrap(); 17 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "declaration": true, 5 | "removeComments": true, 6 | "emitDecoratorMetadata": true, 7 | "experimentalDecorators": true, 8 | "allowSyntheticDefaultImports": true, 9 | "target": "es2017", 10 | "sourceMap": true, 11 | "outDir": "./dist", 12 | "baseUrl": "./", 13 | "incremental": true, 14 | "skipLibCheck": true, 15 | "strictNullChecks": false, 16 | "noImplicitAny": false, 17 | "strictBindCallApply": false, 18 | "forceConsistentCasingInFileNames": false, 19 | "noFallthroughCasesInSwitch": false 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/api.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { APP_INTERCEPTOR } from '@nestjs/core'; 3 | import { LoggingInterceptor } from '../shared/logging.interceptor'; 4 | import { PokemonModule } from './pokemon/pokemon.module'; 5 | import { UserModule } from './user/user.module'; 6 | import { LeagueModule } from './league/league.module'; 7 | 8 | @Module({ 9 | imports: [UserModule, PokemonModule, LeagueModule], 10 | providers: [ 11 | { 12 | provide: APP_INTERCEPTOR, 13 | useClass: LoggingInterceptor, 14 | }, 15 | ], 16 | exports: [UserModule, PokemonModule, LeagueModule], 17 | }) 18 | export class ApiModule {} 19 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.provider.ts: -------------------------------------------------------------------------------- 1 | import { Provider } from "@nestjs/common"; 2 | import { HttpClientModuleOptions } from "./http-client.interface"; 3 | import { HTTP_CLIENT_TOKEN } from "./http-client.constants"; 4 | import { HttpClientService } from "./http-client.service"; 5 | 6 | export const getHttpClientModuleOptions = ( 7 | options: HttpClientModuleOptions 8 | ): HttpClientService => { 9 | return new HttpClientService(options); 10 | }; 11 | 12 | export function createHttpClientProvider( 13 | options: HttpClientModuleOptions 14 | ): Provider { 15 | return { 16 | provide: HTTP_CLIENT_TOKEN, 17 | useValue: getHttpClientModuleOptions(options), 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import * as request from 'supertest'; 3 | import { AppModule } from './../src/app.module'; 4 | 5 | describe('AppController (e2e)', () => { 6 | let app; 7 | 8 | beforeEach(async () => { 9 | const moduleFixture: TestingModule = await Test.createTestingModule({ 10 | imports: [AppModule], 11 | }).compile(); 12 | 13 | app = moduleFixture.createNestApplication(); 14 | await app.init(); 15 | }); 16 | 17 | it('/ (GET)', () => { 18 | return request(app.getHttpServer()) 19 | .get('/') 20 | .expect(200) 21 | .expect('Hello World!'); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/user/user.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsOptional, IsString, ValidateNested } from "class-validator"; 2 | 3 | class CreateAddressDto { 4 | @IsString() 5 | public street: string; 6 | 7 | @IsString() 8 | public city: string; 9 | 10 | @IsString() 11 | public country: string; 12 | } 13 | 14 | class CreateUserDto { 15 | @IsString() 16 | public firstName: string; 17 | 18 | @IsString() 19 | public lastName: string; 20 | 21 | @IsString() 22 | public email: string; 23 | 24 | @IsString() 25 | public password: string; 26 | 27 | @IsOptional() 28 | @ValidateNested() 29 | public address?: CreateAddressDto; 30 | } 31 | 32 | export default CreateUserDto; 33 | -------------------------------------------------------------------------------- /docker-utils/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | set -u 4 | 5 | function create_user_and_database() { 6 | local database=$1 7 | echo " Creating user and database '$database'" 8 | psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL 9 | CREATE USER $database; 10 | CREATE DATABASE $database; 11 | GRANT ALL PRIVILEGES ON DATABASE $database TO $database; 12 | EOSQL 13 | } 14 | 15 | if [ -n "$POSTGRES_MULTIPLE_DATABASES" ]; then 16 | echo "Multiple database creation requested: $POSTGRES_MULTIPLE_DATABASES" 17 | for db in $(echo $POSTGRES_MULTIPLE_DATABASES | tr ',' ' '); do 18 | create_user_and_database $db 19 | done 20 | echo "Multiple databases created" 21 | fi 22 | 23 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/entity/pokemon.entity.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Entity, 3 | PrimaryGeneratedColumn, 4 | Column, 5 | BaseEntity, 6 | ManyToOne, 7 | } from 'typeorm'; 8 | import { LeagueEntity } from './league.entity'; 9 | 10 | @Entity('pokemon') 11 | export class PokemonEntity extends BaseEntity { 12 | @PrimaryGeneratedColumn('uuid') id: string; 13 | 14 | @Column('varchar', { length: 500, unique: true }) 15 | name: string; 16 | 17 | @Column('varchar', { length: 500 }) 18 | type: string; 19 | 20 | @Column('numeric') pokedex: number; 21 | 22 | @ManyToOne((type) => LeagueEntity, (league) => league.pokemons, { 23 | eager: true, 24 | }) 25 | league: LeagueEntity; 26 | } 27 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.interface.ts: -------------------------------------------------------------------------------- 1 | import { ModuleMetadata, Type } from "@nestjs/common"; 2 | 3 | export interface HttpClientModuleOptions { 4 | apiKey: string; 5 | apiUrl: string; 6 | } 7 | 8 | export interface HttpClientModuleFactory { 9 | createHttpModuleOptions: () => 10 | | Promise 11 | | HttpClientModuleOptions; 12 | } 13 | 14 | export interface HttpClientModuleAsyncOptions 15 | extends Pick { 16 | inject?: any[]; 17 | useClass?: Type; 18 | useExisting?: Type; 19 | useFactory?: ( 20 | ...args: any[] 21 | ) => Promise | HttpClientModuleOptions; 22 | } 23 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | tRPC TODO API - Raul CV 9 | 10 | 11 | 12 |

Hello I'M RAUL

13 |

tRPC API Initial route page

14 |

If you want to see the code, loop up that on github.com/raulcv: tRPC API integrated with Reacjs

15 | 16 | 17 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/middleware/index.ts: -------------------------------------------------------------------------------- 1 | import { getUserBySessionToken } from "../db/users"; 2 | import express from "express"; 3 | 4 | export const isAuthenticated = async ( 5 | req: any, 6 | res: express.Response, 7 | next: express.NextFunction 8 | ) => { 9 | try { 10 | const sessionToken = req.cookies["auth-cookie"]; 11 | console.log(sessionToken); 12 | 13 | if (!sessionToken) { 14 | return res.sendStatus(403); 15 | } 16 | const user = await getUserBySessionToken(sessionToken); 17 | if (!user) { 18 | return res.sendStatus(403); 19 | } 20 | req.user = user; 21 | return next(); 22 | } catch (err) { 23 | console.log(err); 24 | return res.sendStatus(400); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | sourceType: 'module', 6 | }, 7 | plugins: ['@typescript-eslint/eslint-plugin'], 8 | extends: [ 9 | 'plugin:@typescript-eslint/recommended', 10 | 'plugin:prettier/recommended', 11 | ], 12 | root: true, 13 | env: { 14 | node: true, 15 | jest: true, 16 | }, 17 | ignorePatterns: ['.eslintrc.js'], 18 | rules: { 19 | '@typescript-eslint/interface-name-prefix': 'off', 20 | '@typescript-eslint/explicit-function-return-type': 'off', 21 | '@typescript-eslint/explicit-module-boundary-types': 'off', 22 | '@typescript-eslint/no-explicit-any': 'off', 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/test/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { INestApplication } from '@nestjs/common'; 3 | import * as request from 'supertest'; 4 | import { AppModule } from './../src/app.module'; 5 | 6 | describe('AppController (e2e)', () => { 7 | let app: INestApplication; 8 | 9 | beforeEach(async () => { 10 | const moduleFixture: TestingModule = await Test.createTestingModule({ 11 | imports: [AppModule], 12 | }).compile(); 13 | 14 | app = moduleFixture.createNestApplication(); 15 | await app.init(); 16 | }); 17 | 18 | it('/ (GET)', () => { 19 | return request(app.getHttpServer()) 20 | .get('/') 21 | .expect(200) 22 | .expect('Hello World!'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /packages/app-email/src/email.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable } from "@nestjs/common"; 2 | import { createTransport } from "nodemailer"; 3 | import * as Mail from "nodemailer/lib/mailer"; 4 | import { EMAIL_CONFIG_OPTIONS, EmailOptions } from "./email.interface"; 5 | 6 | @Injectable() 7 | export class EmailService { 8 | private nodeMailerTransport: Mail; 9 | constructor(@Inject(EMAIL_CONFIG_OPTIONS) private options: EmailOptions) { 10 | this.nodeMailerTransport = createTransport({ 11 | service: this.options.service, 12 | auth: { 13 | user: this.options.user, 14 | pass: this.options.pass, 15 | }, 16 | }); 17 | } 18 | sendEmail(options: Mail.Options) { 19 | return this.nodeMailerTransport.sendMail(options); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/app-email/src/v1/email.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { createTransport } from "nodemailer"; 3 | import { ConfigService } from "@dev/config"; 4 | import * as Mail from "nodemailer/lib/mailer"; 5 | 6 | @Injectable() 7 | export class EmailService { 8 | private nodeMailerTransport: Mail; 9 | constructor(private readonly configService: ConfigService) { 10 | this.nodeMailerTransport = createTransport({ 11 | service: this.configService.get().email.service_name, 12 | auth: { 13 | user: this.configService.get().email.username, 14 | pass: this.configService.get().email.password, 15 | }, 16 | }); 17 | } 18 | sendEmail(options: Mail.Options) { 19 | return this.nodeMailerTransport.sendMail(options); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', 3 | parserOptions: { 4 | project: 'tsconfig.json', 5 | tsconfigRootDir: __dirname, 6 | sourceType: 'module', 7 | }, 8 | plugins: ['@typescript-eslint/eslint-plugin'], 9 | extends: [ 10 | 'plugin:@typescript-eslint/recommended', 11 | 'plugin:prettier/recommended', 12 | ], 13 | root: true, 14 | env: { 15 | node: true, 16 | jest: true, 17 | }, 18 | ignorePatterns: ['.eslintrc.js'], 19 | rules: { 20 | '@typescript-eslint/interface-name-prefix': 'off', 21 | '@typescript-eslint/explicit-function-return-type': 'off', 22 | '@typescript-eslint/explicit-module-boundary-types': 'off', 23 | '@typescript-eslint/no-explicit-any': 'off', 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/guard/api-guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; 2 | import { Reflector } from '@nestjs/core'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable() 6 | export class AuthGuard implements CanActivate { 7 | constructor(private reflector: Reflector) {} 8 | canActivate( 9 | context: ExecutionContext, 10 | ): boolean | Promise | Observable { 11 | // ['admin', 'user'] 12 | const roles = this.reflector.get('roles', context.getHandler()); 13 | if (!roles) { 14 | return true; 15 | } 16 | const request = context.switchToHttp().getRequest(); 17 | const requestRoles = request.user?.roles; // 'admin' 18 | return roles.includes(requestRoles); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/guard/api-guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'; 2 | import { Reflector } from '@nestjs/core'; 3 | import { Observable } from 'rxjs'; 4 | 5 | @Injectable() 6 | export class AuthGuard implements CanActivate { 7 | constructor(private reflector: Reflector) {} 8 | canActivate( 9 | context: ExecutionContext, 10 | ): boolean | Promise | Observable { 11 | // ['admin', 'user'] 12 | const roles = this.reflector.get('roles', context.getHandler()); 13 | if (!roles) { 14 | return true; 15 | } 16 | const request = context.switchToHttp().getRequest(); 17 | const requestRoles = request.user?.roles; // 'admin' 18 | return roles.includes(requestRoles); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/filters/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ExceptionFilter, 3 | Catch, 4 | ArgumentsHost, 5 | HttpException, 6 | } from '@nestjs/common'; 7 | import { Request, Response } from 'express'; 8 | 9 | @Catch(HttpException) 10 | export class HttpExceptionFilter implements ExceptionFilter { 11 | catch(exception: HttpException, host: ArgumentsHost) { 12 | const ctx = host.switchToHttp(); 13 | const response = ctx.getResponse(); 14 | const request = ctx.getRequest(); 15 | const status = exception.getStatus(); 16 | 17 | response.status(status).json({ 18 | statusCode: status, 19 | timestamp: new Date().toISOString(), 20 | path: request.url, 21 | method: request.method, 22 | message: exception.message, 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/filters/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ExceptionFilter, 3 | Catch, 4 | ArgumentsHost, 5 | HttpException, 6 | } from '@nestjs/common'; 7 | import { Request, Response } from 'express'; 8 | 9 | @Catch(HttpException) 10 | export class HttpExceptionFilter implements ExceptionFilter { 11 | catch(exception: HttpException, host: ArgumentsHost) { 12 | const ctx = host.switchToHttp(); 13 | const response = ctx.getResponse(); 14 | const request = ctx.getRequest(); 15 | const status = exception.getStatus(); 16 | 17 | response.status(status).json({ 18 | statusCode: status, 19 | timestamp: new Date().toISOString(), 20 | path: request.url, 21 | method: request.method, 22 | message: exception.message, 23 | }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/dto/register.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from '@nestjs/swagger'; 2 | import { IsEmail, IsString, IsNotEmpty, MinLength } from 'class-validator'; 3 | 4 | export class RegisterDto { 5 | @ApiProperty({ 6 | description: 'email of user', 7 | required: true, 8 | example: 'email@gmail.com', 9 | }) 10 | @IsEmail() 11 | email: string; 12 | 13 | @ApiProperty({ 14 | description: 'name', 15 | required: true, 16 | example: 'name', 17 | }) 18 | @IsString() 19 | @IsNotEmpty() 20 | name: string; 21 | 22 | @ApiProperty({ 23 | description: 'password', 24 | required: true, 25 | example: 'XXXXXXXXXXX', 26 | }) 27 | @IsString() 28 | @IsNotEmpty() 29 | @MinLength(6) 30 | password: string; 31 | } 32 | 33 | export default RegisterDto; 34 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module, forwardRef } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import { UsersEntity } from './user.entity'; 4 | import { UserController } from './user.controller'; 5 | import { UserService } from './user.service'; 6 | import { UserDaoService } from './user.dao.service'; 7 | import { AuthModule } from '../auth/auth.module'; 8 | import { AppLoggerModule } from '@dev/logger'; 9 | 10 | const UserDaoMockService = {}; 11 | 12 | @Module({ 13 | imports: [ 14 | AppLoggerModule, 15 | forwardRef(() => AuthModule), 16 | TypeOrmModule.forFeature([UsersEntity]), 17 | ], 18 | controllers: [UserController], 19 | providers: [UserService, UserDaoService], 20 | exports: [UserService, UserDaoService], 21 | }) 22 | export class UserModule {} 23 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/core/middleware/auth.middleware.ts: -------------------------------------------------------------------------------- 1 | // Package. 2 | import { HttpStatus, Injectable, NestMiddleware } from '@nestjs/common'; 3 | import { HttpException } from '@nestjs/common/exceptions/http.exception'; 4 | import { NextFunction, Response } from 'express'; 5 | 6 | export const MISSING_AUTH_HEADER = 'Missing Authorization Header'; 7 | 8 | @Injectable() 9 | export class AuthMiddleware implements NestMiddleware { 10 | constructor() {} 11 | 12 | public async use(req: any, res: Response, next: NextFunction) { 13 | const tag = 'AuthMiddleware'; 14 | console.log(tag); 15 | const { authorization } = req.headers; 16 | if (!authorization) { 17 | throw new HttpException( 18 | { message: MISSING_AUTH_HEADER }, 19 | HttpStatus.BAD_REQUEST, 20 | ); 21 | } 22 | next(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/core/middleware/auth.middleware.ts: -------------------------------------------------------------------------------- 1 | // Package. 2 | import { HttpStatus, Injectable, NestMiddleware } from '@nestjs/common'; 3 | import { HttpException } from '@nestjs/common/exceptions/http.exception'; 4 | import { NextFunction, Response } from 'express'; 5 | 6 | export const MISSING_AUTH_HEADER = 'Missing Authorization Header'; 7 | 8 | @Injectable() 9 | export class AuthMiddleware implements NestMiddleware { 10 | constructor() {} 11 | 12 | public async use(req: any, res: Response, next: NextFunction) { 13 | const tag = 'AuthMiddleware'; 14 | console.log(tag); 15 | const { authorization } = req.headers; 16 | if (!authorization) { 17 | throw new HttpException( 18 | { message: MISSING_AUTH_HEADER }, 19 | HttpStatus.BAD_REQUEST, 20 | ); 21 | } 22 | next(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/app-config/src/config.interface.ts: -------------------------------------------------------------------------------- 1 | export interface ConfigDatabase { 2 | url: string; 3 | } 4 | 5 | export interface ConfigSwagger { 6 | username: string; 7 | password: string; 8 | } 9 | 10 | export interface UserServiceConfigOptions { 11 | host: string; 12 | port: number; 13 | } 14 | 15 | export interface EmailConfig { 16 | service_name: string; 17 | username: string; 18 | password: string; 19 | } 20 | 21 | export interface ApiConfig { 22 | apiUrl: string; 23 | apiKey: string; 24 | } 25 | 26 | export interface AuthConfig { 27 | secret: string; 28 | expiry: string; 29 | } 30 | 31 | export interface ConfigData { 32 | env: string; 33 | 34 | port: number; 35 | 36 | db: ConfigDatabase; 37 | 38 | swagger: ConfigSwagger; 39 | 40 | logLevel: string; 41 | 42 | email: EmailConfig; 43 | 44 | auth: AuthConfig; 45 | 46 | externalApi: ApiConfig; 47 | } 48 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/user/dto/createUser.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; 2 | import { 3 | IsDefined, 4 | IsEmail, 5 | IsString, 6 | MinLength, 7 | minLength, 8 | } from 'class-validator'; 9 | 10 | export class CreateUserDto { 11 | @ApiProperty({ 12 | description: 'email of user', 13 | required: true, 14 | example: 'email@gmail.com', 15 | }) 16 | @IsDefined() 17 | @IsEmail() 18 | email: string; 19 | 20 | @ApiProperty({ 21 | description: 'name', 22 | required: true, 23 | example: 'name', 24 | }) 25 | @IsDefined() 26 | @IsString() 27 | name: string; 28 | 29 | @ApiProperty({ 30 | description: 'password with min 6 length', 31 | required: true, 32 | example: 'XXXXXXXXXX', 33 | }) 34 | @IsDefined() 35 | @MinLength(6) 36 | password: string; 37 | } 38 | 39 | export default CreateUserDto; 40 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.service.ts: -------------------------------------------------------------------------------- 1 | import axios, { AxiosResponse } from "axios"; 2 | import { Inject } from "@nestjs/common"; 3 | import { HTTP_CLIENT_MODULE_OPTIONS } from "./http-client.constants"; 4 | import { HttpClientModuleOptions } from "./http-client.interface"; 5 | 6 | export class HttpClientService { 7 | private apiUrl; 8 | private apiKey; 9 | 10 | constructor( 11 | @Inject(HTTP_CLIENT_MODULE_OPTIONS) 12 | private readonly options: HttpClientModuleOptions 13 | ) { 14 | this.apiUrl = this.options.apiUrl; 15 | this.apiKey = this.options.apiKey; 16 | } 17 | 18 | async fetch(method: string, data: any): Promise> { 19 | return axios({ 20 | method, 21 | data, 22 | url: `${this.apiUrl}`, 23 | headers: { 24 | "Content-Type": "application/json", 25 | Authorization: `Bearer ${this.apiKey}`, 26 | }, 27 | }); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.entity.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BaseEntity, 3 | Column, 4 | CreateDateColumn, 5 | UpdateDateColumn, 6 | Entity, 7 | PrimaryGeneratedColumn, 8 | OneToMany, 9 | } from 'typeorm'; 10 | 11 | @Entity('users') 12 | export class UsersEntity extends BaseEntity { 13 | @PrimaryGeneratedColumn('uuid') 14 | public id!: string; 15 | 16 | @Column({ type: 'varchar', length: 255, select: true, unique: true }) 17 | public email!: string; 18 | 19 | @Column({ type: 'varchar', length: 255, select: true }) 20 | public username!: string; 21 | 22 | @CreateDateColumn({ 23 | type: 'timestamptz', 24 | default: () => 'CURRENT_TIMESTAMP', 25 | select: true, 26 | }) 27 | public created_at!: Date; 28 | 29 | @UpdateDateColumn({ 30 | type: 'timestamptz', 31 | default: () => 'CURRENT_TIMESTAMP', 32 | select: true, 33 | }) 34 | public updated_at!: Date; 35 | } 36 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/index.ts: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | console.log(process.env.MONGO_URL); 3 | 4 | import express, { NextFunction, Request, Response } from "express"; 5 | import http from "http"; 6 | import bodyParser from "body-parser"; 7 | import cookieParser from "cookie-parser"; 8 | import cors from "cors"; 9 | import mongoose from "mongoose"; 10 | import router from "./router"; 11 | 12 | const app = express(); 13 | app.use(bodyParser.json()); 14 | app.use(cookieParser()); 15 | 16 | app.use((req: Request, res: Response, next: NextFunction) => { 17 | next(); 18 | }); 19 | 20 | mongoose.Promise = Promise; 21 | mongoose.connect(process.env.MONGO_URL); 22 | mongoose.connection.on("error", (error: Error) => console.log(error)); 23 | 24 | app.use("/api", router()); 25 | 26 | app.listen(process.env.PORT || 3002, () => { 27 | console.log( 28 | `Server running on http://localhost:${process.env.PORT || 3002}/` 29 | ); 30 | }); 31 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/user/user.model.ts: -------------------------------------------------------------------------------- 1 | import * as mongoose from "mongoose"; 2 | import User from "./user.interface"; 3 | 4 | const addressSchema = new mongoose.Schema({ 5 | city: String, 6 | country: String, 7 | street: String, 8 | }); 9 | 10 | const userSchema = new mongoose.Schema({ 11 | address: addressSchema, 12 | email: { 13 | type: String, 14 | required: true, 15 | unique: true, 16 | }, 17 | firstName: String, 18 | lastName: String, 19 | password: { 20 | type: String, 21 | get: (): undefined => undefined, 22 | }, 23 | }); 24 | 25 | userSchema.virtual("fullName").get(function () { 26 | return `${this.firstName} ${this.lastName}`; 27 | }); 28 | 29 | userSchema.virtual("posts", { 30 | ref: "Post", 31 | localField: "_id", 32 | foreignField: "author", 33 | }); 34 | 35 | const userModel = mongoose.model("User", userSchema); 36 | 37 | export default userModel; 38 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/express-typescript-apis", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "body-parser": "^1.20.2", 14 | "cookie-parser": "^1.2.0", 15 | "cors": "^2.8.5", 16 | "crypto": "^1.0.1", 17 | "dotenv": "^16.0.3", 18 | "express": "^4.18.2", 19 | "lodash": "^4.17.21", 20 | "mongoose": "^5.8.11" 21 | }, 22 | "devDependencies": { 23 | "@types/body-parser": "^1.19.2", 24 | "@types/cookie-parser": "^1.4.3", 25 | "@types/cors": "^2.8.13", 26 | "@types/express": "^4.17.17", 27 | "@types/lodash": "^4.14.194", 28 | "@types/mongoose": "^5.8.11", 29 | "@types/node": "^20.2.3", 30 | "nodemon": "^2.0.22", 31 | "ts-node": "^10.9.1", 32 | "typescript": "^4.5.4" 33 | } 34 | } -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { ExtractJwt } from 'passport-jwt'; 2 | import { PassportStrategy } from '@nestjs/passport'; 3 | import { Injectable } from '@nestjs/common'; 4 | import { Request } from 'express'; 5 | import { ConfigService } from '@dev/config'; 6 | import { UserService } from '../user/user.service'; 7 | import { Strategy } from 'passport-jwt'; 8 | 9 | @Injectable() 10 | export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { 11 | constructor( 12 | private readonly _configService: ConfigService, 13 | private readonly userService: UserService, 14 | ) { 15 | super({ 16 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 17 | secretOrKey: _configService.get().auth.secret, 18 | }); 19 | } 20 | 21 | async validate(payload: any) { 22 | // req.user 23 | console.log(payload); 24 | return this.userService.getById(payload.userId); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "env": { 5 | "commonjs": true 6 | }, 7 | "plugins": [ 8 | "@typescript-eslint" 9 | ], 10 | "extends": [ 11 | "eslint:recommended", 12 | "plugin:@typescript-eslint/eslint-recommended", 13 | "plugin:@typescript-eslint/recommended" 14 | ], 15 | "rules": { 16 | "@typescript-eslint/no-var-requires": "off", 17 | "@typescript-eslint/ban-ts-comment": "off", 18 | "react/react-in-jsx-scope": "off", 19 | "no-use-before-define": [ 20 | "error", 21 | { 22 | "functions": false, 23 | "classes": false, 24 | "variables": false 25 | } 26 | ], 27 | 28 | "@typescript-eslint/no-empty-function": 0, 29 | "@typescript-eslint/no-unused-vars": 0, 30 | "react/no-unknown-property": 0, 31 | "no-console": 0, 32 | "no-undef": 0, 33 | "no-plusplus": 0 34 | } 35 | } -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/league/league.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Mutation, Args } from '@nestjs/graphql'; 2 | import { LeagueService } from './league.service'; 3 | 4 | @Resolver('League') 5 | export class LeagueResolver { 6 | constructor(private leagueService: LeagueService) {} 7 | 8 | @Query() 9 | async leagues() { 10 | return await this.leagueService.index(); 11 | } 12 | 13 | @Mutation() 14 | async createLeague(@Args('name') name) { 15 | return this.leagueService.create({ name }); 16 | } 17 | 18 | @Mutation() 19 | async updateLeague(@Args('id') id, @Args('name') name) { 20 | return this.leagueService.update(id, { name }); 21 | } 22 | 23 | @Mutation() 24 | async deleteLeague(@Args('id') id) { 25 | await this.leagueService.delete(id); 26 | return { delete: true }; 27 | } 28 | 29 | @Query() 30 | async pokemon(@Args('id') id: string) { 31 | return await this.leagueService.show(id); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/posts/posts.resolvers.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Mutation, Args } from '@nestjs/graphql'; 2 | import { PostService } from './posts.service'; 3 | import { Post, NewPost, UpdatePost } from 'src/graphql'; 4 | 5 | @Resolver('Post') 6 | export class PostResolvers { 7 | constructor(private readonly postService: PostService) {} 8 | 9 | @Query('posts') 10 | async posts() { 11 | return this.postService.posts(); 12 | } 13 | 14 | @Query('post') 15 | async post(@Args('id') args: string) { 16 | return this.postService.post(args); 17 | } 18 | 19 | @Mutation('createPost') 20 | async create(@Args('input') args: NewPost) { 21 | return this.postService.createPost(args); 22 | } 23 | 24 | @Mutation('updatePost') 25 | async update(@Args('input') args: UpdatePost) { 26 | return this.postService.updatePost(args); 27 | } 28 | 29 | @Mutation('deletePost') 30 | async delete(@Args('id') args: string) { 31 | return this.postService.deletePost(args); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/authentication/auth.service.ts: -------------------------------------------------------------------------------- 1 | import UserWithThatEmailAlreadyExistsException from "../exceptions/user.register.exception"; 2 | import CreateUserDto from "../user/user.dto"; 3 | import userModel from "../user/user.model"; 4 | import * as bcrypt from "bcrypt"; 5 | import * as jwt from "jsonwebtoken"; 6 | 7 | class AuthenticationService { 8 | public user = userModel; 9 | public async register(data: CreateUserDto) { 10 | const { email } = data; 11 | const existingUser = await this.user.findOne({ email }); 12 | if (existingUser) { 13 | throw new UserWithThatEmailAlreadyExistsException(email); 14 | } 15 | const hashPassword = await bcrypt.hash(data.password, 10); 16 | const user = await this.user.create({ 17 | ...data, 18 | password: hashPassword, 19 | }); 20 | delete user.password; 21 | return { 22 | user: { 23 | email: user.email, 24 | }, 25 | }; 26 | } 27 | } 28 | 29 | export default AuthenticationService; 30 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.dto.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty, ApiResponseProperty } from '@nestjs/swagger'; 2 | import { IsString, IsInt, IsEmail, IsDefined } from 'class-validator'; 3 | 4 | export class CreateUserDto { 5 | @ApiProperty({ 6 | description: 'email', 7 | example: 'test@gmail.com', 8 | required: true, 9 | }) 10 | @IsDefined() 11 | @IsEmail() 12 | email: string; 13 | 14 | @ApiProperty({ 15 | description: 'username', 16 | example: 'Dev', 17 | required: true, 18 | }) 19 | @IsDefined() 20 | @IsString() 21 | username: string; 22 | } 23 | 24 | export class CrateUserResponseDto { 25 | @ApiResponseProperty({ 26 | example: 'da9b9f51-23b8-4642-97f7-52537b3cf53b', 27 | format: 'v4', 28 | }) 29 | public id: string; 30 | 31 | @ApiResponseProperty({ 32 | example: 'user@gmail.com', 33 | }) 34 | public email: string; 35 | 36 | @ApiResponseProperty({ 37 | example: 'user@gmail.com', 38 | }) 39 | public username: string; 40 | } 41 | -------------------------------------------------------------------------------- /packages/app-email/src/email.module.ts: -------------------------------------------------------------------------------- 1 | import { Module, DynamicModule } from "@nestjs/common"; 2 | import { EmailService } from "./email.service"; 3 | import EmailAsyncOptions, { 4 | EMAIL_CONFIG_OPTIONS, 5 | EmailOptions, 6 | } from "./email.interface"; 7 | 8 | @Module({}) 9 | export class EmailModule { 10 | static register(options: EmailOptions): DynamicModule { 11 | return { 12 | module: EmailModule, 13 | providers: [ 14 | { 15 | provide: EMAIL_CONFIG_OPTIONS, 16 | useValue: options, 17 | }, 18 | EmailService, 19 | ], 20 | }; 21 | } 22 | static registerAsync(options: EmailAsyncOptions): DynamicModule { 23 | return { 24 | module: EmailModule, 25 | imports: options.imports, 26 | providers: [ 27 | { 28 | provide: EMAIL_CONFIG_OPTIONS, 29 | useFactory: options.useFactory, 30 | inject: options.inject, 31 | }, 32 | EmailService, 33 | ], 34 | exports: [EmailService], 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tkssharma/express-trpc-apis", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "ts-node-dev --respawn --transpile-only src/index.ts", 8 | "build:back": "tsc", 9 | "start": "node dist/index.js", 10 | "build:front": "npm run build --prefix client", 11 | "build:prod": "npm run build:back && npm run build:front", 12 | "clean": "rm -rf dist && rm -rf client/dist && rm -rf data", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "@types/express": "^4.17.17", 20 | "ts-node-dev": "^2.0.0" 21 | }, 22 | "dependencies": { 23 | "@trpc/server": "^10.10.0", 24 | "@typegoose/typegoose": "^10.1.1", 25 | "@types/cors": "^2.8.13", 26 | "cors": "^2.8.5", 27 | "dotenv": "^16.0.3", 28 | "ejs": "^3.1.8", 29 | "express": "^4.18.2", 30 | "mongoose": "^6.9.1", 31 | "zod": "^3.20.3" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tkssharma/express-trpc-apis", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "ts-node-dev --respawn --transpile-only src/index.ts", 8 | "build:back": "tsc", 9 | "start": "node dist/index.js", 10 | "build:front": "npm run build --prefix client", 11 | "build:prod": "npm run build:back && npm run build:front", 12 | "clean": "rm -rf dist && rm -rf client/dist && rm -rf data", 13 | "test": "echo \"Error: no test specified\" && exit 1" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "@types/express": "^4.17.17", 20 | "ts-node-dev": "^2.0.0" 21 | }, 22 | "dependencies": { 23 | "@trpc/server": "^10.10.0", 24 | "@typegoose/typegoose": "^10.1.1", 25 | "@types/cors": "^2.8.13", 26 | "cors": "^2.8.5", 27 | "dotenv": "^16.0.3", 28 | "ejs": "^3.1.8", 29 | "express": "^4.18.2", 30 | "mongoose": "^6.9.1", 31 | "zod": "^3.20.3" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { GraphQLModule } from '@nestjs/graphql'; 3 | import { TypeOrmModule, TypeOrmModuleAsyncOptions } from '@nestjs/typeorm'; 4 | import { ApiModule } from './modules/api/api.module'; 5 | import { join } from 'path'; 6 | import { DBModule } from '@dev/database'; 7 | import { ConfigModule } from '@dev/config'; 8 | 9 | import { PokemonEntity } from './modules/entity/pokemon.entity'; 10 | import { LeagueEntity } from './modules/entity/league.entity'; 11 | console.log(process.env); 12 | 13 | @Module({ 14 | imports: [ 15 | ConfigModule, 16 | DBModule.forRoot({ 17 | entities: [LeagueEntity, PokemonEntity], 18 | }), 19 | GraphQLModule.forRoot({ 20 | playground: true, 21 | typePaths: ['./**/*.graphql'], 22 | context: ({ req }) => ({ headers: req.headers }), 23 | debug: true, 24 | definitions: { 25 | path: join(process.cwd(), 'src/graphql.schema.ts'), 26 | outputAs: 'class', 27 | }, 28 | }), 29 | ApiModule, 30 | ], 31 | }) 32 | export class AppModule {} 33 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/user/user.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import User from './user.entity'; 4 | import { Repository } from 'typeorm'; 5 | import CreateUserDto from './dto/createUser.dto'; 6 | 7 | @Injectable() 8 | export class UserService { 9 | constructor( 10 | @InjectRepository(User) 11 | private userRepo: Repository, 12 | ) {} 13 | async getByEmail(email: string) { 14 | const user = await this.userRepo.findOne({ where: { email } }); 15 | if (user) { 16 | return user; 17 | } 18 | return null; 19 | } 20 | 21 | async getById(id: string) { 22 | const user = await this.userRepo.findOne({ where: { id } }); 23 | if (user) { 24 | return user; 25 | } 26 | return null; 27 | } 28 | 29 | async create(userData: CreateUserDto) { 30 | userData.email = userData.email.toLowerCase(); 31 | const newUser = await this.userRepo.create(userData); 32 | await this.userRepo.save(newUser); 33 | return newUser; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/user/user.service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.UserService = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var UserService = /** @class */ (function () { 25 | function UserService() {} 26 | UserService = __decorate([(0, common_1.Injectable)()], UserService); 27 | return UserService; 28 | })(); 29 | exports.UserService = UserService; 30 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/db/users.ts: -------------------------------------------------------------------------------- 1 | import mongoose from "mongoose"; 2 | 3 | const UserSchema = new mongoose.Schema({ 4 | email: { type: String, required: true }, 5 | username: { type: String, required: true }, 6 | authentication: { 7 | password: { type: String, required: true, select: false }, 8 | salt: { type: String, select: false }, 9 | sessionToken: { type: String, select: false }, 10 | }, 11 | }); 12 | 13 | export const UserModel = mongoose.model("User", UserSchema); 14 | 15 | export const getUsers = () => UserModel.find(); 16 | export const getUserByEmail = (email: string) => UserModel.findOne({ email }); 17 | export const getUserBySessionToken = (sessionToken: string) => 18 | UserModel.findOne({ "authentication.sessionToken": sessionToken }); 19 | export const getUserById = (id: string) => UserModel.findById(id); 20 | export const createUser = (values: Record) => 21 | new UserModel(values).save().then((user) => user.toObject()); 22 | export const deleteUserById = (id: string) => 23 | UserModel.findOneAndDelete({ _id: id }); 24 | export const updateUserById = (id: string, values: Record) => 25 | UserModel.findByIdAndUpdate(id, values); 26 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/express-production", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "src/server.ts", 6 | "scripts": { 7 | "test": "jest", 8 | "dev:watch":"nodemon", 9 | "dev":"ts-jest ./src/server.ts" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "license": "ISC", 14 | "dependencies": { 15 | "@types/bcrypt": "^3.0.0", 16 | "bcrypt": "^3.0.8", 17 | "body-parser": "^1.19.0", 18 | "class-transformer": "^0.2.3", 19 | "class-validator": "^0.11.0", 20 | "cookie-parser": "^1.4.4", 21 | "dotenv": "^8.2.0", 22 | "envalid": "^6.0.1", 23 | "express": "^4.17.1", 24 | "jsonwebtoken": "^8.5.1", 25 | "mongoose": "^5.8.11" 26 | }, 27 | "devDependencies": { 28 | "@types/cookie-parser": "^1.4.3", 29 | "@types/express": "^4.17.17", 30 | "@types/jest": "^29.5.1", 31 | "@types/jsonwebtoken": "^9.0.2", 32 | "@types/mongoose": "^5.8.11", 33 | "@types/node": "^20.2.3", 34 | "@types/supertest": "^2.0.12", 35 | "nodemon": "^2.0.22", 36 | "supertest": "^6.3.3", 37 | "ts-jest": "^27.1.2", 38 | "ts-node": "^10.9.1", 39 | "typescript": "^4.5.4" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/graphql.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------- 3 | * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) 4 | * ------------------------------------------------------- 5 | */ 6 | 7 | /* tslint:disable */ 8 | /* eslint-disable */ 9 | export class NewPost { 10 | title: string; 11 | content: string; 12 | } 13 | 14 | export class UpdatePost { 15 | id: string; 16 | published?: Nullable; 17 | title?: Nullable; 18 | content?: Nullable; 19 | } 20 | 21 | export class Post { 22 | id: string; 23 | title: string; 24 | content: string; 25 | published: boolean; 26 | createdAt: string; 27 | } 28 | 29 | export abstract class IQuery { 30 | abstract posts(): Post[] | Promise; 31 | 32 | abstract post(id: string): Nullable | Promise>; 33 | } 34 | 35 | export abstract class IMutation { 36 | abstract createPost(input?: Nullable): Post | Promise; 37 | 38 | abstract updatePost( 39 | input?: Nullable, 40 | ): Nullable | Promise>; 41 | 42 | abstract deletePost(id: string): Nullable | Promise>; 43 | } 44 | 45 | type Nullable = T | null; 46 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/league/league.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { Repository } from 'typeorm'; 3 | import { InjectRepository } from '@nestjs/typeorm'; 4 | import { LeagueEntity } from '../../entity/league.entity'; 5 | 6 | @Injectable() 7 | export class LeagueService { 8 | constructor( 9 | @InjectRepository(LeagueEntity) 10 | private readonly LeagueRepository: Repository, 11 | ) {} 12 | 13 | async create(data: { name: string }) { 14 | let leaggue = new LeagueEntity(); 15 | leaggue.name = data.name; 16 | await leaggue.save(); 17 | return leaggue; 18 | } 19 | 20 | async index() { 21 | return await this.LeagueRepository.find({ relations: ['pokemons'] }); 22 | } 23 | 24 | async show(id: any) { 25 | return LeagueEntity.findOne(id); 26 | } 27 | 28 | async delete(id: any) { 29 | const league = await LeagueEntity.findOne(id); 30 | await this.LeagueRepository.delete(league as any); 31 | return { delete: true }; 32 | } 33 | 34 | async update(id, data: { name: string }) { 35 | let league = await LeagueEntity.findOne(id); 36 | league.name = data.name; 37 | await league.save(); 38 | return league; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/app-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dev/config", 3 | "version": "1.0.3", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "check-engines": "node ../../node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 9 | "clean": "rimraf build && rimraf coverage", 10 | "prebuild": "npm run clean && npm run check-engines", 11 | "prepublishOnly": "npm run build", 12 | "pretest": "npm run build", 13 | "test": "npm run test:ci", 14 | "test:ci": "jest --ci --collectCoverage --maxWorkers 2 --passWithNoTests" 15 | }, 16 | "engines": { 17 | "node": ">=14.x", 18 | "npm": ">=6.14.x" 19 | }, 20 | "devEngines": { 21 | "node": ">=14.x", 22 | "npm": ">=6.14.x" 23 | }, 24 | "dependencies": { 25 | "uuid": "^8.3.2" 26 | }, 27 | "devDependencies": { 28 | "@nestjs/common": "^9.0.0", 29 | "@nestjs/config": "2.3.1", 30 | "@nestjs/core": "^9.0.0", 31 | "@nestjs/testing": "^9.0.0", 32 | "@types/jest": "27.0.2", 33 | "@types/node": "^17.0.8", 34 | "@types/uuid": "^8.3.4", 35 | "reflect-metadata": "^0.1.13", 36 | "rxjs": "^7.2.0", 37 | "tslib": "^2.5.0", 38 | "typescript": "^4.7.4" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/pokemon/pokemon.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Resolver, Query, Args, Mutation } from '@nestjs/graphql'; 2 | import { PokemonService } from './pokemon.service'; 3 | import { PokemonEntity } from '../../entity/pokemon.entity'; 4 | 5 | @Resolver((of) => PokemonEntity) 6 | export class PokemonResolver { 7 | constructor(private pokemonService: PokemonService) {} 8 | 9 | @Query() 10 | async pokemons() { 11 | return await this.pokemonService.getPokemons(); 12 | } 13 | 14 | @Mutation() 15 | async create( 16 | @Args('name') name, 17 | @Args('type') type, 18 | @Args('pokedex') pokedex, 19 | ) { 20 | return this.pokemonService.createPokemon({ name, type, pokedex }); 21 | } 22 | 23 | @Mutation() 24 | async update( 25 | @Args('id') id, 26 | @Args('name') name, 27 | @Args('type') type, 28 | @Args('pokedex') pokedex, 29 | ) { 30 | return this.pokemonService.update(id, { name, type, pokedex }); 31 | } 32 | 33 | @Mutation() 34 | async delete(@Args('id') id) { 35 | await this.pokemonService.delete(id); 36 | return { delete: true }; 37 | } 38 | 39 | @Query() 40 | async pokemon(@Args('id') id: string) { 41 | return await this.pokemonService.show(id); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /docker-utils/entrypoint/init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | echo "*****" 5 | echo "** Application preparing to start up... Hi!" 6 | echo "** Local time :$(date -Is)" 7 | echo "** SERVICE_TITLE :${SERVICE_TITLE}" 8 | echo "** SERVICE_DESCRIPTION:${SERVICE_DESCRIPTION}" 9 | echo "** SERVICE_VERSION :${SERVICE_VERSION}" 10 | echo "** SERVICE_IDENTIFIER :${SERVICE_IDENTIFIER}" 11 | echo "** SERVICE_NAME :${SERVICE_NAME}" 12 | echo "*****" 13 | 14 | if [ -d "/app" ] 15 | then 16 | pushd /app 17 | 18 | if [ "$NPM_INSTALL" = "ENABLE" ] 19 | then 20 | echo "+Running npm install - disable with .env entry NPM_INSTALL=DISABLE" 21 | npm install 22 | npm run build 23 | else 24 | echo "+Skipping npm install - enable with .env entry NPM_INSTALL=ENABLE" 25 | fi 26 | 27 | if [ "$TYPEORM_MIGRATION" = "ENABLE" ] 28 | then 29 | echo "+Running typeorm migrations (caches will be cleared) - disable with .env entry TYPEORM_MIGRATION=DISABLE" 30 | npm run migration:run 31 | else 32 | echo "+Skipping typeorm migrations - enable with .env entry TYPEORM_MIGRATION=ENABLE" 33 | fi 34 | 35 | popd 36 | fi 37 | 38 | if [ "${1#-}" != "${1}" ] || [ -z "$(command -v "${1}")" ]; then 39 | set -- node "$@" 40 | fi 41 | 42 | exec "$@" -------------------------------------------------------------------------------- /packages/app-logger/src/loglevel.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Indicates the severity of a log message. 3 | */ 4 | export enum LogLevel { 5 | /** Critical error, system stability is affected. */ 6 | Error = "error", 7 | 8 | /** Non-critical error, system stability is not affected, but issue should be investigated. */ 9 | Warn = "warn", 10 | 11 | /** Informative message. */ 12 | Info = "info", 13 | 14 | /** HTTP access logging. */ 15 | HTTP = "http", 16 | 17 | /** More verbose informative message. */ 18 | Verbose = "verbose", 19 | 20 | /** Message to assist with debugging. */ 21 | Debug = "debug", 22 | 23 | /** Unnecessarily noisy or frequent message. */ 24 | Silly = "silly", 25 | } 26 | 27 | const allLogLevels: string[] = [ 28 | LogLevel.Error, 29 | LogLevel.Warn, 30 | LogLevel.Info, 31 | LogLevel.HTTP, 32 | LogLevel.Verbose, 33 | LogLevel.Debug, 34 | LogLevel.Silly, 35 | ]; 36 | 37 | /** 38 | * Determines if the value is a valid log level or not. 39 | * @param value the value to test 40 | * @returns true if a log level, false if not 41 | */ 42 | export function isLogLevel(value: unknown): value is LogLevel { 43 | if (typeof value !== "string") { 44 | return false; 45 | } 46 | return allLogLevels.indexOf(value) !== -1; 47 | } 48 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/controller/users.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | 3 | import { deleteUserById, getUsers, getUserById } from "../db/users"; 4 | 5 | export const getAllAPIUsers = async ( 6 | req: express.Request, 7 | res: express.Response 8 | ) => { 9 | try { 10 | const users = await getUsers(); 11 | return res.status(200).json(users); 12 | } catch (err) { 13 | return res.sendStatus(400); 14 | } 15 | }; 16 | 17 | export const deleteUsers = async ( 18 | req: express.Request, 19 | res: express.Response 20 | ) => { 21 | try { 22 | const { id } = req.params; 23 | const user = await deleteUserById(id); 24 | return res.status(200).json(user); 25 | } catch (err) { 26 | return res.sendStatus(400); 27 | } 28 | }; 29 | 30 | export const updateUsers = async ( 31 | req: express.Request, 32 | res: express.Response 33 | ) => { 34 | try { 35 | const { id } = req.params; 36 | const { username } = req.body; 37 | const user = await getUserById(id); 38 | if (!user) { 39 | return res.sendStatus(404); 40 | } 41 | user.username = username; 42 | await user.save(); 43 | return res.status(200).json(user).end(); 44 | } catch (err) { 45 | return res.sendStatus(400); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/middleware/auth.middleware.ts: -------------------------------------------------------------------------------- 1 | import WrongAuthTokenPassedException from "../exceptions/auth.access-token.exception"; 2 | import AuthTokenMissing from "../exceptions/auth.token.exception"; 3 | import HttpException from "../exceptions/http.exception"; 4 | import { NextFunction, Request, Response } from "express"; 5 | import RequestWithUser from "../interfaces/req.user"; 6 | import * as jwt from "jsonwebtoken"; 7 | import userModel from "../user/user.model"; 8 | 9 | async function authMiddleware( 10 | request: RequestWithUser, 11 | response: Response, 12 | next: NextFunction 13 | ) { 14 | const cookies = request.cookies; 15 | if (cookies && cookies.Authorization) { 16 | const secret = process.env.SECRET; 17 | try { 18 | const verifyResponse = jwt.verify(cookies.Authorization, secret) as any; 19 | const id = verifyResponse._id; 20 | const user = await userModel.findById(id); 21 | if (user) { 22 | request.user = user; 23 | next(); 24 | } else { 25 | next(new WrongAuthTokenPassedException()); 26 | } 27 | } catch (err) { 28 | next(new WrongAuthTokenPassedException()); 29 | } 30 | } else { 31 | next(new AuthTokenMissing()); 32 | } 33 | } 34 | 35 | export default authMiddleware; 36 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/app.ts: -------------------------------------------------------------------------------- 1 | import express, { Router as ExpressRouter } from "express"; 2 | import * as trpcExpressAdpater from "@trpc/server/adapters/express"; 3 | import { router, createContext } from "./trpc"; 4 | import cors from "cors"; 5 | import path from "path"; 6 | import { todosRouter } from "./routes/todos"; 7 | 8 | const expressRouter = ExpressRouter(); 9 | 10 | const app = express(); 11 | 12 | const appRouter = router({ 13 | todo: todosRouter, 14 | }); 15 | 16 | app.use(cors()); 17 | 18 | app.use( 19 | "/trpc", 20 | trpcExpressAdpater.createExpressMiddleware({ 21 | router: appRouter, 22 | createContext, 23 | }) 24 | ); 25 | 26 | app.set("views", path.join(__dirname, "views")); 27 | app.engine("html", require("ejs").renderFile); 28 | app.set("view engine", "html"); 29 | 30 | expressRouter.get("/", (req, res) => { 31 | res.render("index.html"); 32 | }); 33 | expressRouter.use("*", (req, res) => { 34 | res.status(404).json({ 35 | errors: { 36 | msg: "URL_NOT_FOUND", 37 | }, 38 | }); 39 | }); 40 | app.use(expressRouter); 41 | 42 | app.use(express.static(path.join(__dirname, "../trpc-client/dist"))); 43 | 44 | /** 45 | * Extract the times of app routers for the client 46 | */ 47 | export type AppRouter = typeof appRouter; 48 | 49 | export default app; 50 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-apis-app", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "node node_modules/prettier/bin-prettier --check \"**/*.{js,json,ts,yml,yaml}\"", 8 | "prepare": "husky install", 9 | "prettier": "node node_modules/prettier/bin-prettier --check '**/*.{js,json,ts,yml,yaml}'", 10 | "prettier:write": "node node_modules/prettier/bin-prettier --write \"**/*.{js,json,ts,yml,yaml}\"" 11 | }, 12 | "keywords": [], 13 | "author": "", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "@commitlint/cli": "^17.6.3", 17 | "@commitlint/config-conventional": "^16.0.0", 18 | "@typescript-eslint/eslint-plugin": "^5.9.0", 19 | "@typescript-eslint/parser": "^5.9.0", 20 | "commitizen": "^4.2.4", 21 | "conventional-changelog-cli": "^2.2.2", 22 | "cz-conventional-changelog": "^3.3.0", 23 | "eslint": "^8.40.0", 24 | "eslint-config-prettier": "^8.5.0", 25 | "fbjs-scripts": "^3.0.1", 26 | "husky": "^7.0.4", 27 | "jest": "^29.5.0", 28 | "prettier": "^2.8.8", 29 | "ts-jest": "^27.1.2", 30 | "nx": "^16.2.2", 31 | "typescript": "^4.5.4" 32 | }, 33 | "config": { 34 | "commitizen": { 35 | "path": "./node_modules/cz-conventional-changelog" 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import { JwtModule } from '@nestjs/jwt'; 4 | 5 | import { AuthenticationService } from './auth.service'; 6 | import { AuthenticationController } from './auth.controller'; 7 | import { UserModule } from '../user/user.module'; 8 | import { ConfigModule, ConfigService } from '@dev/config'; 9 | import { config } from 'process'; 10 | import { PassportModule } from '@nestjs/passport'; 11 | import { LocalStrategy } from './local.strategy'; 12 | import { JwtStrategy } from './jwt.strategy'; 13 | 14 | @Module({ 15 | imports: [ 16 | UserModule, 17 | ConfigModule, 18 | PassportModule, 19 | JwtModule.registerAsync({ 20 | imports: [ConfigModule], 21 | inject: [ConfigService], 22 | useFactory: async (config: ConfigService) => { 23 | return { 24 | secret: config.get().auth.secret, 25 | signOptions: { 26 | expiresIn: `${config.get().auth.expiry}s`, 27 | }, 28 | }; 29 | }, 30 | }), 31 | ], 32 | providers: [AuthenticationService, LocalStrategy, JwtStrategy], 33 | exports: [AuthenticationService], 34 | controllers: [AuthenticationController], 35 | }) 36 | export class AuthModule {} 37 | -------------------------------------------------------------------------------- /apps/express-js-auth-apis/src/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

Registration

10 |
11 | 12 | 13 | 14 |
15 | 16 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/user/user.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.UserModule = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var user_controller_1 = require('./user.controller'); 25 | var user_service_1 = require('./user.service'); 26 | var UserModule = /** @class */ (function () { 27 | function UserModule() {} 28 | UserModule = __decorate( 29 | [ 30 | (0, common_1.Module)({ 31 | controllers: [user_controller_1.UserController], 32 | providers: [user_service_1.UserService], 33 | }), 34 | ], 35 | UserModule, 36 | ); 37 | return UserModule; 38 | })(); 39 | exports.UserModule = UserModule; 40 | -------------------------------------------------------------------------------- /packages/app-database/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dev/database", 3 | "version": "1.0.0", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "tsc-version": "tsc --version", 9 | "check-engines": "node ../../node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 10 | "clean": "rimraf build && rimraf coverage", 11 | "prebuild": "npm run clean && npm run check-engines", 12 | "prepublishOnly": "npm run build", 13 | "pretest": "npm run build", 14 | "test": "npm run test:ci", 15 | "test:ci": "jest --ci --collectCoverage --maxWorkers 2 --passWithNoTests" 16 | }, 17 | "engines": { 18 | "node": ">=14.x", 19 | "npm": ">=6.14.x" 20 | }, 21 | "devEngines": { 22 | "node": ">=14.x", 23 | "npm": ">=6.14.x" 24 | }, 25 | "dependencies": { 26 | "@dev/config": "*" 27 | }, 28 | "devDependencies": { 29 | "@nestjs/typeorm": "^9.0.1", 30 | "typeorm": "^0.3.12", 31 | "@nestjs/common": "^9.0.0", 32 | "@nestjs/config": "2.3.1", 33 | "@nestjs/core": "^9.0.0", 34 | "@nestjs/testing": "^9.0.0", 35 | "@types/express": "^4.17.13", 36 | "@types/jest": "27.0.2", 37 | "@types/node": "^17.0.45", 38 | "@types/uuid": "^8.3.4", 39 | "express": "^4.18.2", 40 | "reflect-metadata": "^0.1.13", 41 | "rxjs": "^7.2.0", 42 | "tslib": "^2.5.0", 43 | "typescript": "^4.7.4" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/shared/logging.interceptor.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Injectable, 3 | NestInterceptor, 4 | ExecutionContext, 5 | Logger, 6 | CallHandler, 7 | } from '@nestjs/common'; 8 | import { GqlExecutionContext } from '@nestjs/graphql'; 9 | import { Observable } from 'rxjs'; 10 | import { tap } from 'rxjs/operators'; 11 | 12 | @Injectable() 13 | export class LoggingInterceptor implements NestInterceptor { 14 | intercept(context: ExecutionContext, next: CallHandler): Observable { 15 | const now = Date.now(); 16 | const req = context.switchToHttp().getRequest(); 17 | if (req) { 18 | const method = req.method; 19 | const url = req.url; 20 | return next 21 | .handle() 22 | .pipe( 23 | tap(() => 24 | Logger.log( 25 | `${method} ${url} ${Date.now() - now}ms`, 26 | context.getClass().name, 27 | ), 28 | ), 29 | ); 30 | } else { 31 | const ctx: any = GqlExecutionContext.create(context); 32 | const resolverName = ctx.constructorRef.name; 33 | const info = ctx.getInfo(); 34 | return next 35 | .handle() 36 | .pipe( 37 | tap(() => 38 | Logger.log( 39 | `${info.parentType} "${info.fieldName}" ${Date.now() - now}ms`, 40 | resolverName, 41 | ), 42 | ), 43 | ); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /packages/app-logger/src/logger.service.ts: -------------------------------------------------------------------------------- 1 | import * as winston from "winston"; 2 | import { LogLevel } from "./loglevel"; 3 | import * as moment from "moment"; 4 | 5 | const formatter = winston.format((info) => { 6 | if (info.level === LogLevel.HTTP) { 7 | // HTTP messages are already formatted by the middleware, so just pass through 8 | return info; 9 | } 10 | info.message = `[${moment().format("ddd MMM DD HH:mm:ss YYYY")}] [${ 11 | info.level 12 | }] ${info.message}`; 13 | 14 | return info; 15 | }); 16 | export class MyLoggerService { 17 | private readonly logger: winston.Logger; 18 | 19 | constructor(private context: string) { 20 | this.logger = winston.createLogger({ 21 | level: process.env.LOG_LEVEL, 22 | format: formatter(), 23 | }); 24 | this.logger.add( 25 | new winston.transports.Console({ 26 | format: winston.format.json(), 27 | stderrLevels: [LogLevel.Error, LogLevel.Warn], 28 | }) 29 | ); 30 | } 31 | 32 | error(message: string, _trace?: string) { 33 | this.logger.error(message, { 34 | context: this.context, 35 | }); 36 | } 37 | 38 | log(message: string) { 39 | this.logger.log(message, { context: this.context }); 40 | } 41 | 42 | warn(message: string) { 43 | this.logger.warn(message, { context: this.context }); 44 | } 45 | 46 | info(message: string) { 47 | this.logger.info(message, { context: this.context }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /packages/app-http/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dev/http", 3 | "version": "1.0.0", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "tsc-version": "tsc --version", 9 | "check-engines": "node ../../node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 10 | "clean": "rimraf build && rimraf coverage", 11 | "prebuild": "npm run clean && npm run check-engines", 12 | "prepublishOnly": "npm run build", 13 | "pretest": "npm run build", 14 | "test": "npm run test:ci", 15 | "test:ci": "jest --ci --collectCoverage --maxWorkers 2 --passWithNoTests" 16 | }, 17 | "engines": { 18 | "node": ">=14.x", 19 | "npm": ">=6.14.x" 20 | }, 21 | "devEngines": { 22 | "node": ">=14.x", 23 | "npm": ">=6.14.x" 24 | }, 25 | "dependencies": { 26 | "@dev/config": "*", 27 | "axios": "^1.4.0" 28 | }, 29 | "devDependencies": { 30 | "@nestjs/common": "^9.0.0", 31 | "@nestjs/config": "2.3.1", 32 | "@nestjs/core": "^9.0.0", 33 | "@nestjs/testing": "^9.0.0", 34 | "@nestjs/typeorm": "^9.0.1", 35 | "@types/express": "^4.17.13", 36 | "@types/jest": "27.0.2", 37 | "@types/node": "^17.0.45", 38 | "@types/uuid": "^8.3.4", 39 | "express": "^4.18.2", 40 | "reflect-metadata": "^0.1.13", 41 | "rxjs": "^7.2.0", 42 | "tslib": "^2.5.0", 43 | "typeorm": "^0.3.12", 44 | "typescript": "^4.7.4" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /apps/express-js-auth-apis/src/static/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Login 7 | 8 | 9 |

Login

10 |
11 | 12 | 13 | 14 |
15 | 16 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/src/posts/posts.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { PrismaService } from 'src/prisma.service'; 3 | // import { any } from '@prisma/client'; 4 | import { NewPost, UpdatePost } from 'src/graphql'; 5 | 6 | @Injectable() 7 | export class PostService { 8 | constructor(private prisma: PrismaService) {} 9 | 10 | // Get a single post 11 | async post(id: string): Promise { 12 | return this.prisma.post.findUnique({ 13 | where: { 14 | id: parseInt(id), 15 | }, 16 | }); 17 | } 18 | 19 | // Get multiple posts 20 | async posts(): Promise { 21 | return this.prisma.post.findMany({}); 22 | } 23 | 24 | // Create a post 25 | async createPost(input: NewPost): Promise { 26 | return this.prisma.post.create({ 27 | data: input, 28 | }); 29 | } 30 | 31 | // Update a post 32 | async updatePost(params: UpdatePost): Promise { 33 | const { id, published, title, content } = params; 34 | return this.prisma.post.update({ 35 | where: { 36 | id: parseInt(id), 37 | }, 38 | data: { 39 | ...(published && { published }), 40 | ...(title && { title }), 41 | ...(content && { content }), 42 | }, 43 | }); 44 | } 45 | 46 | // delete a post 47 | async deletePost(id: string): Promise { 48 | return this.prisma.post.delete({ 49 | where: { 50 | id: parseInt(id), 51 | }, 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/app-email/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dev/email", 3 | "version": "1.0.0", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "tsc-version": "tsc --version", 9 | "check-engines": "node ../../node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 10 | "clean": "rimraf build && rimraf coverage", 11 | "prebuild": "npm run clean && npm run check-engines", 12 | "prepublishOnly": "npm run build", 13 | "pretest": "npm run build", 14 | "test": "npm run test:ci", 15 | "test:ci": "jest --ci --collectCoverage --maxWorkers 2 --passWithNoTests" 16 | }, 17 | "engines": { 18 | "node": ">=14.x", 19 | "npm": ">=6.14.x" 20 | }, 21 | "devEngines": { 22 | "node": ">=14.x", 23 | "npm": ">=6.14.x" 24 | }, 25 | "dependencies": { 26 | "@dev/config": "*", 27 | "@types/nodemailer": "^6.4.7", 28 | "nodemailer": "^6.9.1" 29 | }, 30 | "devDependencies": { 31 | "@nestjs/common": "^9.0.0", 32 | "@nestjs/config": "2.3.1", 33 | "@nestjs/core": "^9.0.0", 34 | "@nestjs/testing": "^9.0.0", 35 | "@nestjs/typeorm": "^9.0.1", 36 | "@types/express": "^4.17.13", 37 | "@types/jest": "27.0.2", 38 | "@types/node": "^17.0.45", 39 | "@types/uuid": "^8.3.4", 40 | "express": "^4.18.2", 41 | "reflect-metadata": "^0.1.13", 42 | "rxjs": "^7.2.0", 43 | "tslib": "^2.5.0", 44 | "typeorm": "^0.3.12", 45 | "typescript": "^4.7.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Inject, Injectable, Logger, forwardRef } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm/repository/Repository'; 4 | import { UsersEntity } from './user.entity'; 5 | import { CreateUserDto } from './user.dto'; 6 | import { UserDaoService } from './user.dao.service'; 7 | import { AuthService } from '../auth/auth.service'; 8 | import { MyLoggerService } from '@dev/logger'; 9 | import { HTTP_CLIENT_TOKEN, HttpClientService } from '@dev/http'; 10 | 11 | @Injectable() 12 | export class UserService { 13 | constructor( 14 | @Inject(HTTP_CLIENT_TOKEN) 15 | private readonly apiService: HttpClientService, 16 | private readonly logger: MyLoggerService, 17 | @Inject(forwardRef(() => AuthService)) 18 | private readonly authService: AuthService, 19 | private readonly userDaoService: UserDaoService, 20 | @InjectRepository(UsersEntity) private userRepo: Repository, 21 | ) {} 22 | async fetchUsers() { 23 | try { 24 | this.logger.log(`handling fetchUsers`); 25 | try { 26 | await this.apiService.fetch('get', {}); 27 | } catch (err) { 28 | console.log(err); 29 | } 30 | return await this.userRepo.find({}); 31 | } catch (err) { 32 | this.logger.error(err); 33 | } 34 | } 35 | 36 | async createUser(body: CreateUserDto) { 37 | return await this.userRepo.save(body); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/domain.module.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MiddlewareConsumer, 3 | Module, 4 | NestModule, 5 | RequestMethod, 6 | } from '@nestjs/common'; 7 | import { DBModule } from '@dev/database'; 8 | 9 | import { RouteInfo } from '@nestjs/common/interfaces'; 10 | import { AuthMiddleware } from '../core/middleware/auth.middleware'; 11 | import { AppLoggerModule, LoggerMiddleware } from '@dev/logger'; 12 | import { UserModule } from './user/user.module'; 13 | import User from './user/user.entity'; 14 | import { PostModule } from './post/post.module'; 15 | import { AuthModule } from './authentication/auth.module'; 16 | export const GLOBAL_PREFIX = '/api/v1'; 17 | 18 | @Module({ 19 | imports: [ 20 | AppLoggerModule, 21 | PostModule, 22 | UserModule, 23 | AuthModule, 24 | DBModule.forRoot({ 25 | entities: [User], 26 | }), 27 | ], 28 | providers: [], 29 | controllers: [], 30 | }) 31 | export class DomainModule { 32 | /* 33 | public authRoutes: Array = [ 34 | { 35 | path: `*`, 36 | method: RequestMethod.ALL, 37 | }, 38 | ]; 39 | 40 | public publicRoutes: Array = [ 41 | { 42 | path: `${GLOBAL_PREFIX}/health`, 43 | method: RequestMethod.GET, 44 | }, 45 | ]; 46 | 47 | configure(consumer: MiddlewareConsumer) { 48 | consumer 49 | .apply(AuthMiddleware) 50 | .exclude(...this.publicRoutes) 51 | .forRoutes(...this.authRoutes); 52 | 53 | consumer.apply(LoggerMiddleware).forRoutes('*'); 54 | } */ 55 | } 56 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/docs/swagger.ts: -------------------------------------------------------------------------------- 1 | import { INestApplication } from '@nestjs/common'; 2 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 3 | import * as basicAuth from 'express-basic-auth'; 4 | import { ConfigService } from '@dev/config'; 5 | import { SWAGGER_CONFIG } from './swagger.config'; 6 | 7 | /** 8 | * Creates an OpenAPI document for an application, via swagger. 9 | * @param app the nestjs application 10 | * @returns the OpenAPI document 11 | */ 12 | const SWAGGER_ENVS = ['local', 'development', 'production']; 13 | 14 | export function createDocument(app: INestApplication) { 15 | const builder = new DocumentBuilder() 16 | .setTitle(SWAGGER_CONFIG.title) 17 | .addBearerAuth( 18 | { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, 19 | 'authorization', 20 | ) 21 | .setDescription(SWAGGER_CONFIG.description) 22 | .setVersion(SWAGGER_CONFIG.version); 23 | for (const tag of SWAGGER_CONFIG.tags) { 24 | builder.addTag(tag); 25 | } 26 | const options = builder.build(); 27 | const env = app.get(ConfigService).get().env; 28 | const { username, password }: any = app.get(ConfigService).get().swagger; 29 | if (SWAGGER_ENVS.includes(env)) { 30 | app.use( 31 | '/docs', 32 | basicAuth({ 33 | challenge: true, 34 | users: { 35 | [username]: password, 36 | }, 37 | }), 38 | ); 39 | const document = SwaggerModule.createDocument(app, options); 40 | SwaggerModule.setup('docs', app, document); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/docs/swagger.ts: -------------------------------------------------------------------------------- 1 | import { INestApplication } from '@nestjs/common'; 2 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 3 | import * as basicAuth from 'express-basic-auth'; 4 | import { ConfigService } from '@dev/config'; 5 | import { SWAGGER_CONFIG } from './swagger.config'; 6 | 7 | /** 8 | * Creates an OpenAPI document for an application, via swagger. 9 | * @param app the nestjs application 10 | * @returns the OpenAPI document 11 | */ 12 | const SWAGGER_ENVS = ['local', 'development', 'production']; 13 | 14 | export function createDocument(app: INestApplication) { 15 | const builder = new DocumentBuilder() 16 | .setTitle(SWAGGER_CONFIG.title) 17 | .addBearerAuth( 18 | { type: 'http', scheme: 'bearer', bearerFormat: 'JWT' }, 19 | 'authorization', 20 | ) 21 | .setDescription(SWAGGER_CONFIG.description) 22 | .setVersion(SWAGGER_CONFIG.version); 23 | for (const tag of SWAGGER_CONFIG.tags) { 24 | builder.addTag(tag); 25 | } 26 | const options = builder.build(); 27 | const env = app.get(ConfigService).get().env; 28 | const { username, password }: any = app.get(ConfigService).get().swagger; 29 | if (SWAGGER_ENVS.includes(env)) { 30 | app.use( 31 | '/docs', 32 | basicAuth({ 33 | challenge: true, 34 | users: { 35 | [username]: password, 36 | }, 37 | }), 38 | ); 39 | const document = SwaggerModule.createDocument(app, options); 40 | SwaggerModule.setup('docs', app, document); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /packages/app-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dev/logger", 3 | "version": "1.0.0", 4 | "main": "./build/index.js", 5 | "types": "./build/index.d.ts", 6 | "scripts": { 7 | "build": "tsc", 8 | "tsc-version": "tsc --version", 9 | "check-engines": "node ../../node_modules/fbjs-scripts/node/check-dev-engines.js package.json", 10 | "clean": "rimraf build && rimraf coverage", 11 | "prebuild": "npm run clean && npm run check-engines", 12 | "prepublishOnly": "npm run build", 13 | "pretest": "npm run build", 14 | "test": "npm run test:ci", 15 | "test:ci": "jest --ci --collectCoverage --maxWorkers 2 --passWithNoTests" 16 | }, 17 | "engines": { 18 | "node": ">=14.x", 19 | "npm": ">=6.14.x" 20 | }, 21 | "devEngines": { 22 | "node": ">=14.x", 23 | "npm": ">=6.14.x" 24 | }, 25 | "dependencies": { 26 | "@dev/config": "*", 27 | "@types/luxon": "^3.3.0", 28 | "luxon": "^3.3.0", 29 | "moment": "^2.29.4", 30 | "winston": "^3.8.2" 31 | }, 32 | "devDependencies": { 33 | "@nestjs/common": "^9.0.0", 34 | "@nestjs/config": "2.3.1", 35 | "@nestjs/core": "^9.0.0", 36 | "@nestjs/testing": "^9.0.0", 37 | "@nestjs/typeorm": "^9.0.1", 38 | "@types/express": "^4.17.13", 39 | "@types/jest": "27.0.2", 40 | "@types/node": "^17.0.45", 41 | "@types/uuid": "^8.3.4", 42 | "express": "^4.18.2", 43 | "reflect-metadata": "^0.1.13", 44 | "rxjs": "^7.2.0", 45 | "tslib": "^2.5.0", 46 | "typeorm": "^0.3.12", 47 | "typescript": "^4.7.4" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/pokemon/pokemon.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm'; 4 | import { PokemonEntity } from '../../entity/pokemon.entity'; 5 | import { CreatePokemonDto } from '../../ressources/pokemon.ressource'; 6 | 7 | @Injectable() 8 | export class PokemonService { 9 | constructor( 10 | @InjectRepository(PokemonEntity) 11 | private readonly PokemonRepository: Repository, 12 | ) {} 13 | 14 | async createPokemon(data: CreatePokemonDto): Promise { 15 | let pokemon = new PokemonEntity(); 16 | pokemon.name = data.name; 17 | pokemon.pokedex = data.pokedex; 18 | pokemon.type = data.type; 19 | await pokemon.save(); 20 | return pokemon; 21 | } 22 | 23 | async delete(id): Promise { 24 | const pokemon = await PokemonEntity.findOne(id); 25 | this.PokemonRepository.delete(pokemon as any); 26 | return pokemon; 27 | } 28 | 29 | async update(id, data: CreatePokemonDto): Promise { 30 | const pokemon = await PokemonEntity.findOne(id); 31 | pokemon.name = data.name; 32 | pokemon.pokedex = data.pokedex; 33 | pokemon.type = data.type; 34 | await pokemon.save(); 35 | return pokemon; 36 | } 37 | 38 | async show(id: string) { 39 | return await this.PokemonRepository.findOne({ where: { id } }); 40 | } 41 | 42 | async getPokemons() { 43 | return await this.PokemonRepository.find(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/app.ts: -------------------------------------------------------------------------------- 1 | import Controller from "./interfaces/controller.interface"; 2 | import * as cookieParser from "cookie-parser"; 3 | import * as express from "express"; 4 | import errorMiddleware from "./middleware/error.middleware"; 5 | import * as mongoose from "mongoose"; 6 | const bodyParser = require("body-parser"); 7 | 8 | class App { 9 | public app: express.Application; 10 | 11 | constructor(controller: Controller[]) { 12 | this.app = express(); 13 | this.connectToDatabase(); 14 | this.initializeMiddleware(); 15 | this.initializeControllers(controller); 16 | this.initializeErrorHandling(); 17 | } 18 | 19 | public listen() { 20 | this.app.listen(process.env.PORT || 3002, () => { 21 | console.log(`application started on PORT ${process.env.PORT || 3002}`); 22 | }); 23 | } 24 | private initializeErrorHandling() { 25 | this.app.use(errorMiddleware); 26 | } 27 | public getServer() { 28 | return this.app; 29 | } 30 | 31 | private initializeMiddleware() { 32 | this.app.use(bodyParser.json()); 33 | this.app.use(bodyParser.urlencoded({ extended: false })); 34 | this.app.use(cookieParser()); 35 | } 36 | private initializeControllers(controllers: Controller[]) { 37 | controllers.forEach((controller) => { 38 | this.app.use("/", controller.router); 39 | }); 40 | } 41 | private connectToDatabase() { 42 | mongoose.connect(process.env.MONGO_URL, { 43 | useNewUrlParser: true, 44 | useUnifiedTopology: true, 45 | }); 46 | } 47 | } 48 | 49 | export default App; 50 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/routes/todos.ts: -------------------------------------------------------------------------------- 1 | import todo from "../models/todo"; 2 | import { publicProcedure, router } from "../trpc"; 3 | import { z } from "zod"; 4 | 5 | const getTodos = publicProcedure.query(async () => { 6 | const todos = await todo.find(); 7 | return todos; 8 | }); 9 | 10 | /** 11 | * Add new TODO to db 12 | */ 13 | const addTodo = publicProcedure 14 | .input( 15 | z.object({ 16 | title: z.string(), 17 | description: z.string(), 18 | }) 19 | ) 20 | .mutation(async ({ input: { title, description } }) => { 21 | const newTodo = new todo({ title, description }); 22 | const addedTodo = await newTodo.save(); 23 | return addedTodo; 24 | }); 25 | 26 | const deleteTodo = publicProcedure 27 | .input(z.string()) 28 | .mutation(async ({ input }) => { 29 | console.log("input: ", input); 30 | const deletedTodo = await todo.findByIdAndDelete(input); 31 | if (!deletedTodo) throw new Error("Todo not found"); 32 | return true; 33 | }); 34 | 35 | const toggleTodoStatus = publicProcedure 36 | .input(z.string()) 37 | .mutation(async ({ input }) => { 38 | try { 39 | const foundTodo = await todo.findById(input); 40 | if (!foundTodo) throw new Error("Todo not found"); 41 | foundTodo.done = !foundTodo.done; 42 | await foundTodo.save(); 43 | return true; 44 | } catch (error) { 45 | console.error(error); 46 | return false; 47 | } 48 | }); 49 | 50 | export const todosRouter = router({ 51 | get: getTodos, 52 | add: addTodo, 53 | delete: deleteTodo, 54 | toggleTodoStatus, 55 | }); 56 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/user/user.controller.ts: -------------------------------------------------------------------------------- 1 | import Controller from "../interfaces/controller.interface"; 2 | import { Request, Response, NextFunction, Router } from "express"; 3 | import userModel from "./user.model"; 4 | import postModel from "../post/post.model"; 5 | import UserNotFoundException from "../exceptions/user.exception"; 6 | import RequestWithUser from "../interfaces/req.user"; 7 | import UnauthorizedException from "../exceptions/user.acces.exception"; 8 | 9 | class UserController implements Controller { 10 | public path = "/users"; 11 | public router = Router(); 12 | public user = userModel; 13 | public post = postModel; 14 | 15 | constructor() { 16 | this.initializeRoutes(); 17 | } 18 | 19 | private initializeRoutes() { 20 | this.router.get(`${this.path}/:id`, this.getUserById); 21 | } 22 | 23 | private getUserById = async ( 24 | req: Request, 25 | res: Response, 26 | next: NextFunction 27 | ) => { 28 | const id = req.params.id; 29 | const userQuery = this.user.findById(id); 30 | const user = userQuery.populate("posts").exec(); 31 | if (user) { 32 | res.send(user); 33 | } else { 34 | next(new UserNotFoundException(id)); 35 | } 36 | }; 37 | 38 | private getAllPostsOfUser = async ( 39 | req: RequestWithUser, 40 | res: Response, 41 | next: NextFunction 42 | ) => { 43 | const id = req.params.id; 44 | if (id === req.user._id) { 45 | const data = await this.post.find({ author: id }); 46 | res.send(data); 47 | } 48 | next(new UnauthorizedException(id)); 49 | }; 50 | } 51 | 52 | export default UserController; 53 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/league/league.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.LeagueModule = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var league_resolver_1 = require('./league.resolver'); 25 | var league_service_1 = require('./league.service'); 26 | var typeorm_1 = require('@nestjs/typeorm'); 27 | var league_entity_1 = require('../../entity/league.entity'); 28 | var LeagueModule = /** @class */ (function () { 29 | function LeagueModule() {} 30 | LeagueModule = __decorate( 31 | [ 32 | (0, common_1.Module)({ 33 | imports: [ 34 | typeorm_1.TypeOrmModule.forFeature([league_entity_1.LeagueEntity]), 35 | ], 36 | providers: [ 37 | league_resolver_1.LeagueResolver, 38 | league_service_1.LeagueService, 39 | ], 40 | }), 41 | ], 42 | LeagueModule, 43 | ); 44 | return LeagueModule; 45 | })(); 46 | exports.LeagueModule = LeagueModule; 47 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/pokemon/pokemon.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.PokemonModule = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var pokemon_service_1 = require('./pokemon.service'); 25 | var typeorm_1 = require('@nestjs/typeorm'); 26 | var pokemon_entity_1 = require('../../entity/pokemon.entity'); 27 | var pokemon_resolver_1 = require('./pokemon.resolver'); 28 | var PokemonModule = /** @class */ (function () { 29 | function PokemonModule() {} 30 | PokemonModule = __decorate( 31 | [ 32 | (0, common_1.Module)({ 33 | imports: [ 34 | typeorm_1.TypeOrmModule.forFeature([pokemon_entity_1.PokemonEntity]), 35 | ], 36 | providers: [ 37 | pokemon_service_1.PokemonService, 38 | pokemon_resolver_1.PokemonResolver, 39 | ], 40 | }), 41 | ], 42 | PokemonModule, 43 | ); 44 | return PokemonModule; 45 | })(); 46 | exports.PokemonModule = PokemonModule; 47 | -------------------------------------------------------------------------------- /packages/app-database/src/db.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { DbConfig } from "./db.interface"; 3 | import { TypeOrmModule, TypeOrmModuleOptions } from "@nestjs/typeorm"; 4 | import { ConfigModule } from "@dev/config"; 5 | import { ConfigService } from "@dev/config"; 6 | import { ConfigDatabase } from "@dev/config"; 7 | 8 | @Module({}) 9 | export class DBModule { 10 | private static getConnectionOptions( 11 | config: ConfigService, 12 | dbConfig: DbConfig 13 | ): TypeOrmModuleOptions { 14 | const dbData = config.get().db; 15 | if (!dbData) { 16 | throw Error(""); 17 | } 18 | const connectionOptions = this.getConnectionOptionsPostgres(dbData); 19 | return { 20 | ...connectionOptions, 21 | entities: dbConfig.entities, 22 | synchronize: true, 23 | logging: true, 24 | }; 25 | } 26 | 27 | private static getConnectionOptionsPostgres( 28 | dbData: ConfigDatabase 29 | ): TypeOrmModuleOptions { 30 | return { 31 | type: "postgres", 32 | url: dbData.url, 33 | keepConnectionAlive: true, 34 | ssl: 35 | process.env.NODE_ENV !== "local" && process.env.NODE_ENV !== "test" 36 | ? { rejectUnauthorized: false } 37 | : false, 38 | }; 39 | } 40 | 41 | public static forRoot(dbConfig: DbConfig) { 42 | return { 43 | module: DBModule, 44 | imports: [ 45 | TypeOrmModule.forRootAsync({ 46 | imports: [ConfigModule], 47 | useFactory: (configService: ConfigService) => { 48 | return DBModule.getConnectionOptions(configService, dbConfig); 49 | }, 50 | inject: [ConfigService], 51 | }), 52 | ], 53 | controllers: [], 54 | providers: [], 55 | exports: [], 56 | }; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/graphql.schema.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * ------------------------------------------------------- 3 | * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY) 4 | * ------------------------------------------------------- 5 | */ 6 | 7 | /* tslint:disable */ 8 | /* eslint-disable */ 9 | export class League { 10 | id: string; 11 | name: string; 12 | pokemons?: Nullable; 13 | } 14 | 15 | export abstract class IQuery { 16 | abstract leagues(): Nullable | Promise>; 17 | 18 | abstract league(id?: Nullable): League | Promise; 19 | 20 | abstract pokemons(): Nullable | Promise>; 21 | 22 | abstract pokemon(id?: Nullable): Pokemon | Promise; 23 | } 24 | 25 | export abstract class IMutation { 26 | abstract createLeague( 27 | name: string, 28 | ): Nullable | Promise>; 29 | 30 | abstract updateLeague( 31 | id?: Nullable, 32 | name: string, 33 | ): Nullable | Promise>; 34 | 35 | abstract deleteLeague( 36 | id?: Nullable, 37 | ): Nullable | Promise>; 38 | 39 | abstract create( 40 | name: string, 41 | type: string, 42 | pokedex: string, 43 | ): Nullable | Promise>; 44 | 45 | abstract update( 46 | id: string, 47 | name: string, 48 | type: string, 49 | pokedex: string, 50 | ): Nullable | Promise>; 51 | 52 | abstract delete(id: string): Nullable | Promise>; 53 | } 54 | 55 | export class Pokemon { 56 | id: string; 57 | name: string; 58 | pokedex: string; 59 | type: string; 60 | league: League; 61 | } 62 | 63 | export class Deleted { 64 | delete: boolean; 65 | } 66 | 67 | type Nullable = T | null; 68 | -------------------------------------------------------------------------------- /apps/nest-graphql-prisma/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/nest-graphql-prisma", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "prebuild": "rimraf dist", 10 | "build": "nest build", 11 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 12 | "start": "nest start", 13 | "start:dev": "nest start --watch", 14 | "start:debug": "nest start --debug --watch", 15 | "start:prod": "node dist/main", 16 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 17 | "test": "jest", 18 | "test:watch": "jest --watch", 19 | "test:cov": "jest --coverage", 20 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 21 | "test:e2e": "jest --config ./test/jest-e2e.json" 22 | }, 23 | "dependencies": { 24 | "@apollo/gateway": "^0.35.1", 25 | "@nestjs/common": "^9.0.0", 26 | "@nestjs/core": "^9.0.0", 27 | "@nestjs/graphql": "^9.0.0", 28 | "@nestjs/platform-express": "^9.0.0", 29 | "@prisma/client": "^2.28.0", 30 | "apollo-server-express": "^2.25.2", 31 | "graphql": "^15.5.1", 32 | "graphql-tools": "^8.0.0", 33 | "reflect-metadata": "^0.1.13", 34 | "rimraf": "^3.0.2", 35 | "rxjs": "^7.2.0", 36 | "ts-morph": "^11.0.3" 37 | }, 38 | "devDependencies": { 39 | "@nestjs/cli": "^9.0.0", 40 | "@nestjs/schematics": "^9.0.0", 41 | "@nestjs/testing": "^9.0.0", 42 | "@types/express": "^4.17.13", 43 | "@types/jest": "^26.0.24", 44 | "@types/node": "^16.0.0", 45 | "@types/supertest": "^2.0.11", 46 | "prisma": "^2.28.0", 47 | "supertest": "^6.1.3", 48 | "ts-jest": "^27.0.3", 49 | "ts-loader": "^9.2.3", 50 | "ts-node": "^10.9.1", 51 | "tsconfig-paths": "^3.10.1", 52 | "typescript": "^4.3.5" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /packages/app-config/src/config.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { DEFAULT_CONFIG } from "./config.default"; 3 | import { ConfigData, ConfigDatabase, ConfigSwagger } from "./config.interface"; 4 | 5 | @Injectable() 6 | export class ConfigService { 7 | private config: ConfigData; 8 | constructor(data: ConfigData = DEFAULT_CONFIG) { 9 | this.config = data; 10 | } 11 | 12 | public loadFromEnv() { 13 | this.config = this.parseConfigFromEnv(process.env); 14 | } 15 | 16 | private parseConfigFromEnv(env: NodeJS.ProcessEnv): ConfigData { 17 | return { 18 | env: env.NODE_ENV || DEFAULT_CONFIG.env, 19 | port: parseInt(env.PORT!, 10), 20 | db: this.parseDBConfig(env, DEFAULT_CONFIG.db), 21 | swagger: this.parseSwaggerConfig(env, DEFAULT_CONFIG.swagger), 22 | logLevel: env.LOG_LEVEL!, 23 | auth: { 24 | secret: env.AUTH_SECRET || "", 25 | expiry: env.AUTH_TOKEN_EXPIRY || "", 26 | }, 27 | email: { 28 | service_name: env.EMAIL_SERVICE_NAME || "", 29 | username: env.EMAIL_USERNAME || "", 30 | password: env.EMAIL_PASSWORD || "", 31 | }, 32 | externalApi: { 33 | apiKey: env.PLATFORM_API_KEY || "", 34 | apiUrl: env.PLATFORM_API_URL || "", 35 | }, 36 | }; 37 | } 38 | private parseDBConfig( 39 | env: NodeJS.ProcessEnv, 40 | defaultConfig: Readonly 41 | ) { 42 | return { 43 | url: env.DATABASE_URL || defaultConfig.url, 44 | }; 45 | } 46 | private parseSwaggerConfig( 47 | env: NodeJS.ProcessEnv, 48 | defaultConfig: Readonly 49 | ) { 50 | return { 51 | username: env.SWAGGER_USERNAME || defaultConfig.username, 52 | password: env.SWAGGER_PASSWORD || defaultConfig.password, 53 | }; 54 | } 55 | 56 | public get(): Readonly { 57 | return this.config; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/api/api.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.ApiModule = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var core_1 = require('@nestjs/core'); 25 | var logging_interceptor_1 = require('../shared/logging.interceptor'); 26 | var pokemon_module_1 = require('./pokemon/pokemon.module'); 27 | var user_module_1 = require('./user/user.module'); 28 | var league_module_1 = require('./league/league.module'); 29 | var ApiModule = /** @class */ (function () { 30 | function ApiModule() {} 31 | ApiModule = __decorate( 32 | [ 33 | (0, common_1.Module)({ 34 | imports: [ 35 | user_module_1.UserModule, 36 | pokemon_module_1.PokemonModule, 37 | league_module_1.LeagueModule, 38 | ], 39 | providers: [ 40 | { 41 | provide: core_1.APP_INTERCEPTOR, 42 | useClass: logging_interceptor_1.LoggingInterceptor, 43 | }, 44 | ], 45 | exports: [ 46 | user_module_1.UserModule, 47 | pokemon_module_1.PokemonModule, 48 | league_module_1.LeagueModule, 49 | ], 50 | }), 51 | ], 52 | ApiModule, 53 | ); 54 | return ApiModule; 55 | })(); 56 | exports.ApiModule = ApiModule; 57 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/users/user.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Body, 3 | Controller, 4 | Get, 5 | HttpCode, 6 | HttpStatus, 7 | Post, 8 | Req, 9 | UseGuards, 10 | UsePipes, 11 | ValidationPipe, 12 | } from '@nestjs/common'; 13 | import { Request } from 'express'; 14 | import { UserService } from './user.service'; 15 | import { UsersEntity } from './user.entity'; 16 | import { 17 | ApiBearerAuth, 18 | ApiConsumes, 19 | ApiCreatedResponse, 20 | ApiOkResponse, 21 | ApiOperation, 22 | ApiTags, 23 | } from '@nestjs/swagger'; 24 | import { CrateUserResponseDto, CreateUserDto } from './user.dto'; 25 | import { AuthGuard } from 'src/app/core/guard/api-guard'; 26 | import { RoleAllowed } from 'src/app/core/decorator/role-allowed'; 27 | import { User } from 'src/app/core/decorator/user'; 28 | 29 | @ApiTags('users') 30 | @Controller('users') 31 | @ApiBearerAuth('authorization') 32 | @UsePipes( 33 | new ValidationPipe({ 34 | whitelist: true, 35 | transform: true, 36 | }), 37 | ) 38 | export class UserController { 39 | constructor(private readonly userService: UserService) {} 40 | 41 | @UseGuards(AuthGuard) 42 | //@RoleAllowed('admin', 'user') 43 | @HttpCode(HttpStatus.OK) 44 | @ApiOkResponse({ 45 | type: [CrateUserResponseDto], 46 | description: 'user fetched successfully', 47 | }) 48 | @ApiOperation({ description: 'user fetch api ' }) 49 | @ApiConsumes('application/json') 50 | @Get() 51 | async findAll(@User() user: any): Promise { 52 | return await this.userService.fetchUsers(); 53 | } 54 | 55 | @HttpCode(HttpStatus.CREATED) 56 | @ApiCreatedResponse({ 57 | type: CrateUserResponseDto, 58 | description: 'user created successfully', 59 | }) 60 | @ApiOperation({ description: 'user create api ' }) 61 | @ApiConsumes('application/json') 62 | @Post() 63 | async create(@Body() body: CreateUserDto): Promise { 64 | return await this.userService.createUser(body); 65 | } 66 | } 67 | 68 | /* 69 | 70 | Module 71 | Controller 72 | Services 73 | Dto --> validation Pipe works 74 | DI - Deps Injection 75 | @nestjs/typeorm 76 | 77 | */ 78 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Body, 3 | Req, 4 | Controller, 5 | HttpCode, 6 | Post, 7 | UseGuards, 8 | Get, 9 | ClassSerializerInterceptor, 10 | UseInterceptors, 11 | Res, 12 | } from '@nestjs/common'; 13 | import { AuthenticationService } from './auth.service'; 14 | import { 15 | ApiConsumes, 16 | ApiCreatedResponse, 17 | ApiOkResponse, 18 | } from '@nestjs/swagger'; 19 | import RegisterDto from './dto/register.dto'; 20 | import { LocalAuthGuard } from './local.auth.guard'; 21 | import RequestWithUser from './request-with.user'; 22 | import { Response } from 'express'; 23 | import JwtAuthenticationGuard from './jwt-authentication.guard'; 24 | 25 | @Controller('authentication') 26 | @UseInterceptors(ClassSerializerInterceptor) 27 | export class AuthenticationController { 28 | constructor(private readonly authenticationService: AuthenticationService) {} 29 | 30 | @Post('register') 31 | @HttpCode(201) 32 | @ApiConsumes('application/json') 33 | @ApiCreatedResponse({ 34 | description: 'user registered successfully', 35 | }) 36 | async register(@Body() body: RegisterDto) { 37 | return this.authenticationService.register(body); 38 | } 39 | 40 | @UseGuards(LocalAuthGuard) 41 | @Post('login') 42 | @HttpCode(200) 43 | @ApiConsumes('application/json') 44 | @ApiCreatedResponse({ 45 | description: 'user logged in successfully', 46 | }) 47 | async login(@Req() request: RequestWithUser) { 48 | const { user } = request; 49 | const token = this.authenticationService.getCookiesWithJwtToken(user); 50 | return { 51 | token, 52 | }; 53 | } 54 | 55 | @UseGuards(JwtAuthenticationGuard) 56 | @Post('logout') 57 | @HttpCode(200) 58 | @ApiConsumes('application/json') 59 | @ApiCreatedResponse({ 60 | description: 'user session logout in successfully', 61 | }) 62 | async logout(@Req() request: RequestWithUser) { 63 | const { user } = request; 64 | return null; 65 | } 66 | 67 | @UseGuards(JwtAuthenticationGuard) 68 | @Get() 69 | authenticate(@Req() request: RequestWithUser) { 70 | return request.user; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/nest-graphql-typeorm", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "scripts": { 8 | "prebuild": "rimraf dist", 9 | "build": "nest build", 10 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 11 | "start": "nest start", 12 | "start:dev": "nest start --watch", 13 | "start:debug": "nest start --debug --watch", 14 | "start:prod": "node dist/main", 15 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --config ./test/jest-e2e.json" 21 | }, 22 | "dependencies": { 23 | "@dev/config": "*", 24 | "@dev/http": "*", 25 | "@dev/email": "*", 26 | "@dev/logger":"*", 27 | "@dev/database": "*", 28 | "@apollo/gateway": "^0.35.1", 29 | "@nestjs/common": "^9.0.0", 30 | "@nestjs/core": "^9.0.0", 31 | "@nestjs/graphql": "^9.0.0", 32 | "@nestjs/passport": "^9.0.3", 33 | "@nestjs/platform-express": "^9.0.0", 34 | "@nestjs/swagger": "^6.3.0", 35 | "@nestjs/typeorm": "^9.0.1", 36 | "@prisma/client": "^2.28.0", 37 | "apollo-server-express": "^2.25.2", 38 | "dotenv": "^16.1.4", 39 | "graphql": "^15.5.1", 40 | "graphql-tools": "^8.0.0", 41 | "reflect-metadata": "^0.1.13", 42 | "rimraf": "^3.0.2", 43 | "rxjs": "^7.2.0", 44 | "ts-morph": "^11.0.3", 45 | "typeorm": "^0.3.12" 46 | }, 47 | "devDependencies": { 48 | "@nestjs/cli": "^9.0.0", 49 | "@nestjs/schematics": "^9.0.0", 50 | "@nestjs/testing": "^9.0.0", 51 | "@types/express": "^4.17.13", 52 | "@types/jest": "^26.0.24", 53 | "@types/node": "^16.0.0", 54 | "@types/supertest": "^2.0.11", 55 | "prisma": "^2.28.0", 56 | "supertest": "^6.1.3", 57 | "ts-jest": "^27.0.3", 58 | "ts-loader": "^9.2.3", 59 | "ts-node": "^10.9.1", 60 | "tsconfig-paths": "^3.10.1", 61 | "typescript": "^4.3.5" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /apps/express-typescript-apis/src/controller/auth.ts: -------------------------------------------------------------------------------- 1 | import express from "express"; 2 | import { random, authentication } from "../helpers/index"; 3 | import { createUser, getUserByEmail } from "../db/users"; 4 | 5 | export const login = async (req: express.Request, res: express.Response) => { 6 | try { 7 | const { email, password } = req.body; 8 | if (!email || !password) { 9 | return res.sendStatus(400); 10 | } 11 | const user = await getUserByEmail(email).select( 12 | "+authentication.salt +authentication.password" 13 | ); 14 | if (!user) { 15 | return res.sendStatus(400); 16 | } 17 | const expectedHash = authentication(user.authentication.salt, password); 18 | if (user.authentication.password !== expectedHash) { 19 | return res.sendStatus(403); 20 | } 21 | 22 | const salt = random(); 23 | user.authentication.sessionToken = authentication( 24 | salt, 25 | user._id.toString() 26 | ); 27 | await user.save(); 28 | 29 | res.cookie("auth-cookie", user.authentication.sessionToken, { 30 | domain: "localhost", 31 | path: "/", 32 | }); 33 | return res 34 | .status(200) 35 | .json({ email: user.email, username: user.username }) 36 | .end(); 37 | } catch (err) { 38 | throw err; 39 | } 40 | }; 41 | 42 | export const register = async (req: express.Request, res: express.Response) => { 43 | console.log("hello"); 44 | try { 45 | const { email, password, username } = req.body; 46 | if (!email || !password || !username) { 47 | return res.sendStatus(400); 48 | } 49 | const existingUser = await getUserByEmail(email); 50 | console.log(existingUser); 51 | 52 | if (existingUser) { 53 | return res.sendStatus(409); 54 | } 55 | const salt = random(); 56 | const user = await createUser({ 57 | email, 58 | username, 59 | authentication: { 60 | salt, 61 | password: authentication(salt, password), 62 | }, 63 | }); 64 | return res 65 | .status(201) 66 | .json({ email: user.email, username: user.username }) 67 | .end(); 68 | } catch (err) { 69 | console.log(err); 70 | throw err; 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/README.md: -------------------------------------------------------------------------------- 1 | ## TRPC API with Reactjs Consumer all of them with TypeScript 2 | 3 | API Rest with the these operations 4 | * GET 5 | * POST 6 | * DELETE 7 | 8 | It's fully functional persisting data in mongodb database 9 | 10 | ### 🛠  This project uses the following technologies: 11 | 12 | * NodeJS 13 | * Express 14 | * @trpc/server 15 | * mongoose 16 | * zod 17 | * dotenv 18 | * ts-node-dev ... 19 | 20 | ### Run this project in your local machine 21 | > clone this repository, you need git installed in your machine ¡ how to install link [![GIT](https://img.shields.io/badge/Git-0077B5?style=for-the-badge&logo=git&logoColor=red)](https://github.com/git-guides/install-git) 22 | >> In your local machine open some cmd, bash etc command line tool. Located where you will have your local repository. You can navigate with cd somepath/mydirectory etc. 23 | ```bash 24 | git glone https://github.com/raulcv/trpc-todo.git 25 | ``` 26 | 27 | ### For backend API 28 | > Enter to your local repository created with git clone 29 | ```bash 30 | cd trpc-todo 31 | ``` 32 | 33 | > Install NPM Dependencies 34 | ```bash 35 | npm install 36 | ``` 37 | 38 | > create a .env or you can created it manually into your project folder 39 | ```bash 40 | touch .env 41 | ``` 42 | 43 | Into .env file copy from envtext.txt file included, and change with your own credentials 44 | 45 | Run the tRPC API on dev mode 46 | ```bash 47 | npm run dev 48 | ``` 49 | Open your browser and type localhost:3000/ 50 | 51 | ### For react frontend APP 52 | > Go to trpc-client 53 | ```bash 54 | cd trpc-client 55 | ``` 56 | 57 | > Install NPM Dependencies for client app 58 | ```bash 59 | npm install 60 | ``` 61 | 62 | Finally run the React APP on dev mode 🤪 63 | ```bash 64 | npm run dev 65 | ``` 66 | 67 | Open your browser and type localhost:3007/ 68 | 69 | # 70 |

71 | With :heart: by raulcv 72 |

73 | 74 | # 75 |

🤗 If you found helpful this repo, let me a star or ... 🐣

76 |

77 | Buy Me A Coffee 78 |

79 | 80 | -------------------------------------------------------------------------------- /apps/express-trpc-apis/src/README.md: -------------------------------------------------------------------------------- 1 | ## TRPC API with Reactjs Consumer all of them with TypeScript 2 | 3 | API Rest with the these operations 4 | * GET 5 | * POST 6 | * DELETE 7 | 8 | It's fully functional persisting data in mongodb database 9 | 10 | ### 🛠  This project uses the following technologies: 11 | 12 | * NodeJS 13 | * Express 14 | * @trpc/server 15 | * mongoose 16 | * zod 17 | * dotenv 18 | * ts-node-dev ... 19 | 20 | ### Run this project in your local machine 21 | > clone this repository, you need git installed in your machine ¡ how to install link [![GIT](https://img.shields.io/badge/Git-0077B5?style=for-the-badge&logo=git&logoColor=red)](https://github.com/git-guides/install-git) 22 | >> In your local machine open some cmd, bash etc command line tool. Located where you will have your local repository. You can navigate with cd somepath/mydirectory etc. 23 | ```bash 24 | git glone https://github.com/raulcv/trpc-todo.git 25 | ``` 26 | 27 | ### For backend API 28 | > Enter to your local repository created with git clone 29 | ```bash 30 | cd trpc-todo 31 | ``` 32 | 33 | > Install NPM Dependencies 34 | ```bash 35 | npm install 36 | ``` 37 | 38 | > create a .env or you can created it manually into your project folder 39 | ```bash 40 | touch .env 41 | ``` 42 | 43 | Into .env file copy from envtext.txt file included, and change with your own credentials 44 | 45 | Run the tRPC API on dev mode 46 | ```bash 47 | npm run dev 48 | ``` 49 | Open your browser and type localhost:3000/ 50 | 51 | ### For react frontend APP 52 | > Go to trpc-client 53 | ```bash 54 | cd trpc-client 55 | ``` 56 | 57 | > Install NPM Dependencies for client app 58 | ```bash 59 | npm install 60 | ``` 61 | 62 | Finally run the React APP on dev mode 🤪 63 | ```bash 64 | npm run dev 65 | ``` 66 | 67 | Open your browser and type localhost:3007/ 68 | 69 | # 70 |

71 | With :heart: by raulcv 72 |

73 | 74 | # 75 |

🤗 If you found helpful this repo, let me a star or ... 🐣

76 |

77 | Buy Me A Coffee 78 |

79 | 80 | -------------------------------------------------------------------------------- /apps/express-js-auth-apis/src/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | console.log(process.env); 3 | const express = require("express"); 4 | const bodyParser = require("body-parser"); 5 | const mongoose = require("mongoose"); 6 | const jwt = require("jsonwebtoken"); 7 | const User = require("./model/user"); 8 | const bcrypt = require("bcryptjs"); 9 | const path = require("path"); 10 | 11 | mongoose.connect("mongodb://localhost:27017/usermgmtdb", { 12 | useNewUrlParser: true, 13 | }); 14 | const app = express(); 15 | app.use("/", (req, res, next) => { 16 | next(); 17 | }); 18 | app.use("/", express.static(path.join(__dirname, "static"))); 19 | app.use(bodyParser.json()); 20 | 21 | app.post("/auth/login", async (req, res) => { 22 | const { username, password } = req.body; 23 | 24 | const user = await User.findOne({ username }); 25 | if (!user) { 26 | return res.status(400).json({ message: "invalid" }); 27 | } 28 | const isEqual = await bcrypt.compare(password, user.password); 29 | if (isEqual) { 30 | const token = jwt.sign( 31 | { 32 | id: user._id, 33 | username: user.username, 34 | }, 35 | process.env.SECRET 36 | ); 37 | 38 | return res.status(200).json({ status: "ok", access_token: token }); 39 | } 40 | return res.status(400).json({ message: "invalid username/password" }); 41 | }); 42 | 43 | app.post("/auth/register", async (req, res) => { 44 | const { username, password: plainTextPassword } = req.body; 45 | 46 | if (!username || typeof username !== "string") { 47 | return res.status(400).json({ message: "invalid payload" }); 48 | } 49 | if (!plainTextPassword || typeof plainTextPassword !== "string") { 50 | return res.status(400).json({ message: "invalid payload" }); 51 | } 52 | const password = await bcrypt.hash(plainTextPassword, 10); 53 | try { 54 | const response = await User.create({ 55 | username, 56 | password, 57 | }); 58 | return res 59 | .status(201) 60 | .json({ message: { id: response._id, username: response.username } }); 61 | } catch (err) { 62 | if (err.code === 11000) { 63 | return res.status(409).json({ 64 | message: `user already exists with this username ${username}`, 65 | }); 66 | } 67 | return res.status(500).send(); 68 | } 69 | }); 70 | 71 | app.listen(process.env.PORT || 3005, () => { 72 | console.log(`Example app listening on port ${process.env.PORT}`); 73 | }); 74 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/shared/logging.interceptor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.LoggingInterceptor = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var graphql_1 = require('@nestjs/graphql'); 25 | var operators_1 = require('rxjs/operators'); 26 | var LoggingInterceptor = /** @class */ (function () { 27 | function LoggingInterceptor() {} 28 | LoggingInterceptor.prototype.intercept = function (context, next) { 29 | var now = Date.now(); 30 | var req = context.switchToHttp().getRequest(); 31 | if (req) { 32 | var method_1 = req.method; 33 | var url_1 = req.url; 34 | return next.handle().pipe( 35 | (0, operators_1.tap)(function () { 36 | return common_1.Logger.log( 37 | '' 38 | .concat(method_1, ' ') 39 | .concat(url_1, ' ') 40 | .concat(Date.now() - now, 'ms'), 41 | context.getClass().name, 42 | ); 43 | }), 44 | ); 45 | } else { 46 | var ctx = graphql_1.GqlExecutionContext.create(context); 47 | var resolverName_1 = ctx.constructorRef.name; 48 | var info_1 = ctx.getInfo(); 49 | return next.handle().pipe( 50 | (0, operators_1.tap)(function () { 51 | return common_1.Logger.log( 52 | '' 53 | .concat(info_1.parentType, ' "') 54 | .concat(info_1.fieldName, '" ') 55 | .concat(Date.now() - now, 'ms'), 56 | resolverName_1, 57 | ); 58 | }), 59 | ); 60 | } 61 | }; 62 | LoggingInterceptor = __decorate( 63 | [(0, common_1.Injectable)()], 64 | LoggingInterceptor, 65 | ); 66 | return LoggingInterceptor; 67 | })(); 68 | exports.LoggingInterceptor = LoggingInterceptor; 69 | -------------------------------------------------------------------------------- /packages/app-http/src/http-client.module.ts: -------------------------------------------------------------------------------- 1 | import { DynamicModule, Global, Module, Provider, Type } from "@nestjs/common"; 2 | import { 3 | HttpClientModuleAsyncOptions, 4 | HttpClientModuleFactory, 5 | HttpClientModuleOptions, 6 | } from "./http-client.interface"; 7 | import { 8 | HTTP_CLIENT_MODULE_OPTIONS, 9 | HTTP_CLIENT_TOKEN, 10 | } from "./http-client.constants"; 11 | import { 12 | createHttpClientProvider, 13 | getHttpClientModuleOptions, 14 | } from "./http-client.provider"; 15 | 16 | @Global() 17 | @Module({}) 18 | export class HttpClientModule { 19 | public static forRoot(options: HttpClientModuleOptions): DynamicModule { 20 | const provider: Provider = createHttpClientProvider(options); 21 | return { 22 | module: HttpClientModule, 23 | providers: [provider], 24 | exports: [provider], 25 | }; 26 | } 27 | public static forRootAsync( 28 | options: HttpClientModuleAsyncOptions 29 | ): DynamicModule { 30 | const provider: Provider = { 31 | inject: [HTTP_CLIENT_MODULE_OPTIONS], 32 | provide: HTTP_CLIENT_TOKEN, 33 | useFactory: async (options: HttpClientModuleOptions) => { 34 | return getHttpClientModuleOptions(options); 35 | }, 36 | }; 37 | return { 38 | module: HttpClientModule, 39 | imports: options.imports, 40 | providers: [...this.createAsyncProviders(options), provider], 41 | exports: [provider], 42 | }; 43 | } 44 | private static createAsyncProviders( 45 | options: HttpClientModuleAsyncOptions 46 | ): Provider[] { 47 | if (options.useExisting || options.useFactory) { 48 | return [this.createAsyncOptionsProvider(options)]; 49 | } 50 | const useClass = options.useClass as Type; 51 | return [ 52 | this.createAsyncOptionsProvider(options), 53 | { 54 | provide: useClass, 55 | useClass, 56 | }, 57 | ]; 58 | } 59 | private static createAsyncOptionsProvider( 60 | options: HttpClientModuleAsyncOptions 61 | ): Provider { 62 | if (options.useFactory) { 63 | return { 64 | provide: HTTP_CLIENT_MODULE_OPTIONS, 65 | useFactory: options.useFactory, 66 | inject: options.inject || [], 67 | }; 68 | } 69 | 70 | const inject = [ 71 | (options.useClass || 72 | options.useExisting) as Type, 73 | ]; 74 | 75 | return { 76 | provide: HTTP_CLIENT_MODULE_OPTIONS, 77 | useFactory: async (optionsFactory: HttpClientModuleFactory) => 78 | await optionsFactory.createHttpModuleOptions(), 79 | inject, 80 | }; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /apps/nestjs-rest-api-auth/src/app/domain/authentication/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { 2 | BadRequestException, 3 | ConflictException, 4 | HttpException, 5 | HttpStatus, 6 | Injectable, 7 | InternalServerErrorException, 8 | } from '@nestjs/common'; 9 | import { UserService } from '../user/user.service'; 10 | import RegisterDto from './dto/register.dto'; 11 | import * as bcrypt from 'bcrypt'; 12 | import User from '../user/user.entity'; 13 | import { JwtService } from '@nestjs/jwt'; 14 | import { ConfigService } from '@dev/config'; 15 | 16 | enum PostgresErrorCode { 17 | UniqueViolation = '23505', 18 | } 19 | interface TokenPayload { 20 | userId: string; 21 | email: string; 22 | } 23 | 24 | @Injectable() 25 | export class AuthenticationService { 26 | constructor( 27 | private readonly userService: UserService, 28 | private readonly jwtService: JwtService, 29 | private readonly configService: ConfigService, 30 | ) {} 31 | 32 | public async register(body: RegisterDto) { 33 | const { email, name, password } = body; 34 | const hashPassword = await bcrypt.hash(password, 10); 35 | 36 | try { 37 | const isUserExists = await this.userService.getByEmail( 38 | email.toLowerCase(), 39 | ); 40 | if (isUserExists) { 41 | throw new ConflictException(`User with Email already exists`); 42 | } 43 | const createdUser = await this.userService.create({ 44 | ...body, 45 | password: hashPassword, 46 | }); 47 | createdUser.password = undefined; 48 | return createdUser; 49 | } catch (err) { 50 | throw new InternalServerErrorException(err); 51 | } 52 | } 53 | public getCookiesWithJwtToken(user: User) { 54 | const payload: TokenPayload = { userId: user.id, email: user.email }; 55 | const token = this.jwtService.sign(payload); 56 | return token; 57 | } 58 | 59 | public async getAuthUser(email: string, textPassword: string) { 60 | try { 61 | const user = await this.userService.getByEmail(email.toLowerCase()); 62 | if (user) { 63 | await this.verifyPassword(textPassword, user.password); 64 | return user; 65 | } 66 | throw new BadRequestException('Wrong credentials provided'); 67 | } catch (err) { 68 | throw new HttpException(err, HttpStatus.INTERNAL_SERVER_ERROR); 69 | } 70 | } 71 | 72 | private async verifyPassword( 73 | plainTextPassword: string, 74 | hashedPassword: string, 75 | ) { 76 | const isMatchFound = await bcrypt.compare( 77 | plainTextPassword, 78 | hashedPassword, 79 | ); 80 | if (!isMatchFound) { 81 | throw new BadRequestException('Wrong credentials provided'); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/src/app/domain/domain.module.ts: -------------------------------------------------------------------------------- 1 | import { 2 | MiddlewareConsumer, 3 | Module, 4 | NestModule, 5 | RequestMethod, 6 | } from '@nestjs/common'; 7 | import { DBModule } from '@dev/database'; 8 | import { UserModule } from './users/user.module'; 9 | import { UsersEntity } from './users/user.entity'; 10 | import { UserController } from './users/user.controller'; 11 | import { METHODS } from 'http'; 12 | import { RouteInfo } from '@nestjs/common/interfaces'; 13 | import { AuthMiddleware } from '../core/middleware/auth.middleware'; 14 | import { AuthModule } from './auth/auth.module'; 15 | import { AppLoggerMiddleware } from '../core/middleware/app-log.middleware'; 16 | import { AppLoggerModule, LoggerMiddleware } from '@dev/logger'; 17 | import { EmailModule } from '@dev/email'; 18 | import { ConfigModule, ConfigService } from '@dev/config'; 19 | import { HttpClientModule } from '@dev/http'; 20 | export const GLOBAL_PREFIX = '/api/v1'; 21 | 22 | /* 23 | useClass - to get a private instance of the options provider. 24 | useFactory - to use a function as the options provider. 25 | useExisting - to re-use an existing (shared, SINGLETON) service as the options provider. 26 | */ 27 | @Module({ 28 | imports: [ 29 | HttpClientModule.forRootAsync({ 30 | imports: [ConfigModule], 31 | inject: [ConfigService], 32 | useFactory: (config: ConfigService) => ({ 33 | apiUrl: config.get().externalApi.apiUrl, 34 | apiKey: config.get().externalApi.apiKey, 35 | }), 36 | }), 37 | EmailModule.registerAsync({ 38 | imports: [ConfigModule], 39 | inject: [ConfigService], 40 | useFactory: (config: ConfigService) => { 41 | return { 42 | service: config.get().email.service_name, 43 | user: config.get().email.username, 44 | pass: config.get().email.password, 45 | }; 46 | }, 47 | }), 48 | AppLoggerModule, 49 | UserModule, 50 | AuthModule, 51 | DBModule.forRoot({ 52 | entities: [UsersEntity], 53 | }), 54 | ], 55 | providers: [], 56 | controllers: [], 57 | }) 58 | export class DomainModule implements NestModule { 59 | public authRoutes: Array = [ 60 | { 61 | path: `*`, 62 | method: RequestMethod.ALL, 63 | }, 64 | ]; 65 | 66 | public publicRoutes: Array = [ 67 | { 68 | path: `${GLOBAL_PREFIX}/health`, 69 | method: RequestMethod.GET, 70 | }, 71 | ]; 72 | 73 | configure(consumer: MiddlewareConsumer) { 74 | consumer 75 | .apply(AuthMiddleware) 76 | .exclude(...this.publicRoutes) 77 | .forRoutes(...this.authRoutes); 78 | 79 | consumer.apply(LoggerMiddleware).forRoutes('*'); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /apps/nestjs-baseline-rest-apis/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tkssharma/01-nestjs-baseline-rest-apis", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "build": "nest build", 10 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 11 | "start": "nest start", 12 | "start:dev": "nest start --watch", 13 | "start:debug": "nest start --debug --watch", 14 | "start:prod": "node dist/main", 15 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --config ./test/jest-e2e.json" 21 | }, 22 | "dependencies": { 23 | "@dev/config": "*", 24 | "@dev/http": "*", 25 | "@dev/email": "*", 26 | "@dev/logger":"*", 27 | "@dev/database": "*", 28 | "@nestjs/common": "^9.0.0", 29 | "@nestjs/core": "^9.0.0", 30 | "@nestjs/platform-express": "^9.0.0", 31 | "@nestjs/swagger": "^6.3.0", 32 | "@nestjs/typeorm": "^9.0.1", 33 | "@types/uuid": "^8.3.4", 34 | "class-transformer": "^0.5.1", 35 | "class-validator": "^0.14.0", 36 | "express": "^4.18.2", 37 | "express-basic-auth": "^1.2.1", 38 | "helmet": "^6.1.5", 39 | "pg": "^8.10.0", 40 | "reflect-metadata": "^0.1.13", 41 | "rxjs": "^7.2.0", 42 | "swagger-ui-express": "^4.6.2", 43 | "typeorm": "^0.3.12", 44 | "uuid": "^8.3.2" 45 | }, 46 | "devDependencies": { 47 | "@nestjs/cli": "^9.0.0", 48 | "@nestjs/schematics": "^9.0.0", 49 | "@nestjs/testing": "^9.0.0", 50 | "@types/express": "^4.17.13", 51 | "@types/jest": "29.5.0", 52 | "@types/node": "18.15.11", 53 | "@types/supertest": "^2.0.11", 54 | "@typescript-eslint/eslint-plugin": "^5.0.0", 55 | "@typescript-eslint/parser": "^5.0.0", 56 | "eslint": "^8.0.1", 57 | "eslint-config-prettier": "^8.3.0", 58 | "eslint-plugin-prettier": "^4.0.0", 59 | "jest": "29.5.0", 60 | "prettier": "^2.3.2", 61 | "source-map-support": "^0.5.20", 62 | "supertest": "^6.1.3", 63 | "ts-jest": "29.0.5", 64 | "ts-loader": "^9.2.3", 65 | "ts-node": "^10.0.0", 66 | "tsconfig-paths": "4.2.0", 67 | "typescript": "^4.7.4" 68 | }, 69 | "jest": { 70 | "moduleFileExtensions": [ 71 | "js", 72 | "json", 73 | "ts" 74 | ], 75 | "rootDir": "src", 76 | "testRegex": ".*\\.spec\\.ts$", 77 | "transform": { 78 | "^.+\\.(t|j)s$": "ts-jest" 79 | }, 80 | "collectCoverageFrom": [ 81 | "**/*.(t|j)s" 82 | ], 83 | "coverageDirectory": "../coverage", 84 | "testEnvironment": "node" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/app.module.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __decorate = 3 | (this && this.__decorate) || 4 | function (decorators, target, key, desc) { 5 | var c = arguments.length, 6 | r = 7 | c < 3 8 | ? target 9 | : desc === null 10 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 11 | : desc, 12 | d; 13 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 14 | r = Reflect.decorate(decorators, target, key, desc); 15 | else 16 | for (var i = decorators.length - 1; i >= 0; i--) 17 | if ((d = decorators[i])) 18 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 19 | return c > 3 && r && Object.defineProperty(target, key, r), r; 20 | }; 21 | exports.__esModule = true; 22 | exports.AppModule = void 0; 23 | var common_1 = require('@nestjs/common'); 24 | var graphql_1 = require('@nestjs/graphql'); 25 | var config_module_1 = require('./modules/config/config.module'); 26 | var typeorm_1 = require('@nestjs/typeorm'); 27 | var config_service_1 = require('./modules/config/config.service'); 28 | var api_module_1 = require('./modules/api/api.module'); 29 | var path_1 = require('path'); 30 | var AppModule = /** @class */ (function () { 31 | function AppModule() {} 32 | AppModule = __decorate( 33 | [ 34 | (0, common_1.Module)({ 35 | imports: [ 36 | config_module_1.ConfigModule, 37 | typeorm_1.TypeOrmModule.forRootAsync({ 38 | imports: [config_module_1.ConfigModule], 39 | inject: [config_service_1.ConfigService], 40 | useFactory: function (configService) { 41 | return { 42 | name: 'default', 43 | type: configService.get('DB_TYPE'), 44 | host: configService.get('DB_HOST'), 45 | port: configService.get('DB_PORT'), 46 | username: configService.get('DB_USERNAME'), 47 | password: configService.get('DB_PASSWORD'), 48 | database: configService.get('DB_DATABASE'), 49 | entities: [__dirname + '/**/**.entity{.ts,.js}'], 50 | synchronize: configService.get('DB_SYNC'), 51 | }; 52 | }, 53 | }), 54 | graphql_1.GraphQLModule.forRoot({ 55 | playground: true, 56 | typePaths: ['./**/*.graphql'], 57 | context: function (_a) { 58 | var req = _a.req; 59 | return { headers: req.headers }; 60 | }, 61 | debug: true, 62 | definitions: { 63 | path: (0, path_1.join)(process.cwd(), 'src/graphql.schema.ts'), 64 | outputAs: 'class', 65 | }, 66 | }), 67 | api_module_1.ApiModule, 68 | ], 69 | }), 70 | ], 71 | AppModule, 72 | ); 73 | return AppModule; 74 | })(); 75 | exports.AppModule = AppModule; 76 | -------------------------------------------------------------------------------- /apps/nestjs-graphql-typeorm/src/modules/entity/league.entity.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var __extends = 3 | (this && this.__extends) || 4 | (function () { 5 | var extendStatics = function (d, b) { 6 | extendStatics = 7 | Object.setPrototypeOf || 8 | ({ __proto__: [] } instanceof Array && 9 | function (d, b) { 10 | d.__proto__ = b; 11 | }) || 12 | function (d, b) { 13 | for (var p in b) 14 | if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; 15 | }; 16 | return extendStatics(d, b); 17 | }; 18 | return function (d, b) { 19 | if (typeof b !== 'function' && b !== null) 20 | throw new TypeError( 21 | 'Class extends value ' + String(b) + ' is not a constructor or null', 22 | ); 23 | extendStatics(d, b); 24 | function __() { 25 | this.constructor = d; 26 | } 27 | d.prototype = 28 | b === null 29 | ? Object.create(b) 30 | : ((__.prototype = b.prototype), new __()); 31 | }; 32 | })(); 33 | var __decorate = 34 | (this && this.__decorate) || 35 | function (decorators, target, key, desc) { 36 | var c = arguments.length, 37 | r = 38 | c < 3 39 | ? target 40 | : desc === null 41 | ? (desc = Object.getOwnPropertyDescriptor(target, key)) 42 | : desc, 43 | d; 44 | if (typeof Reflect === 'object' && typeof Reflect.decorate === 'function') 45 | r = Reflect.decorate(decorators, target, key, desc); 46 | else 47 | for (var i = decorators.length - 1; i >= 0; i--) 48 | if ((d = decorators[i])) 49 | r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; 50 | return c > 3 && r && Object.defineProperty(target, key, r), r; 51 | }; 52 | exports.__esModule = true; 53 | exports.LeagueEntity = void 0; 54 | var typeorm_1 = require('typeorm'); 55 | var pokemon_entity_1 = require('./pokemon.entity'); 56 | var LeagueEntity = /** @class */ (function (_super) { 57 | __extends(LeagueEntity, _super); 58 | function LeagueEntity() { 59 | return (_super !== null && _super.apply(this, arguments)) || this; 60 | } 61 | __decorate( 62 | [(0, typeorm_1.PrimaryGeneratedColumn)('uuid')], 63 | LeagueEntity.prototype, 64 | 'id', 65 | ); 66 | __decorate( 67 | [(0, typeorm_1.Column)('varchar', { length: 500, unique: true })], 68 | LeagueEntity.prototype, 69 | 'name', 70 | ); 71 | __decorate( 72 | [ 73 | (0, typeorm_1.OneToMany)( 74 | function (type) { 75 | return pokemon_entity_1.PokemonEntity; 76 | }, 77 | function (pokemon) { 78 | return pokemon.league; 79 | }, 80 | ), 81 | ], 82 | LeagueEntity.prototype, 83 | 'pokemons', 84 | ); 85 | LeagueEntity = __decorate([(0, typeorm_1.Entity)('league')], LeagueEntity); 86 | return LeagueEntity; 87 | })(typeorm_1.BaseEntity); 88 | exports.LeagueEntity = LeagueEntity; 89 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/post/post.controller.ts: -------------------------------------------------------------------------------- 1 | import Controller from "interfaces/controller.interface"; 2 | import { Request, Response, NextFunction, Router } from "express"; 3 | import postModel from "../post/post.model"; 4 | import PostNotFoundException from "../exceptions/post.exception"; 5 | import CreatePostDto from "./post.dto"; 6 | import RequestWithUser from "../interfaces/req.user"; 7 | import userModel from "../user/user.model"; 8 | import authMiddleware from "../middleware/auth.middleware"; 9 | 10 | class PostController implements Controller { 11 | public path = "/posts"; 12 | public router = Router(); 13 | public user = userModel; 14 | public post = postModel; 15 | 16 | constructor() { 17 | this.initializeRoutes(); 18 | } 19 | 20 | private initializeRoutes() { 21 | this.router 22 | .get(this.path, this.getAllPosts) 23 | .post(this.path, authMiddleware, this.createPost); 24 | this.router.get(`${this.path}/:id`, this.getPostById); 25 | this.router 26 | .all(`${this.path}/*`, authMiddleware) 27 | .patch(`${this.path}/:id`, this.updatePost) 28 | .delete(`${this.path}/:id`, this.deletePost); 29 | } 30 | 31 | private getAllPosts = async ( 32 | req: Request, 33 | res: Response, 34 | next: NextFunction 35 | ) => { 36 | const postQuery = this.post.find(); 37 | const posts = await postQuery.populate("author", "-password"); 38 | res.send(posts); 39 | }; 40 | 41 | private getPostById = async ( 42 | req: Request, 43 | res: Response, 44 | next: NextFunction 45 | ) => { 46 | const id = req.params.id; 47 | const post = await this.post.findById(id); 48 | if (post) { 49 | res.send(post); 50 | } else { 51 | next(new PostNotFoundException(id)); 52 | } 53 | }; 54 | 55 | private updatePost = async ( 56 | req: Request, 57 | res: Response, 58 | next: NextFunction 59 | ) => { 60 | const id = req.params.id; 61 | const postData: any = req.body; 62 | const post = await this.post.findByIdAndUpdate(id, postData, { new: true }); 63 | if (post) { 64 | res.send(post); 65 | } else { 66 | next(new PostNotFoundException(id)); 67 | } 68 | }; 69 | 70 | private createPost = async ( 71 | req: RequestWithUser, 72 | res: Response, 73 | next: NextFunction 74 | ) => { 75 | const postData: any = req.body; 76 | console.log(req.body); 77 | const createPost = await this.post.create({ 78 | content: postData.content, 79 | title: postData.title, 80 | author: req.user._id, 81 | }); 82 | res.send(createPost); 83 | }; 84 | 85 | private deletePost = async ( 86 | req: Request, 87 | res: Response, 88 | next: NextFunction 89 | ) => { 90 | const id = req.params.id; 91 | const post = await this.post.findByIdAndDelete(id); 92 | if (post) { 93 | res.send(post); 94 | } else { 95 | next(new PostNotFoundException(id)); 96 | } 97 | }; 98 | } 99 | 100 | export default PostController; 101 | -------------------------------------------------------------------------------- /apps/express-typescript-mongo-apis/src/authentication/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import * as bcrypt from "bcrypt"; 2 | import { Request, Response, NextFunction, Router } from "express"; 3 | import * as jwt from "jsonwebtoken"; 4 | import CreateUserDto from "../user/user.dto"; 5 | import User from "../user/user.interface"; 6 | import userModel from "./../user/user.model"; 7 | import LogInDto from "./logIn.dto"; 8 | import AuthenticationService from "./auth.service"; 9 | import Controller from "../interfaces/controller.interface"; 10 | import WrongCredentialsException from "../exceptions/wrong.credentials.exception"; 11 | import TokenData from "../interfaces/token.interface"; 12 | 13 | class AuthenticationController implements Controller { 14 | public path = "/auth"; 15 | public router = Router(); 16 | public authenticationService = new AuthenticationService(); 17 | private user = userModel; 18 | 19 | constructor() { 20 | this.initializeRoutes(); 21 | } 22 | 23 | private initializeRoutes() { 24 | this.router.post(`${this.path}/register`, this.registration); 25 | this.router.post(`${this.path}/login`, this.loggingIn); 26 | this.router.post(`${this.path}/logout`, this.loggingOut); 27 | } 28 | 29 | private registration = async ( 30 | request: Request, 31 | response: Response, 32 | next: NextFunction 33 | ) => { 34 | const userData: CreateUserDto = request.body; 35 | try { 36 | const { user } = await this.authenticationService.register(userData); 37 | response.send(user); 38 | } catch (error) { 39 | next(error); 40 | } 41 | }; 42 | 43 | private loggingIn = async ( 44 | request: Request, 45 | response: Response, 46 | next: NextFunction 47 | ) => { 48 | const logInData: LogInDto = request.body; 49 | console.log(request.body); 50 | const user = await this.user.findOne({ email: logInData.email }); 51 | if (user) { 52 | const isPasswordMatching = await bcrypt.compare( 53 | logInData.password, 54 | user.get("password", null, { getters: false }) 55 | ); 56 | if (isPasswordMatching) { 57 | const tokenData = this.createToken(user); 58 | response.setHeader("Set-Cookie", [this.createCookie(tokenData)]); 59 | response.send(user); 60 | } else { 61 | next(new WrongCredentialsException()); 62 | } 63 | } else { 64 | next(new WrongCredentialsException()); 65 | } 66 | }; 67 | 68 | private loggingOut = (request: Request, response: Response) => { 69 | response.setHeader("Set-Cookie", ["Authorization=;Max-age=0"]); 70 | response.send(200); 71 | }; 72 | 73 | private createCookie(tokenData: TokenData) { 74 | return `Authorization=${tokenData.token}; HttpOnly; Max-Age=${tokenData.expiresIn}`; 75 | } 76 | 77 | private createToken(user: User): TokenData { 78 | const expiresIn = 60 * 60; // an hour 79 | const secret = process.env.SECRET; 80 | const dataStoredInToken: any = { 81 | _id: user._id, 82 | }; 83 | return { 84 | expiresIn, 85 | token: jwt.sign(dataStoredInToken, secret, { expiresIn }), 86 | }; 87 | } 88 | } 89 | 90 | export default AuthenticationController; 91 | --------------------------------------------------------------------------------