├── .env
├── .eslintrc.js
├── .gitignore
├── .prettierrc
├── README.md
├── nest-cli.json
├── package-lock.json
├── package.json
├── src
├── app.module.ts
├── dto
│ └── rs-generic-header.dto.ts
├── main.ts
├── midlewares
│ └── correlation-id.middleware.ts
└── modules
│ ├── company-dependencies
│ ├── company-dependencies.controller.ts
│ ├── company-dependencies.module.ts
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-create-company-dependency.dto.ts
│ │ ├── rq-get-company-dependencies-by-zone.dto.ts
│ │ ├── rq-get-company-dependency.dto.ts
│ │ ├── rs-create-company-dependency.dto.ts
│ │ ├── rs-get-company-dependency-by-zone.dto.ts
│ │ └── rs-get-company-dependency.dto.ts
│ ├── interfaces
│ │ ├── company-dependency.interface.ts
│ │ └── index.ts
│ ├── services
│ │ └── company-dependency-factory.service.ts
│ └── types
│ │ └── enums.ts
│ ├── customers
│ ├── customers.controller.ts
│ ├── customers.module.ts
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-create-customer.dto.ts
│ │ ├── rq-get-customer.dto.ts
│ │ ├── rs-create-customer.dto.ts
│ │ └── rs-get-customer.dto.ts
│ ├── interfaces
│ │ ├── customer-factory.interface.ts
│ │ └── index.ts
│ └── services
│ │ └── customer-factory.service.ts
│ ├── location
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-create-location.dto.ts
│ │ ├── rq-get-locations-transport.dto.ts
│ │ ├── rs-create-location.dto.ts
│ │ └── rs-get-locations-transport.dto.ts
│ ├── location.controller.ts
│ └── location.module.ts
│ ├── orders
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-cancelled-order.dto.ts
│ │ ├── rq-create-order.dto.ts
│ │ ├── rq-delete-order.dto.ts
│ │ ├── rq-delivered-order.dto.ts
│ │ ├── rq-get-order.dto.ts
│ │ ├── rq-loaded-order.dto.ts
│ │ ├── rs-cancelled-order.dto.ts
│ │ ├── rs-create-order.dto.ts
│ │ ├── rs-delete-orders.dto.ts
│ │ ├── rs-delivered-order.dto.ts
│ │ ├── rs-get-order.dto.ts
│ │ ├── rs-get-orders.dto.ts
│ │ └── rs-loaded-order.dto.ts
│ ├── interfaces
│ │ ├── index.ts
│ │ └── orders-factory.interface.ts
│ ├── orders.controller.ts
│ ├── orders.module.ts
│ ├── services
│ │ └── orders-factory.service.ts
│ └── types
│ │ └── enums.ts
│ ├── params
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-get-params.dto.ts
│ │ └── rs-get-params.dto.ts
│ ├── params.controller.ts
│ └── params.module.ts
│ ├── products
│ ├── product.pb.ts
│ ├── product.proto
│ ├── products.controller.ts
│ └── products.module.ts
│ ├── routes
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-cash-deposit-route.dto.ts
│ │ ├── rq-generate-route.dto.ts
│ │ ├── rq-get-orders-details-route.dto.ts
│ │ ├── rq-get-route-amount.dto.ts
│ │ ├── rq-get-route-for-map.dto.ts
│ │ ├── rq-loaded-transport-route.dto.ts
│ │ ├── rs-cash-deposit-route.dto.ts
│ │ ├── rs-get-orders-details-route.dto.ts
│ │ ├── rs-get-route-amount.dto.ts
│ │ ├── rs-get-route-for-map.dto.ts
│ │ └── rs-loaded-transport-route.dto.ts
│ ├── routes.controller.ts
│ └── routes.module.ts
│ ├── security
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-login-user.dto.ts
│ │ ├── rq-register-user.dto.ts
│ │ ├── rs-login-user.dto.ts
│ │ └── rs-register-user.dto.ts
│ ├── interfaces
│ │ └── jwt-payload.interface.ts
│ ├── security.controller.ts
│ ├── security.module.ts
│ ├── services
│ │ ├── jwt-strategy.service.ts
│ │ └── jwt-tokens.service.ts
│ └── utilities
│ │ └── jwt-auth-guard.ts
│ ├── transport
│ ├── dto
│ │ ├── index.ts
│ │ ├── rq-create-transport.dto.ts
│ │ ├── rq-delete-transport.dto.ts
│ │ ├── rq-get-transport.dto.ts
│ │ ├── rq-update-transport.dto.ts
│ │ ├── rs-create-transport.dto.ts
│ │ └── rs-get-transport.dto.ts
│ ├── interfaces
│ │ ├── index.ts
│ │ └── transport-factory.interface.ts
│ ├── services
│ │ └── transport-factory.service.ts
│ ├── transport.controller.ts
│ └── transport.module.ts
│ └── zones
│ ├── dto
│ ├── index.ts
│ ├── rq-create-zones.dto.ts
│ ├── rs-create-zones.dto.ts
│ └── rs-get-zones.dto.ts
│ ├── zones.controller.ts
│ └── zones.module.ts
├── test
├── app.e2e-spec.ts
└── jest-e2e.json
├── tsconfig.build.json
└── tsconfig.json
/.env:
--------------------------------------------------------------------------------
1 | #api-gateway
2 | PORT_APP = 3000
3 |
4 | #ms-customer
5 | CUSTOMER_PORT = 8776
6 | CUSTOMER_HOST = 127.0.0.1
7 |
8 | #ms-security
9 | SECURITY_PORT = 8777
10 | SECURITY_HOST = 127.0.0.1
11 | JWT_SECRET_KEY = "CLAVE"
12 | JWT_EXPIRESION_KEY = 3600
13 |
14 | #ms-transport
15 | TRANSPORT_PORT = 5672
16 | TRANSPORT_HOST = localhost
17 | TRANSPORT_USER = admin
18 | TRANSPORT_PASSWORD = admin
19 | QUEUE_INPUT = queue_transport_input
20 |
21 | #ms-zones
22 | ZONES_PORT = 5673
23 | ZONES_HOST = localhost
24 | ZONES_USER = admin
25 | ZONES_PASSWORD = admin
26 | ZONES_QUEUE_INPUT = queue_zones_input
27 |
28 | #ms-company-dependencies
29 | COMPANY_DEPENDENCIES_URL=redis://localhost:6379
30 |
31 | #ms-products
32 | URL_PRODUCTS=localhost:50051
33 |
34 | #ms-routes
35 | ROUTE_HOST=localhost
36 | ROUTE_PORT=4222
37 |
38 | #ms-order
39 | ORDER_PORT = 8778
40 | ORDER_HOST = 127.0.0.1
41 |
42 | #ms-location
43 | LOCATION_PORT = 1883
44 | LOCATION_HOST = localhost
45 |
46 | NODE_ENV = development
47 |
48 | TCP_RESPONSE_TIMEOUT=5000
49 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/.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
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "singleQuote": true,
3 | "trailingComma": "all"
4 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # MiniDev-Logistic: api-gateway
6 |
7 | La presente iniciativa contiene el codigo de un mini desarrollo de software BackEnd.
8 | En particular, este proyecto contiene el modulo denominado api-gateway.
9 | Es totalmente gratuito y compartido como un aporte a la comunidad.
10 | Se focalizará en el procesamiento distribuido, mediante la aplicación del enfoque de microservicios.
11 | Se apoya en videos que seran publicados en el canal de youtube: [Developer Web MS](https://www.youtube.com/playlist?list=PLWnRJL1SdIio8TshcHJrJ6_3btfZDuz4O).
12 |
13 | ___
14 |
15 | This initiative contains the code of a mini BackEnd software development.
16 | In particular, this project contains the module called api-gateway.
17 | It is completely free and shared as a contribution to the community. It will focus on distributed processing, by applying the microservices approach.
18 | It is supported by videos that will be published on the YouTube channel: [Developer Web MS](https://www.youtube.com/playlist?list=PLWnRJL1SdIio8TshcHJrJ6_3btfZDuz4O).
19 |
20 | ___
21 |
22 | ## Tecnologías / Technologies
23 |
24 | * NestJS
25 | * Express.js
26 | * TypeScript
27 | * TypeORM
28 | * Prisma ORM
29 | * Sequelize ORM
30 | * MongoDB
31 | * MySQL
32 | * Postgres
33 | * JSON Web Token
34 | * Bcrypt
35 | * Passport
36 | * Swagger
37 | * TCP-IP
38 | * gRPC
39 | * NATS
40 | * Redis
41 | * RabbitMQ
42 | * Kafka
43 | * Kafdrop
44 | * MQTT
45 | * Mosquitto
46 |
47 | ___
48 |
49 | ## Información del proyecto / Project information
50 |
51 | * Developer Web MS - [Youtube channel](https://www.youtube.com/playlist?list=PLWnRJL1SdIio8TshcHJrJ6_3btfZDuz4O) - (YOUTUBE)
52 |
53 | ___
54 |
55 | ## Otros microservicios del proyecto / Other project microservices
56 |
57 | * [api-gateway](https://github.com/mspano-web/minidev-logistics-api-gateway)
58 | * [ms-company-dependencies](https://github.com/mspano-web/minidev-logistics-ms-company-dependencies)
59 | * [ms-customers](https://github.com/mspano-web/minidev-logistics-ms-customers)
60 | * [ms-location](https://github.com/mspano-web/minidev-logistics-ms-location)
61 | * [ms-orders](https://github.com/mspano-web/minidev-logistics-ms-orders)
62 | * [ms-params](https://github.com/mspano-web/minidev-logistics-ms-params)
63 | * [ms-products](https://github.com/mspano-web/minidev-logistics-ms-products)
64 | * [ms-route](https://github.com/mspano-web/minidev-logistics-ms-route)
65 | * [ms-security](https://github.com/mspano-web/minidev-logistics-ms-security)
66 | * [ms-transports](https://github.com/mspano-web/minidev-logistics-ms-transports)
67 | * [ms-zones](https://github.com/mspano-web/minidev-logistics-ms-zones)
68 |
69 | ___
70 |
71 | ## Documentacion de soporte / Support documentation
72 |
73 | * [NestJS Oficial Page](https://nestjs.com/)
74 | * [Nest Documentation](https://docs.nestjs.com)
75 |
76 | * [Conceptual model](https://drive.google.com/file/d/1J8SP8eegLsDO6UXshc8mSwEt9JNpoYGT/view?usp=sharing) (Google Drive)
77 | * [UI Mobile](https://www.figma.com/file/uyaK3PgTdLR0PPF6ggmqEi/LOGISTIC) (Figma)
78 | * [Application Architecture Diagram](https://drive.google.com/file/d/1BmU9Eli3F8ZYEzie3Xy9RB_6Lpt-DPnU/view) (Google Drive)
79 | * [Kafka Internals Diagram](https://www.figma.com/file/Qol9O1fev7oDu5zQ0xWLbx/Kafka?node-id=0%3A1) (Figma)
80 | * [Kafgrop](https://github.com/obsidiandynamics/kafdrop) (GitHub)
81 |
82 | (Figma) : use + para acercar, - para alejar) / (Figma: use + to zoom in, - to zoom out)*
83 |
--------------------------------------------------------------------------------
/nest-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/nest-cli",
3 | "collection": "@nestjs/schematics",
4 | "sourceRoot": "src",
5 | "compilerOptions": {
6 | "assets": ["**/*.proto"],
7 | "watchAssets": true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api-gateway",
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 | "@grpc/grpc-js": "^1.6.8",
25 | "@grpc/proto-loader": "^0.7.0",
26 | "@nestjs/common": "^9.0.0",
27 | "@nestjs/config": "^2.2.0",
28 | "@nestjs/core": "^9.0.0",
29 | "@nestjs/jwt": "^9.0.0",
30 | "@nestjs/mapped-types": "*",
31 | "@nestjs/microservices": "^9.0.2",
32 | "@nestjs/passport": "^9.0.0",
33 | "@nestjs/platform-express": "^9.0.0",
34 | "@nestjs/swagger": "^6.0.4",
35 | "@types/passport-jwt": "^3.0.6",
36 | "@types/swagger-ui": "^3.52.0",
37 | "amqp-connection-manager": "^4.1.3",
38 | "amqplib": "^0.10.0",
39 | "class-transformer": "^0.5.1",
40 | "class-validator": "^0.13.2",
41 | "ioredis": "^5.2.2",
42 | "kafkajs": "^2.1.0",
43 | "mqtt": "^4.3.7",
44 | "nats": "^2.7.1",
45 | "nestjs-pino": "^3.1.1",
46 | "nestjs-proto-gen-ts": "^1.0.20",
47 | "passport-jwt": "^4.0.0",
48 | "pino-http": "^8.2.0",
49 | "reflect-metadata": "^0.1.13",
50 | "rimraf": "^3.0.2",
51 | "rxjs": "^7.2.0",
52 | "swagger-ui-express": "^4.5.0"
53 | },
54 | "devDependencies": {
55 | "@nestjs/cli": "^9.0.0",
56 | "@nestjs/schematics": "^9.0.0",
57 | "@nestjs/testing": "^9.0.0",
58 | "@types/express": "^4.17.13",
59 | "@types/jest": "28.1.4",
60 | "@types/node": "^16.11.45",
61 | "@types/supertest": "^2.0.11",
62 | "@typescript-eslint/eslint-plugin": "^5.0.0",
63 | "@typescript-eslint/parser": "^5.0.0",
64 | "eslint": "^8.0.1",
65 | "eslint-config-prettier": "^8.3.0",
66 | "eslint-plugin-prettier": "^4.0.0",
67 | "jest": "28.1.2",
68 | "pino-pretty": "^9.0.1",
69 | "prettier": "^2.3.2",
70 | "source-map-support": "^0.5.20",
71 | "supertest": "^6.1.3",
72 | "ts-jest": "28.0.5",
73 | "ts-loader": "^9.2.3",
74 | "ts-node": "^10.0.0",
75 | "ts-proto": "^1.120.0",
76 | "tsconfig-paths": "4.0.0",
77 | "typescript": "^4.3.5"
78 | },
79 | "jest": {
80 | "moduleFileExtensions": [
81 | "js",
82 | "json",
83 | "ts"
84 | ],
85 | "rootDir": "src",
86 | "testRegex": ".*\\.spec\\.ts$",
87 | "transform": {
88 | "^.+\\.(t|j)s$": "ts-jest"
89 | },
90 | "collectCoverageFrom": [
91 | "**/*.(t|j)s"
92 | ],
93 | "coverageDirectory": "../coverage",
94 | "testEnvironment": "node"
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/app.module.ts:
--------------------------------------------------------------------------------
1 | import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
2 | import { ConfigModule, ConfigService } from '@nestjs/config';
3 |
4 | import { CustomersModule } from './modules/customers/customers.module';
5 | import { SecurityModule } from './modules/security/security.module';
6 | import { TransportModule } from './modules/transport/transport.module';
7 | import { ZonesModule } from './modules/zones/zones.module';
8 | import { CompanyDependenciesModule } from './modules/company-dependencies/company-dependencies.module';
9 | import { ProductsModule } from './modules/products/products.module';
10 | import { OrdersModule } from './modules/orders/orders.module';
11 | import { RoutesModule } from './modules/routes/routes.module';
12 | import { ParamsModule } from './modules/params/params.module';
13 | import { LocationModule } from './modules/location/location.module';
14 | import { LoggerModule } from 'nestjs-pino';
15 | import { CorrelationIdMiddleware, CORRELATION_ID_HEADER } from './midlewares/correlation-id.middleware';
16 | import { Request } from 'express';
17 |
18 | /* ---------------------------------------------- */
19 |
20 | @Module({
21 | imports: [
22 | ConfigModule.forRoot( { isGlobal: true } ),
23 | LoggerModule.forRoot({
24 | pinoHttp: {
25 | transport: process.env.NODE_ENV === 'development' ? {
26 | target: 'pino-pretty',
27 | options: {
28 | messageKey: 'message'
29 | }
30 | } : undefined,
31 | messageKey: 'message',
32 | customProps: (req: Request) => { // All request show correlation Id
33 | return {
34 | correlationId: req[CORRELATION_ID_HEADER]
35 | }
36 | },
37 | autoLogging: false,
38 | serializers: {
39 | req: () => {
40 | return undefined
41 | },
42 | res: () => {
43 | return undefined
44 | }
45 |
46 | }
47 | }
48 | }),
49 | CustomersModule, SecurityModule, TransportModule, ZonesModule, CompanyDependenciesModule, ProductsModule, OrdersModule, RoutesModule, ParamsModule, LocationModule],
50 | controllers: [],
51 | providers: [],
52 | })
53 |
54 | /* ---------------------------------------------- */
55 |
56 | export class AppModule implements NestModule {
57 | static port: number;
58 | constructor(private readonly configService: ConfigService) {
59 | AppModule.port = +this.configService.get("PORT_APP") // + --> cast to number
60 | }
61 |
62 | configure(consumer: MiddlewareConsumer) {
63 | consumer.apply(CorrelationIdMiddleware).forRoutes('*')
64 | }
65 | }
66 |
67 | /* ---------------------------------------------- */
68 |
--------------------------------------------------------------------------------
/src/dto/rs-generic-header.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | /* ---------------------------------------------- */
4 |
5 | export class RsGenericHeaderDto {
6 | @ApiProperty({
7 | type: Number,
8 | description: 'Status Code',
9 | })
10 | statusCode: number;
11 |
12 | @ApiProperty({
13 | type: String,
14 | description: 'Message',
15 | })
16 | message?: string;
17 | }
18 |
19 | /* ---------------------------------------------- */
20 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { ValidationPipe } from '@nestjs/common';
2 | import { NestFactory } from '@nestjs/core';
3 | import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
4 |
5 | import { AppModule } from './app.module';
6 | import { Logger } from 'nestjs-pino';
7 |
8 | /* ---------------------------------------------- */
9 |
10 | async function bootstrap() {
11 | const app = await NestFactory.create(AppModule,);
12 |
13 | app.useLogger(app.get(Logger)); // use the pine logger
14 |
15 | app.useGlobalPipes( // it is applied to every route handler across the entire application
16 | new ValidationPipe({ // Cast automaticaly class-transform
17 | transform: true, // If true, it allows to transform the flat JSON objects to objects of the DTO class.
18 | forbidUnknownValues: true, // Setting true will cause fail validation of unknown objects.
19 | forbidNonWhitelisted: true, // If set to true, instead of stripping non-whitelisted properties validator will throw an error
20 | }),
21 | );
22 |
23 | const config = new DocumentBuilder() // RESTful web services documentation
24 | .setTitle('Logistic')
25 | .setDescription('Demo')
26 | .setVersion('1.0')
27 | .addTag('logistic')
28 | .build();
29 | const document = SwaggerModule.createDocument(app, config);
30 | SwaggerModule.setup('api', app, document);
31 |
32 | await app.listen(AppModule.port);
33 | }
34 |
35 | /* ---------------------------------------------- */
36 |
37 | bootstrap();
38 |
39 |
--------------------------------------------------------------------------------
/src/midlewares/correlation-id.middleware.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
2 |
3 | import { randomUUID } from 'crypto';
4 | import { Request, Response, NextFunction } from 'express';
5 |
6 | export const CORRELATION_ID_HEADER = 'X-Correlation-Id';
7 |
8 | /* ---------------------------------------------- */
9 |
10 | @Injectable()
11 | export class CorrelationIdMiddleware implements NestMiddleware {
12 | private logger = new Logger('HTTP');
13 |
14 | use(req: Request, res: Response, next: NextFunction) {
15 | const { ip, method, originalUrl, } = req;
16 | const userAgent = req.get('user-agent') || '';
17 | const id = randomUUID();
18 |
19 | const preCorrelation = req.get(CORRELATION_ID_HEADER)
20 | if ( preCorrelation !== undefined) {
21 | res.set(CORRELATION_ID_HEADER, preCorrelation)
22 | } else {
23 | res.set(CORRELATION_ID_HEADER, id)
24 | }
25 |
26 | res.on('finish', () => {
27 | const { statusCode } = res;
28 | const contentLength = res.get('content-length');
29 |
30 | this.logger.log(
31 | `[${method}][${originalUrl}][${statusCode}][${contentLength}] - [${userAgent}] [${ip}] [CORRELARION_ID:${res.get(CORRELATION_ID_HEADER)}]`,
32 | );
33 | });
34 | next();
35 | }
36 | }
37 |
38 | /* ---------------------------------------------- */
39 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/company-dependencies.controller.ts:
--------------------------------------------------------------------------------
1 | import { Body, Controller, Get, Inject, Param, Post } from '@nestjs/common';
2 | import { ConfigService } from '@nestjs/config';
3 | import { ClientProxy } from '@nestjs/microservices';
4 |
5 | import { Observable, timeout } from 'rxjs';
6 |
7 | import {
8 | RqCreateCompanyDependencyDto,
9 | RsCreateCompanyDependencyDto,
10 | RsGetCompanyDependencyByZoneDto,
11 | RsGetCompanyDependencyDto,
12 | } from './dto';
13 |
14 | import {
15 | COMPANY_DEPENDENCY_FACTORY_SERVICE,
16 | ICompanyDependencyFactory,
17 | } from './interfaces/company-dependency.interface';
18 |
19 | /* ------------------------------------------------------------ */
20 |
21 | @Controller('company-dependencies')
22 | export class CompanyDependenciesController {
23 | constructor(
24 | @Inject('COMPANY_DEPENDENCIES_TRANSPORT')
25 | private company_dependency_transport: ClientProxy,
26 |
27 | @Inject(COMPANY_DEPENDENCY_FACTORY_SERVICE)
28 | private readonly companyDependencyFactoryService: ICompanyDependencyFactory,
29 |
30 | private readonly configService: ConfigService,
31 | ) {}
32 |
33 | /* --------------------------- */
34 |
35 | @Get(':id')
36 | async getCompanyDependency(
37 | @Param('id') id: string,
38 | ): Promise> {
39 | const rqGetCompanyDependencyDto =
40 | this.companyDependencyFactoryService.createGetRequestDTO(parseInt(id));
41 |
42 | return this.company_dependency_transport
43 | .send(
44 | { cmd: 'ms-get-company-dependency' },
45 | rqGetCompanyDependencyDto,
46 | )
47 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
48 | }
49 |
50 | /* --------------------------- */
51 |
52 | @Get('zone/:id')
53 | async getCompanyDependencyByZone(
54 | @Param('id') id: string,
55 | ): Promise> {
56 | const rqGetCompanyDependenciesByZoneDto =
57 | this.companyDependencyFactoryService.createGetByZoneRequestDTO(
58 | parseInt(id),
59 | );
60 |
61 | return this.company_dependency_transport
62 | .send(
63 | { cmd: 'ms-get-company-dependency-by-zone' },
64 | rqGetCompanyDependenciesByZoneDto,
65 | )
66 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
67 | }
68 |
69 | /* --------------------------- */
70 |
71 | @Post()
72 | async createCompanyDependency(
73 | @Body() rqCreateZonesDto: RqCreateCompanyDependencyDto,
74 | ): Promise> {
75 | return this.company_dependency_transport.send(
76 | { cmd: 'ms-create-company-dependency' },
77 | rqCreateZonesDto,
78 | );
79 | }
80 | }
81 |
82 | /* ------------------------------------------------------------ */
83 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/company-dependencies.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ConfigModule, ConfigService } from '@nestjs/config';
3 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
4 |
5 | import { CompanyDependenciesController } from './company-dependencies.controller';
6 | import { COMPANY_DEPENDENCY_FACTORY_SERVICE } from './interfaces';
7 | import { CompanyDependencyFactoryService } from './services/company-dependency-factory.service';
8 |
9 | /* ------------------------------------------------- */
10 |
11 | @Module({
12 | imports: [ConfigModule.forRoot()],
13 | controllers: [CompanyDependenciesController],
14 | providers: [
15 | {
16 | provide: 'COMPANY_DEPENDENCIES_TRANSPORT',
17 | inject: [ConfigService],
18 | useFactory: (configService: ConfigService) =>
19 | ClientProxyFactory.create({
20 | transport: Transport.REDIS,
21 | options: {
22 | url: configService.get('COMPANY_DEPENDENCIES_URL'),
23 | },
24 | }),
25 | },
26 | {
27 | useClass: CompanyDependencyFactoryService, // You can switch useClass to different implementation
28 | provide: COMPANY_DEPENDENCY_FACTORY_SERVICE,
29 | },
30 | ]
31 | })
32 |
33 | /* ------------------------------------------------- */
34 |
35 | export class CompanyDependenciesModule {}
36 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateCompanyDependencyDto } from "./rq-create-company-dependency.dto"
2 | export { RsCreateCompanyDependencyDto } from "./rs-create-company-dependency.dto"
3 | export { RqGetCompanyDependencyDto } from "./rq-get-company-dependency.dto"
4 | export { RsGetCompanyDependencyDto } from "./rs-get-company-dependency.dto"
5 | export { RqGetCompanyDependenciesByZoneDto } from "./rq-get-company-dependencies-by-zone.dto"
6 | export { RsGetCompanyDependencyByZoneDto } from "./rs-get-company-dependency-by-zone.dto"
7 |
8 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rq-create-company-dependency.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import {
4 | IsEnum,
5 | IsNotEmpty,
6 | IsNumber,
7 | IsObject,
8 | IsString,
9 | } from 'class-validator';
10 |
11 | import { DependencyType } from '../types/enums';
12 |
13 | /* -------------------------------------------- */
14 |
15 | export class PointDto {
16 | @IsNumber()
17 | latitude: number;
18 | @IsNumber()
19 | longitud: number;
20 | }
21 |
22 | /* ------------- */
23 |
24 | export class RqCreateCompanyDependencyDto {
25 | @ApiProperty({
26 | type: String,
27 | description: 'Description',
28 | })
29 | @IsString()
30 | description: string;
31 |
32 | @IsEnum(DependencyType)
33 | @ApiProperty({
34 | description: 'Dependency Type',
35 | enum: DependencyType,
36 | })
37 | dependencyType: DependencyType;
38 |
39 | @ApiProperty({
40 | type: Number,
41 | description: 'Zone_id',
42 | })
43 | @IsNumber()
44 | zone_id: number;
45 |
46 | @ApiProperty({
47 | type: String,
48 | description: 'Address',
49 | })
50 | @IsString()
51 | address: string;
52 |
53 | @ApiProperty({
54 | type: Object,
55 | description: 'Location',
56 | })
57 | @IsNotEmpty()
58 | @IsObject()
59 | location: PointDto;
60 | }
61 |
62 | /* -------------------------------------------- */
63 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rq-get-company-dependencies-by-zone.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* -------------------------------------------- */
7 |
8 | @Exclude()
9 | export class RqGetCompanyDependenciesByZoneDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Company Dependency Zone Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(zone_id: number) {
20 | this.id = zone_id;
21 | }
22 | }
23 |
24 | /* -------------------------------------------- */
25 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rq-get-company-dependency.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* -------------------------------------------- */
7 |
8 | @Exclude()
9 | export class RqGetCompanyDependencyDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Company Dependency Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(id: number) {
20 | this.id = id;
21 | }
22 | }
23 |
24 | /* -------------------------------------------- */
25 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rs-create-company-dependency.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------------------------------- */
4 |
5 | export class RsCreateCompanyDependencyDataDto {
6 | id: number;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
11 | export class RsCreateCompanyDependencyDto {
12 | rsGenericHeaderDto: RsGenericHeaderDto;
13 | rsCreateCompanyDependencyDataDto: RsCreateCompanyDependencyDataDto;
14 | }
15 |
16 | /* ----------------------------------------------------------- */
17 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rs-get-company-dependency-by-zone.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 | import { PointDto } from './rq-create-company-dependency.dto';
3 |
4 | /* -------------------------------------------------- */
5 |
6 | export class RsGetCompanyDependencyDataByZoneDto {
7 | id: number;
8 | description: string;
9 | dependencyType: string;
10 | zone_id: number;
11 | address: string;
12 | position: PointDto;
13 | }
14 |
15 | /* --------------- */
16 |
17 | export class RsGetCompanyDependencyByZoneDto {
18 | rsGenericHeaderDto: RsGenericHeaderDto;
19 | rsGetCompanyDependencyDataByZoneDto: RsGetCompanyDependencyDataByZoneDto[];
20 | }
21 |
22 | /* -------------------------------------------------- */
23 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/dto/rs-get-company-dependency.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 | import { DependencyType } from '../types/enums';
3 | import { PointDto } from './rq-create-company-dependency.dto';
4 |
5 | /* -------------------------------------------------- */
6 |
7 | export class RsGetCompanyDependencyDataDto {
8 | statusCode: number;
9 | message: string;
10 | description: string;
11 | dependencyType: DependencyType;
12 | zone_id: number;
13 | address: string;
14 | position: PointDto;
15 | }
16 |
17 | /* --------------- */
18 |
19 | export class RsGetCompanyDependencyDto {
20 | rsGenericHeaderDto: RsGenericHeaderDto;
21 | rsGetCompanyDependencyDataDto: RsGetCompanyDependencyDataDto[];
22 | }
23 |
24 | /* -------------------------------------------------- */
25 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/interfaces/company-dependency.interface.ts:
--------------------------------------------------------------------------------
1 | import { RqGetCompanyDependenciesByZoneDto, RqGetCompanyDependencyDto } from "../dto";
2 |
3 | // interface and provide that token when injecting to an interface type.
4 | export const COMPANY_DEPENDENCY_FACTORY_SERVICE = 'COMPANY_DEPENDENCY_FACTORY_SERVICE';
5 |
6 | /* ------------------------------------ */
7 |
8 | export interface ICompanyDependencyFactory {
9 | createGetRequestDTO(id: number): RqGetCompanyDependencyDto;
10 | createGetByZoneRequestDTO(zone_id: number): RqGetCompanyDependenciesByZoneDto;
11 | }
12 |
13 | /* ------------------------------------ */
14 |
15 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export { COMPANY_DEPENDENCY_FACTORY_SERVICE, ICompanyDependencyFactory } from "./company-dependency.interface"
2 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/services/company-dependency-factory.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { RqGetCompanyDependenciesByZoneDto, RqGetCompanyDependencyDto } from '../dto';
3 | import { ICompanyDependencyFactory } from '../interfaces/company-dependency.interface';
4 |
5 |
6 | /* ------------------------------------------------------- */
7 |
8 | @Injectable()
9 | export class CompanyDependencyFactoryService implements ICompanyDependencyFactory {
10 |
11 | createGetRequestDTO(id: number): RqGetCompanyDependencyDto {
12 |
13 | return new RqGetCompanyDependencyDto(id);
14 | }
15 |
16 | createGetByZoneRequestDTO(zone_id: number): RqGetCompanyDependenciesByZoneDto {
17 | return new RqGetCompanyDependencyDto(zone_id);
18 | }
19 |
20 | }
21 |
22 | /* ------------------------------------------------------- */
23 |
--------------------------------------------------------------------------------
/src/modules/company-dependencies/types/enums.ts:
--------------------------------------------------------------------------------
1 | export enum DependencyType {
2 | OTHER = 'OTHER',
3 | ORIGIN = 'ORIGIN',
4 | DESTINY = 'DESTINY',
5 | }
6 |
--------------------------------------------------------------------------------
/src/modules/customers/customers.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Get,
5 | HttpStatus,
6 | Inject,
7 | Param,
8 | Post,
9 | UseGuards,
10 | } from '@nestjs/common';
11 | import { ConfigService } from '@nestjs/config';
12 | import { ClientProxy } from '@nestjs/microservices';
13 | import { ApiTags, ApiOperation, ApiResponse, } from '@nestjs/swagger';
14 |
15 | import { Observable, timeout } from 'rxjs';
16 |
17 | import { JwtAuthGuard } from '../security/utilities/jwt-auth-guard';
18 | import {
19 | RqCreateCustomerDto,
20 | RsCreateCustomerDto,
21 | RsGetCustomerDto,
22 | } from './dto';
23 | import { CUSTOMER_FACTORY_SERVICE, ICustomerFactory } from './interfaces';
24 |
25 | /* ------------------------------------------------------- */
26 |
27 | @ApiTags('Customers')
28 | @Controller('customers')
29 | export class CustomersController {
30 | constructor(
31 | @Inject('CUSTOMER_TRANSPORT') private customer_transport: ClientProxy,
32 |
33 | private readonly configService: ConfigService,
34 |
35 | @Inject(CUSTOMER_FACTORY_SERVICE)
36 | private readonly customerFactoryService: ICustomerFactory,
37 | ) {}
38 |
39 | /* --------------------- */
40 |
41 | @UseGuards(JwtAuthGuard)
42 | @Get(':id')
43 | @ApiOperation({ summary: 'Get Customer' })
44 | @ApiResponse({ status: HttpStatus.OK, description: 'Customer OK.', type: RsGetCustomerDto })
45 | async findOne(
46 | @Param('id') id: string,
47 | ): Promise> {
48 | const rqGetCustomerDto =
49 | this.customerFactoryService.createGetRequestDTO(parseInt(id));
50 |
51 | return this.customer_transport
52 | .send('ms-customer-get', rqGetCustomerDto)
53 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
54 | }
55 |
56 | /* --------------------------- */
57 |
58 | @UseGuards(JwtAuthGuard)
59 | @Post()
60 | @ApiOperation({ summary: 'Create User' })
61 | @ApiResponse({ status: HttpStatus.OK, description: 'Created Succesfully.' })
62 | async createUser(
63 | @Body() rqCreateCustomerDto: RqCreateCustomerDto,
64 | ): Promise> {
65 | return await this.customer_transport
66 | .send('ms-customer-create', rqCreateCustomerDto)
67 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
68 | }
69 | }
70 |
71 | /* ------------------------------------------------------- */
72 |
--------------------------------------------------------------------------------
/src/modules/customers/customers.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ConfigModule, ConfigService } from '@nestjs/config';
3 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
4 |
5 | import { CustomersController } from './customers.controller';
6 | import { CUSTOMER_FACTORY_SERVICE } from './interfaces';
7 | import { CustomerFactoryService } from './services/customer-factory.service';
8 |
9 | /* ------------------------------------------------- */
10 |
11 | @Module({
12 | imports: [ConfigModule.forRoot()],
13 | controllers: [CustomersController],
14 | providers: [
15 | {
16 | provide: 'CUSTOMER_TRANSPORT',
17 | inject: [ConfigService],
18 | useFactory: (configService: ConfigService) =>
19 | ClientProxyFactory.create({
20 | transport: Transport.TCP,
21 | options: {
22 | host: configService.get('CUSTOMER_HOST'),
23 | port: configService.get('CUSTOMER_PORT'),
24 | },
25 | }),
26 | },
27 | {
28 | useClass: CustomerFactoryService, // You can switch useClass to different implementation
29 | provide: CUSTOMER_FACTORY_SERVICE,
30 | },
31 | ]
32 | })
33 |
34 | /* ------------------------------------------------- */
35 |
36 | export class CustomersModule {}
37 |
--------------------------------------------------------------------------------
/src/modules/customers/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateCustomerDto } from "./rq-create-customer.dto"
2 | export { RqGetCustomerDto } from "./rq-get-customer.dto"
3 | export { RsCreateCustomerDto } from "./rs-create-customer.dto"
4 | export { RsGetCustomerDto } from "./rs-get-customer.dto"
5 |
--------------------------------------------------------------------------------
/src/modules/customers/dto/rq-create-customer.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNotEmpty, IsNumber, IsObject, IsString } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ----------------------------------- */
5 |
6 | export class PointDto {
7 | @IsNumber()
8 | latitude: number;
9 | @IsNumber()
10 | longitud: number;
11 | }
12 |
13 | /* ----------------------------------- */
14 |
15 | export class RqCreateCustomerDto {
16 | @ApiProperty({
17 | type: String,
18 | description: 'Name',
19 | })
20 | @IsString()
21 | @IsNotEmpty()
22 | name: string;
23 |
24 | @ApiProperty({
25 | type: String,
26 | description: 'Address',
27 | })
28 | @IsNotEmpty()
29 | @IsString()
30 | address: string;
31 |
32 | @ApiProperty({
33 | type: Object,
34 | description: 'Location',
35 | })
36 | @IsNotEmpty()
37 | @IsObject()
38 | location: PointDto;
39 |
40 | @ApiProperty({
41 | type: Number,
42 | description: 'Zone_id',
43 | })
44 | @IsNotEmpty()
45 | @IsNumber()
46 | zone_id: number;
47 |
48 | @ApiProperty({
49 | type: Number,
50 | description: 'Role_id',
51 | })
52 | @IsNotEmpty()
53 | @IsNumber()
54 | role_id: number;
55 |
56 | @ApiProperty({
57 | type: String,
58 | description: 'Username',
59 | })
60 | @IsNotEmpty()
61 | @IsString()
62 | username: string;
63 |
64 | @ApiProperty({
65 | type: String,
66 | description: 'Password',
67 | })
68 | @IsNotEmpty()
69 | @IsString()
70 | password: string;
71 |
72 | }
73 |
74 | /* ----------------------------------- */
75 |
--------------------------------------------------------------------------------
/src/modules/customers/dto/rq-get-customer.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* ----------------------------------- */
7 |
8 | @Exclude()
9 | export class RqGetCustomerDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'User Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(idParam: number) {
20 | this.id = idParam
21 | }
22 |
23 | }
24 |
25 | /* ----------------------------------- */
26 |
--------------------------------------------------------------------------------
/src/modules/customers/dto/rs-create-customer.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsCreateCustomerDataDto {
6 | id: number;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
11 | export class RsCreateCustomerDto {
12 | rsGenericHeaderDto: RsGenericHeaderDto;
13 | rsCreateCustomerDataDto: RsCreateCustomerDataDto;
14 | }
15 |
16 | /* ----------------------------------- */
17 |
--------------------------------------------------------------------------------
/src/modules/customers/dto/rs-get-customer.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 | import { PointDto } from './rq-create-customer.dto';
3 |
4 | /* ----------------------------------- */
5 |
6 | export class RsGetCustomerDataDto {
7 | name: string;
8 | address: string;
9 | position: PointDto;
10 | zone_id: number;
11 | role_id: number;
12 | }
13 |
14 | /* ----------------------------------- */
15 |
16 | export class RsGetCustomerDto {
17 | rsGenericHeaderDto: RsGenericHeaderDto;
18 | rtsGetCustomerDataDto: RsGetCustomerDataDto;
19 | }
20 |
21 | /* ----------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/customers/interfaces/customer-factory.interface.ts:
--------------------------------------------------------------------------------
1 | // To use dependency injection with interfaces we need to create a token to associate with an
2 |
3 | import { RqGetCustomerDto } from "../dto";
4 |
5 |
6 | // interface and provide that token when injecting to an interface type.
7 | export const CUSTOMER_FACTORY_SERVICE = 'CUSTOMER_FACTORY_SERVICE';
8 |
9 | /* ------------------------------------ */
10 |
11 | export interface ICustomerFactory {
12 | createGetRequestDTO(id: number): RqGetCustomerDto;
13 | }
14 |
15 | /* ------------------------------------ */
16 |
17 |
--------------------------------------------------------------------------------
/src/modules/customers/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export { CUSTOMER_FACTORY_SERVICE, ICustomerFactory } from "./customer-factory.interface"
2 |
--------------------------------------------------------------------------------
/src/modules/customers/services/customer-factory.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | import { RqGetCustomerDto } from '../dto';
4 | import { ICustomerFactory } from '../interfaces';
5 |
6 |
7 | /* ------------------------------------------------------- */
8 |
9 | @Injectable()
10 | export class CustomerFactoryService implements ICustomerFactory {
11 |
12 | createGetRequestDTO(id: number): RqGetCustomerDto {
13 | return new RqGetCustomerDto(id);
14 | }
15 |
16 | }
17 |
18 | /* ------------------------------------------------------- */
19 |
--------------------------------------------------------------------------------
/src/modules/location/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateLocationDto } from "./rq-create-location.dto"
2 | export { RsCreateLocationDto } from "./rs-create-location.dto"
3 | export { RqGetLocationsTransportDto } from "./rq-get-locations-transport.dto"
4 | export { RsGetLocationsTransportDto } from "./rs-get-locations-transport.dto"
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/modules/location/dto/rq-create-location.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsDateString, IsNumber, IsObject } from "class-validator";
2 |
3 | /* ------------------------- */
4 |
5 | export class PointDto {
6 | @IsNumber()
7 | latitude: number;
8 | @IsNumber()
9 | longitud: number;
10 | }
11 |
12 | /* ------------------------- */
13 |
14 | export class RqCreateLocationDto {
15 | @IsNumber()
16 | transport_id: number;
17 |
18 | @IsObject()
19 | position: PointDto;
20 |
21 | @IsDateString()
22 | readonly date_register: string;
23 | }
24 |
25 | /* ------------------------- */
26 |
--------------------------------------------------------------------------------
/src/modules/location/dto/rq-get-locations-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsDateString, IsString } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------- */
5 |
6 | export class RqGetLocationsTransportDto {
7 | @ApiProperty({
8 | type: Date,
9 | description: 'Date Route',
10 | })
11 | @IsDateString()
12 | readonly date_route: string;
13 |
14 | @ApiProperty({
15 | type: String,
16 | description: 'Id Transport',
17 | })
18 | @IsString()
19 | readonly transport_id: string;
20 |
21 | }
22 |
23 | /* ------------------------- */
24 |
--------------------------------------------------------------------------------
/src/modules/location/dto/rs-create-location.dto.ts:
--------------------------------------------------------------------------------
1 |
2 | export class RsCreateLocationDto {
3 | statusCode: number;
4 | message: string;
5 | }
6 |
--------------------------------------------------------------------------------
/src/modules/location/dto/rs-get-locations-transport.dto.ts:
--------------------------------------------------------------------------------
1 |
2 | import { PointDto } from "./rq-create-location.dto";
3 |
4 | export class RsGetLocationsTransportDto {
5 | statusCode: number;
6 | message: string;
7 | position: PointDto[];
8 | }
9 |
--------------------------------------------------------------------------------
/src/modules/location/location.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Get,
5 | Inject,
6 | Logger,
7 | Post,
8 | Query,
9 | } from '@nestjs/common';
10 | import { ClientProxy } from '@nestjs/microservices';
11 |
12 | import {
13 | RqCreateLocationDto,
14 | RqGetLocationsTransportDto,
15 | RsCreateLocationDto,
16 | RsGetLocationsTransportDto,
17 | } from './dto';
18 |
19 | /* ----------------------------------- */
20 |
21 | @Controller('location')
22 | export class LocationController {
23 | constructor(
24 | @Inject('LOCATION_TRANSPORT') private location_transport: ClientProxy,
25 |
26 | private readonly logger: Logger,
27 | ) {}
28 |
29 | /* ------------- */
30 |
31 | @Post()
32 | createLocationTransport(@Body() rqCreateLocationDto: RqCreateLocationDto) {
33 | this.logger.log(
34 | `[POST][location] rqCreateLocationDto: ${rqCreateLocationDto}`,
35 | );
36 | return this.location_transport.emit(
37 | 'ms-create-location',
38 | rqCreateLocationDto,
39 | );
40 | }
41 |
42 | /* ------------- */
43 |
44 | @Get('get-locations-transport')
45 | getLocationsTransport(@Query() query: RqGetLocationsTransportDto) {
46 | this.logger.log(
47 | `[GET][location/get-locations-transport] date_route: , ${query.date_route}, ' transport_id:', ${query.transport_id}`,
48 | );
49 | return this.location_transport.send(
50 | 'ms-get-locations-transport',
51 | query,
52 | );
53 | }
54 |
55 |
56 | }
57 |
58 | /* ----------------------------------- */
59 |
--------------------------------------------------------------------------------
/src/modules/location/location.module.ts:
--------------------------------------------------------------------------------
1 | import { Logger, Module } from '@nestjs/common';
2 | import { ConfigModule, ConfigService } from '@nestjs/config';
3 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
4 |
5 | import { LocationController } from './location.controller';
6 |
7 | /* ----------------------------------- */
8 |
9 | @Module({
10 | imports: [ConfigModule.forRoot(),
11 | ],
12 | controllers: [LocationController],
13 | providers: [
14 | {
15 | provide: 'LOCATION_TRANSPORT',
16 | inject: [ConfigService],
17 | useFactory: (configService: ConfigService) =>
18 | ClientProxyFactory.create({
19 | transport: Transport.MQTT,
20 | options: {
21 | host: configService.get('LOCATION_HOST'),
22 | port: configService.get('LOCATION_PORT'),
23 | },
24 | }),
25 | },
26 | Logger
27 | ]
28 | })
29 |
30 | /* ----------------------------------- */
31 |
32 | export class LocationModule {}
33 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateOrderDto } from "./rq-create-order.dto"
2 | export { RsCreateOrderDto } from "./rs-create-order.dto"
3 | export { RqGetOrderDto } from "./rq-get-order.dto"
4 | export { RsGetOrderDto } from "./rs-get-order.dto"
5 | export { RsGetOrdersDto } from "./rs-get-orders.dto"
6 | export { RqDeleteOrderDto } from "./rq-delete-order.dto"
7 | export { RsDeleteOrdersDto } from "./rs-delete-orders.dto"
8 | export { RqDeliveredOrder } from "./rq-delivered-order.dto"
9 | export { RsDeliveredOrderDto } from "./rs-delivered-order.dto"
10 | export { RqLoadedOrder } from "./rq-loaded-order.dto"
11 | export { RsLoadedOrderDto } from "./rs-loaded-order.dto"
12 | export { RqCancelledOrder } from "./rq-cancelled-order.dto"
13 | export { RsCancelledOrderDto } from "./rs-cancelled-order.dto"
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-cancelled-order.dto.ts:
--------------------------------------------------------------------------------
1 | export class RqCancelledOrder {
2 | }
3 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-create-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsDateString, IsEnum, IsNumber, IsPositive, IsString } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 | import { StateType } from "../types/enums"
4 |
5 | /* ------------------------------------ */
6 |
7 | export class RqCreateOrderDetailsDto {
8 | @ApiProperty({
9 | type: Number,
10 | description: 'Product ID',
11 | })
12 | @IsString()
13 | product_id: string;
14 |
15 | @ApiProperty({
16 | type: Number,
17 | description: 'Quantity',
18 | })
19 | @IsNumber()
20 | quantity: number;
21 | }
22 |
23 | /* ------------------------------------ */
24 |
25 | export class RqCreateOrderDto {
26 |
27 | @IsEnum(StateType)
28 | @ApiProperty({
29 | description: 'State',
30 | enum: StateType
31 | })
32 | state: StateType;
33 |
34 | @ApiProperty({
35 | type: Date,
36 | description: 'Date Delivery',
37 | })
38 | @IsDateString()
39 | readonly date_delivery: string;
40 |
41 | @ApiProperty({
42 | type: Number,
43 | description: 'Client ID',
44 | })
45 | @IsPositive()
46 | @IsNumber()
47 | client_id: number;
48 |
49 | @ApiProperty({
50 | type: Number,
51 | description: 'Amount',
52 | })
53 | @IsPositive()
54 | @IsNumber()
55 | amount: number;
56 |
57 | @ApiProperty({
58 | type: Array,
59 | description: 'Order Detail',
60 | })
61 | rqCreateOrderDetailsDto: RqCreateOrderDetailsDto[];
62 | }
63 |
64 | /* ------------------------------------ */
65 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-delete-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* ------------------------------------ */
7 |
8 | @Exclude()
9 | export class RqDeleteOrderDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Order Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(idParam: number) {
20 | this.id = idParam
21 | }
22 | }
23 |
24 | /* ------------------------------------ */
25 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-delivered-order.dto.ts:
--------------------------------------------------------------------------------
1 | export class RqDeliveredOrder {
2 | }
3 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-get-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* ------------------------------------ */
7 |
8 | @Exclude()
9 | export class RqGetOrderDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Order Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(idParam: number) {
20 | this.id = idParam
21 | }
22 | }
23 |
24 | /* ------------------------------------ */
25 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rq-loaded-order.dto.ts:
--------------------------------------------------------------------------------
1 | export class RqLoadedOrder {
2 | }
3 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-cancelled-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsCancelledOrderDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-create-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | export class RsCreateOrderDataDto {
4 | id: number;
5 | }
6 |
7 | export class RsCreateOrderDto {
8 | rsGenericHeaderDto: RsGenericHeaderDto;
9 | rsCreateOrderDataDto: RsCreateOrderDataDto;
10 | }
11 |
12 | /* ----------------------------------- */
13 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-delete-orders.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsDeleteOrdersDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-delivered-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsDeliveredOrderDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-get-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 | import { StateType } from '../types/enums';
3 |
4 | /* ------------------------------------------------- */
5 |
6 | export class RsGetOrderDetailsDto {
7 | product_id: string;
8 | quantity: number;
9 | }
10 |
11 | /* --------------- */
12 |
13 | export class RsGetOrderHeaderDto {
14 | state: StateType;
15 | date_delivery: string;
16 | client_id: number;
17 | amount: number;
18 | rsGetOrderDetails: RsGetOrderDetailsDto[];
19 | }
20 |
21 | /* --------------- */
22 |
23 | export class RsGetOrderDto {
24 | rsGenericHeaderDto: RsGenericHeaderDto;
25 | rsGetOrderHeaderDto: RsGetOrderHeaderDto;
26 | }
27 |
28 | /* ------------------------------------------------- */
29 |
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-get-orders.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 | import { StateType } from '../types/enums';
3 |
4 | /* ------------------------------------------------- */
5 |
6 | export class RsGetOrdersDetailsDto {
7 | product_id: string;
8 | quantity: number;
9 | }
10 |
11 | /* --------------- */
12 |
13 | export class RsGetOrdersHeaderDto {
14 | state: StateType;
15 | date_delivery: string;
16 | client_id: number;
17 | amount: number;
18 | rsGetOrdersDetails: RsGetOrdersDetailsDto[];
19 | }
20 |
21 | /* --------------- */
22 |
23 | export class RsGetOrdersDto {
24 | rsGenericHeaderDto: RsGenericHeaderDto;
25 | rsGetOrdersHeaderDto: RsGetOrdersHeaderDto[];
26 | }
27 |
28 | /* ------------------------------------------------- */
--------------------------------------------------------------------------------
/src/modules/orders/dto/rs-loaded-order.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsLoadedOrderDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
--------------------------------------------------------------------------------
/src/modules/orders/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export { ORDERS_FACTORY_SERVICE, IOrdersFactory } from "./orders-factory.interface"
2 |
--------------------------------------------------------------------------------
/src/modules/orders/interfaces/orders-factory.interface.ts:
--------------------------------------------------------------------------------
1 | // To use dependency injection with interfaces we need to create a token to associate with an
2 |
3 | import { RqDeleteOrderDto, RqGetOrderDto } from "../dto";
4 |
5 | // interface and provide that token when injecting to an interface type.
6 | export const ORDERS_FACTORY_SERVICE = 'ORDERS_FACTORY_SERVICE';
7 |
8 | /* ------------------------------------ */
9 |
10 | export interface IOrdersFactory {
11 | createGetRequestDTO(id: number): RqGetOrderDto;
12 | deleteRequestDTO(id: number): RqDeleteOrderDto;
13 | }
14 |
15 | /* ------------------------------------ */
16 |
17 |
--------------------------------------------------------------------------------
/src/modules/orders/orders.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Delete,
5 | Get,
6 | Inject,
7 | Param,
8 | Patch,
9 | Post,
10 | } from '@nestjs/common';
11 | import { ClientProxy } from '@nestjs/microservices';
12 |
13 | import {
14 | RqCreateOrderDto,
15 | RsCancelledOrderDto,
16 | RsDeleteOrdersDto,
17 | RsGetOrderDto,
18 | RsGetOrdersDto,
19 | RsLoadedOrderDto,
20 | } from './dto';
21 | import { RsDeliveredOrderDto } from './dto/rs-delivered-order.dto';
22 | import { IOrdersFactory, ORDERS_FACTORY_SERVICE } from './interfaces';
23 |
24 | /* --------------------------------------------------- */
25 |
26 | @Controller('orders')
27 | export class OrdersController {
28 | constructor(
29 | @Inject('ORDER_SERVICE') private orderClient: ClientProxy,
30 |
31 | @Inject(ORDERS_FACTORY_SERVICE)
32 | private readonly ordersFactoryService: IOrdersFactory,
33 | ) {}
34 |
35 | /* ---------------- */
36 |
37 | @Post()
38 | createOrder(@Body() rqCreateOrderDto: RqCreateOrderDto) {
39 | this.orderClient.emit('order-created', rqCreateOrderDto);
40 | }
41 |
42 | /* ---------------- */
43 |
44 | @Get(':id')
45 | async getOrder(@Param('id') id: string) {
46 | const rqGetOrderDto = this.ordersFactoryService.createGetRequestDTO(
47 | parseInt(id),
48 | );
49 |
50 | return this.orderClient.send('ms-order-get', rqGetOrderDto);
51 | }
52 |
53 | /* ---------------- */
54 |
55 | @Get()
56 | async getOrders() {
57 | return this.orderClient.send('ms-orders-get', '');
58 | }
59 |
60 | /* ---------------- */
61 |
62 | @Delete(':id')
63 | async delete(@Param('id') id: string) {
64 | const rqDeleteOrderDto = this.ordersFactoryService.deleteRequestDTO(
65 | parseInt(id),
66 | );
67 |
68 | return this.orderClient.send(
69 | 'ms-order-delete',
70 | rqDeleteOrderDto,
71 | );
72 | }
73 |
74 | /* ---------------- */
75 |
76 | @Patch('delivered/:id')
77 | async deliveredOrder(@Param('id') id: string) {
78 | return this.orderClient.send('ms-order-delivered', {
79 | key: id,
80 | });
81 | }
82 |
83 | /* ---------------- */
84 |
85 | @Patch('loaded/:id')
86 | async loadedOrder(@Param('id') id: string) {
87 | return this.orderClient.send('ms-order-loaded', {
88 | key: id,
89 | });
90 | }
91 |
92 | /* ---------------- */
93 |
94 | @Patch('cancelled/:id')
95 | async cancelledOrder(@Param('id') id: string) {
96 | return this.orderClient.send('ms-order-cancelled', {
97 | key: id,
98 | });
99 | }
100 | }
101 |
102 | /* --------------------------------------------------- */
103 |
--------------------------------------------------------------------------------
/src/modules/orders/orders.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
3 | import { ConfigService } from '@nestjs/config';
4 |
5 | import { OrdersController } from './orders.controller';
6 | import { OrdersFactoryService } from './services/orders-factory.service';
7 | import { ORDERS_FACTORY_SERVICE } from './interfaces';
8 |
9 | /* ----------------------------------------------- */
10 |
11 | @Module({
12 | imports: [],
13 | controllers: [OrdersController],
14 | providers: [
15 | {
16 | provide: 'ORDER_SERVICE',
17 | inject: [ConfigService],
18 | useFactory: (configService: ConfigService) =>
19 | ClientProxyFactory.create({
20 | transport: Transport.TCP,
21 | options: {
22 | host: configService.get('ORDER_HOST'),
23 | port: configService.get('ORDER_PORT'),
24 | },
25 | }),
26 | },
27 | {
28 | useClass: OrdersFactoryService, // You can switch useClass to different implementation
29 | provide: ORDERS_FACTORY_SERVICE,
30 | },
31 | ],
32 | })
33 |
34 | /* ----------------------------------------------- */
35 | export class OrdersModule {}
36 |
--------------------------------------------------------------------------------
/src/modules/orders/services/orders-factory.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | import { RqDeleteOrderDto, RqGetOrderDto } from '../dto';
4 | import { IOrdersFactory } from '../interfaces';
5 |
6 |
7 | /* ------------------------------------------------------- */
8 |
9 | @Injectable()
10 | export class OrdersFactoryService implements IOrdersFactory {
11 |
12 | createGetRequestDTO(id: number): RqGetOrderDto {
13 | return new RqGetOrderDto(id);
14 | }
15 |
16 | deleteRequestDTO(id: number): RqDeleteOrderDto {
17 | return new RqDeleteOrderDto(id);
18 | }
19 | }
20 |
21 | /* ------------------------------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/orders/types/enums.ts:
--------------------------------------------------------------------------------
1 | export enum StateType {
2 | PENDING = 'PENDING',
3 | IN_PROGRESS = 'IN_PROGRESS',
4 | DELIVERED = 'DELIVERED',
5 | CANCELLED = 'CANCELLED',
6 | }
7 |
--------------------------------------------------------------------------------
/src/modules/params/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RsGetParamsDto } from "./rs-get-params.dto"
2 | export { RqGetParamsDto } from "./rq-get-params.dto"
3 |
--------------------------------------------------------------------------------
/src/modules/params/dto/rq-get-params.dto.ts:
--------------------------------------------------------------------------------
1 | export class RqGetParamsDto {
2 | }
--------------------------------------------------------------------------------
/src/modules/params/dto/rs-get-params.dto.ts:
--------------------------------------------------------------------------------
1 | export class ParamsDto {
2 | key: string;
3 | value: string;
4 | }
5 |
6 | /* ----------------- */
7 |
8 | export class RsGetParamsDto {
9 | statusCode: number;
10 | message: string;
11 | paramsDto: ParamsDto[];
12 | }
13 |
14 | /* ----------------- */
15 |
--------------------------------------------------------------------------------
/src/modules/params/params.controller.ts:
--------------------------------------------------------------------------------
1 | import { Controller, Get, Inject } from '@nestjs/common';
2 | import { ClientKafka } from '@nestjs/microservices';
3 |
4 | import { Observable } from 'rxjs';
5 | import { RqGetParamsDto, RsGetParamsDto } from './dto';
6 |
7 | /* -------------------------------- */
8 |
9 | @Controller('params')
10 | export class ParamsController {
11 | constructor(
12 | @Inject('PARAMS_TRANSPORT') private readonly paramsClient: ClientKafka,
13 | private readonly rqGetParamsDto: RqGetParamsDto,
14 | ) {}
15 |
16 | /* --------------- */
17 |
18 | @Get()
19 | async findAll(): Promise> {
20 | return this.paramsClient.send(
21 | 'ms-params-get',
22 | JSON.stringify(this.rqGetParamsDto),
23 | );
24 | }
25 |
26 | /* --------------- */
27 |
28 | async onModuleInit() {
29 | this.paramsClient.subscribeToResponseOf('ms-params-get');
30 | await this.paramsClient.connect();
31 | }
32 | }
33 |
34 | /* -------------------------------- */
35 |
--------------------------------------------------------------------------------
/src/modules/params/params.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ParamsController } from './params.controller';
3 | import { ClientsModule, Transport } from '@nestjs/microservices';
4 | import { RqGetParamsDto } from './dto';
5 |
6 | /* -------------------------------- */
7 |
8 | @Module({
9 | imports: [
10 | ClientsModule.register([
11 | {
12 | name: 'PARAMS_TRANSPORT',
13 | transport: Transport.KAFKA,
14 | options: {
15 | client: {
16 | clientId: 'params',
17 | brokers: ['localhost:9092'],
18 | },
19 | consumer: {
20 | groupId: 'params-consumer',
21 | },
22 | },
23 | },
24 | ]),
25 | ],
26 | controllers: [ParamsController],
27 | providers: [RqGetParamsDto],
28 | })
29 |
30 | /* -------------------------------- */
31 |
32 | export class ParamsModule {}
33 |
--------------------------------------------------------------------------------
/src/modules/products/product.pb.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-empty-interface */
2 | /**
3 | * This file is auto-generated by nestjs-proto-gen-ts
4 | */
5 |
6 | import { Observable } from 'rxjs';
7 |
8 | export interface ProductServices {
9 | getProduct(request: RqFindProduct): Observable;
10 | getProducts(request: RqFindProducts): Observable;
11 | createProduct(request: RqCreateProduct): Observable;
12 | }
13 |
14 | export interface ProductData {
15 | id?: string;
16 | description?: string;
17 | weight?: number;
18 | volume?: number;
19 | price?: number;
20 | }
21 | export interface RqFindProduct {
22 | id?: string;
23 | }
24 | export interface RsFindProduct {
25 | status?: number;
26 | error?: string;
27 | data?: ProductData;
28 | }
29 | export interface RqFindProducts {}
30 |
31 | export interface RsFindProducts {
32 | status?: number;
33 | error?: string;
34 | data?: ProductData[];
35 | }
36 | export interface RqCreateProduct {
37 | description?: string;
38 | weight?: number;
39 | volume?: number;
40 | price?: number;
41 | }
42 | export interface RsCreateProduct {
43 | status?: number;
44 | error?: string;
45 | id?: string;
46 | }
47 |
--------------------------------------------------------------------------------
/src/modules/products/product.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 |
3 | package product;
4 |
5 | service ProductServices {
6 | rpc GetProduct (RqFindProduct) returns (RsFindProduct) {};
7 | rpc GetProducts (RqFindProducts) returns (RsFindProducts) {};
8 | rpc CreateProduct (RqCreateProduct) returns (RsCreateProduct) {};
9 | }
10 |
11 | /* --------------------- getProduct --------------------- */
12 |
13 | message ProductData{
14 | string id = 1;
15 | string description = 2;
16 | double weight = 3;
17 | double volume = 4;
18 | double price = 5;
19 | }
20 |
21 | message RqFindProduct {
22 | string id = 1;
23 | }
24 |
25 | message RsFindProduct {
26 | int32 status = 1;
27 | string error = 2;
28 | ProductData data = 3;
29 | }
30 |
31 | /* --------------------- getProducts --------------------- */
32 |
33 | message RqFindProducts {}
34 |
35 | message RsFindProducts {
36 | int32 status = 1;
37 | string error = 2;
38 | repeated ProductData data = 3;
39 | }
40 |
41 | /* --------------------- createProducts --------------------- */
42 |
43 | message RqCreateProduct {
44 | string description = 2;
45 | double weight = 3;
46 | double volume = 4;
47 | double price = 5;
48 | }
49 |
50 | message RsCreateProduct {
51 | int32 status = 1;
52 | string error = 2;
53 | string id = 3;
54 | }
--------------------------------------------------------------------------------
/src/modules/products/products.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Get,
5 | Inject,
6 | OnModuleInit,
7 | Param,
8 | Post,
9 | } from '@nestjs/common';
10 | import { ClientGrpc } from '@nestjs/microservices';
11 |
12 | import { Observable } from 'rxjs';
13 | import {
14 | ProductServices,
15 | RqCreateProduct,
16 | RsCreateProduct,
17 | RsFindProduct,
18 | RsFindProducts,
19 | } from './product.pb';
20 |
21 | /* -------------------------------------------------- */
22 |
23 | @Controller('products')
24 | export class ProductsController implements OnModuleInit {
25 | private srv: ProductServices;
26 |
27 | constructor(@Inject('PRODUCT_TRANSPORT') private client: ClientGrpc) {}
28 |
29 | /* ----------------- */
30 |
31 | onModuleInit() {
32 | this.srv = this.client.getService('ProductServices');
33 | }
34 |
35 | /* ----------------- */
36 |
37 | @Get()
38 | async getProducts(): Promise> {
39 | return this.srv.getProducts({});
40 | }
41 |
42 | /* ----------------- */
43 |
44 | @Post()
45 | private async createProduct(
46 | @Body() body: RqCreateProduct,
47 | ): Promise> {
48 | return this.srv.createProduct(body);
49 | }
50 |
51 | /* ----------------- */
52 |
53 | @Get(':id')
54 | private async getProduct(
55 | @Param('id') id: string,
56 | ): Promise> {
57 | return this.srv.getProduct({ id });
58 | }
59 | }
60 |
61 | /* -------------------------------------------------- */
62 |
--------------------------------------------------------------------------------
/src/modules/products/products.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ConfigModule, ConfigService, } from '@nestjs/config';
3 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
4 |
5 | import { join } from 'path';
6 |
7 | import { ProductsController } from './products.controller';
8 |
9 | /* ------------------------------------------ */
10 |
11 | @Module({
12 | imports: [ConfigModule.forRoot(),],
13 | controllers: [ProductsController],
14 | providers: [
15 | {
16 | provide: 'PRODUCT_TRANSPORT',
17 | useFactory: (configService: ConfigService) => {
18 | return ClientProxyFactory.create({
19 | transport: Transport.GRPC,
20 | options: {
21 | package: 'product',
22 | protoPath: join(__dirname, './product.proto'),
23 | url: configService.get('URL_PRODUCTS')
24 | },
25 | })
26 | },
27 | inject: [ConfigService],
28 | }
29 | ]
30 | })
31 |
32 | /* ------------------------------------------ */
33 |
34 | export class ProductsModule {}
35 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqGenerateRouteDto } from "./rq-generate-route.dto"
2 | export { RqGetRouteForMapDto } from "./rq-get-route-for-map.dto"
3 | export { RqGetRouteOrdersDetailsDto } from "./rq-get-orders-details-route.dto"
4 | export { RsGetRouteOrdersDetailsDto } from "./rs-get-orders-details-route.dto"
5 | export { RsGetRouteAmountDto } from "./rs-get-route-amount.dto"
6 | export { RqGetRouteAmountDto } from "./rq-get-route-amount.dto"
7 | export { RqCashDepositRouteDto } from "./rq-cash-deposit-route.dto"
8 | export { RsCashDepositRouteDto } from "./rs-cash-deposit-route.dto"
9 | export { RqLoadedTransportRouteDto } from "./rq-loaded-transport-route.dto"
10 | export { RsLoadedTransportRouteDto } from "./rs-loaded-transport-route.dto"
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-cash-deposit-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString, } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqCashDepositRouteDto {
7 |
8 | @ApiProperty({
9 | type: String,
10 | description: 'Id Route',
11 | })
12 | @IsString()
13 | readonly route_id: string;
14 | }
15 |
16 | /* ------------------------------------------ */
17 |
18 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-generate-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsDateString, } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqGenerateRouteDto {
7 |
8 | @ApiProperty({
9 | type: Date,
10 | description: 'Date Generate',
11 | })
12 | @IsDateString()
13 | readonly date_generate: string;
14 |
15 | }
16 |
17 | /* ------------------------------------------ */
18 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-get-orders-details-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqGetRouteOrdersDetailsDto {
7 | @ApiProperty({
8 | type: String,
9 | description: 'Id Route',
10 | })
11 | @IsString()
12 | readonly route_id: string;
13 |
14 | }
15 |
16 | /* ------------------------------------------ */
17 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-get-route-amount.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqGetRouteAmountDto {
7 | @ApiProperty({
8 | type: String,
9 | description: 'Id Route',
10 | })
11 | @IsString()
12 | readonly route_id: string;
13 |
14 | }
15 |
16 | /* ------------------------------------------ */
17 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-get-route-for-map.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsDateString, IsString } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqGetRouteForMapDto {
7 | @ApiProperty({
8 | type: Date,
9 | description: 'Date Route',
10 | })
11 | @IsDateString()
12 | readonly date_route: string;
13 |
14 | @ApiProperty({
15 | type: String,
16 | description: 'Id Transport',
17 | })
18 | @IsString()
19 | readonly transport_id: string;
20 |
21 | }
22 |
23 | /* ------------------------------------------ */
24 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rq-loaded-transport-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString } from 'class-validator';
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ------------------------------------------ */
5 |
6 | export class RqLoadedTransportRouteDto {
7 | @ApiProperty({
8 | type: String,
9 | description: 'Id Route',
10 | })
11 | @IsString()
12 | readonly route_id: string;
13 |
14 | }
15 |
16 | /* ------------------------------------------ */
17 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rs-cash-deposit-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
2 |
3 | /* ------------------------------------------ */
4 |
5 | export class RsCashDepositRouteDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | }
8 |
9 | /* ------------------------------------------ */
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rs-get-orders-details-route.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
2 |
3 | /* ------------------- */
4 |
5 | export class RsRouteOrderDetailDto {
6 | product_id: string;
7 | description: string;
8 | quantity: number;
9 | }
10 |
11 | /* ------------------- */
12 |
13 | export class RsGetRouteOrdersDetailsDto {
14 | rsGenericHeaderDto: RsGenericHeaderDto;
15 | rsRouteDetailDto: RsRouteOrderDetailDto[];
16 |
17 | constructor(
18 | rsGenericHeaderDto: RsGenericHeaderDto,
19 | rsRouteDetailDto: RsRouteOrderDetailDto[],
20 | ) {
21 | this.rsGenericHeaderDto = rsGenericHeaderDto;
22 | this.rsRouteDetailDto = rsRouteDetailDto;
23 | }
24 | }
25 |
26 | /* ------------------------------------------ */
27 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rs-get-route-amount.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
2 |
3 | /* ------------------------------------------ */
4 |
5 | export class RsGetRouteAmountDto {
6 | rsGenericHeaderDto: RsGenericHeaderDto;
7 | amount: number;
8 | }
9 |
10 | /* ------------------------------------------ */
11 |
12 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rs-get-route-for-map.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
2 |
3 | /* ------------------------------------------ */
4 |
5 | export class RoutesDetailsEntity {
6 | order_id: number;
7 | }
8 |
9 | /* --------------- */
10 |
11 | export class RsRouteDetailDto {
12 | transport_id: number;
13 | origin_id: number;
14 | destination_id: number;
15 | zone_id: number;
16 | time_started: Date;
17 | time_end: Date;
18 | routesDetails: RoutesDetailsEntity[]
19 | }
20 |
21 | /* --------------- */
22 |
23 | export class RsGetRouteForMapDto {
24 |
25 | rsGenericHeaderDto: RsGenericHeaderDto;
26 | rsRouteDetailDto: RsRouteDetailDto;
27 |
28 | constructor(
29 | rsGenericHeaderDto: RsGenericHeaderDto,
30 | rsRouteDetailDto: RsRouteDetailDto,
31 | ) {
32 | this.rsGenericHeaderDto = rsGenericHeaderDto;
33 | this.rsRouteDetailDto = rsRouteDetailDto;
34 | }
35 |
36 | }
37 |
38 | /* ------------------------------------------ */
39 |
--------------------------------------------------------------------------------
/src/modules/routes/dto/rs-loaded-transport-route.dto.ts:
--------------------------------------------------------------------------------
1 |
2 | export class RsLoadedTransportRouteDto {
3 | statusCode: number;
4 | message: string;
5 | }
6 |
7 | /* ---------------------------------------- */
8 |
9 |
--------------------------------------------------------------------------------
/src/modules/routes/routes.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Get,
5 | Inject,
6 | Patch,
7 | Post,
8 | Query,
9 | } from '@nestjs/common';
10 | import { ClientNats } from '@nestjs/microservices';
11 |
12 | import {
13 | RqCashDepositRouteDto,
14 | RqGenerateRouteDto,
15 | RqGetRouteAmountDto,
16 | RqGetRouteForMapDto,
17 | RqGetRouteOrdersDetailsDto,
18 | RqLoadedTransportRouteDto,
19 | RsCashDepositRouteDto,
20 | RsGetRouteOrdersDetailsDto,
21 | RsLoadedTransportRouteDto,
22 | } from './dto';
23 | import { RsGetRouteAmountDto } from './dto/rs-get-route-amount.dto';
24 | import { RsGetRouteForMapDto } from './dto/rs-get-route-for-map.dto';
25 |
26 | /* ------------------------------------------ */
27 |
28 | @Controller('routes')
29 | export class RoutesController {
30 | constructor(
31 | @Inject('ROUTE_TRANSPORT') private readonly routClient: ClientNats,
32 | ) {}
33 |
34 | /* -------------------- */
35 |
36 | @Post('generate')
37 | generateRoute(@Body() rqGenerateRouteDto: RqGenerateRouteDto) {
38 | this.routClient.emit('generate-route', rqGenerateRouteDto);
39 | }
40 |
41 | /* -------------------- */
42 |
43 | @Get('map')
44 | getRouteForMap(@Query() query: RqGetRouteForMapDto) {
45 | return this.routClient.send(
46 | 'get-route-for-map',
47 | query,
48 | );
49 | }
50 |
51 | /* -------------------- */
52 |
53 | @Get('orders-details')
54 | getOrdesrDetailsRoute(@Query() query: RqGetRouteOrdersDetailsDto) {
55 | return this.routClient.send(
56 | 'get-route-orders-details',
57 | query,
58 | );
59 | }
60 |
61 | /* -------------------- */
62 |
63 | @Get('route-amount')
64 | getAmountRoute(@Query() query: RqGetRouteAmountDto) {
65 | return this.routClient.send('get-route-amount', query);
66 | }
67 |
68 | /* -------------------- */
69 |
70 | @Patch('cash-deposited')
71 | cashDepositedRoute(@Query() query: RqCashDepositRouteDto) {
72 | return this.routClient.send('cash-deposited', query);
73 | }
74 |
75 | /* -------------------- */
76 |
77 | @Patch('loaded-transport')
78 | loadedTransportRoute(@Query() query: RqLoadedTransportRouteDto) {
79 | return this.routClient.send(
80 | 'loaded-transport',
81 | query,
82 | );
83 | }
84 | }
85 |
86 | /* ------------------------------------------ */
87 |
--------------------------------------------------------------------------------
/src/modules/routes/routes.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ConfigService } from '@nestjs/config';
3 | import {
4 | ClientProxyFactory,
5 | Transport,
6 | } from '@nestjs/microservices';
7 |
8 | import { RoutesController } from './routes.controller';
9 |
10 | /* ------------------------------------------ */
11 |
12 | @Module({
13 | imports: [],
14 | controllers: [RoutesController],
15 | providers: [
16 | {
17 | provide: 'ROUTE_TRANSPORT',
18 | inject: [ConfigService],
19 | useFactory: (configService: ConfigService) =>
20 | ClientProxyFactory.create({
21 | transport: Transport.NATS,
22 | options: {
23 | servers: [
24 | `nats://${configService.get('ROUTE_HOST')}:${configService.get(
25 | 'ROUTE_PORT',
26 | )}`,
27 | ],
28 | },
29 | }),
30 | },
31 | ],
32 | })
33 |
34 | /* ------------------------------------------ */
35 |
36 | export class RoutesModule {}
37 |
--------------------------------------------------------------------------------
/src/modules/security/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqLoginUserDto } from "./rq-login-user.dto"
2 | export { RsLoginUserDto } from "./rs-login-user.dto"
3 | export { RqRegisterUserDto } from "./rq-register-user.dto"
4 | export { RsRegisterUserDto } from "./rs-register-user.dto"
5 |
--------------------------------------------------------------------------------
/src/modules/security/dto/rq-login-user.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { IsNotEmpty, IsString } from "class-validator";
4 |
5 | /* -------------------------------------------------------- */
6 |
7 | export class RqLoginUserDto {
8 | @ApiProperty({
9 | type: String,
10 | description: 'Username',
11 | })
12 | @IsNotEmpty()
13 | @IsString()
14 | readonly username: string;
15 | @ApiProperty({
16 | type: String,
17 | description: 'Password',
18 | })
19 | @IsNotEmpty()
20 | @IsString()
21 | readonly password: string;
22 | }
23 |
24 | /* -------------------------------------------------------- */
25 |
26 |
--------------------------------------------------------------------------------
/src/modules/security/dto/rq-register-user.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from "@nestjs/swagger";
2 | import { IsNotEmpty, IsNumber, IsString, Length } from "class-validator";
3 |
4 | /* -------------------------------------------------------- */
5 |
6 | export class RqRegisterUserDto {
7 | @ApiProperty({
8 | type: Number,
9 | description: 'Role Id',
10 | })
11 | @IsNotEmpty()
12 | @IsNumber()
13 | readonly role_id: number;
14 | @ApiProperty({
15 | type: Number,
16 | description: 'User Id',
17 | })
18 | @IsNotEmpty()
19 | @IsNumber()
20 | readonly user_id: number;
21 | @ApiProperty({
22 | type: String,
23 | description: 'Username',
24 | })
25 | @IsNotEmpty()
26 | @IsString()
27 | readonly username: string;
28 | @ApiProperty({
29 | type: String,
30 | minLength: 6,
31 | maxLength: 20,
32 | description: 'Password',
33 | })
34 | @IsNotEmpty()
35 | @IsString()
36 | @Length(6, 20)
37 | readonly password: string;
38 | }
39 |
40 | /* -------------------------------------------------------- */
41 |
42 |
--------------------------------------------------------------------------------
/src/modules/security/dto/rs-login-user.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from "@nestjs/swagger";
2 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
3 |
4 | /* --------------------------------------------------------------------- */
5 |
6 | export class RsLoginUserDataDto {
7 | @ApiProperty({
8 | type: Number,
9 | description: 'Status Code',
10 | })
11 | statusCode: number;
12 | @ApiProperty({
13 | type: String,
14 | description: 'Message',
15 | })
16 | message: string;
17 | @ApiProperty({
18 | type: String,
19 | description: 'Session Token',
20 | })
21 | session_token: string;
22 | @ApiProperty({
23 | type: Number,
24 | description: 'User Id',
25 | })
26 | user_id: number;
27 | @ApiProperty({
28 | type: Number,
29 | description: 'Role Id',
30 | })
31 | role_id: number;
32 | }
33 |
34 | /* --------------------------------------------------------------------- */
35 |
36 | export class RsLoginUserDto {
37 | rsGenericHeaderDto: RsGenericHeaderDto;
38 | rsLoginUserData: RsLoginUserDataDto;
39 | }
40 |
41 | /* --------------------------------------------------------------------- */
42 |
--------------------------------------------------------------------------------
/src/modules/security/dto/rs-register-user.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from "@nestjs/swagger";
2 | import { RsGenericHeaderDto } from "src/dto/rs-generic-header.dto";
3 |
4 | /* -------------------------------------------------------- */
5 |
6 | export class RsRegisterUserDataDto {
7 | @ApiProperty({
8 | type: Number,
9 | description: 'User Id',
10 | })
11 | id: number;
12 | }
13 |
14 | /* -------------------------------------------------------- */
15 |
16 | export class RsRegisterUserDto {
17 | rsGenericHeaderDto: RsGenericHeaderDto;
18 | rsRegisterUserDataDto: RsRegisterUserDataDto;
19 | }
20 |
21 | /* -------------------------------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/security/interfaces/jwt-payload.interface.ts:
--------------------------------------------------------------------------------
1 | export interface JwtPayload {
2 | id: string,
3 | username: string,
4 | }
--------------------------------------------------------------------------------
/src/modules/security/security.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | ClassSerializerInterceptor,
4 | Controller,
5 | HttpStatus,
6 | Inject,
7 | Post,
8 | UseInterceptors,
9 | } from '@nestjs/common';
10 | import { ClientProxy } from '@nestjs/microservices';
11 | import { ConfigService } from '@nestjs/config';
12 | import { ApiTags, ApiOperation, ApiResponse, ApiBody, } from '@nestjs/swagger';
13 |
14 | import { map, Observable, timeout } from 'rxjs';
15 | import { JwtTokens } from './services/jwt-tokens.service';
16 |
17 | import {
18 | RqLoginUserDto,
19 | RqRegisterUserDto,
20 | RsLoginUserDto,
21 | RsRegisterUserDto,
22 | } from './dto';
23 |
24 | /* --------------------------------------------------- */
25 |
26 | @ApiTags('Security') // To grouping endpoints
27 | @Controller('security')
28 | // ClassSerializerInterceptor to automatically cast your returned Entity instances
29 | // from services into the proper returned type defined in your controller's method.
30 | @UseInterceptors(ClassSerializerInterceptor)
31 | export class SecurityController {
32 | constructor(
33 | @Inject('AUTH_TRANSPORT') private readonly security_user: ClientProxy,
34 | private readonly jwtTokens: JwtTokens,
35 | private readonly configService: ConfigService,
36 | ) {}
37 |
38 | /* -------------------- */
39 |
40 | @Post('login')
41 | @ApiOperation({ summary: 'Login User'} )
42 | @ApiResponse({
43 | status: HttpStatus.OK,
44 | description: 'Login Succesfully.',
45 | type: RsLoginUserDto,
46 | })
47 | @ApiResponse({ status: HttpStatus.FORBIDDEN,description: 'Invalid user-password.' })
48 | @ApiResponse({ status: HttpStatus.NOT_FOUND,description: 'Invalid user.' })
49 | @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR ,description: 'Failed to login user.' })
50 | @ApiBody({ type: RqLoginUserDto })
51 | async loginUser(
52 | @Body() loginUserDto: RqLoginUserDto,
53 | ): Promise> {
54 | return this.security_user
55 | .send('ms-security-login', loginUserDto)
56 | .pipe(
57 | map((x) => {
58 | if (x.rsGenericHeaderDto.statusCode === HttpStatus.OK) {
59 | x.rsLoginUserData.session_token = this.jwtTokens.jwtTokenGenerate(
60 | x.rsLoginUserData.user_id.toString(),
61 | loginUserDto.username,
62 | );
63 | }
64 | return x;
65 | }),
66 | )
67 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
68 | }
69 |
70 | /* -------------------- */
71 |
72 | @Post('register')
73 | @ApiOperation({ summary: 'Register User' })
74 | @ApiResponse({
75 | status: HttpStatus.OK,
76 | description: 'Register Succesfully.',
77 | type: RsRegisterUserDto,
78 | })
79 | @ApiResponse({ status: HttpStatus.FOUND, description: 'Inconsistency detected. Security information previously registered for the user.' })
80 | @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Failed to register user.' })
81 | @ApiBody({ type: RqRegisterUserDto })
82 | async registerUser(
83 | @Body() registerUserDto: RqRegisterUserDto,
84 | ): Promise> {
85 | return this.security_user
86 | .send('ms-security-register', registerUserDto)
87 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
88 | }
89 | }
90 |
91 | /* --------------------------------------------------- */
92 |
--------------------------------------------------------------------------------
/src/modules/security/security.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { JwtModule } from '@nestjs/jwt';
3 | import { ConfigModule, ConfigService } from '@nestjs/config';
4 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
5 |
6 | import { SecurityController } from './security.controller';
7 | import { JwtStrategy } from './services/jwt-strategy.service';
8 | import { JwtTokens } from './services/jwt-tokens.service';
9 |
10 | /* --------------------------------------------------- */
11 |
12 |
13 | @Module({
14 | imports: [ConfigModule.forRoot(),
15 | JwtModule.registerAsync({
16 | imports: [ConfigModule],
17 | useFactory: async (configService: ConfigService) => ({
18 | secretOrPrivateKey: configService.get('JWT_SECRET_KEY'),
19 | signOptions: {
20 | expiresIn: parseInt(configService.get('JWT_EXPIRESION_KEY')),
21 | },
22 | }),
23 | inject: [ConfigService],
24 | }),
25 | ],
26 |
27 | controllers: [SecurityController],
28 | providers: [
29 | {
30 | provide: 'AUTH_TRANSPORT',
31 | inject: [ConfigService],
32 | useFactory: (configService: ConfigService) =>
33 | ClientProxyFactory.create({
34 | transport: Transport.TCP,
35 | options: {
36 | host: configService.get('SECURITY_HOST'),
37 | port: configService.get('SECURITY_PORT'),
38 | },
39 | }),
40 | },
41 | JwtStrategy,
42 | JwtTokens
43 | ],
44 | })
45 |
46 | /* --------------------------------------------------- */
47 |
48 | export class SecurityModule {}
49 |
50 | /* --------------------------------------------------- */
51 |
--------------------------------------------------------------------------------
/src/modules/security/services/jwt-strategy.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { ConfigService } from '@nestjs/config';
3 | import { PassportStrategy } from '@nestjs/passport';
4 |
5 | import { ExtractJwt, Strategy } from 'passport-jwt';
6 |
7 | import { JwtPayload } from '../interfaces/jwt-payload.interface';
8 |
9 | /* --------------------------------------------------- */
10 |
11 | @Injectable()
12 | export class JwtStrategy extends PassportStrategy(Strategy) {
13 | constructor(private readonly configService: ConfigService) {
14 | super({
15 | secretOrKey: configService.get('JWT_SECRET_KEY'),
16 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
17 | ignoreExpirarion: false,
18 | });
19 | }
20 |
21 | /* --------------- */
22 |
23 | async validate(payload: JwtPayload): Promise {
24 | const { id, username } = payload;
25 | console.log("validate id:", id, " username:",username )
26 |
27 | return { id, username };
28 | }
29 | }
30 |
31 | /* --------------------------------------------------- */
32 |
--------------------------------------------------------------------------------
/src/modules/security/services/jwt-tokens.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 | import { JwtService } from '@nestjs/jwt';
3 |
4 | import { JwtPayload } from '../interfaces/jwt-payload.interface';
5 |
6 | /* --------------------------------------------------- */
7 |
8 | @Injectable()
9 | export class JwtTokens {
10 | constructor(private readonly jwtService: JwtService) {}
11 |
12 | /* --------------- */
13 |
14 | jwtTokenGenerate(id: string, username: string): string {
15 | const payload: JwtPayload = { id: id, username: username };
16 | console.log("jwtTokenGenerate id:", id, " username:",username )
17 | return this.jwtService.sign(payload);
18 | }
19 | }
20 |
21 | /* --------------------------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/security/utilities/jwt-auth-guard.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from "@nestjs/common";
2 | import { AuthGuard } from "@nestjs/passport";
3 |
4 | /* --------------------------------------------------- */
5 |
6 | @Injectable()
7 | export class JwtAuthGuard extends AuthGuard('jwt') {
8 |
9 | // Next ---> canActivate
10 | }
11 |
12 | /* --------------------------------------------------- */
13 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateTransportDto } from "./rq-create-transport.dto"
2 | export { RsCreateTransportDto } from "./rs-create-transport.dto"
3 | export { RqGetTransportDto } from "./rq-get-transport.dto"
4 | export { RsGetTransportDto } from "./rs-get-transport.dto"
5 | export { RqDeleteTransportDto } from "./rq-delete-transport.dto"
6 | export { RqUpdateTransportDto } from "./rq-update-transport.dto"
7 |
8 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rq-create-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNumber, IsString, MaxLength } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 | /* ----------------------------------- */
5 |
6 | export class RqCreateTransportDto {
7 | @ApiProperty({
8 | type: String,
9 | description: 'Name',
10 | })
11 | @IsString()
12 | owner_name: string;
13 |
14 | @ApiProperty({
15 | type: String,
16 | description: 'Vehicle Identification',
17 | })
18 | @MaxLength(10)
19 | @IsString()
20 | vehicle_identification: string;
21 |
22 | @ApiProperty({
23 | type: Number,
24 | description: 'Volume Capacity',
25 | })
26 | @IsNumber()
27 | volume_capacity: number;
28 |
29 | @ApiProperty({
30 | type: Number,
31 | description: 'Weight Capacity',
32 | })
33 | @IsNumber()
34 | weight_capacity: number;
35 |
36 | @ApiProperty({
37 | type: String,
38 | description: 'Mobile',
39 | })
40 | @IsString()
41 | cellphone_number: string;
42 |
43 | @ApiProperty({
44 | type: Number,
45 | description: 'Zone_id',
46 | })
47 | @IsNumber()
48 | zone_id: number;
49 | }
50 |
51 | /* ----------------------------------- */
52 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rq-delete-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* ----------------------------------- */
7 |
8 | @Exclude()
9 | export class RqDeleteTransportDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Transport Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(idParam: number) {
20 | this.id = idParam
21 | }
22 | }
23 |
24 | /* ----------------------------------- */
25 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rq-get-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { ApiProperty } from '@nestjs/swagger';
2 |
3 | import { Exclude, Expose } from "class-transformer";
4 | import { IsNotEmpty, IsNumber } from "class-validator";
5 |
6 | /* ----------------------------------- */
7 |
8 | @Exclude()
9 | export class RqGetTransportDto {
10 | @ApiProperty({
11 | type: String,
12 | description: 'Transport Id',
13 | })
14 | @Expose()
15 | @IsNotEmpty()
16 | @IsNumber()
17 | id: number;
18 |
19 | constructor(idParam: number) {
20 | this.id = idParam
21 | }
22 | }
23 |
24 | /* ----------------------------------- */
25 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rq-update-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsNumber, IsString } from "class-validator";
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RqUpdateTransportDto {
6 | @IsString()
7 | owner_name: string;
8 |
9 | @IsString()
10 | vehicle_identification: string;
11 |
12 | @IsNumber()
13 | volume_capacity: number;
14 |
15 | @IsNumber()
16 | weight_capacity: number;
17 |
18 | @IsString()
19 | cellphone_number: string;
20 |
21 | @IsNumber()
22 | zone_id: number;
23 | }
24 |
25 | /* ----------------------------------- */
26 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rs-create-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsCreateTransportDataDto {
6 | id: number;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
11 | export class RsCreateTransportDto {
12 | rsGenericHeaderDto: RsGenericHeaderDto;
13 | rsCreateCustomerDataDto: RsCreateTransportDataDto;
14 | }
15 |
16 | /* ----------------------------------- */
17 |
--------------------------------------------------------------------------------
/src/modules/transport/dto/rs-get-transport.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsGetTransportDataDto {
6 | owner_name: string;
7 | vehicle_identification: string;
8 | volume_capacity: number;
9 | weight_capacity: number;
10 | cellphone_number: string;
11 | zone_id: number;
12 | }
13 |
14 | /* ----------------------------------- */
15 |
16 | export class RsGetTransportDto {
17 | rsGenericHeaderDto: RsGenericHeaderDto;
18 | rsGetTransportDataDto: RsGetTransportDataDto;
19 | }
20 |
21 | /* ----------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/transport/interfaces/index.ts:
--------------------------------------------------------------------------------
1 | export { TRANSPORT_FACTORY_SERVICE, ITransportFactory } from "./transport-factory.interface"
2 |
--------------------------------------------------------------------------------
/src/modules/transport/interfaces/transport-factory.interface.ts:
--------------------------------------------------------------------------------
1 | // To use dependency injection with interfaces we need to create a token to associate with an
2 |
3 | import { RqDeleteTransportDto, RqGetTransportDto } from "../dto";
4 |
5 |
6 | // interface and provide that token when injecting to an interface type.
7 | export const TRANSPORT_FACTORY_SERVICE = 'TRANSPORT_FACTORY_SERVICE';
8 |
9 | /* ----------------------------------- */
10 |
11 | export interface ITransportFactory {
12 | createGetRequestDTO(id: number): RqGetTransportDto;
13 | createDeleteRequestDTO(id: number): RqDeleteTransportDto;
14 | }
15 |
16 | /* ----------------------------------- */
17 |
18 |
--------------------------------------------------------------------------------
/src/modules/transport/services/transport-factory.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@nestjs/common';
2 |
3 | import { RqDeleteTransportDto, RqGetTransportDto } from '../dto';
4 | import { ITransportFactory } from '../interfaces/transport-factory.interface';
5 |
6 | /* ------------------------------------------------------- */
7 |
8 | @Injectable()
9 | export class TransportFactoryService implements ITransportFactory {
10 | createGetRequestDTO(id: number): RqGetTransportDto {
11 | return new RqGetTransportDto(id);
12 | }
13 |
14 | /* ------------------- */
15 |
16 | createDeleteRequestDTO(id: number): RqDeleteTransportDto {
17 | return new RqDeleteTransportDto(id);
18 | }
19 | }
20 |
21 | /* ------------------------------------------------------- */
22 |
--------------------------------------------------------------------------------
/src/modules/transport/transport.controller.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Body,
3 | Controller,
4 | Delete,
5 | Get,
6 | Inject,
7 | Param,
8 | ParseIntPipe,
9 | Patch,
10 | Post,
11 | UsePipes,
12 | ValidationPipe,
13 | } from '@nestjs/common';
14 | import { ConfigService } from '@nestjs/config';
15 | import { ClientProxy } from '@nestjs/microservices';
16 | import { Observable, timeout } from 'rxjs';
17 | import { RqCreateTransportDto, RsCreateTransportDto } from './dto';
18 | import { RqUpdateTransportDto } from './dto/rq-update-transport.dto';
19 | import { RsGetTransportDto } from './dto/rs-get-transport.dto';
20 | import {
21 | ITransportFactory,
22 | TRANSPORT_FACTORY_SERVICE,
23 | } from './interfaces/transport-factory.interface';
24 |
25 | /* ------------------------------------------------- */
26 |
27 | @Controller('transports')
28 | export class TransportController {
29 | constructor(
30 | @Inject('RABIT_SERVICE_TRANSPORT') private client: ClientProxy,
31 |
32 | private readonly configService: ConfigService,
33 |
34 | @Inject(TRANSPORT_FACTORY_SERVICE)
35 | private readonly transportFactoryService: ITransportFactory,
36 | ) {}
37 |
38 | /* ---------------- */
39 |
40 | @Get()
41 | async getTransports() {
42 | return this.client.send({ cmd: 'ms-get-transports' }, '');
43 | }
44 |
45 | /* ---------------- */
46 |
47 | @Get(':id')
48 | async getTransport(
49 | @Param('id') id: string,
50 | ): Promise> {
51 | const rqGetTransportDto = this.transportFactoryService.createGetRequestDTO(
52 | parseInt(id),
53 | );
54 |
55 | return this.client
56 | .send({ cmd: 'ms-get-transport' }, rqGetTransportDto)
57 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
58 | }
59 |
60 | /* ---------------- */
61 |
62 | @Post()
63 | async createTransport(
64 | @Body() rqCreateTransportDto: RqCreateTransportDto,
65 | ): Promise> {
66 | return this.client
67 | .send({ cmd: 'ms-transport-create' }, rqCreateTransportDto)
68 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
69 | }
70 |
71 | /* ---------------- */
72 |
73 | @Delete(':id')
74 | async remove(@Param('id') id: string): Promise> {
75 | const rqDeleteTransportDto =
76 | this.transportFactoryService.createDeleteRequestDTO(parseInt(id));
77 |
78 | return this.client
79 | .send({ cmd: 'ms-delete-transport' }, rqDeleteTransportDto)
80 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
81 | }
82 |
83 | /* ---------------- */
84 |
85 | @Patch(':id')
86 | @UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
87 | async update(
88 | @Param('id', ParseIntPipe) id: string,
89 | @Body() rqUpdateTransportDto: RqUpdateTransportDto,
90 | ) {
91 | return this.client
92 | .send({ cmd: 'ms-update-transport' }, { id, rqUpdateTransportDto })
93 | .pipe(timeout(+this.configService.get('TCP_RESPONSE_TIMEOUT')));
94 | }
95 | }
96 |
97 | /* ------------------------------------------------- */
98 |
--------------------------------------------------------------------------------
/src/modules/transport/transport.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
3 | import { ConfigModule, ConfigService } from '@nestjs/config';
4 |
5 | import { TransportController } from './transport.controller';
6 | import { TransportFactoryService } from './services/transport-factory.service';
7 | import { TRANSPORT_FACTORY_SERVICE } from './interfaces/transport-factory.interface';
8 |
9 | /* ------------------------------------------------------ */
10 |
11 | @Module({
12 | imports: [ConfigModule.forRoot()],
13 | controllers: [TransportController],
14 | providers: [
15 | {
16 | provide: 'RABIT_SERVICE_TRANSPORT',
17 | useFactory: (configService: ConfigService) => {
18 | const queue_input = configService.get('QUEUE_INPUT');
19 | const host = configService.get('TRANSPORT_HOST');
20 | //const user = configService.get('TRANSPORT_USER')
21 | //const password = configService.get('TRANSPORT_PASSWORD')
22 | const port = parseInt(configService.get('TRANSPORT_PORT'));
23 |
24 | return ClientProxyFactory.create({
25 | transport: Transport.RMQ,
26 | options: {
27 | //urls: [`amqp://${user}:${password}@${host}:${port}`],
28 | urls: [`amqp://${host}:${port}`],
29 | queue: `${queue_input}`,
30 | queueOptions: {
31 | durable: true, //persistent
32 | },
33 | },
34 | });
35 | },
36 | inject: [ConfigService],
37 | },
38 | {
39 | useClass: TransportFactoryService, // You can switch useClass to different implementation
40 | provide: TRANSPORT_FACTORY_SERVICE,
41 | },
42 | ],
43 | })
44 |
45 | /* ------------------------------------------------------ */
46 |
47 | export class TransportModule {}
48 |
49 |
--------------------------------------------------------------------------------
/src/modules/zones/dto/index.ts:
--------------------------------------------------------------------------------
1 | export { RqCreateZonesDto } from "./rq-create-zones.dto"
2 | export { RsCreateZonesDto } from "./rs-create-zones.dto"
3 | export { RsGetZonesDto } from "./rs-get-zones.dto"
4 |
--------------------------------------------------------------------------------
/src/modules/zones/dto/rq-create-zones.dto.ts:
--------------------------------------------------------------------------------
1 | import { IsString } from "class-validator";
2 | import { ApiProperty } from '@nestjs/swagger';
3 |
4 |
5 | /* ----------------------------------- */
6 |
7 | export class RqCreateZonesDto {
8 | @ApiProperty({
9 | type: String,
10 | description: 'Description',
11 | })
12 | @IsString()
13 | description: string;
14 | }
15 |
16 | /* ----------------------------------- */
17 |
--------------------------------------------------------------------------------
/src/modules/zones/dto/rs-create-zones.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsCreateZonesDataDto {
6 | id: number;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
11 | export class RsCreateZonesDto {
12 | rsGenericHeaderDto: RsGenericHeaderDto;
13 | rsCreateZonesDataDto: RsCreateZonesDataDto;
14 | }
15 |
16 | /* ----------------------------------- */
17 |
--------------------------------------------------------------------------------
/src/modules/zones/dto/rs-get-zones.dto.ts:
--------------------------------------------------------------------------------
1 | import { RsGenericHeaderDto } from 'src/dto/rs-generic-header.dto';
2 |
3 | /* ----------------------------------- */
4 |
5 | export class RsGetZonesDataDto {
6 | description: string;
7 | }
8 |
9 | /* ----------------------------------- */
10 |
11 | export class RsGetZonesDto {
12 | rsGenericHeaderDto: RsGenericHeaderDto;
13 | rsGetZonesDataDto: RsGetZonesDataDto;
14 | }
15 |
--------------------------------------------------------------------------------
/src/modules/zones/zones.controller.ts:
--------------------------------------------------------------------------------
1 | import { Body, Controller, Get, Inject, Post } from '@nestjs/common';
2 | import { ClientProxy } from '@nestjs/microservices';
3 | import { Observable } from 'rxjs';
4 | import { RqCreateZonesDto, RsCreateZonesDto, RsGetZonesDto } from './dto';
5 |
6 | /* ------------------------------------------------*/
7 |
8 | @Controller('zones')
9 | export class ZonesController {
10 | constructor(@Inject('RABBIT_SERVICE_ZONES') private client: ClientProxy) {}
11 |
12 | /* ------------ */
13 |
14 | @Get()
15 | async getZones(): Promise> {
16 | return this.client.send({ cmd: 'ms-get-zones' }, '');
17 | }
18 |
19 | /* ------------ */
20 |
21 | @Post()
22 | async createZones(
23 | @Body() rqCreateZonesDto: RqCreateZonesDto,
24 | ): Promise> {
25 | return this.client.emit({ cmd: 'ms-create-zones' }, rqCreateZonesDto);
26 | }
27 | }
28 |
29 | /* ------------------------------------------------*/
30 |
--------------------------------------------------------------------------------
/src/modules/zones/zones.module.ts:
--------------------------------------------------------------------------------
1 | import { Module } from '@nestjs/common';
2 |
3 | import { ZonesController } from './zones.controller';
4 | import { ConfigModule, ConfigService } from '@nestjs/config';
5 | import { ClientProxyFactory, Transport } from '@nestjs/microservices';
6 |
7 | /* ----------------------------------- */
8 |
9 | @Module({
10 | imports: [
11 | ConfigModule.forRoot(),
12 | ],
13 | controllers: [ZonesController],
14 | providers: [
15 | {
16 | provide: 'RABBIT_SERVICE_ZONES',
17 | useFactory: (configService: ConfigService) => {
18 | const queue_input = configService.get('ZONES_QUEUE_INPUT')
19 | const host = configService.get('ZONES_HOST')
20 | //const user = configService.get('ZONES_USER')
21 | //const password = configService.get('ZONES_PASSWORD')
22 | const port = parseInt(configService.get('ZONES_PORT'))
23 |
24 | return ClientProxyFactory.create({
25 | transport: Transport.RMQ,
26 | options: {
27 | //urls: [`amqp://${user}:${password}@${host}:${port}`],
28 | urls: [`amqp://${host}:${port}`],
29 | queue: `${queue_input}`,
30 | queueOptions: {
31 | durable: true, //persistent
32 | },
33 | },
34 | });
35 | },
36 | inject: [ConfigService],
37 | },]
38 | })
39 | export class ZonesModule {}
40 | /* ----------------------------------- */
41 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/tsconfig.build.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
4 | }
5 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------