├── README.md ├── auth-example ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── package-lock.json ├── package.json ├── src │ ├── app.controller.spec.ts │ ├── app.controller.ts │ ├── app.module.ts │ ├── app.service.ts │ ├── auth │ │ ├── auth.controller.ts │ │ ├── auth.module.ts │ │ ├── auth.service.ts │ │ ├── local-auth.guard.ts │ │ └── local.strategy.ts │ ├── main.ts │ └── types │ │ └── User.ts ├── test │ ├── app.e2e-spec.ts │ └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json ├── clase01-intro ├── node-hello-world │ ├── .readme │ ├── index.js │ └── package.json └── node-ts-hello-world │ ├── .readme │ ├── index.ts │ ├── package-lock.json │ └── package.json ├── clase02-repaso-js ├── algoritmia-resuelto.js ├── algoritmia.js ├── demo-typescript.ts ├── ecma.js ├── primitivos.js ├── prototipos-clases.js ├── prototipos.js └── strict-mode.js └── clase09-nestapi ├── .eslintrc.js ├── .gitignore ├── .prettierrc ├── README.md ├── nest-cli.json ├── package-lock.json ├── package.json ├── src ├── Examples │ ├── express │ │ ├── mvc.ts │ │ └── no-mvc.ts │ ├── patrones │ │ ├── factory.ts │ │ ├── observable.ts │ │ ├── singleton.ts │ │ ├── srtrategy.ts │ │ └── strategy.ts │ ├── poo │ │ ├── abtraction.ts │ │ ├── encapsulation.ts │ │ ├── inheritance.ts │ │ └── polymorphism.ts │ └── solid │ │ └── isp.ts ├── app.controller.spec.ts ├── app.controller.ts ├── app.module.ts ├── app.service.ts ├── main.ts ├── pokemon.controller.ts ├── pokemon.module.ts └── pokemon.service.ts ├── test ├── app.e2e-spec.ts └── jest-e2e.json ├── tsconfig.build.json └── tsconfig.json /README.md: -------------------------------------------------------------------------------- 1 | [![](https://i.ibb.co/pxkk9Fk/portada.png)](https://i.ibb.co/pxkk9Fk/portada.png) 2 | 3 | ### ¡Bienvenido al repositorio de Ejemplos de Código para JavaScript en el Backend del Bootcamp! 🐊 4 | 5 | Aquí encontrarás una colección de valiosos fragmentos de código, vistos en clase, y ejemplos prácticos diseñados para mejorar tus habilidades en JavaScript en el ámbito del desarrollo backend. Ya sea que estés empezando y necesites comprender los conceptos fundamentales o si eres un desarrollador experimentado deseando explorar técnicas avanzadas, esta colección es tu recurso central para perfeccionar tus habilidades de desarrollo backend en JavaScript/TypeScript. 6 | 7 | - ##### Clase 1: "Bienvenidos al bootcamp". 8 | - ##### Clase 1: "Repaso de JavaScript". 9 | -------------------------------------------------------------------------------- /auth-example/.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 | -------------------------------------------------------------------------------- /auth-example/.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 -------------------------------------------------------------------------------- /auth-example/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /auth-example/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 6 | [circleci-url]: https://circleci.com/gh/nestjs/nest 7 | 8 |

A progressive Node.js framework for building efficient and scalable server-side applications.

9 |

10 | NPM Version 11 | Package License 12 | NPM Downloads 13 | CircleCI 14 | Coverage 15 | Discord 16 | Backers on Open Collective 17 | Sponsors on Open Collective 18 | 19 | Support us 20 | 21 |

22 | 24 | 25 | ## Description 26 | 27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 28 | 29 | ## Installation 30 | 31 | ```bash 32 | $ npm install 33 | ``` 34 | 35 | ## Running the app 36 | 37 | ```bash 38 | # development 39 | $ npm run start 40 | 41 | # watch mode 42 | $ npm run start:dev 43 | 44 | # production mode 45 | $ npm run start:prod 46 | ``` 47 | 48 | ## Test 49 | 50 | ```bash 51 | # unit tests 52 | $ npm run test 53 | 54 | # e2e tests 55 | $ npm run test:e2e 56 | 57 | # test coverage 58 | $ npm run test:cov 59 | ``` 60 | 61 | ## Support 62 | 63 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 64 | 65 | ## Stay in touch 66 | 67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 68 | - Website - [https://nestjs.com](https://nestjs.com/) 69 | - Twitter - [@nestframework](https://twitter.com/nestframework) 70 | 71 | ## License 72 | 73 | Nest is [MIT licensed](LICENSE). 74 | -------------------------------------------------------------------------------- /auth-example/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 | -------------------------------------------------------------------------------- /auth-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "auth-example", 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/core": "^10.0.0", 25 | "@nestjs/platform-express": "^10.0.0", 26 | "reflect-metadata": "^0.1.13", 27 | "rxjs": "^7.8.1" 28 | }, 29 | "devDependencies": { 30 | "@nestjs/cli": "^10.0.0", 31 | "@nestjs/schematics": "^10.0.0", 32 | "@nestjs/testing": "^10.0.0", 33 | "@types/express": "^4.17.17", 34 | "@types/jest": "^29.5.2", 35 | "@types/node": "^20.3.1", 36 | "@types/supertest": "^2.0.12", 37 | "@typescript-eslint/eslint-plugin": "^6.0.0", 38 | "@typescript-eslint/parser": "^6.0.0", 39 | "eslint": "^8.42.0", 40 | "eslint-config-prettier": "^9.0.0", 41 | "eslint-plugin-prettier": "^5.0.0", 42 | "jest": "^29.5.0", 43 | "prettier": "^3.0.0", 44 | "source-map-support": "^0.5.21", 45 | "supertest": "^6.3.3", 46 | "ts-jest": "^29.1.0", 47 | "ts-loader": "^9.4.3", 48 | "ts-node": "^10.9.1", 49 | "tsconfig-paths": "^4.2.0", 50 | "typescript": "^5.1.3" 51 | }, 52 | "jest": { 53 | "moduleFileExtensions": [ 54 | "js", 55 | "json", 56 | "ts" 57 | ], 58 | "rootDir": "src", 59 | "testRegex": ".*\\.spec\\.ts$", 60 | "transform": { 61 | "^.+\\.(t|j)s$": "ts-jest" 62 | }, 63 | "collectCoverageFrom": [ 64 | "**/*.(t|j)s" 65 | ], 66 | "coverageDirectory": "../coverage", 67 | "testEnvironment": "node" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /auth-example/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /auth-example/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /auth-example/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { AuthModule } from './auth/auth.module'; 5 | import { AuthController } from './auth/auth.controller'; 6 | 7 | @Module({ 8 | imports: [AuthModule], 9 | controllers: [AppController, AuthController], 10 | providers: [AppService], 11 | }) 12 | export class AppModule {} 13 | -------------------------------------------------------------------------------- /auth-example/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 | -------------------------------------------------------------------------------- /auth-example/src/auth/auth.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Request, Post, UseGuards } from '@nestjs/common'; 2 | import { LocalAuthGuard } from './local-auth.guard'; 3 | 4 | @Controller('auth') 5 | export class AuthController { 6 | constructor() {} 7 | 8 | @UseGuards(LocalAuthGuard) 9 | @Post('login') 10 | login(@Request() req) { 11 | console.log('Controller'); 12 | return req.user; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /auth-example/src/auth/auth.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AuthService } from './auth.service'; 3 | import { LocalStrategy } from './local.strategy'; 4 | import { PassportModule } from '@nestjs/passport'; 5 | 6 | @Module({ 7 | imports: [PassportModule], 8 | providers: [AuthService, LocalStrategy], 9 | exports: [AuthService], 10 | }) 11 | export class AuthModule {} 12 | -------------------------------------------------------------------------------- /auth-example/src/auth/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { User } from '../types/User'; 3 | 4 | @Injectable() 5 | export class AuthService { 6 | testUser: User; 7 | 8 | constructor() { 9 | this.testUser = { 10 | id: 10, 11 | name: 'juani', 12 | password: 'test', 13 | }; 14 | } 15 | 16 | //ACA TRAEMOS AL USUARIO DE MONGO 17 | validateUser(username: string, password: string): any { 18 | console.log('AuthService validateUser()'); 19 | if ( 20 | this.testUser.name.toLowerCase() == username.toLowerCase() && 21 | this.testUser.password == password 22 | ) { 23 | return { 24 | userId: this.testUser.id, 25 | name: this.testUser.name, 26 | }; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /auth-example/src/auth/local-auth.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { AuthGuard } from '@nestjs/passport'; 3 | 4 | @Injectable() 5 | export class LocalAuthGuard extends AuthGuard('local') { 6 | constructor() { 7 | super(); 8 | console.log('LocalAuthGuard'); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /auth-example/src/auth/local.strategy.ts: -------------------------------------------------------------------------------- 1 | import { Strategy } from 'passport-local'; 2 | import { PassportStrategy } from '@nestjs/passport'; 3 | import { Injectable, UnauthorizedException } from '@nestjs/common'; 4 | import { AuthService } from './auth.service'; 5 | 6 | @Injectable() 7 | export class LocalStrategy extends PassportStrategy(Strategy) { 8 | constructor(private authService: AuthService) { 9 | super({ usernameField: 'username' }); 10 | } 11 | 12 | validate(username: string, password: string): any { 13 | console.log('LocalStrategy validate()'); 14 | const user = this.authService.validateUser(username, password); 15 | if (!user) { 16 | throw new UnauthorizedException(); 17 | } 18 | return user; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /auth-example/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule); 6 | await app.listen(3000); 7 | } 8 | bootstrap(); 9 | -------------------------------------------------------------------------------- /auth-example/src/types/User.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id: number; 3 | name: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /auth-example/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 | -------------------------------------------------------------------------------- /auth-example/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 | -------------------------------------------------------------------------------- /auth-example/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /auth-example/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 | -------------------------------------------------------------------------------- /clase01-intro/node-hello-world/.readme: -------------------------------------------------------------------------------- 1 | # Los pasos para crear este proyecto fueron: 2 | 3 | 1. Crear el repositorio del proyecto 4 | 2. Ejecutar en la terminal el comando `npm init --y` (Inicializa un proyecto en node, creando un package.json) 5 | 3. Crear el archivo index.json 6 | 4. Escribir nuestro código 7 | 5. Ejecutar el código con el comando `node index.js` 8 | -------------------------------------------------------------------------------- /clase01-intro/node-hello-world/index.js: -------------------------------------------------------------------------------- 1 | // Defino la función sayHello que acepta como parámetro un nombre 2 | function sayHello(name) { 3 | // imprimo en pantalla 4 | console.log(`Hola ${name}`); 5 | } 6 | 7 | // ejecuto la función 8 | sayHello("mundo"); 9 | -------------------------------------------------------------------------------- /clase01-intro/node-hello-world/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hello-world", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC" 12 | } 13 | -------------------------------------------------------------------------------- /clase01-intro/node-ts-hello-world/.readme: -------------------------------------------------------------------------------- 1 | # Los pasos para crear este proyecto fueron: 2 | 3 | 1. Crear el repositorio del proyecto 4 | 2. Ejecutar en la terminal el comando `npm init --y` (Inicializa un proyecto en node, creando un package.json) 5 | 3. Crear el archivo index.json 6 | 4. Escribir nuestro código 7 | 5. Ejecutar el código con el comando `node index.js` 8 | -------------------------------------------------------------------------------- /clase01-intro/node-ts-hello-world/index.ts: -------------------------------------------------------------------------------- 1 | function sayHi(name: string) { 2 | console.log(`Hola ${name}`); 3 | } 4 | 5 | sayHi("Bel"); 6 | -------------------------------------------------------------------------------- /clase01-intro/node-ts-hello-world/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-ts-hello-world", 3 | "lockfileVersion": 3, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "devDependencies": { 8 | "typescript": "^5.2.2" 9 | } 10 | }, 11 | "node_modules/typescript": { 12 | "version": "5.2.2", 13 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", 14 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", 15 | "dev": true, 16 | "bin": { 17 | "tsc": "bin/tsc", 18 | "tsserver": "bin/tsserver" 19 | }, 20 | "engines": { 21 | "node": ">=14.17" 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /clase01-intro/node-ts-hello-world/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "typescript": "^5.2.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /clase02-repaso-js/algoritmia-resuelto.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Tenemos una funcion que sirve para determinar si una palabra es un palindromo sin utilizar funciones predefinidas de javascript 3 | * Se les ocurre como mejorarla? 4 | */ 5 | 6 | const word = "reconocer" 7 | 8 | // Inicial 9 | function isPalindrome(word) { 10 | let reversedWord = "" 11 | 12 | for (let i = 0; i < word.length; i++) { 13 | reversedWord += word[word.length - i - 1] 14 | } 15 | 16 | return reversedWord === word 17 | } 18 | 19 | // Primera mejora 20 | function isPalindrome(word) { 21 | for (let i = word.length - 1; i >= 0; i--) { 22 | if (word[i] !== word[word.length - i - 1]) { 23 | return false 24 | } 25 | } 26 | 27 | return true 28 | } 29 | 30 | // Segunda mejora 31 | function isPalindrome(word) { 32 | for (let i = 0; i < Math.floor(word.length / 2); i++) { 33 | if (word[i] !== word[word.length - 1 - i]) { 34 | return false; 35 | } 36 | } 37 | 38 | return true 39 | } 40 | 41 | console.log(isPalindrome(word)) 42 | 43 | 44 | 45 | /* 46 | * Tenemos un array de estudiantes con su nombre, edad y numero de pasaporte. Tambien tenemos una funcion que nos devuelve la edad de 47 | * un estudiante a partir de su numero de pasaporte. 48 | * Como podemos mejorar nuestra funcion? Total libertad para cambiar lo que quieran 49 | */ 50 | 51 | 52 | // Inicial 53 | const students = [ 54 | { 55 | name: "Juani", 56 | passportId: 1, 57 | age: 29 58 | }, 59 | { 60 | name: "Carla", 61 | passportId: 2, 62 | age: 25 63 | } 64 | ] 65 | 66 | function getStudentAge(passportId) { 67 | for (let i = 0; i < students.length; i++) { 68 | if (students[i].passportId === passportId) { 69 | return students[i].age 70 | } 71 | } 72 | } 73 | 74 | 75 | // Mejora 76 | const improvedStudents = { 77 | 1: { 78 | name: "Juani", 79 | age: 29 80 | }, 81 | 2: { 82 | name: "Carla", 83 | age: 25 84 | } 85 | } 86 | 87 | 88 | function getStudentAge(passportId) { 89 | return improvedStudents[passportId].age 90 | } 91 | 92 | 93 | console.log(getStudentAge(1)) 94 | -------------------------------------------------------------------------------- /clase02-repaso-js/algoritmia.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Tenemos una funcion que sirve para determinar si una palabra es un palindromo sin utilizar funciones predefinidas de javascript 3 | * Se les ocurre como mejorarla? 4 | */ 5 | 6 | const word = "reconocer" 7 | 8 | function isPalindrome(word) { 9 | let reversedWord = "" 10 | 11 | for (let i = 0; i < word.length; i++) { 12 | reversedWord += word[word.length - i - 1] 13 | } 14 | 15 | return reversedWord === word 16 | } 17 | 18 | console.log(isPalindrome(word)) 19 | 20 | 21 | /* 22 | * Tenemos un array de estudiantes con su nombre, edad y numero de pasaporte. Tambien tenemos una funcion que nos devuelve la edad de 23 | * un estudiante a partir de su numero de pasaporte. 24 | * Como podemos mejorar nuestra funcion? Total libertad para cambiar lo que quieran 25 | */ 26 | 27 | const students = [ 28 | { 29 | name: "Juani", 30 | passportId: 1, 31 | age: 29 32 | }, 33 | { 34 | name: "Carla", 35 | passportId: 2, 36 | age: 25 37 | } 38 | ] 39 | 40 | function getStudentAge(passportId) { 41 | for (let i = 0; i < students.length; i++) { 42 | if (students[i].passportId === passportId) { 43 | return students[i].age 44 | } 45 | } 46 | } 47 | 48 | 49 | console.log(getStudentAge(1)) 50 | -------------------------------------------------------------------------------- /clase02-repaso-js/demo-typescript.ts: -------------------------------------------------------------------------------- 1 | // Number 2 | const thisIsANumber: number = 1; 3 | 4 | // String 5 | const thisIsAString: string = "hello"; 6 | 7 | // Boolean 8 | const thisIsABoolean: boolean = true; 9 | 10 | // Array 11 | const firstArray: number[] = [1, 2, 3]; 12 | const secondArray: (number | string | boolean)[] = [1, "a", false]; 13 | 14 | // Object 15 | interface IObject { 16 | name: string; 17 | age: number; 18 | } 19 | const thisIsAnObject: IObject = { 20 | name: "Juani", 21 | age: 29, 22 | }; 23 | 24 | // Undefined 25 | const thisIsUndefined: undefined = undefined; 26 | 27 | // Null 28 | const thisIsNull: null = null; 29 | -------------------------------------------------------------------------------- /clase02-repaso-js/ecma.js: -------------------------------------------------------------------------------- 1 | // const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 2 | 3 | // // Map, filter, etc 4 | // const even = arr.filter((number) => number % 2 === 0) 5 | // console.log(even) 6 | 7 | 8 | // Optional chaining (?.) 9 | // const firstStudent = { 10 | // name: "Juani", 11 | // age: 29, 12 | // passport: { 13 | // number: 123456, 14 | // country: "Argentina" 15 | // } 16 | // } 17 | 18 | // const secondStudent = { 19 | // name: "Juani", 20 | // age: 29, 21 | // } 22 | 23 | // console.log(firstStudent?.passport?.country) 24 | // console.log(secondStudent?.passport?.country) 25 | 26 | 27 | // Nullish operator (??) 28 | 29 | const age = 20; 30 | 31 | //Sin nullish operator 32 | const canDrive = age >= 18 ? true : false 33 | 34 | //Con nullish operator 35 | const canDrive2 = age >= 18 ?? false 36 | 37 | console.log(canDrive) 38 | console.log(canDrive2) 39 | -------------------------------------------------------------------------------- /clase02-repaso-js/primitivos.js: -------------------------------------------------------------------------------- 1 | // // Number 2 | // const thisIsANumber = 1; 3 | 4 | // // String 5 | // const thisIsAString = 'hello'; 6 | 7 | // // Boolean 8 | // const thisIsABoolean = true; 9 | 10 | // // Array 11 | // const firstArray = [1, 2, 3]; 12 | // const secondArray = [1, 'a', false]; 13 | 14 | // // Object 15 | // const thisIsAnObject = { 16 | // name: "Juani", 17 | // age: 29 18 | // } 19 | 20 | 21 | // // Undefined 22 | // const thisIsUndefined = undefined; 23 | 24 | // // Null 25 | // const thisIsNull = null; 26 | 27 | // const numbers = [1, 2, 3]; 28 | 29 | // const newNumbers = [] 30 | 31 | // numbers.forEach((number) => { 32 | // newNumbers.push(number * 2); 33 | // }) 34 | 35 | // console.log(numbers); 36 | // console.log(newNumbers) 37 | 38 | 39 | function Persona(nombre) { 40 | this.nombre = nombre; 41 | } 42 | 43 | Persona.prototype.saludar = function () { 44 | return `Hola, mi nombre es ${this.nombre}` 45 | } 46 | 47 | const newPersona = new Persona("Juani"); 48 | const newPersona2 = new Persona("Juani2"); 49 | 50 | console.log(newPersona) 51 | console.log(newPersona.nombre); 52 | console.log(newPersona.saludar()) 53 | console.log(newPersona.__proto__) 54 | 55 | 56 | console.log(newPersona2.saludar()) 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /clase02-repaso-js/prototipos-clases.js: -------------------------------------------------------------------------------- 1 | class LikesService { 2 | constructor() { 3 | this.likes = 0; 4 | this.dislikes = 0; 5 | } 6 | 7 | like() { 8 | this.likes++; 9 | } 10 | 11 | dislike() { 12 | this.dislikes++; 13 | } 14 | 15 | getLikes() { 16 | return this.likes; 17 | } 18 | 19 | getDislikes() { 20 | return this.dislikes; 21 | } 22 | } 23 | 24 | class Comment extends LikesService { 25 | constructor(msg) { 26 | super(); 27 | this.message = msg; 28 | } 29 | } 30 | 31 | class CommentsService { 32 | constructor() { 33 | this.comments = []; 34 | this.commentsQty = 0; 35 | } 36 | 37 | addComment(comment) { 38 | this.commentsQty++; 39 | 40 | this.comments.push({ id: this.commentsQty, comment }); 41 | } 42 | 43 | getComments() { 44 | return this.comments; 45 | } 46 | } 47 | 48 | 49 | console.log('\n') 50 | 51 | console.log("Creamos una nueva instancia de nuestro servicio de comentarios") 52 | const thread = new CommentsService(); 53 | console.log(thread) 54 | console.log('\n') 55 | 56 | console.log("Si llamamos a la funcion getComments vemos que viene vacia porque todavia no agregamos nada") 57 | console.log(thread.getComments()) 58 | console.log('\n') 59 | 60 | console.log("Creamos una nueva instancia de un comentario con un mensaje que querramos") 61 | const firstComment = new Comment("this is a test") 62 | console.log(firstComment) 63 | console.log('\n') 64 | 65 | console.log("Agregamos nuestro comentario a nuestro thread") 66 | thread.addComment(firstComment) 67 | console.log(thread) 68 | console.log('\n') 69 | 70 | console.log("Ahora nuestro thread tiene un comentario") 71 | console.log(thread.getComments()) 72 | console.log('\n') 73 | 74 | console.log("Le damos like a nuestro comentario") 75 | firstComment.like(); 76 | console.log(firstComment) 77 | console.log('\n') 78 | 79 | console.log("Vemos que nuestro comentario tiene un like dentro de nuestro thread") 80 | console.log(thread.getComments()) 81 | 82 | -------------------------------------------------------------------------------- /clase02-repaso-js/prototipos.js: -------------------------------------------------------------------------------- 1 | // Un sistema de comentarios 2 | 3 | //LikesService 4 | function LikesService() { 5 | this.likes = 0; 6 | this.dislikes = 0; 7 | } 8 | 9 | LikesService.prototype.like = function () { 10 | this.likes++; 11 | } 12 | 13 | LikesService.prototype.dislike = function () { 14 | this.dislikes++; 15 | } 16 | 17 | LikesService.prototype.getLikes = function () { 18 | return this.likes; 19 | } 20 | 21 | LikesService.prototype.getDislikes = function () { 22 | return this.dislikes; 23 | } 24 | 25 | //Comment 26 | function Comment(msg) { 27 | LikesService.call(this) 28 | this.message = msg 29 | } 30 | 31 | Comment.prototype = Object.create(LikesService.prototype); 32 | Comment.prototype.constructor = Comment; 33 | 34 | 35 | // CommentsService 36 | function CommentsService() { 37 | this.comments = []; 38 | this.commentsQty = 0; 39 | } 40 | 41 | CommentsService.prototype.addComment = function (comment) { 42 | this.commentsQty++; 43 | 44 | this.comments.push({ id: this.commentsQty, comment }); 45 | } 46 | 47 | CommentsService.prototype.getComments = function () { 48 | return this.comments; 49 | } 50 | 51 | console.log('\n') 52 | 53 | console.log("Creamos una nueva instancia de nuestro servicio de comentarios") 54 | const thread = new CommentsService(); 55 | console.log(thread) 56 | console.log('\n') 57 | 58 | console.log("Si llamamos a la funcion getComments vemos que viene vacia porque todavia no agregamos nada") 59 | console.log(thread.getComments()) 60 | console.log('\n') 61 | 62 | console.log("Creamos una nueva instancia de un comentario con un mensaje que querramos") 63 | const firstComment = new Comment("this is a test") 64 | console.log(firstComment) 65 | console.log('\n') 66 | 67 | console.log("Agregamos nuestro comentario a nuestro thread") 68 | thread.addComment(firstComment) 69 | console.log(thread) 70 | console.log('\n') 71 | 72 | console.log("Ahora nuestro thread tiene un comentario") 73 | console.log(thread.getComments()) 74 | console.log('\n') 75 | 76 | console.log("Le damos like a nuestro comentario") 77 | firstComment.like(); 78 | console.log(firstComment) 79 | console.log('\n') 80 | 81 | console.log("Vemos que nuestro comentario tiene un like dentro de nuestro thread") 82 | console.log(thread.getComments()) 83 | 84 | -------------------------------------------------------------------------------- /clase02-repaso-js/strict-mode.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | x = 1; 3 | console.log(x); 4 | -------------------------------------------------------------------------------- /clase09-nestapi/.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 | -------------------------------------------------------------------------------- /clase09-nestapi/.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 -------------------------------------------------------------------------------- /clase09-nestapi/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } -------------------------------------------------------------------------------- /clase09-nestapi/README.md: -------------------------------------------------------------------------------- 1 |

2 | Nest Logo 3 |

4 | 5 | [circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 6 | [circleci-url]: https://circleci.com/gh/nestjs/nest 7 | 8 |

A progressive Node.js framework for building efficient and scalable server-side applications.

9 |

10 | NPM Version 11 | Package License 12 | NPM Downloads 13 | CircleCI 14 | Coverage 15 | Discord 16 | Backers on Open Collective 17 | Sponsors on Open Collective 18 | 19 | Support us 20 | 21 |

22 | 24 | 25 | ## Description 26 | 27 | [Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. 28 | 29 | ## Installation 30 | 31 | ```bash 32 | $ npm install 33 | ``` 34 | 35 | ## Running the app 36 | 37 | ```bash 38 | # development 39 | $ npm run start 40 | 41 | # watch mode 42 | $ npm run start:dev 43 | 44 | # production mode 45 | $ npm run start:prod 46 | ``` 47 | 48 | ## Test 49 | 50 | ```bash 51 | # unit tests 52 | $ npm run test 53 | 54 | # e2e tests 55 | $ npm run test:e2e 56 | 57 | # test coverage 58 | $ npm run test:cov 59 | ``` 60 | 61 | ## Support 62 | 63 | Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). 64 | 65 | ## Stay in touch 66 | 67 | - Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) 68 | - Website - [https://nestjs.com](https://nestjs.com/) 69 | - Twitter - [@nestframework](https://twitter.com/nestframework) 70 | 71 | ## License 72 | 73 | Nest is [MIT licensed](LICENSE). 74 | -------------------------------------------------------------------------------- /clase09-nestapi/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 | -------------------------------------------------------------------------------- /clase09-nestapi/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nestapi", 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/axios": "^3.0.1", 24 | "@nestjs/common": "^10.2.8", 25 | "@nestjs/config": "^3.1.1", 26 | "@nestjs/core": "^10.0.0", 27 | "@nestjs/jwt": "^10.1.1", 28 | "@nestjs/passport": "^10.0.2", 29 | "@nestjs/platform-express": "^10.0.0", 30 | "axios": "^1.6.0", 31 | "passport": "^0.6.0", 32 | "passport-jwt": "^4.0.1", 33 | "reflect-metadata": "^0.1.13", 34 | "rxjs": "^7.8.1" 35 | }, 36 | "devDependencies": { 37 | "@nestjs/cli": "^10.0.0", 38 | "@nestjs/schematics": "^10.0.0", 39 | "@nestjs/testing": "^10.0.0", 40 | "@types/express": "^4.17.17", 41 | "@types/jest": "^29.5.2", 42 | "@types/node": "^20.3.1", 43 | "@types/supertest": "^2.0.12", 44 | "@typescript-eslint/eslint-plugin": "^6.0.0", 45 | "@typescript-eslint/parser": "^6.0.0", 46 | "eslint": "^8.42.0", 47 | "eslint-config-prettier": "^9.0.0", 48 | "eslint-plugin-prettier": "^5.0.0", 49 | "jest": "^29.5.0", 50 | "prettier": "^3.0.0", 51 | "source-map-support": "^0.5.21", 52 | "supertest": "^6.3.3", 53 | "ts-jest": "^29.1.0", 54 | "ts-loader": "^9.4.3", 55 | "ts-node": "^10.9.1", 56 | "tsconfig-paths": "^4.2.0", 57 | "typescript": "^5.1.3" 58 | }, 59 | "jest": { 60 | "moduleFileExtensions": [ 61 | "js", 62 | "json", 63 | "ts" 64 | ], 65 | "rootDir": "src", 66 | "testRegex": ".*\\.spec\\.ts$", 67 | "transform": { 68 | "^.+\\.(t|j)s$": "ts-jest" 69 | }, 70 | "collectCoverageFrom": [ 71 | "**/*.(t|j)s" 72 | ], 73 | "coverageDirectory": "../coverage", 74 | "testEnvironment": "node" 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/express/mvc.ts: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const app = express(); 3 | const PORT = 3000; 4 | 5 | // Permite a Express entender datos de formularios y JSON 6 | app.use(express.urlencoded({ extended: true })); 7 | app.use(express.json()); 8 | 9 | // Configuración para usar EJS como motor de plantillas 10 | app.set('view engine', 'ejs'); 11 | 12 | // Modelo 13 | const messages = []; 14 | 15 | // Controlador 16 | const MessagesController = { 17 | findAll: (req, res) => { 18 | res.render('messages', { messages }); 19 | }, 20 | create: (req, res) => { 21 | const { text } = req.body; 22 | if (text) { 23 | const message = { id: messages.length + 1, text }; 24 | messages.push(message); 25 | res.redirect('/messages'); 26 | } else { 27 | res.status(400).send('Bad Request'); 28 | } 29 | }, 30 | }; 31 | 32 | // Rutas 33 | app.get('/messages', MessagesController.findAll); 34 | app.post('/messages', MessagesController.create); 35 | 36 | // Vista simple para mostrar mensajes y un formulario para enviarlos 37 | app.get('/', (req, res) => { 38 | res.render('index'); 39 | }); 40 | 41 | // Iniciando el servidor 42 | app.listen(PORT, () => { 43 | console.log(`Servidor escuchando en el puerto ${PORT}`); 44 | }); 45 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/express/no-mvc.ts: -------------------------------------------------------------------------------- 1 | // const express = require('express'); 2 | // const app = express(); 3 | // const PORT = 3000; 4 | 5 | // // Permite a Express entender datos de formularios y JSON 6 | // app.use(express.urlencoded({ extended: true })); 7 | // app.use(express.json()); 8 | 9 | // // Configuración para usar EJS como motor de plantillas 10 | // app.set('view engine', 'ejs'); 11 | 12 | // // Datos almacenados en memoria 13 | // const messages = []; 14 | 15 | // // Ruta para mostrar el formulario y los mensajes 16 | // app.get('/', (req, res) => { 17 | // res.render('index', { messages }); 18 | // }); 19 | 20 | // // Ruta para manejar la creación de un mensaje 21 | // app.post('/messages', (req, res) => { 22 | // const { text } = req.body; 23 | // if (text) { 24 | // const message = { id: messages.length + 1, text }; 25 | // messages.push(message); 26 | // res.redirect('/'); 27 | // } else { 28 | // res.status(400).send('Bad Request'); 29 | // } 30 | // }); 31 | 32 | // // Iniciar el servidor 33 | // app.listen(PORT, () => { 34 | // console.log(`Servidor escuchando en el puerto ${PORT}`); 35 | // }); 36 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/patrones/factory.ts: -------------------------------------------------------------------------------- 1 | import { Module, Injectable, Global } from '@nestjs/common'; 2 | 3 | // Este servicio podría ser responsable de cargar y validar las opciones de configuración. 4 | @Injectable() 5 | class ConfigOptionsService { 6 | private readonly envConfig: { [key: string]: string }; 7 | 8 | constructor() { 9 | // Aquí podrías cargar las configuraciones de un archivo .env o cualquier otra fuente 10 | // y realizar validaciones necesarias. 11 | this.envConfig = { 12 | NODE_ENV: process.env.NODE_ENV || 'development', 13 | PORT: process.env.PORT || '3000', 14 | // Aquí agregarías más configuraciones según sea necesario 15 | }; 16 | } 17 | 18 | get(key: string): string { 19 | return this.envConfig[key]; 20 | } 21 | } 22 | 23 | // El módulo que utiliza el servicio de ConfigOptionsService para proporcionar las configuraciones. 24 | @Global() 25 | @Module({ 26 | providers: [ 27 | { 28 | provide: 'CONFIG_OPTIONS', 29 | useFactory: (configService: ConfigOptionsService) => { 30 | // La factory podría devolver un objeto de configuración más complejo o personalizado. 31 | // y lo crea dependiendo de sus necesidades al momento de la ejecución 32 | return { 33 | nodeEnv: configService.get('NODE_ENV'), 34 | port: parseInt(configService.get('PORT'), 10), 35 | }; 36 | }, 37 | inject: [ConfigOptionsService], 38 | }, 39 | ConfigOptionsService, 40 | ], 41 | exports: ['CONFIG_OPTIONS', ConfigOptionsService], // Exportamos CONFIG_OPTIONS para que pueda ser inyectado en otros módulos. 42 | }) 43 | export class ConfigModule {} 44 | 45 | // En otros lugares de tu aplicación, podrías inyectar 'CONFIG_OPTIONS' para obtener acceso a estas configuraciones. 46 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/patrones/observable.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Controller, 3 | Get, 4 | Param, 5 | Res, 6 | HttpException, 7 | HttpStatus, 8 | } from '@nestjs/common'; 9 | import { PokemonService } from './pokemon.service'; 10 | import { Response } from 'express'; 11 | 12 | @Controller() 13 | export class PokemonController { 14 | constructor(private readonly pokemonService: PokemonService) {} 15 | 16 | @Get('/pokemon/:name') 17 | getPokemon(@Param('name') name: string, @Res() response: Response) { 18 | this.pokemonService.getPokemonByName(name).subscribe({ 19 | next: (data) => { 20 | response.send(data); 21 | }, 22 | error: () => { 23 | throw new HttpException( 24 | 'Error al obtener el Pokémon', 25 | HttpStatus.INTERNAL_SERVER_ERROR, 26 | ); 27 | }, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/patrones/singleton.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Scope, Controller, Get } from '@nestjs/common'; 2 | 3 | // Este es un servicio singleton, el cual es el ámbito por defecto en NestJS. 4 | // Nest creará una única instancia de este servicio y la compartirá en toda la aplicación. 5 | @Injectable() 6 | export class SingletonService { 7 | private count = 0; 8 | 9 | increment() { 10 | this.count++; 11 | } 12 | 13 | getCount() { 14 | return this.count; 15 | } 16 | } 17 | 18 | // Este es un servicio con ámbito transitorio. 19 | // Nest creará una nueva instancia del servicio cada vez que se inyecte. 20 | @Injectable({ scope: Scope.TRANSIENT }) 21 | export class TransientService { 22 | private count = 0; 23 | 24 | increment() { 25 | this.count++; 26 | } 27 | 28 | getCount() { 29 | return this.count; 30 | } 31 | } 32 | 33 | // Un controlador para demostrar el uso de ambos servicios. 34 | @Controller('counter') 35 | export class AppController { 36 | constructor( 37 | private readonly singletonService: SingletonService, 38 | private readonly transientService: TransientService, 39 | ) {} 40 | 41 | @Get('/singleton') 42 | getSingletonCount(): string { 43 | this.singletonService.increment(); 44 | return `Singleton count is now: ${this.singletonService.getCount()}`; 45 | } 46 | 47 | @Get('/transient') 48 | getTransientCount(): string { 49 | this.transientService.increment(); 50 | return `Transient count is now: ${this.transientService.getCount()}`; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/patrones/srtrategy.ts: -------------------------------------------------------------------------------- 1 | // jwt.strategy.ts 2 | import { Injectable } from '@nestjs/common'; 3 | import { PassportStrategy } from '@nestjs/passport'; 4 | import { Strategy, ExtractJwt } from 'passport-jwt'; 5 | import { ConfigService } from '@nestjs/config'; 6 | 7 | @Injectable() 8 | export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { 9 | constructor(private configService: ConfigService) { 10 | super({ 11 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 12 | ignoreExpiration: false, 13 | secretOrKey: configService.get('JWT_SECRET'), 14 | }); 15 | } 16 | 17 | async validate(payload: any) { 18 | return { userId: payload.sub, username: payload.username }; 19 | } 20 | } 21 | 22 | // auth.module.ts 23 | import { Module } from '@nestjs/common'; 24 | import { PassportModule } from '@nestjs/passport'; 25 | import { JwtModule } from '@nestjs/jwt'; 26 | import { JwtStrategy } from './jwt.strategy'; 27 | import { ConfigModule, ConfigService } from '@nestjs/config'; 28 | 29 | @Module({ 30 | imports: [ 31 | PassportModule, 32 | JwtModule.registerAsync({ 33 | imports: [ConfigModule], 34 | useFactory: async (configService: ConfigService) => ({ 35 | secret: configService.get('JWT_SECRET'), 36 | signOptions: { expiresIn: '60s' }, 37 | }), 38 | inject: [ConfigService], 39 | }), 40 | ConfigModule, 41 | ], 42 | providers: [JwtStrategy], 43 | }) 44 | export class AuthModule {} 45 | 46 | // profile.controller.ts 47 | import { Controller, Get, UseGuards, Request } from '@nestjs/common'; 48 | import { AuthGuard } from '@nestjs/passport'; 49 | 50 | @Controller('profile') 51 | export class ProfileController { 52 | @UseGuards(AuthGuard('jwt')) 53 | @Get() 54 | getProfile(@Request() req) { 55 | return req.user; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/patrones/strategy.ts: -------------------------------------------------------------------------------- 1 | // jwt.strategy.ts 2 | import { Injectable } from '@nestjs/common'; 3 | import { PassportStrategy } from '@nestjs/passport'; 4 | import { Strategy, ExtractJwt } from 'passport-jwt'; 5 | import { ConfigService } from '@nestjs/config'; 6 | 7 | @Injectable() 8 | class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { 9 | constructor(private configService: ConfigService) { 10 | super({ 11 | jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), 12 | ignoreExpiration: false, 13 | secretOrKey: configService.get('JWT_SECRET'), 14 | }); 15 | } 16 | 17 | async validate(payload: any) { 18 | return { userId: payload.sub, username: payload.username }; 19 | } 20 | } 21 | 22 | // auth.module.ts 23 | import { Module } from '@nestjs/common'; 24 | import { PassportModule } from '@nestjs/passport'; 25 | import { JwtModule } from '@nestjs/jwt'; 26 | import { JwtStrategy } from './jwt.strategy'; 27 | import { ConfigModule, ConfigService } from '@nestjs/config'; 28 | 29 | @Module({ 30 | imports: [ 31 | PassportModule, 32 | JwtModule.registerAsync({ 33 | imports: [ConfigModule], 34 | useFactory: async (configService: ConfigService) => ({ 35 | secret: configService.get('JWT_SECRET'), 36 | signOptions: { expiresIn: '60s' }, 37 | }), 38 | inject: [ConfigService], 39 | }), 40 | ConfigModule, 41 | ], 42 | providers: [JwtStrategy], 43 | }) 44 | class AuthModule {} 45 | 46 | // profile.controller.ts 47 | import { Controller, Get, UseGuards, Request } from '@nestjs/common'; 48 | import { AuthGuard } from '@nestjs/passport'; 49 | 50 | @Controller('profile') 51 | class ProfileController { 52 | @UseGuards(AuthGuard('jwt')) 53 | @Get() 54 | getProfile(@Request() req) { 55 | return req.user; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/poo/abtraction.ts: -------------------------------------------------------------------------------- 1 | // Esto normalmente estaría en un archivo llamado create-user.dto.ts 2 | export class CreateUserDto { 3 | readonly name: string; 4 | readonly email: string; 5 | readonly password: string; 6 | } 7 | 8 | // Esto normalmente estaría en un archivo llamado update-user.dto.ts 9 | export class UpdateUserDto { 10 | readonly name?: string; 11 | readonly email?: string; 12 | readonly password?: string; 13 | } 14 | 15 | // Esto normalmente estaría en un archivo llamado user.entity.ts 16 | export class User { 17 | id: string; 18 | name: string; 19 | email: string; 20 | password: string; 21 | // Otras propiedades y métodos de la entidad User 22 | } 23 | 24 | // Esto normalmente estaría en un archivo llamado user.repository.ts 25 | // Definimos una clase abstracta con los métodos esperados 26 | export abstract class UserRepository { 27 | abstract findAllUsers(): Promise; 28 | abstract findUserById(id: string): Promise; 29 | abstract createUser(user: CreateUserDto): Promise; 30 | abstract updateUser(id: string, updateUserDto: UpdateUserDto): Promise; 31 | abstract deleteUser(id: string): Promise; 32 | } 33 | 34 | // Esto normalmente estaría en un archivo llamado sql.user.repository.ts 35 | // Tenemos una definición concreta para manejar específicamente los usuarios que vengan desde SQL 36 | // podemos tener otra para Mongo y fácilmente desacoplar nuestras decisiones de datos del código 37 | import { Injectable } from '@nestjs/common'; 38 | 39 | @Injectable() 40 | export class SqlUserRepository extends UserRepository { 41 | private users: User[] = []; // Simula una base de datos con un array en memoria 42 | 43 | // implementaciones concretas 44 | 45 | async findAllUsers(): Promise { 46 | return this.users; 47 | } 48 | 49 | async findUserById(id: string): Promise { 50 | return this.users.find((user) => user.id === id) || null; 51 | } 52 | 53 | async createUser(createUserDto: CreateUserDto): Promise { 54 | const newUser = { 55 | ...createUserDto, 56 | id: Date.now().toString(), // Generación simple de ID para fines de ejemplo 57 | }; 58 | this.users.push(newUser); 59 | return newUser; 60 | } 61 | 62 | async updateUser(id: string, updateUserDto: UpdateUserDto): Promise { 63 | let user = await this.findUserById(id); 64 | if (!user) throw new Error('Usuario no encontrado'); 65 | user = { ...user, ...updateUserDto }; 66 | const index = this.users.findIndex((user) => user.id === id); 67 | this.users[index] = user; 68 | return user; 69 | } 70 | 71 | async deleteUser(id: string): Promise { 72 | const index = this.users.findIndex((user) => user.id === id); 73 | if (index > -1) { 74 | this.users.splice(index, 1); 75 | } 76 | } 77 | } 78 | 79 | // Esto normalmente estaría en un archivo llamado app.module.ts o user.module.ts 80 | import { Module } from '@nestjs/common'; 81 | 82 | @Module({ 83 | providers: [ 84 | { 85 | provide: UserRepository, 86 | useClass: SqlUserRepository, 87 | }, 88 | ], 89 | exports: [UserRepository], 90 | }) 91 | export class UserModule {} 92 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/poo/encapsulation.ts: -------------------------------------------------------------------------------- 1 | // Este código normalmente se dividiría en varios archivos: 2 | 3 | // user.entity.ts 4 | export class User { 5 | private password: string; // Encapsulado, no accesible fuera de esta clase 6 | constructor( 7 | public readonly id: string, 8 | public readonly email: string, 9 | password: string, 10 | ) { 11 | this.password = password; 12 | } 13 | 14 | validatePassword(password: string): boolean { 15 | return this.password === password; 16 | } 17 | 18 | // ... Otros métodos y propiedades 19 | } 20 | 21 | // user.service.ts 22 | import { Injectable } from '@nestjs/common'; 23 | 24 | @Injectable() 25 | class UserService { 26 | private users: User[] = []; // Datos encapsulados, no directamente accesibles 27 | 28 | createUser(email: string, password: string): User { 29 | const newUser = new User(Date.now().toString(), email, password); 30 | this.users.push(newUser); 31 | return newUser; 32 | } 33 | 34 | // ... Otros métodos 35 | } 36 | 37 | // user.module.ts 38 | import { Module } from '@nestjs/common'; 39 | 40 | @Module({ 41 | providers: [UserService], 42 | exports: [UserService], // UserService está disponible para otros módulos 43 | }) 44 | class UserModule {} 45 | 46 | // En un ejemplo de uso, tendrías algo como esto: 47 | 48 | // user.controller.ts 49 | import { Controller, Post, Body } from '@nestjs/common'; 50 | //import { UserService } from './user.service'; 51 | 52 | @Controller('users') 53 | export class UserController { 54 | constructor(private userService: UserService) {} 55 | 56 | @Post() 57 | createUser(@Body() body: { email: string; password: string }) { 58 | return this.userService.createUser(body.email, body.password); 59 | } 60 | 61 | // ... Otros endpoints 62 | } 63 | 64 | // app.module.ts 65 | //import { Module } from '@nestjs/common'; 66 | //import { UserModule } from './user.module'; 67 | 68 | @Module({ 69 | imports: [UserModule], 70 | controllers: [], 71 | providers: [], 72 | }) 73 | export class AppModule {} 74 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/poo/inheritance.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, Controller, Get, Module } from '@nestjs/common'; 2 | import { NestFactory } from '@nestjs/core'; 3 | import { HttpService } from '@nestjs/axios'; 4 | import { firstValueFrom } from 'rxjs'; 5 | 6 | // Servicio base para obtener información de Pokémon de la PokeAPI. 7 | @Injectable() 8 | class PokemonService { 9 | constructor(private httpService: HttpService) {} 10 | 11 | // Método para obtener un Pokémon por nombre. 12 | async getPokemonByName(name: string): Promise { 13 | // Realiza la petición HTTP y devuelve la respuesta. 14 | const response = await firstValueFrom( 15 | this.httpService.get(`https://pokeapi.co/api/v2/pokemon/${name}`), 16 | ); 17 | return response.data; 18 | } 19 | } 20 | 21 | // Servicio especializado para Pokémon de tipo agua que extiende de PokemonService. 22 | @Injectable() 23 | class WaterPokemonService extends PokemonService { 24 | // Sobreescribe el método getPokemonByName para filtrar solo los Pokémon de tipo agua. 25 | async getPokemonByName(name: string): Promise { 26 | const pokemon = await super.getPokemonByName(name); 27 | // Verifica si el Pokémon es de tipo agua, si no, lanza un error. 28 | if (!pokemon.types.some((typeInfo) => typeInfo.type.name === 'water')) { 29 | throw new Error('This is not a water-type Pokémon.'); 30 | } 31 | return pokemon; 32 | } 33 | } 34 | 35 | // Controlador con las rutas de la API. 36 | @Controller() 37 | class PokemonController { 38 | constructor( 39 | private pokemonService: PokemonService, 40 | private waterPokemonService: WaterPokemonService, 41 | ) {} 42 | 43 | // Ruta para obtener cualquier Pokémon. 44 | @Get('pokemon/:name') 45 | async getPokemon(name: string) { 46 | return this.pokemonService.getPokemonByName(name); 47 | } 48 | 49 | // Ruta para obtener solo Pokémon de tipo agua. 50 | @Get('water-pokemon/:name') 51 | async getWaterPokemon(name: string) { 52 | return this.waterPokemonService.getPokemonByName(name); 53 | } 54 | } 55 | 56 | // Módulo 57 | 58 | @Module({ 59 | controllers: [PokemonController], 60 | providers: [PokemonService, WaterPokemonService, HttpService], 61 | }) 62 | class AppModule {} 63 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/poo/polymorphism.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | // Clase base User 4 | class User { 5 | constructor( 6 | public id: number, 7 | public email: string, 8 | protected password: string, // Cambiado a protected para permitir el acceso en clases derivadas 9 | ) {} 10 | 11 | // Método para validar la contraseña 12 | validatePassword(password: string): boolean { 13 | return this.password === password; 14 | } 15 | } 16 | 17 | // Clase derivada para AdminUser 18 | class AdminUser extends User { 19 | public readonly privileges: string[]; 20 | 21 | constructor( 22 | id: number, 23 | email: string, 24 | password: string, 25 | privileges: string[], 26 | ) { 27 | super(id, email, password); 28 | this.privileges = privileges; 29 | } 30 | 31 | // Sobrescribiendo el método validatePassword 32 | validatePassword(password: string): boolean { 33 | const valid = super.validatePassword(password); 34 | console.log( 35 | `Administrador ${ 36 | valid ? 'validó' : 'no validó' 37 | } correctamente la contraseña.`, 38 | ); 39 | return valid; 40 | } 41 | 42 | // Método específico de Admin para agregar privilegios 43 | addPrivilege(privilege: string): void { 44 | this.privileges.push(privilege); 45 | } 46 | } 47 | 48 | // Ejemplo de uso: 49 | const admin = new AdminUser(1, 'admin@example.com', 'securepassword', [ 50 | 'manage-system', 51 | ]); 52 | const isValid = admin.validatePassword('securepassword'); // Esto también imprimirá un mensaje en la consola. 53 | -------------------------------------------------------------------------------- /clase09-nestapi/src/Examples/solid/isp.ts: -------------------------------------------------------------------------------- 1 | // interfaces.ts 2 | // Definición de la interfaz Readable para las operaciones de lectura. 3 | export interface Readable { 4 | findAll(): Promise; 5 | findById(id: string): Promise; 6 | } 7 | 8 | // Definición de la interfaz Writable para las operaciones de escritura. 9 | export interface Writable { 10 | create(item: T): Promise; 11 | update(id: string, item: T): Promise; 12 | delete(id: string): Promise; 13 | } 14 | 15 | // user.service.ts 16 | import { Injectable } from '@nestjs/common'; 17 | 18 | // Definición de la estructura de datos para un Usuario. 19 | export interface User { 20 | id: string; 21 | name: string; 22 | // Otras propiedades del usuario 23 | } 24 | 25 | // Servicio que implementa las interfaces Readable y Writable para usuarios. 26 | @Injectable() 27 | export class UserService implements Readable, Writable { 28 | private users: User[] = []; // Almacenamiento en memoria para ejemplificar. 29 | 30 | // Método para obtener todos los usuarios. 31 | async findAll(): Promise { 32 | return this.users; 33 | } 34 | 35 | // Método para obtener un usuario por su ID. 36 | async findById(id: string): Promise { 37 | return this.users.find((user) => user.id === id); 38 | } 39 | 40 | // Método para crear un nuevo usuario. 41 | async create(user: User): Promise { 42 | this.users.push(user); 43 | } 44 | 45 | // Método para actualizar un usuario existente. 46 | async update(id: string, user: User): Promise { 47 | const index = this.users.findIndex((u) => u.id === id); 48 | this.users[index] = user; 49 | } 50 | 51 | // Método para eliminar un usuario por su ID. 52 | async delete(id: string): Promise { 53 | this.users = this.users.filter((user) => user.id !== id); 54 | } 55 | } 56 | 57 | // user.controller.ts 58 | import { 59 | Controller, 60 | Get, 61 | Param, 62 | Post, 63 | Body, 64 | Put, 65 | Delete, 66 | } from '@nestjs/common'; 67 | // import { UserService, User } from './user.service'; 68 | 69 | // Controlador que maneja las rutas de la API para los usuarios. 70 | @Controller('users') 71 | class UserController { 72 | constructor(private readonly userService: UserService) {} 73 | 74 | // Ruta para obtener todos los usuarios. 75 | @Get() 76 | async getAllUsers(): Promise { 77 | return this.userService.findAll(); 78 | } 79 | 80 | // Ruta para obtener un usuario específico por ID. 81 | @Get(':id') 82 | async getUser(@Param('id') id: string): Promise { 83 | return this.userService.findById(id); 84 | } 85 | 86 | // Ruta para crear un nuevo usuario. 87 | @Post() 88 | async createUser(@Body() user: User): Promise { 89 | return this.userService.create(user); 90 | } 91 | 92 | // Ruta para actualizar un usuario existente. 93 | @Put(':id') 94 | async updateUser(@Param('id') id: string, @Body() user: User): Promise { 95 | return this.userService.update(id, user); 96 | } 97 | 98 | // Ruta para eliminar un usuario por ID. 99 | @Delete(':id') 100 | async deleteUser(@Param('id') id: string): Promise { 101 | return this.userService.delete(id); 102 | } 103 | } 104 | 105 | // app.module.ts 106 | import { Module } from '@nestjs/common'; 107 | 108 | // Módulo principal de la aplicación que registra el controlador y el servicio de usuarios. 109 | @Module({ 110 | controllers: [UserController], 111 | providers: [UserService], 112 | }) 113 | export class AppModule {} 114 | -------------------------------------------------------------------------------- /clase09-nestapi/src/app.controller.spec.ts: -------------------------------------------------------------------------------- 1 | import { Test, TestingModule } from '@nestjs/testing'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | 5 | describe('AppController', () => { 6 | let appController: AppController; 7 | 8 | beforeEach(async () => { 9 | const app: TestingModule = await Test.createTestingModule({ 10 | controllers: [AppController], 11 | providers: [AppService], 12 | }).compile(); 13 | 14 | appController = app.get(AppController); 15 | }); 16 | 17 | describe('root', () => { 18 | it('should return "Hello World!"', () => { 19 | expect(appController.getHello()).toBe('Hello World!'); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /clase09-nestapi/src/app.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { AppService } from './app.service'; 3 | 4 | @Controller() 5 | export class AppController { 6 | constructor(private readonly appService: AppService) {} 7 | 8 | @Get() 9 | getHello(): string { 10 | return this.appService.getHello(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /clase09-nestapi/src/app.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { AppController } from './app.controller'; 3 | import { AppService } from './app.service'; 4 | import { PokemonModule } from './pokemon.module'; 5 | 6 | @Module({ 7 | imports: [PokemonModule], 8 | controllers: [AppController], 9 | providers: [AppService], 10 | }) 11 | export class AppModule {} 12 | -------------------------------------------------------------------------------- /clase09-nestapi/src/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | 3 | @Injectable() 4 | export class AppService { 5 | getHello(): string { 6 | return 'Hello Bel!'; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /clase09-nestapi/src/main.ts: -------------------------------------------------------------------------------- 1 | import { NestFactory } from '@nestjs/core'; 2 | import { AppModule } from './app.module'; 3 | 4 | async function bootstrap() { 5 | const app = await NestFactory.create(AppModule); 6 | await app.listen(3000); 7 | } 8 | 9 | bootstrap(); 10 | -------------------------------------------------------------------------------- /clase09-nestapi/src/pokemon.controller.ts: -------------------------------------------------------------------------------- 1 | import { Controller, Get } from '@nestjs/common'; 2 | import { PokemonService } from './pokemon.service'; 3 | import { firstValueFrom } from 'rxjs'; 4 | import { Param, Res } from '@nestjs/common'; 5 | import { HttpException, HttpStatus } from '@nestjs/common'; 6 | 7 | @Controller() 8 | export class PokemonController { 9 | pokemon: any[]; 10 | 11 | constructor(private readonly pokemonService: PokemonService) { 12 | this.pokemon = []; 13 | } 14 | 15 | @Get('/pokemon/:name') 16 | async getPokemon(@Param('name') pokemon, @Res() response): Promise { 17 | try { 18 | const { data } = await firstValueFrom( 19 | await this.pokemonService.getPokemonByName(pokemon), 20 | ); 21 | response.send(data.name); 22 | } catch (e) { 23 | throw new HttpException( 24 | 'Error al obtener el Pokémon', 25 | HttpStatus.INTERNAL_SERVER_ERROR, 26 | ); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /clase09-nestapi/src/pokemon.module.ts: -------------------------------------------------------------------------------- 1 | import { Module } from '@nestjs/common'; 2 | import { PokemonController } from './pokemon.controller'; 3 | import { PokemonService } from './pokemon.service'; 4 | import { HttpModule } from '@nestjs/axios'; 5 | 6 | @Module({ 7 | imports: [HttpModule], 8 | controllers: [PokemonController], 9 | providers: [PokemonService], 10 | }) 11 | export class PokemonModule {} 12 | -------------------------------------------------------------------------------- /clase09-nestapi/src/pokemon.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@nestjs/common'; 2 | import { HttpService } from '@nestjs/axios'; 3 | 4 | @Injectable() 5 | export class PokemonService { 6 | constructor(private readonly httpService: HttpService) {} 7 | 8 | async getPokemonByName(name: string) { 9 | return this.httpService.get(`https://pokeapi.co/api/v2/pokemon/${name}`); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /clase09-nestapi/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 | -------------------------------------------------------------------------------- /clase09-nestapi/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 | -------------------------------------------------------------------------------- /clase09-nestapi/tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /clase09-nestapi/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 | --------------------------------------------------------------------------------