├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── LICENSE.md ├── README.md ├── nest-cli.json ├── package-lock.json ├── package.json ├── src ├── app.controller.ts ├── app.module.ts ├── app.service.ts ├── auth │ ├── auth.module.ts │ ├── bcrypt │ │ └── bcrypt.ts │ ├── constants │ │ └── constants.ts │ ├── controllers │ │ └── auth.controller.ts │ ├── entites │ │ └── userlogin.entity.ts │ ├── guard │ │ ├── jwt-auth.guard.ts │ │ └── local-auth.guard.ts │ ├── services │ │ └── auth.service.ts │ └── strategy │ │ ├── jwt.strategy.ts │ │ └── local-strategy.ts ├── coverageArea │ ├── controllers │ │ └── coverageArea.controller.ts │ ├── coverageArea.module.ts │ ├── entities │ │ └── coverageArea.entity.ts │ └── services │ │ └── coverageArea.service.ts ├── data │ └── services │ │ ├── dev.service.ts │ │ └── prod.service.ts ├── infrastructure │ ├── controllers │ │ └── infrastructure.controller.ts │ ├── entities │ │ └── infrastructure.entity.ts │ ├── insfrastructure.module.ts │ └── services │ │ └── infrastructure.service.ts ├── main.ts ├── offering │ ├── controllers │ │ └── offering.controller.ts │ ├── entities │ │ └── offering.entity.ts │ ├── offering.module.ts │ └── services │ │ └── offering.service.ts ├── provider │ ├── controllers │ │ └── provider.controller.ts │ ├── entities │ │ └── provider.entity.ts │ ├── provider.module.ts │ └── services │ │ └── provider.service.ts ├── request │ ├── controllers │ │ └── request.controller.ts │ ├── entites │ │ └── request.entity.ts │ ├── request.module.ts │ └── services │ │ └── request.service.ts └── user │ ├── controllers │ └── user.controller.ts │ ├── entities │ └── user.entity.ts │ ├── services │ └── user.service.ts │ └── user.module.ts ├── test ├── app.e2e-spec.ts └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json /.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 | "linebreak-style": ["error", "auto"] 25 | }, 26 | }; 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | /dist 3 | /node_modules 4 | /build 5 | 6 | # Logs 7 | logs 8 | *.log 9 | npm-debug.log* 10 | pnpm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | lerna-debug.log* 14 | 15 | # OS 16 | .DS_Store 17 | 18 | # Tests 19 | /coverage 20 | /.nyc_output 21 | 22 | # IDEs and editors 23 | /.idea 24 | .project 25 | .classpath 26 | .c9/ 27 | *.launch 28 | .settings/ 29 | *.sublime-workspace 30 | 31 | # IDE - VSCode 32 | .vscode/* 33 | !.vscode/settings.json 34 | !.vscode/tasks.json 35 | !.vscode/launch.json 36 | !.vscode/extensions.json 37 | 38 | # dotenv environment variable files 39 | .env 40 | .env.development.local 41 | .env.test.local 42 | .env.production.local 43 | .env.local 44 | 45 | # temp directory 46 | .temp 47 | .tmp 48 | 49 | # Runtime data 50 | pids 51 | *.pid 52 | *.seed 53 | *.pid.lock 54 | 55 | # Diagnostic reports (https://nodejs.org/api/report.html) 56 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 57 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all", 4 | "endOfLine": "auto" 5 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Softex | Recife 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Logo](https://github.com/IgorCavalcantiMoura/fap2024/blob/main/FBR%201.png?raw=true) 2 | 3 | # FBR digital - Cadastro de Provedores 4 | 5 |

6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

15 | 16 | ## Descrição 17 | O Cadastro de Provedores da FBR Digital é uma aplicação que visa facilitar o cadastro e homologação de provedores de internet na base da FBR Digital. A plataforma permite o registro detalhado dos provedores, incluindo informações de infraestrutura, área de cobertura e serviços oferecidos, proporcionando maior visibilidade para a geração de novas demandas de serviços. 18 | 19 | ## Objetivo 20 | O objetivo principal é garantir que os provedores de internet tenham seus cadastros completos, permitindo a homologação e visualização de demandas de serviços de acordo com a área de cobertura cadastrada. 21 | 22 | ## Funcionalidades Principais 23 | - Cadastro de Provedores: Registro de informações corporativas como CNPJ, Nome Fantasia, Endereço e Contatos. 24 | - Cadastro de Áreas de Cobertura: Definição das áreas onde o provedor opera, com a possibilidade de upload via CSV ou KMZ. 25 | - Cadastro de Infraestrutura: Detalhamento da infraestrutura, incluindo ASN, participação em PTTs e operadoras de backbone. 26 | - Cadastro de Serviços: Registro dos planos oferecidos, velocidade de conexão, SLA e preços. 27 | - Sistema de Ranking: Ranking dos serviços baseado na razão preço/velocidade. 28 | - Apresentação de Demandas: Exibição de demandas recebidas através de um painel que permite envio de propostas. 29 | 30 | ## Tecnologias Utilizadas 31 | - Backend: NestJS 32 | - Banco de Dados: MySQL 33 | - ORM: TypeORM 34 | - Linguagem: TypeScript 35 | - Banco de dados em desenvolvimento: PostgreSQL 36 | 37 | ## Instalação e Configuração 38 | - Node.js (>= 14.x) 39 | - MySQL 40 | 41 | ## Passos para rodar o projeto localmente 42 |
43 | 1- Clone o repositório: 44 | 45 | git clone https://github.com/softexrecifepe/PI-T1-GP1-FBR.git 46 |
47 |
48 | 2- Acesse o diretório do projeto: 49 | 50 | cd fbr-digital-provedores 51 |
52 |
53 | 3- Instale as dependências: 54 | 55 | npm install 56 |
57 |
58 | 4- Configure as variáveis de ambiente no arquivo .env: 59 | 60 | DB_HOST=localhost 61 | DB_PORT=3306 62 | DB_USERNAME=root 63 | DB_PASSWORD=sua_senha 64 | DB_DATABASE=fbr_digital 65 |
66 |
67 | 5- Inicie o servidor de desenvolvimento: 68 | 69 | npm run start:dev 70 | #### O projeto estará rodando em: 71 | http://localhost:4000 72 |
73 |
74 | 75 | > [!Note]\ 76 | > Ao acessar a API no navegador você terá acesso a uma documentação das rotas construida com o [Swagger](https://fbrdigital-pvsh.onrender.com) 77 |
78 | 79 | ## Contribuição 80 | - Faça um fork do projeto. 81 | - Crie uma branch para sua nova funcionalidade (git checkout -b feat/nova-funcionalidade). 82 | - Faça commit das suas alterações (git commit -m 'Adiciona nova funcionalidade'). 83 | - Envie para o repositório remoto (git push origin feat/nova-funcionalidade). 84 | - Crie um pull request. 85 | 86 | ## Equipe 87 | 88 | 89 | 105 | 121 | 137 | 153 | 169 | 170 |
90 | 91 | Igor Moura Profile Picture
92 |
93 | 94 | Igor Moura 95 | 96 |
97 | 98 | 99 | 100 |
101 | 102 | 103 | 104 |
106 | 107 | Alyff Antônio Picture
108 |
109 | 110 | Alyff Antônio 111 | 112 |
113 | 114 | 115 | 116 |
117 | 118 | 119 | 120 |
122 | 123 | Foto do Willians K.
124 |
125 | 126 | Willians K. 127 | 128 |
129 | 130 | 131 | 132 |
133 | 134 | 135 | 136 |
138 | 139 | Foto do José Felipe
140 |
141 | 142 | José Felipe 143 | 144 |
145 | 146 | 147 | 148 |
149 | 150 | 151 | 152 |
154 | 155 | Foto do Thiago Dias
156 |
157 | 158 | Thiago Dias 159 | 160 |
161 | 162 | 163 | 164 |
165 | 166 | 167 | 168 |
171 | 172 | ## Licença 173 | Este projeto é licenciado sob a licença MIT. Veja o arquivo LICENSE para mais detalhes. 174 | 175 | ## Contato 176 | Para maiores informações ou sugestões, entre em contato: projetofbr@gmail.com 177 | 178 |

179 | 180 | 181 | 182 | 183 |

184 | -------------------------------------------------------------------------------- /nest-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/nest-cli", 3 | "collection": "@nestjs/schematics", 4 | "sourceRoot": "src", 5 | "compilerOptions": { 6 | "deleteOutDir": true 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fbr_providers", 3 | "version": "0.0.1", 4 | "description": "", 5 | "author": "", 6 | "private": true, 7 | "license": "UNLICENSED", 8 | "scripts": { 9 | "build": "nest build", 10 | "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", 11 | "start": "nest start", 12 | "start:dev": "nest start --watch", 13 | "start:debug": "nest start --debug --watch", 14 | "start:prod": "node dist/main", 15 | "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", 16 | "test": "jest", 17 | "test:watch": "jest --watch", 18 | "test:cov": "jest --coverage", 19 | "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", 20 | "test:e2e": "jest --config ./test/jest-e2e.json" 21 | }, 22 | "dependencies": { 23 | "@nestjs/common": "^10.0.0", 24 | "@nestjs/config": "^3.3.0", 25 | "@nestjs/core": "^10.0.0", 26 | "@nestjs/jwt": "^10.2.0", 27 | "@nestjs/passport": "^10.0.3", 28 | "@nestjs/platform-express": "^10.0.0", 29 | "@nestjs/swagger": "^7.4.2", 30 | "@nestjs/typeorm": "^10.0.2", 31 | "@types/bcrypt": "^5.0.2", 32 | "bcrypt": "^5.1.1", 33 | "class-transformer": "^0.5.1", 34 | "class-validator": "^0.14.1", 35 | "mysql2": "^3.11.3", 36 | "passport": "^0.7.0", 37 | "passport-jwt": "^4.0.1", 38 | "passport-local": "^1.0.0", 39 | "pg": "^8.13.1", 40 | "reflect-metadata": "^0.2.0", 41 | "rxjs": "^7.8.1", 42 | "swagger-ui-express": "^5.0.1", 43 | "typeorm": "^0.3.20" 44 | }, 45 | "devDependencies": { 46 | "@nestjs/cli": "^10.0.0", 47 | "@nestjs/schematics": "^10.0.0", 48 | "@nestjs/testing": "^10.0.0", 49 | "@types/express": "^4.17.17", 50 | "@types/jest": "^29.5.2", 51 | "@types/node": "^20.3.1", 52 | "@types/passport-jwt": "^4.0.1", 53 | "@types/passport-local": "^1.0.38", 54 | "@types/supertest": "^6.0.0", 55 | "@typescript-eslint/eslint-plugin": "^8.0.0", 56 | "@typescript-eslint/parser": "^8.0.0", 57 | "eslint": "^8.42.0", 58 | "eslint-config-prettier": "^9.0.0", 59 | "eslint-plugin-prettier": "^5.0.0", 60 | "jest": "^29.5.0", 61 | "prettier": "^3.0.0", 62 | "source-map-support": "^0.5.21", 63 | "supertest": "^7.0.0", 64 | "ts-jest": "^29.1.0", 65 | "ts-loader": "^9.4.3", 66 | "ts-node": "^10.9.1", 67 | "tsconfig-paths": "^4.2.0", 68 | "typescript": "^5.1.3" 69 | }, 70 | "jest": { 71 | "moduleFileExtensions": [ 72 | "js", 73 | "json", 74 | "ts" 75 | ], 76 | "rootDir": "src", 77 | "testRegex": ".*\\.spec\\.ts$", 78 | "transform": { 79 | "^.+\\.(t|j)s$": "ts-jest" 80 | }, 81 | "collectCoverageFrom": [ 82 | "**/*.(t|j)s" 83 | ], 84 | "coverageDirectory": "../coverage", 85 | "testEnvironment": "node" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get, Res } from '@nestjs/common'; 2 | import { ApiExcludeEndpoint } from '@nestjs/swagger'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor() {} 7 | 8 | @ApiExcludeEndpoint() 9 | @Get() 10 | async redirect(@Res() resposta: any) { 11 | return resposta.redirect('/swagger'); 12 | } 13 | } -------------------------------------------------------------------------------- /src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import { AuthModule } from './auth/auth.module'; 4 | import { User } from './user/entities/user.entity'; 5 | import { UserModule } from './user/user.module'; 6 | import { AppController } from './app.controller'; 7 | import { CoverageArea } from './coverageArea/entities/coverageArea.entity'; 8 | import { CoverageAreaModule } from './coverageArea/coverageArea.module'; 9 | import { Offering } from './offering/entities/offering.entity'; 10 | import { OfferingModule } from './offering/offering.module'; 11 | import { Provider } from './provider/entities/provider.entity'; 12 | import { ProviderModule } from './provider/provider.module'; 13 | import { Infrastructure } from './infrastructure/entities/infrastructure.entity'; 14 | import { InfrastructureModule } from './infrastructure/insfrastructure.module'; 15 | import { Request } from './request/entites/request.entity'; 16 | import { RequestModule } from './request/request.module'; 17 | import { ConfigModule } from '@nestjs/config'; 18 | import { ProdService } from './data/services/prod.service'; 19 | 20 | 21 | 22 | @Module({ 23 | imports: [ 24 | ConfigModule.forRoot(), 25 | TypeOrmModule.forRootAsync({ 26 | useClass: ProdService, 27 | imports: [ConfigModule], 28 | }), 29 | AuthModule, 30 | UserModule, 31 | CoverageAreaModule, 32 | OfferingModule, 33 | ProviderModule, 34 | InfrastructureModule, 35 | RequestModule 36 | ], 37 | controllers: [AppController], 38 | providers: [], 39 | }) 40 | export class AppModule {} 41 | -------------------------------------------------------------------------------- /src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello World!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { Bcrypt } from "./bcrypt/bcrypt"; 3 | import { AuthService } from "./services/auth.service"; 4 | import { LocalStrategy } from "./strategy/local-strategy"; 5 | import { UserModule } from "../user/user.module"; 6 | import { PassportModule } from "@nestjs/passport"; 7 | import { JwtModule } from "@nestjs/jwt"; 8 | import { jwtConstants } from "./constants/constants"; 9 | import { JwtStrategy } from "./strategy/jwt.strategy"; 10 | import { AuthController } from "./controllers/auth.controller"; 11 | 12 | @Module({ 13 | imports: [ 14 | UserModule, 15 | PassportModule, 16 | JwtModule.register({ 17 | secret: jwtConstants.secret, 18 | signOptions: { expiresIn: '1h'} 19 | }), 20 | ], 21 | providers: [Bcrypt, AuthService, LocalStrategy, JwtStrategy], 22 | controllers: [AuthController], 23 | exports: [Bcrypt], 24 | }) 25 | 26 | export class AuthModule { } -------------------------------------------------------------------------------- /src/auth/bcrypt/bcrypt.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import * as bcrypt from 'bcrypt'; 3 | 4 | @Injectable() 5 | export class Bcrypt{ 6 | 7 | async criptografarSenha(senha: string): Promise { 8 | 9 | let saltos: number = 10; 10 | return await bcrypt.hash(senha, saltos) 11 | 12 | } 13 | 14 | async compararSenhas(senhaDigitada: string, senhaBanco: string): Promise { 15 | return await bcrypt.compare(senhaDigitada, senhaBanco); 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /src/auth/constants/constants.ts: -------------------------------------------------------------------------------- 1 | export const jwtConstants = { 2 | secret: '37eb3d74e44561d2b9ec3e40da179f9e91571b7f350aee31cfee06b481f146fe', 3 | }; -------------------------------------------------------------------------------- /src/auth/controllers/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, HttpCode, HttpStatus, Post, UseGuards } from '@nestjs/common'; 2 | import { LocalAuthGuard } from '../guard/local-auth.guard'; 3 | import { AuthService } from '../services/auth.service'; 4 | import { UserLogin } from '../entites/userlogin.entity'; 5 | import { ApiTags } from '@nestjs/swagger'; 6 | 7 | @ApiTags('User') 8 | @Controller("/user") 9 | export class AuthController { 10 | constructor(private authService: AuthService) { } 11 | 12 | @UseGuards(LocalAuthGuard) 13 | @HttpCode(HttpStatus.OK) 14 | @Post('/logar') 15 | async login(@Body() user: UserLogin): Promise { 16 | return this.authService.login(user); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /src/auth/entites/userlogin.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger" 2 | 3 | export class UserLogin { 4 | 5 | @ApiProperty() 6 | public usuario: string 7 | 8 | @ApiProperty() 9 | public senha: string 10 | 11 | } -------------------------------------------------------------------------------- /src/auth/guard/jwt-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class JwtAuthGuard extends AuthGuard('jwt') {} -------------------------------------------------------------------------------- /src/auth/guard/local-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class LocalAuthGuard extends AuthGuard('local') {} -------------------------------------------------------------------------------- /src/auth/services/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { JwtService } from '@nestjs/jwt'; 2 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 3 | import { Bcrypt } from '../bcrypt/bcrypt'; 4 | import { UserService } from '../../user/services/user.service'; 5 | import { UserLogin } from '../entites/userlogin.entity'; 6 | 7 | 8 | @Injectable() 9 | export class AuthService{ 10 | constructor( 11 | private usuarioService: UserService, 12 | private jwtService: JwtService, 13 | private bcrypt: Bcrypt 14 | ){ } 15 | 16 | async validateUser(username: string, password: string): Promise{ 17 | 18 | const buscaUsuario = await this.usuarioService.findByUsuario(username) 19 | 20 | if(!buscaUsuario) 21 | throw new HttpException('Usuário não encontrado!', HttpStatus.NOT_FOUND) 22 | 23 | const matchPassword = await this.bcrypt.compararSenhas(password, buscaUsuario.senha) 24 | 25 | if(buscaUsuario && matchPassword){ 26 | const { senha, ...resposta } = buscaUsuario 27 | return resposta 28 | } 29 | 30 | return null 31 | 32 | } 33 | 34 | async login(usuarioLogin: UserLogin){ 35 | 36 | const payload = { sub: usuarioLogin.usuario } 37 | 38 | const buscaUsuario = await this.usuarioService.findByUsuario(usuarioLogin.usuario) 39 | 40 | return{ 41 | id: buscaUsuario.id, 42 | nome: buscaUsuario.nome, 43 | usuario: usuarioLogin.usuario, 44 | senha: '', 45 | foto: buscaUsuario.foto, 46 | token: `Bearer ${this.jwtService.sign(payload)}`, 47 | } 48 | 49 | } 50 | } -------------------------------------------------------------------------------- /src/auth/strategy/jwt.strategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { PassportStrategy } from "@nestjs/passport"; 3 | import { ExtractJwt, Strategy } from "passport-jwt"; 4 | import { jwtConstants } from "../constants/constants"; 5 | 6 | @Injectable() 7 | export class JwtStrategy extends PassportStrategy(Strategy) { 8 | constructor(){ 9 | super({ 10 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 11 | ignoreExpiration: false, 12 | secretOrKey: jwtConstants.secret, 13 | }); 14 | } 15 | 16 | async validate(payload: any){ 17 | return payload; 18 | } 19 | } -------------------------------------------------------------------------------- /src/auth/strategy/local-strategy.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, UnauthorizedException } from "@nestjs/common"; 2 | import { PassportStrategy } from "@nestjs/passport"; 3 | import { Strategy } from "passport-local"; 4 | import { AuthService } from "../services/auth.service"; 5 | 6 | 7 | @Injectable() 8 | export class LocalStrategy extends PassportStrategy(Strategy) { 9 | constructor(private authService: AuthService) { 10 | super({ 11 | usernameField: 'usuario', 12 | passwordField: 'senha' 13 | }) 14 | } 15 | 16 | async validate(username: string, password: string): Promise { 17 | 18 | const user = await this.authService.validateUser(username, password); 19 | 20 | if(!user){ 21 | throw new UnauthorizedException(); 22 | } 23 | 24 | return user; 25 | } 26 | } -------------------------------------------------------------------------------- /src/coverageArea/controllers/coverageArea.controller.ts: -------------------------------------------------------------------------------- 1 | import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; 2 | import { CoverageArea } from '../entities/coverageArea.entity'; 3 | import { CoverageAreaService } from './../services/coverageArea.service'; 4 | import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 5 | import { JwtAuthGuard } from '../../auth/guard/jwt-auth.guard'; 6 | 7 | @ApiTags('CoverageArea') 8 | @UseGuards(JwtAuthGuard) 9 | @ApiBearerAuth() 10 | @Controller("/coverage-area") 11 | export class CoverageAreaController { 12 | constructor(private readonly coverageAreaService: CoverageAreaService){ } 13 | 14 | @Get() 15 | @HttpCode(HttpStatus.OK) 16 | findAll(): Promise { 17 | return this.coverageAreaService.findAll(); 18 | } 19 | 20 | @Get('/:id') 21 | @HttpCode(HttpStatus.OK) 22 | findById(@Param('id', ParseIntPipe) id: number): Promise { 23 | return this.coverageAreaService.findById(id); 24 | } 25 | 26 | @Get('/provider-name/:providerName') 27 | @HttpCode(HttpStatus.OK) 28 | findByProviderName(@Param('providerName')providerName: string): Promise { 29 | return this.coverageAreaService.findByProviderName(providerName); 30 | } 31 | 32 | @Post() 33 | @HttpCode(HttpStatus.CREATED) 34 | create(@Body() coverageArea: CoverageArea): Promise{ 35 | return this.coverageAreaService.create(coverageArea) 36 | } 37 | 38 | @Put() 39 | @HttpCode(HttpStatus.OK) 40 | update(@Body() coverageArea: CoverageArea): Promise { 41 | return this.coverageAreaService.update(coverageArea) 42 | } 43 | 44 | @Delete('/:id') 45 | @HttpCode(HttpStatus.NO_CONTENT) 46 | delete(@Param('id', ParseIntPipe) id: number) { 47 | return this.coverageAreaService.delete(id) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/coverageArea/coverageArea.module.ts: -------------------------------------------------------------------------------- 1 | import { CoverageAreaService } from './services/coverageArea.service'; 2 | import { Module } from "@nestjs/common"; 3 | import { TypeOrmModule } from "@nestjs/typeorm"; 4 | import { CoverageArea } from "./entities/coverageArea.entity"; 5 | import { CoverageAreaController } from './controllers/coverageArea.controller'; 6 | import { OfferingModule } from '../offering/offering.module'; 7 | import { OfferingService } from '../offering/services/offering.service'; 8 | import { ProviderModule } from '../provider/provider.module'; 9 | import { ProviderService } from '../provider/services/provider.service'; 10 | 11 | @Module({ 12 | imports: [TypeOrmModule.forFeature([CoverageArea]), OfferingModule, ProviderModule], 13 | providers:[CoverageAreaService, OfferingService, ProviderService], 14 | controllers: [CoverageAreaController], 15 | exports: [TypeOrmModule] 16 | }) 17 | export class CoverageAreaModule { } -------------------------------------------------------------------------------- /src/coverageArea/entities/coverageArea.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger"; 2 | import { IsNotEmpty } from "class-validator"; 3 | import { Column, CreateDateColumn, Entity, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm"; 4 | import { Offering } from "../../offering/entities/offering.entity"; 5 | 6 | @Entity({name: "tb_coverage_area"}) 7 | export class CoverageArea { 8 | 9 | @ApiProperty() 10 | @PrimaryGeneratedColumn() 11 | id: number; 12 | 13 | @ApiProperty() 14 | @IsNotEmpty() 15 | @Column({ type: 'varchar', length: 100, nullable: false }) 16 | providerName: string; // Nome do provedor de internet 17 | 18 | @ApiProperty() 19 | @IsNotEmpty() 20 | @Column({ type: 'text', nullable: true }) 21 | description: string; // Descrição da área de cobertura 22 | 23 | // @ApiProperty() 24 | // @IsNotEmpty() 25 | // @Column({ type: 'varchar', length: 255 }) 26 | // coverageFilePath: string; // Caminho do arquivo de área de cobertura (CSV/KMZ) 27 | 28 | @ApiProperty() 29 | @IsNotEmpty() 30 | @Column({ type: 'varchar', length: 255, nullable: false }) 31 | city: string; // Cidade onde o provedor oferece cobertura 32 | 33 | @ApiProperty() 34 | @IsNotEmpty() 35 | @Column({ type: 'varchar', length: 255, nullable: false }) 36 | state: string; // Estado onde o provedor oferece cobertura 37 | 38 | @ApiProperty() 39 | @IsNotEmpty() 40 | @Column({ type: 'varchar', length: 50, nullable: false }) 41 | technology: string; // Tecnologia usada (fibra, rádio, satélite, etc.) 42 | 43 | @ApiProperty() 44 | @IsNotEmpty() 45 | @Column({ type: 'decimal', precision: 10, scale: 7, nullable: false }) 46 | latitude: number; // Latitude da área de cobertura 47 | 48 | @ApiProperty() 49 | @IsNotEmpty() 50 | @Column({ type: 'decimal', precision: 10, scale: 7, nullable: false }) 51 | longitude: number; // Longitude da área de cobertura 52 | 53 | @ApiProperty() 54 | @CreateDateColumn() 55 | createdAt: Date; // Data de criação do registro 56 | 57 | @ApiProperty() 58 | @UpdateDateColumn() 59 | updatedAt: Date; // Data de atualização do registro 60 | 61 | @ApiProperty({type: ()=> Offering}) 62 | @ManyToOne(() => Offering, (offering) => offering.coverageArea, { 63 | onDelete: 'CASCADE', 64 | }) 65 | offering: Offering; 66 | } -------------------------------------------------------------------------------- /src/coverageArea/services/coverageArea.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 2 | import { InjectRepository } from "@nestjs/typeorm"; 3 | import { CoverageArea } from "../entities/coverageArea.entity"; 4 | import { DeleteResult, ILike, Repository } from "typeorm"; 5 | import { OfferingService } from "../../offering/services/offering.service"; 6 | 7 | @Injectable() 8 | export class CoverageAreaService { 9 | constructor( 10 | @InjectRepository(CoverageArea) 11 | private coverageAreaRepository: Repository, 12 | private offeringService: OfferingService 13 | ){ } 14 | 15 | async findAll(): Promise { 16 | return await this.coverageAreaRepository.find({ 17 | relations:{ 18 | offering: true 19 | } 20 | }); 21 | } 22 | 23 | async findById(id: number): Promise { 24 | 25 | let coverageArea = await this.coverageAreaRepository.findOne({ 26 | where: { 27 | id 28 | }, 29 | relations:{ 30 | offering: true 31 | } 32 | }); 33 | 34 | if (!coverageArea) 35 | throw new HttpException("Área de Cobertura não localizada!", HttpStatus.NOT_FOUND); 36 | 37 | return coverageArea; 38 | } 39 | 40 | async findByProviderName(providerName: string): Promise { 41 | return await this.coverageAreaRepository.find({ 42 | where: { 43 | providerName: ILike(`${providerName}`) 44 | }, 45 | relations:{ 46 | offering: true 47 | } 48 | }) 49 | } 50 | 51 | async create(coverageArea: CoverageArea): Promise{ 52 | 53 | if(coverageArea.offering){ 54 | 55 | let offering = await this.offeringService.findById(coverageArea.offering.id) 56 | 57 | if(!offering) 58 | throw new HttpException('Serviço não encontrado!', HttpStatus.NOT_FOUND); 59 | 60 | return await this.coverageAreaRepository.save(coverageArea) 61 | } 62 | 63 | return await this.coverageAreaRepository.save(coverageArea) 64 | } 65 | 66 | 67 | async update(coverageArea: CoverageArea): Promise { 68 | 69 | let findCoverageArea: CoverageArea = await this.findById(coverageArea.id) 70 | 71 | if(!findCoverageArea || !coverageArea.id) 72 | throw new HttpException('Área de Cobertura não localizada!', HttpStatus.NOT_FOUND); 73 | 74 | if (coverageArea.offering){ 75 | 76 | let offering = await this.offeringService.findById(coverageArea.offering.id) 77 | 78 | if (!offering) 79 | throw new HttpException("Serviço não encontrado!", HttpStatus.NOT_FOUND); 80 | 81 | return await this.coverageAreaRepository.save(coverageArea) 82 | } 83 | 84 | return await this.coverageAreaRepository.save(coverageArea) 85 | } 86 | 87 | async delete(id: number): Promise{ 88 | 89 | let findCoverageArea = await this.findById(id); 90 | 91 | if (!findCoverageArea) 92 | throw new HttpException("Área de Cobertura não localizada!", HttpStatus.NOT_FOUND) 93 | 94 | return await this.coverageAreaRepository.delete(id) 95 | } 96 | } -------------------------------------------------------------------------------- /src/data/services/dev.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from "@nestjs/typeorm"; 3 | import { User } from "../../user/entities/user.entity"; 4 | import { CoverageArea } from "../../coverageArea/entities/coverageArea.entity"; 5 | import { Offering } from "../../offering/entities/offering.entity"; 6 | import { Infrastructure } from "../../infrastructure/entities/infrastructure.entity"; 7 | import { Provider } from "../../provider/entities/provider.entity"; 8 | 9 | 10 | @Injectable() 11 | export class DevService implements TypeOrmOptionsFactory { 12 | 13 | createTypeOrmOptions(): TypeOrmModuleOptions { 14 | return { 15 | type: 'mysql', 16 | host: 'localhost', 17 | port: 3306, 18 | username: 'root', 19 | password: 'root', 20 | database: 'db_fbr_digital', 21 | entities: [User, CoverageArea, Offering, Provider, Infrastructure, Request], 22 | synchronize: true, 23 | }; 24 | } 25 | } -------------------------------------------------------------------------------- /src/data/services/prod.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@nestjs/common"; 2 | import { ConfigService } from "@nestjs/config"; 3 | import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from "@nestjs/typeorm"; 4 | 5 | @Injectable() 6 | export class ProdService implements TypeOrmOptionsFactory { 7 | 8 | createTypeOrmOptions(): TypeOrmModuleOptions { 9 | return { 10 | type: 'postgres', 11 | url: process.env.DATABASE_URL, 12 | logging: false, 13 | dropSchema: false, 14 | ssl: { 15 | rejectUnauthorized: false, 16 | }, 17 | synchronize: true, 18 | autoLoadEntities: true, 19 | }; 20 | } 21 | } -------------------------------------------------------------------------------- /src/infrastructure/controllers/infrastructure.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 2 | import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; 3 | import { JwtAuthGuard } from "../../auth/guard/jwt-auth.guard"; 4 | import { InfrastructureService } from "../services/infrastructure.service"; 5 | import { Infrastructure } from "../entities/infrastructure.entity"; 6 | 7 | 8 | @ApiTags('Infrastructure') 9 | @UseGuards(JwtAuthGuard) 10 | @Controller('/infrastructure') 11 | @ApiBearerAuth() 12 | export class InfrastructureController{ 13 | constructor(private readonly infrastructureService: InfrastructureService) {} 14 | 15 | @Get() 16 | @HttpCode(HttpStatus.OK) 17 | findAll(): Promise { 18 | return this.infrastructureService.findAll(); 19 | } 20 | 21 | @Get('/:id') 22 | @HttpCode(HttpStatus.OK) 23 | findById(@Param('id', ParseIntPipe) id: number): Promise { 24 | return this.infrastructureService.findById(id) 25 | } 26 | 27 | @Post() 28 | @HttpCode(HttpStatus.CREATED) 29 | create(@Body() infrastructure: Infrastructure): Promise { 30 | return this.infrastructureService.create(infrastructure); 31 | } 32 | 33 | @Put() 34 | @HttpCode(HttpStatus.OK) 35 | update(@Body() infrastructure: Infrastructure): Promise { 36 | return this.infrastructureService.update(infrastructure) 37 | } 38 | 39 | @Delete('/:id') 40 | @HttpCode(HttpStatus.NO_CONTENT) 41 | delete(@Param('id', ParseIntPipe) id: number){ 42 | return this.infrastructureService.delete(id) 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/infrastructure/entities/infrastructure.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger"; 2 | import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; 3 | import { Provider } from "../../provider/entities/provider.entity"; 4 | 5 | @Entity({ name: 'tb_infrastructure' }) 6 | export class Infrastructure { 7 | @ApiProperty() 8 | @PrimaryGeneratedColumn() 9 | id: number; 10 | 11 | @ApiProperty() 12 | @Column({ length: 100 }) 13 | asn: string; 14 | 15 | @ApiProperty() 16 | @Column({ length: 100 }) 17 | ptts: string; 18 | 19 | @ApiProperty() 20 | @Column({ length: 255 }) 21 | backbone: string; 22 | 23 | @ApiProperty({type: ()=> Provider}) 24 | @ManyToOne(() => Provider, (provider) => provider.infrastructure, { 25 | onDelete: 'CASCADE', 26 | }) 27 | provider: Provider; 28 | } -------------------------------------------------------------------------------- /src/infrastructure/insfrastructure.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { Infrastructure } from "./entities/infrastructure.entity"; 4 | import { ProviderModule } from "../provider/provider.module"; 5 | import { InfrastructureService } from "./services/infrastructure.service"; 6 | import { ProviderService } from "../provider/services/provider.service"; 7 | import { InfrastructureController } from "./controllers/infrastructure.controller"; 8 | 9 | @Module({ 10 | imports: [TypeOrmModule.forFeature([Infrastructure]), ProviderModule], 11 | providers: [InfrastructureService, ProviderService], 12 | controllers: [InfrastructureController], 13 | exports: [TypeOrmModule] 14 | }) 15 | export class InfrastructureModule {} -------------------------------------------------------------------------------- /src/infrastructure/services/infrastructure.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 2 | import { InjectRepository } from "@nestjs/typeorm"; 3 | import { DeleteResult, Repository } from "typeorm"; 4 | import { Infrastructure } from "../entities/infrastructure.entity"; 5 | import { ProviderService } from "../../provider/services/provider.service"; 6 | 7 | 8 | @Injectable() 9 | export class InfrastructureService { 10 | constructor( 11 | @InjectRepository(Infrastructure) 12 | private infrastrutureRepository: Repository, 13 | private providerService: ProviderService 14 | ) {} 15 | 16 | async findAll(): Promise { 17 | return await this.infrastrutureRepository.find({ 18 | relations: { 19 | provider: true 20 | } 21 | }); 22 | } 23 | 24 | async findById(id: number): Promise { 25 | 26 | let infrastructure = await this.infrastrutureRepository.findOne({ 27 | where: { 28 | id 29 | }, 30 | relations: { 31 | provider: true 32 | } 33 | }) 34 | 35 | if(!infrastructure) 36 | throw new HttpException('Infraestrutura não encontrada!', HttpStatus.NOT_FOUND); 37 | 38 | return infrastructure 39 | } 40 | 41 | async create(infrastructure: Infrastructure): Promise { 42 | 43 | if (infrastructure.provider){ 44 | 45 | let provider = await this.providerService.findById(infrastructure.provider.id) 46 | 47 | if (!provider) 48 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND) 49 | 50 | return await this.infrastrutureRepository.save(infrastructure) 51 | } 52 | 53 | return await this.infrastrutureRepository.save(infrastructure) 54 | } 55 | 56 | async update(infrastructure: Infrastructure): Promise { 57 | 58 | let findInfrastructure: Infrastructure = await this.findById(infrastructure.id); 59 | 60 | if(!findInfrastructure || infrastructure.id) 61 | throw new HttpException('Infraestrutura não encontrada!', HttpStatus.NOT_FOUND); 62 | 63 | if (infrastructure.provider){ 64 | 65 | let provider = await this.providerService.findById(infrastructure.provider.id) 66 | 67 | if (!provider) 68 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND) 69 | 70 | return await this.infrastrutureRepository.save(infrastructure) 71 | } 72 | 73 | return await this.infrastrutureRepository.save(infrastructure) 74 | } 75 | 76 | async delete(id: number): Promise { 77 | 78 | let findInfrastructure = await this.findById(id); 79 | 80 | if(!findInfrastructure) 81 | throw new HttpException('Infraestrutura não encontrada!', HttpStatus.NOT_FOUND); 82 | 83 | return await this.infrastrutureRepository.delete(id) 84 | } 85 | } -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | import { ValidationPipe } from '@nestjs/common'; 4 | import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; 5 | 6 | async function bootstrap() { 7 | const app = await NestFactory.create(AppModule); 8 | 9 | const config = new DocumentBuilder() 10 | .setTitle('FBR Digital') 11 | .setDescription('API de cadastro de provedores') 12 | .setContact("Projeto Integrador - Softex | Recife ","https://github.com/softexrecifepe/PI-T1-GP1-FBR","projetofbr@gmail.com") 13 | .setVersion('1.0') 14 | .addBearerAuth() 15 | .build(); 16 | const document = SwaggerModule.createDocument(app, config); 17 | SwaggerModule.setup('/swagger', app, document); 18 | 19 | process.env.TZ= '-03:00' 20 | 21 | app.useGlobalPipes(new ValidationPipe()) 22 | app.enableCors() 23 | await app.listen(process.env.PORT || 4000); 24 | } 25 | bootstrap(); 26 | -------------------------------------------------------------------------------- /src/offering/controllers/offering.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 2 | import { OfferingService } from "../services/offering.service"; 3 | import { Offering } from "../entities/offering.entity"; 4 | import { JwtAuthGuard } from "../../auth/guard/jwt-auth.guard"; 5 | import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; 6 | 7 | @ApiTags('Offering') 8 | @UseGuards(JwtAuthGuard) 9 | @Controller("/offering") 10 | @ApiBearerAuth() 11 | export class OfferingController { 12 | constructor(private readonly offeringService: OfferingService) { } 13 | 14 | @Get() 15 | @HttpCode(HttpStatus.OK) 16 | findAll(): Promise { 17 | return this.offeringService.findAll(); 18 | } 19 | 20 | @Get('/:id') 21 | @HttpCode(HttpStatus.OK) 22 | findById(@Param('id', ParseIntPipe) id: number): Promise { 23 | return this.offeringService.findById(id); 24 | } 25 | 26 | @Get('/tipo-do-plano/:tipoPlano') 27 | @HttpCode(HttpStatus.OK) 28 | findBydescricao(@Param('tipoPlano') tipoPlano: string): Promise { 29 | return this.offeringService.findByTipoPlano(tipoPlano); 30 | } 31 | 32 | @Post() 33 | @HttpCode(HttpStatus.CREATED) 34 | create(@Body() offering: Offering): Promise { 35 | return this.offeringService.create(offering); 36 | } 37 | 38 | @Put() 39 | @HttpCode(HttpStatus.OK) 40 | update(@Body() offering: Offering): Promise { 41 | return this.offeringService.update(offering); 42 | } 43 | 44 | @Delete('/:id') 45 | @HttpCode(HttpStatus.NO_CONTENT) 46 | delete(@Param('id', ParseIntPipe) id: number){ 47 | return this.offeringService.delete(id); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /src/offering/entities/offering.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger"; 2 | import { IsNotEmpty } from "class-validator"; 3 | import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; 4 | import { CoverageArea } from "../../coverageArea/entities/coverageArea.entity"; 5 | import { Provider } from "../../provider/entities/provider.entity"; 6 | 7 | @Entity({ name: 'tb_offering' }) 8 | export class Offering { 9 | 10 | @ApiProperty() 11 | @PrimaryGeneratedColumn() 12 | id: number; 13 | 14 | @ApiProperty() 15 | @IsNotEmpty() 16 | @Column({ length: 100, nullable: false }) 17 | tipoPlano: string; 18 | 19 | @ApiProperty() 20 | @IsNotEmpty() 21 | @Column({nullable: false}) 22 | velocidade: number; // Velocidade em MB/GB 23 | 24 | @ApiProperty() 25 | @IsNotEmpty() 26 | @Column({ length: 50, nullable: false }) 27 | sla: string; // SLA do plano 28 | 29 | @ApiProperty() 30 | @IsNotEmpty() 31 | @Column({nullable: false}) 32 | preco: number; 33 | 34 | @ApiProperty() 35 | @IsNotEmpty() 36 | @Column({ type: 'float', default: 0 }) 37 | ranking: number; // Campo para armazenar o ranking 38 | 39 | @ApiProperty() 40 | @OneToMany(() => CoverageArea, (coverageArea) => coverageArea.offering) 41 | coverageArea: CoverageArea[] 42 | 43 | @ManyToOne(() => Provider, (provider) => provider.offering, { 44 | onDelete: "CASCADE" 45 | }) 46 | provider: Provider 47 | 48 | } -------------------------------------------------------------------------------- /src/offering/offering.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { Offering } from "./entities/offering.entity"; 4 | import { OfferingService } from "./services/offering.service"; 5 | import { OfferingController } from "./controllers/offering.controller"; 6 | import { ProviderModule } from "../provider/provider.module"; 7 | import { ProviderService } from "../provider/services/provider.service"; 8 | 9 | 10 | @Module({ 11 | imports: [TypeOrmModule.forFeature([Offering]), ProviderModule], 12 | providers: [OfferingService, ProviderService], 13 | controllers: [OfferingController], 14 | exports: [TypeOrmModule] 15 | }) 16 | export class OfferingModule {} -------------------------------------------------------------------------------- /src/offering/services/offering.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 2 | import { Offering } from "../entities/offering.entity"; 3 | import { InjectRepository } from "@nestjs/typeorm"; 4 | import { DeleteResult, ILike, Repository } from "typeorm"; 5 | import { ProviderService } from "../../provider/services/provider.service"; 6 | 7 | @Injectable() 8 | export class OfferingService { 9 | constructor( 10 | @InjectRepository(Offering) 11 | private offeringRepository: Repository, 12 | private providerService:ProviderService 13 | ) { } 14 | 15 | async findAll(): Promise { 16 | return await this.offeringRepository.find({ 17 | relations: { 18 | coverageArea: true, 19 | provider: true 20 | } 21 | }); 22 | } 23 | 24 | async findById(id: number): Promise { 25 | 26 | let offering = await this.offeringRepository.findOne({ 27 | where: { 28 | id 29 | }, 30 | relations: { 31 | coverageArea: true, 32 | provider: true 33 | } 34 | }); 35 | 36 | if (!offering) 37 | throw new HttpException('Serviço não encontrado!', HttpStatus.NOT_FOUND); 38 | 39 | return offering; 40 | } 41 | 42 | async findByTipoPlano(tipoPlano: string): Promise { 43 | return await this.offeringRepository.find({ 44 | where: { 45 | tipoPlano: ILike(`%${tipoPlano}%`) 46 | }, 47 | relations: { 48 | coverageArea: true, 49 | provider: true 50 | } 51 | }) 52 | } 53 | 54 | async create(offering: Offering): Promise { 55 | 56 | if (offering.provider){ 57 | 58 | let provider = await this.providerService.findById(offering.provider.id) 59 | 60 | if (!provider) 61 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND); 62 | 63 | return await this.offeringRepository.save(offering) 64 | } 65 | 66 | return await this.offeringRepository.save(offering); 67 | } 68 | 69 | async update(offering: Offering): Promise { 70 | 71 | let findOffering = await this.findById(offering.id); 72 | 73 | if (!findOffering || !offering.id) 74 | throw new HttpException('Serviço não encontrado!', HttpStatus.NOT_FOUND); 75 | 76 | if (offering.provider){ 77 | 78 | let provider = await this.providerService.findById(offering.provider.id) 79 | 80 | if (!provider) 81 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND); 82 | 83 | return await this.offeringRepository.save(offering) 84 | } 85 | 86 | return await this.offeringRepository.save(offering); 87 | } 88 | 89 | async delete(id: number): Promise { 90 | 91 | let findOffering = await this.findById(id); 92 | 93 | if (!findOffering) 94 | throw new HttpException('Serviço não encontrado!', HttpStatus.NOT_FOUND); 95 | 96 | return await this.offeringRepository.delete(id); 97 | 98 | } 99 | } -------------------------------------------------------------------------------- /src/provider/controllers/provider.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 2 | import { ProviderService } from "../services/provider.service"; 3 | import { Provider } from './../entities/provider.entity'; 4 | import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; 5 | import { JwtAuthGuard } from "../../auth/guard/jwt-auth.guard"; 6 | 7 | @ApiTags('Provider') 8 | @UseGuards(JwtAuthGuard) 9 | @ApiBearerAuth() 10 | @Controller("/provider") 11 | export class ProviderController { 12 | constructor(private readonly providerService: ProviderService) { } 13 | 14 | @Get() 15 | @HttpCode(HttpStatus.OK) 16 | findAll(): Promise { 17 | return this.providerService.findAll(); 18 | } 19 | 20 | @Get('/:id') 21 | @HttpCode(HttpStatus.OK) 22 | findById(@Param('id', ParseIntPipe) id: number): Promise { 23 | return this.providerService.findById(id); 24 | } 25 | 26 | @Get('/fantasy_name/:fantasy_name') 27 | @HttpCode(HttpStatus.OK) 28 | findByName(@Param('fantasy_name') fantasy_name: string): Promise { 29 | return this.providerService.findByName(fantasy_name); 30 | } 31 | 32 | @Post() 33 | @HttpCode(HttpStatus.CREATED) 34 | create(@Body() provider: Provider): Promise { 35 | return this.providerService.create(provider); 36 | } 37 | 38 | @Put() 39 | @HttpCode(HttpStatus.OK) 40 | update(@Body() provider: Provider): Promise { 41 | return this.providerService.update(provider); 42 | } 43 | 44 | @Delete('/:id') 45 | @HttpCode(HttpStatus.NO_CONTENT) 46 | delete(@Param('id', ParseIntPipe) id: number){ 47 | return this.providerService.delete(id); 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /src/provider/entities/provider.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger" 2 | import { IsNotEmpty } from "class-validator" 3 | import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm" 4 | import { Offering } from "../../offering/entities/offering.entity" 5 | import { Infrastructure } from "../../infrastructure/entities/infrastructure.entity" 6 | import { Request } from "../../request/entites/request.entity" 7 | 8 | @Entity({name: "tb_provider"}) 9 | export class Provider { 10 | @ApiProperty() 11 | @PrimaryGeneratedColumn() 12 | id: number 13 | 14 | @ApiProperty() 15 | @IsNotEmpty() 16 | @Column({length: 100, nullable: false}) 17 | cnpj: string 18 | 19 | @ApiProperty() 20 | @IsNotEmpty() 21 | @Column({length: 100, nullable: false}) 22 | fantasy_name: string 23 | 24 | @ApiProperty() 25 | @IsNotEmpty() 26 | @Column({length: 100, nullable: false}) 27 | corporate_name: string 28 | 29 | @ApiProperty() 30 | @IsNotEmpty() 31 | @Column({length: 100, nullable: false}) 32 | headquarters_adress: string 33 | 34 | @ApiProperty() 35 | @IsNotEmpty() 36 | @Column({length: 100, nullable: false}) 37 | legal_representative_contact: string 38 | 39 | @ApiProperty() 40 | @OneToMany(() => Offering, (offering) => offering.provider) 41 | offering: Offering[] 42 | 43 | @ApiProperty() 44 | @OneToMany(() => Infrastructure, (infrastructure) => infrastructure.provider) 45 | infrastructure: Infrastructure[] 46 | 47 | @ApiProperty() 48 | @OneToMany(() => Request, (request) => request.provider) 49 | request: Request[] 50 | } -------------------------------------------------------------------------------- /src/provider/provider.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { Provider } from "./entities/provider.entity"; 4 | import { ProviderService } from "./services/provider.service"; 5 | import { ProviderController } from "./controllers/provider.controller"; 6 | 7 | 8 | @Module({ 9 | imports: [TypeOrmModule.forFeature([Provider])], 10 | providers: [ProviderService], 11 | controllers: [ProviderController], 12 | exports: [TypeOrmModule] 13 | }) 14 | export class ProviderModule {} -------------------------------------------------------------------------------- /src/provider/services/provider.service.ts: -------------------------------------------------------------------------------- 1 | import { InjectRepository } from '@nestjs/typeorm'; 2 | import { Provider } from './../entities/provider.entity'; 3 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 4 | import { DeleteResult, ILike, Repository } from 'typeorm'; 5 | 6 | @Injectable() 7 | export class ProviderService { 8 | constructor( 9 | @InjectRepository(Provider) 10 | private providerRepository: Repository 11 | ) { } 12 | 13 | async findAll(): Promise { 14 | return await this.providerRepository.find({ 15 | relations: { 16 | offering: true, 17 | infrastructure: true, 18 | request: true 19 | } 20 | }); 21 | } 22 | 23 | async findById(id: number): Promise { 24 | 25 | let provider = await this.providerRepository.findOne({ 26 | where: { 27 | id 28 | }, 29 | relations: { 30 | offering: true, 31 | infrastructure: true, 32 | request: true 33 | } 34 | }); 35 | 36 | if (!provider) 37 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND); 38 | 39 | return provider; 40 | } 41 | 42 | async findByName(fantasy_name: string): Promise { 43 | return await this.providerRepository.find({ 44 | where: { 45 | fantasy_name: ILike(`%${fantasy_name}%`) 46 | }, 47 | relations: { 48 | offering: true, 49 | infrastructure: true, 50 | request: true 51 | } 52 | }) 53 | } 54 | 55 | async create(provider: Provider): Promise { 56 | return await this.providerRepository.save(provider); 57 | } 58 | 59 | async update(provider: Provider): Promise { 60 | 61 | let findProvider = await this.findById(provider.id); 62 | 63 | if (!findProvider || !provider.id) 64 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND); 65 | 66 | return await this.providerRepository.save(provider); 67 | } 68 | 69 | async delete(id: number): Promise { 70 | 71 | let findProvider = await this.findById(id); 72 | 73 | if (!findProvider) 74 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND); 75 | 76 | return await this.providerRepository.delete(id); 77 | 78 | } 79 | } -------------------------------------------------------------------------------- /src/request/controllers/request.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 2 | import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; 3 | import { JwtAuthGuard } from "../../auth/guard/jwt-auth.guard"; 4 | import { RequestService } from "../services/request.service"; 5 | import { Request } from "../entites/request.entity"; 6 | 7 | @ApiTags('Request') 8 | @UseGuards(JwtAuthGuard) 9 | @Controller('/request') 10 | @ApiBearerAuth() 11 | export class RequestController { 12 | constructor(private readonly requestService: RequestService) {} 13 | 14 | @Get() 15 | @HttpCode(HttpStatus.OK) 16 | findAll(): Promise { 17 | return this.requestService.findAll(); 18 | } 19 | 20 | @Get('/:id') 21 | @HttpCode(HttpStatus.OK) 22 | findById(@Param('id', ParseIntPipe) id: number): Promise { 23 | return this.requestService.findById(id); 24 | } 25 | 26 | @Get('status/:status') 27 | @HttpCode(HttpStatus.OK) 28 | findByStatus(@Param('status') status: string): Promise { 29 | return this.requestService.findByStatus(status); 30 | } 31 | 32 | @Post() 33 | @HttpCode(HttpStatus.CREATED) 34 | create(@Body() request: Request): Promise { 35 | return this.requestService.create(request) 36 | } 37 | 38 | @Put() 39 | @HttpCode(HttpStatus.OK) 40 | update(@Body() request: Request): Promise { 41 | return this.requestService.update(request) 42 | } 43 | 44 | @Delete('/:id') 45 | @HttpCode(HttpStatus.NO_CONTENT) 46 | delete(@Param('id', ParseIntPipe)id: number){ 47 | return this.requestService.delete(id) 48 | } 49 | } -------------------------------------------------------------------------------- /src/request/entites/request.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger"; 2 | import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; 3 | import { Provider } from "../../provider/entities/provider.entity"; 4 | 5 | @Entity({ name: 'tb_request' }) 6 | export class Request { 7 | 8 | @ApiProperty() 9 | @PrimaryGeneratedColumn() 10 | id: number; 11 | 12 | @ApiProperty() 13 | @Column({ type: 'text' }) 14 | descricao: string; 15 | 16 | @ApiProperty() 17 | @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) 18 | data_criacao: Date; 19 | 20 | @ApiProperty() 21 | @Column({ 22 | type: 'enum', 23 | enum: ['pendente', 'aceita', 'recusada', 'concluída'], 24 | default: 'pendente', 25 | }) 26 | status: string; 27 | 28 | @ApiProperty() 29 | @Column({ type: 'varchar', length: 255 }) 30 | solicitante_email: string; 31 | 32 | @ApiProperty() 33 | @Column({ type: 'decimal', precision: 10, scale: 2, nullable: true }) 34 | valor_proposto: number; 35 | 36 | // @ManyToOne(() => CoverageArea, (area) => area.demandas, { 37 | // onDelete: 'CASCADE', 38 | // }) 39 | // area_cobertura: CoverageArea; 40 | 41 | // @ManyToOne(() => Offering, (offering) => offering.demandas, { 42 | // onDelete: 'CASCADE', 43 | // }) 44 | // servico: Offering; 45 | 46 | @ApiProperty({type: ()=> Provider}) 47 | @ManyToOne(() => Provider, (provider) => provider.request, { 48 | onDelete: 'CASCADE', 49 | }) 50 | provider: Provider; 51 | } -------------------------------------------------------------------------------- /src/request/request.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from "@nestjs/common"; 2 | import { TypeOrmModule } from "@nestjs/typeorm"; 3 | import { RequestService } from "./services/request.service"; 4 | import { RequestController } from "./controllers/request.controller"; 5 | import { ProviderModule } from "../provider/provider.module"; 6 | import { ProviderService } from "../provider/services/provider.service"; 7 | import { Request } from "./entites/request.entity"; 8 | 9 | @Module({ 10 | imports: [TypeOrmModule.forFeature([Request]), ProviderModule], 11 | providers: [RequestService, ProviderService], 12 | controllers: [RequestController], 13 | exports: [TypeOrmModule], 14 | }) 15 | 16 | export class RequestModule {} -------------------------------------------------------------------------------- /src/request/services/request.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; 2 | import { InjectRepository } from "@nestjs/typeorm"; 3 | import { DeleteResult, Repository } from "typeorm"; 4 | import { ProviderService } from "../../provider/services/provider.service"; 5 | import { Request } from "../entites/request.entity"; 6 | 7 | @Injectable() 8 | export class RequestService { 9 | constructor( 10 | @InjectRepository(Request) 11 | private requestRepository: Repository, 12 | private providerService: ProviderService 13 | ) {} 14 | 15 | async findAll(): Promise { 16 | return await this.requestRepository.find({ 17 | relations: { 18 | provider: true 19 | } 20 | }); 21 | } 22 | 23 | async findById(id: number): Promise { 24 | let request = await this.requestRepository.findOne({ 25 | where: { 26 | id, 27 | }, 28 | relations: { 29 | provider: true 30 | } 31 | }); 32 | 33 | if (!request) 34 | throw new HttpException('Demanda não encontrada!', HttpStatus.NOT_FOUND); 35 | 36 | return request; 37 | } 38 | 39 | async findByStatus(status: string): Promise { 40 | return this.requestRepository.find({ 41 | where: { 42 | status, 43 | }, 44 | relations: { 45 | provider: true 46 | } 47 | }); 48 | } 49 | 50 | async create(request: Request): Promise { 51 | 52 | if (request.provider){ 53 | 54 | let provider = await this.providerService.findById(request.provider.id) 55 | 56 | if (!provider) 57 | throw new HttpException('Provedor não encontrado!', HttpStatus.NOT_FOUND) 58 | 59 | return await this.requestRepository.save(request) 60 | } 61 | 62 | return await this.requestRepository.save(request) 63 | } 64 | 65 | async update(request: Request): Promise{ 66 | 67 | let findRequest: Request = await this.findById(request.id); 68 | 69 | if (!findRequest || !request.id) 70 | throw new HttpException("Demanda não encotrada!", HttpStatus.NOT_FOUND) 71 | 72 | if (request.provider){ 73 | 74 | let provider = await this.providerService.findById(request.provider.id) 75 | 76 | if (!provider) 77 | throw new HttpException("Provedor não encontrado!", HttpStatus.NOT_FOUND) 78 | 79 | return await this.requestRepository.save(request) 80 | } 81 | 82 | return await this.requestRepository.save(request) 83 | } 84 | 85 | async delete(id: number): Promise{ 86 | 87 | let findRequest = await this.findById(id); 88 | 89 | if (!findRequest) 90 | throw new HttpException("Demanda não enontrada!", HttpStatus.NOT_FOUND); 91 | 92 | return await this.requestRepository.delete(id) 93 | } 94 | } -------------------------------------------------------------------------------- /src/user/controllers/user.controller.ts: -------------------------------------------------------------------------------- 1 | import { Body, Controller, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post, Put, UseGuards } from "@nestjs/common"; 2 | import { UserService } from "../services/user.service"; 3 | import { User } from "../entities/user.entity"; 4 | import { JwtAuthGuard } from "../../auth/guard/jwt-auth.guard"; 5 | import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; 6 | 7 | @ApiTags('User') 8 | @Controller("/user") 9 | @ApiBearerAuth() 10 | export class UserController{ 11 | 12 | constructor(private readonly usuarioService: UserService){ } 13 | @UseGuards(JwtAuthGuard) 14 | @Get('/all') 15 | @HttpCode(HttpStatus.OK) 16 | findAll(): Promise{ 17 | return this.usuarioService.findAll(); 18 | } 19 | 20 | @UseGuards(JwtAuthGuard) 21 | @Get('/:id') 22 | @HttpCode(HttpStatus.OK) 23 | findById(@Param('id', ParseIntPipe) id: number): Promise{ 24 | return this.usuarioService.findById(id) 25 | } 26 | 27 | @Post('/cadastrar') 28 | @HttpCode(HttpStatus.CREATED) 29 | async create(@Body() usuario: User): Promise{ 30 | return this.usuarioService.create(usuario) 31 | } 32 | 33 | @UseGuards(JwtAuthGuard) 34 | @Put('/atualizar') 35 | @HttpCode(HttpStatus.OK) 36 | async update(@Body() usuario: User): Promise{ 37 | return this.usuarioService.update(usuario) 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/user/entities/user.entity.ts: -------------------------------------------------------------------------------- 1 | import { ApiProperty } from "@nestjs/swagger" 2 | import { IsEmail, IsNotEmpty, MinLength } from "class-validator" 3 | import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm" 4 | 5 | @Entity({name: "tb_users"}) 6 | export class User { 7 | 8 | @ApiProperty() 9 | @PrimaryGeneratedColumn() 10 | id: number 11 | 12 | @ApiProperty() 13 | @IsNotEmpty() 14 | @Column({length: 255, nullable: false}) 15 | nome: string 16 | 17 | @IsEmail() 18 | @IsNotEmpty() 19 | @ApiProperty({example: "email@email.com.br"}) 20 | @Column({length: 255, nullable: false }) 21 | usuario: string 22 | 23 | @ApiProperty() 24 | @MinLength(8) 25 | @IsNotEmpty() 26 | @Column({length: 255, nullable: false }) 27 | senha: string 28 | 29 | @ApiProperty() 30 | @Column({length: 5000 }) 31 | foto: string 32 | 33 | } -------------------------------------------------------------------------------- /src/user/services/user.service.ts: -------------------------------------------------------------------------------- 1 | import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; 2 | import { InjectRepository } from '@nestjs/typeorm'; 3 | import { Repository } from 'typeorm'; 4 | import { Bcrypt } from '../../auth/bcrypt/bcrypt'; 5 | import { User } from '../entities/user.entity'; 6 | 7 | @Injectable() 8 | export class UserService { 9 | constructor( 10 | @InjectRepository(User) 11 | private usuarioRepository: Repository, 12 | private bcrypt: Bcrypt 13 | ) { } 14 | 15 | async findByUsuario(usuario: string): Promise { 16 | return await this.usuarioRepository.findOne({ 17 | where: { 18 | usuario: usuario 19 | } 20 | }) 21 | } 22 | 23 | async findAll(): Promise { 24 | return await this.usuarioRepository.find( 25 | { 26 | relations:{ 27 | 28 | } 29 | } 30 | ); 31 | 32 | } 33 | 34 | async findById(id: number): Promise { 35 | 36 | let usuario = await this.usuarioRepository.findOne({ 37 | where: { 38 | id 39 | }, 40 | relations: { 41 | 42 | } 43 | }); 44 | 45 | if (!usuario) 46 | throw new HttpException('Usuario não encontrado!', HttpStatus.NOT_FOUND); 47 | 48 | return usuario; 49 | 50 | } 51 | 52 | async create(usuario: User): Promise { 53 | 54 | let buscaUsuario = await this.findByUsuario(usuario.usuario); 55 | 56 | if (!buscaUsuario) { 57 | usuario.senha = await this.bcrypt.criptografarSenha(usuario.senha) 58 | return await this.usuarioRepository.save(usuario); 59 | } 60 | 61 | throw new HttpException("O Usuario ja existe!", HttpStatus.BAD_REQUEST); 62 | 63 | } 64 | 65 | async update(usuario: User): Promise { 66 | 67 | let updateUsuario: User = await this.findById(usuario.id); 68 | let buscaUsuario = await this.findByUsuario(usuario.usuario); 69 | 70 | if (!updateUsuario) 71 | throw new HttpException('Usuário não encontrado!', HttpStatus.NOT_FOUND); 72 | 73 | if (buscaUsuario && buscaUsuario.id !== usuario.id) 74 | throw new HttpException('Usuário (e-mail) já Cadastrado!', HttpStatus.BAD_REQUEST); 75 | 76 | usuario.senha = await this.bcrypt.criptografarSenha(usuario.senha) 77 | return await this.usuarioRepository.save(usuario); 78 | 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /src/user/user.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { TypeOrmModule } from '@nestjs/typeorm'; 3 | import { User } from './entities/user.entity'; 4 | import { UserService } from './services/user.service'; 5 | import { Bcrypt } from '../auth/bcrypt/bcrypt'; 6 | import { UserController } from './controllers/user.controller'; 7 | 8 | @Module({ 9 | imports: [TypeOrmModule.forFeature([User])], 10 | providers: [UserService, Bcrypt], 11 | controllers: [UserController], 12 | exports: [UserService], 13 | }) 14 | export class UserModule {} -------------------------------------------------------------------------------- /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": "ES2021", 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 | --------------------------------------------------------------------------------