├── .gitignore ├── clean-architecture ├── 1. Entities - Enterprise Business Rules │ ├── City.ts │ └── PaddleCourt.ts ├── 2. UseCases - Application Business Rules │ ├── PaddleCourts.ts │ ├── SportsClubRepository.ts │ └── Weather.ts ├── 3. Presenters & Controllers & Gateways - Interface Adapters │ ├── SportsClub.ts │ └── SportsClubUserInterface.ts ├── 4. UI & Devices & Web & DB - Frameworks & Drivers │ ├── SportsClubInMemoryRepository.ts │ ├── SportsClubWebApi.ts │ └── WeatherWebApiClient.ts ├── README.md ├── container.ts ├── container.types.ts ├── main.ts ├── package-lock.json ├── package.json └── tsconfig.json ├── hexagonal-architecture ├── Application │ ├── PaddleCourts.ts │ ├── SportsClub.ts │ ├── adapters │ │ ├── SportsClubInMemoryRepository.ts │ │ ├── SportsClubWebApi.ts │ │ └── WeatherWebApi.ts │ └── ports │ │ ├── SportsClubRepository.ts │ │ ├── SportsClubUserInterface.ts │ │ └── Weather.ts ├── README.md ├── main.ts ├── package-lock.json ├── package.json └── tsconfig.json ├── onion-architecture ├── 1. DomainModel │ ├── City.ts │ └── PaddleCourt.ts ├── 2. DomainServices │ └── SportsClubRepository.ts ├── 3. ApplicationServices │ ├── PaddleCourts.ts │ └── Weather.ts ├── 4.A Infrastructure │ ├── SportsClubInMemoryRepository.ts │ └── WeatherWebApiClient.ts ├── 4.B UserInterface │ └── SportsClubWebApi.ts ├── README.md ├── container.ts ├── container.types.ts ├── main.ts ├── package-lock.json ├── package.json └── tsconfig.json └── three-layer-architecture ├── 1. Presentation └── SportsClubWebApi.ts ├── 2. Business Logic ├── PaddleCourts.ts └── Weather.ts ├── 3. Data Access └── SportsClubRepository.ts ├── README.md ├── main.ts ├── package-lock.json ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | */node_modules -------------------------------------------------------------------------------- /clean-architecture/1. Entities - Enterprise Business Rules/City.ts: -------------------------------------------------------------------------------- 1 | export type City = 'Madrid' | 'Valencia'; -------------------------------------------------------------------------------- /clean-architecture/1. Entities - Enterprise Business Rules/PaddleCourt.ts: -------------------------------------------------------------------------------- 1 | import { City } from "./City"; 2 | 3 | export class PaddleCourt { 4 | number: number; 5 | city: City 6 | } -------------------------------------------------------------------------------- /clean-architecture/2. UseCases - Application Business Rules/PaddleCourts.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubRepository } from "./SportsClubRepository"; 2 | import { Weather } from "./Weather"; 3 | import { PaddleCourt } from "../1. Entities - Enterprise Business Rules/PaddleCourt"; 4 | import { inject, injectable } from 'inversify'; 5 | import TYPES from "../container.types"; 6 | 7 | @injectable() 8 | export class PaddleCourts { 9 | constructor( 10 | @inject(TYPES.Weather) private weather: Weather, 11 | @inject(TYPES.SportsClubRepository) private sportsClubRepository: SportsClubRepository 12 | ) { } 13 | 14 | async getAvailables(): Promise> { 15 | const sportsClubPaddleCourts = await this.sportsClubRepository.getAllPaddleCourts(); 16 | const availablePaddleCourts = []; 17 | for (let paddelCourt of sportsClubPaddleCourts) { 18 | const isRainingInPaddelCourt = await this.weather.isRainingIn(paddelCourt.city); 19 | if (!isRainingInPaddelCourt) { 20 | availablePaddleCourts.push(paddelCourt); 21 | } 22 | } 23 | return availablePaddleCourts; 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /clean-architecture/2. UseCases - Application Business Rules/SportsClubRepository.ts: -------------------------------------------------------------------------------- 1 | import { PaddleCourt } from "../1. Entities - Enterprise Business Rules/PaddleCourt"; 2 | 3 | export interface SportsClubRepository { 4 | getAllPaddleCourts(): Promise>; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /clean-architecture/2. UseCases - Application Business Rules/Weather.ts: -------------------------------------------------------------------------------- 1 | import { City } from "../1. Entities - Enterprise Business Rules/City"; 2 | 3 | export interface Weather { 4 | isRainingIn(city: City): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /clean-architecture/3. Presenters & Controllers & Gateways - Interface Adapters/SportsClub.ts: -------------------------------------------------------------------------------- 1 | import { inject, injectable } from "inversify"; 2 | import { PaddleCourts } from "../2. UseCases - Application Business Rules/PaddleCourts"; 3 | import TYPES from "../container.types"; 4 | import { SportsClubUserInterface } from "./SportsClubUserInterface"; 5 | 6 | @injectable() 7 | export class SportsClub { 8 | constructor( 9 | @inject(TYPES.SportsClubUserInterface) private userInterface: SportsClubUserInterface, 10 | @inject(TYPES.PaddleCourts) private paddleCourts: PaddleCourts 11 | ) { } 12 | 13 | init() { 14 | this.userInterface.installGetAvailablePaddleCourts( 15 | () => this.paddleCourts.getAvailables() // Adapter logic here: from entities to ui structures 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /clean-architecture/3. Presenters & Controllers & Gateways - Interface Adapters/SportsClubUserInterface.ts: -------------------------------------------------------------------------------- 1 | import { PaddleCourt } from "../1. Entities - Enterprise Business Rules/PaddleCourt"; 2 | 3 | export interface SportsClubUserInterface { 4 | installGetAvailablePaddleCourts(callback: () => Promise): void; 5 | } 6 | -------------------------------------------------------------------------------- /clean-architecture/4. UI & Devices & Web & DB - Frameworks & Drivers/SportsClubInMemoryRepository.ts: -------------------------------------------------------------------------------- 1 | 2 | import { PaddleCourt } from "../1. Entities - Enterprise Business Rules/PaddleCourt"; 3 | import { SportsClubRepository } from "../2. UseCases - Application Business Rules/SportsClubRepository"; 4 | import { injectable } from "inversify"; 5 | 6 | @injectable() 7 | export class SportsClubInMemoryRepository implements SportsClubRepository { 8 | getAllPaddleCourts(): Promise> { 9 | return Promise.resolve([ 10 | { number: 5, city: 'Madrid' }, 11 | { number: 1, city: 'Valencia' }, 12 | { number: 2, city: 'Madrid' } 13 | ]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /clean-architecture/4. UI & Devices & Web & DB - Frameworks & Drivers/SportsClubWebApi.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { injectable } from 'inversify'; 3 | import { PaddleCourt } from '../1. Entities - Enterprise Business Rules/PaddleCourt'; 4 | import { SportsClubUserInterface } from '../3. Presenters & Controllers & Gateways - Interface Adapters/SportsClubUserInterface'; 5 | 6 | @injectable() 7 | export class SportsClubWebApiUserInterface implements SportsClubUserInterface { 8 | static PORT = 3000; 9 | api = express(); 10 | 11 | constructor() { 12 | this.api.listen(SportsClubWebApiUserInterface.PORT, () => { 13 | console.log(`web api listening on port ${SportsClubWebApiUserInterface.PORT}`); 14 | }); 15 | } 16 | 17 | installGetAvailablePaddleCourts(callback: () => Promise): void { 18 | this.api.get('/api/paddle/courts', async (req, res) => { 19 | const availablePaddleCourts = await callback(); 20 | res.json(availablePaddleCourts); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /clean-architecture/4. UI & Devices & Web & DB - Frameworks & Drivers/WeatherWebApiClient.ts: -------------------------------------------------------------------------------- 1 | import { Weather } from "../2. UseCases - Application Business Rules/Weather"; 2 | import { City } from "../1. Entities - Enterprise Business Rules/City"; 3 | // import axios from 'axios'; 4 | import { injectable } from "inversify"; 5 | 6 | @injectable() 7 | export class WeatherWebApiClient implements Weather { 8 | isRainingIn(city: City): Promise { 9 | 10 | // HTTP call logic: await axios.get('https://weather.com/api/israining') 11 | return Promise.resolve(false); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /clean-architecture/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbastos/web-api-microservice-architectures/27cb2ee9eb7a045c26f1a979c39c0e403c638e12/clean-architecture/README.md -------------------------------------------------------------------------------- /clean-architecture/container.ts: -------------------------------------------------------------------------------- 1 | import { Container } from 'inversify'; 2 | import { SportsClubRepository } from './2. UseCases - Application Business Rules/SportsClubRepository'; 3 | import { PaddleCourts } from './2. UseCases - Application Business Rules/PaddleCourts'; 4 | import { Weather } from './2. UseCases - Application Business Rules/Weather'; 5 | import { SportsClubInMemoryRepository } from './4. UI & Devices & Web & DB - Frameworks & Drivers/SportsClubInMemoryRepository'; 6 | import { WeatherWebApiClient } from './4. UI & Devices & Web & DB - Frameworks & Drivers/WeatherWebApiClient'; 7 | import { SportsClubWebApiUserInterface } from './4. UI & Devices & Web & DB - Frameworks & Drivers/SportsClubWebApi'; 8 | import TYPES from './container.types'; 9 | import { SportsClub } from './3. Presenters & Controllers & Gateways - Interface Adapters/SportsClub'; 10 | 11 | export const container = new Container(); 12 | container.bind(TYPES.PaddleCourts).to(PaddleCourts); 13 | container.bind(TYPES.SportsClub).to(SportsClub); 14 | container.bind(TYPES.Weather).to(WeatherWebApiClient); 15 | container.bind(TYPES.SportsClubUserInterface).to(SportsClubWebApiUserInterface); 16 | container.bind(TYPES.SportsClubRepository).to(SportsClubInMemoryRepository); 17 | -------------------------------------------------------------------------------- /clean-architecture/container.types.ts: -------------------------------------------------------------------------------- 1 | const TYPES = { 2 | PaddleCourts: Symbol('PaddleCourts'), 3 | SportsClubUserInterface: Symbol('SportsClubUserInterface'), 4 | SportsClubRepository: Symbol('SportsClubRepository'), 5 | SportsClub: Symbol('SportsClub'), 6 | Weather: Symbol('Weather') 7 | }; 8 | 9 | export default TYPES; -------------------------------------------------------------------------------- /clean-architecture/main.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import { SportsClub } from './3. Presenters & Controllers & Gateways - Interface Adapters/SportsClub'; 3 | import { container } from './container'; 4 | import TYPES from './container.types'; 5 | 6 | container.get(TYPES.SportsClub).init(); -------------------------------------------------------------------------------- /clean-architecture/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/body-parser": { 8 | "version": "1.19.0", 9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", 10 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", 11 | "dev": true, 12 | "requires": { 13 | "@types/connect": "*", 14 | "@types/node": "*" 15 | } 16 | }, 17 | "@types/connect": { 18 | "version": "3.4.34", 19 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", 20 | "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", 21 | "dev": true, 22 | "requires": { 23 | "@types/node": "*" 24 | } 25 | }, 26 | "@types/express": { 27 | "version": "4.17.12", 28 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", 29 | "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", 30 | "dev": true, 31 | "requires": { 32 | "@types/body-parser": "*", 33 | "@types/express-serve-static-core": "^4.17.18", 34 | "@types/qs": "*", 35 | "@types/serve-static": "*" 36 | } 37 | }, 38 | "@types/express-serve-static-core": { 39 | "version": "4.17.21", 40 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", 41 | "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", 42 | "dev": true, 43 | "requires": { 44 | "@types/node": "*", 45 | "@types/qs": "*", 46 | "@types/range-parser": "*" 47 | } 48 | }, 49 | "@types/jaeger-client": { 50 | "version": "3.18.0", 51 | "resolved": "https://registry.npmjs.org/@types/jaeger-client/-/jaeger-client-3.18.0.tgz", 52 | "integrity": "sha512-RbQvsCpapGqnuC4jVycOH/AthHr9Ze5hzbjdHclVRta29rsrA/0iHVJCsNi+nQ/iGJ3r6bQSJjp7uE29Xd+EdA==", 53 | "dev": true, 54 | "requires": { 55 | "@types/node": "*", 56 | "opentracing": "~0.14.3", 57 | "prom-client": "~11.3.0 || ^12.0.0 || ^13.0.0" 58 | } 59 | }, 60 | "@types/mime": { 61 | "version": "1.3.2", 62 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 63 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 64 | "dev": true 65 | }, 66 | "@types/mysql": { 67 | "version": "2.15.18", 68 | "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz", 69 | "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==", 70 | "dev": true, 71 | "requires": { 72 | "@types/node": "*" 73 | } 74 | }, 75 | "@types/node": { 76 | "version": "14.17.2", 77 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", 78 | "integrity": "sha512-sld7b/xmFum66AAKuz/rp/CUO8+98fMpyQ3SBfzzBNGMd/1iHBTAg9oyAvcYlAj46bpc74r91jSw2iFdnx29nw==", 79 | "dev": true 80 | }, 81 | "@types/qs": { 82 | "version": "6.9.6", 83 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", 84 | "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", 85 | "dev": true 86 | }, 87 | "@types/range-parser": { 88 | "version": "1.2.3", 89 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 90 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", 91 | "dev": true 92 | }, 93 | "@types/serve-static": { 94 | "version": "1.13.9", 95 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", 96 | "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", 97 | "dev": true, 98 | "requires": { 99 | "@types/mime": "^1", 100 | "@types/node": "*" 101 | } 102 | }, 103 | "accepts": { 104 | "version": "1.3.7", 105 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 106 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 107 | "requires": { 108 | "mime-types": "~2.1.24", 109 | "negotiator": "0.6.2" 110 | } 111 | }, 112 | "arg": { 113 | "version": "4.1.3", 114 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 115 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 116 | }, 117 | "array-flatten": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 120 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 121 | }, 122 | "axios": { 123 | "version": "0.21.1", 124 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 125 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 126 | "requires": { 127 | "follow-redirects": "^1.10.0" 128 | } 129 | }, 130 | "bignumber.js": { 131 | "version": "9.0.0", 132 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", 133 | "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" 134 | }, 135 | "bintrees": { 136 | "version": "1.0.1", 137 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 138 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=", 139 | "dev": true 140 | }, 141 | "body-parser": { 142 | "version": "1.19.0", 143 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 144 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 145 | "requires": { 146 | "bytes": "3.1.0", 147 | "content-type": "~1.0.4", 148 | "debug": "2.6.9", 149 | "depd": "~1.1.2", 150 | "http-errors": "1.7.2", 151 | "iconv-lite": "0.4.24", 152 | "on-finished": "~2.3.0", 153 | "qs": "6.7.0", 154 | "raw-body": "2.4.0", 155 | "type-is": "~1.6.17" 156 | } 157 | }, 158 | "buffer-from": { 159 | "version": "1.1.1", 160 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 161 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 162 | }, 163 | "bytes": { 164 | "version": "3.1.0", 165 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 166 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 167 | }, 168 | "content-disposition": { 169 | "version": "0.5.3", 170 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 171 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 172 | "requires": { 173 | "safe-buffer": "5.1.2" 174 | } 175 | }, 176 | "content-type": { 177 | "version": "1.0.4", 178 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 179 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 180 | }, 181 | "cookie": { 182 | "version": "0.4.0", 183 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 184 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 185 | }, 186 | "cookie-signature": { 187 | "version": "1.0.6", 188 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 189 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 190 | }, 191 | "core-util-is": { 192 | "version": "1.0.2", 193 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 194 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 195 | }, 196 | "create-require": { 197 | "version": "1.1.1", 198 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 199 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 200 | }, 201 | "debug": { 202 | "version": "2.6.9", 203 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 204 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 205 | "requires": { 206 | "ms": "2.0.0" 207 | } 208 | }, 209 | "depd": { 210 | "version": "1.1.2", 211 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 212 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 213 | }, 214 | "destroy": { 215 | "version": "1.0.4", 216 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 217 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 218 | }, 219 | "diff": { 220 | "version": "4.0.2", 221 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 222 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 223 | }, 224 | "ee-first": { 225 | "version": "1.1.1", 226 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 227 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 228 | }, 229 | "encodeurl": { 230 | "version": "1.0.2", 231 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 232 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 233 | }, 234 | "escape-html": { 235 | "version": "1.0.3", 236 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 237 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 238 | }, 239 | "etag": { 240 | "version": "1.8.1", 241 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 242 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 243 | }, 244 | "express": { 245 | "version": "4.17.1", 246 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 247 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 248 | "requires": { 249 | "accepts": "~1.3.7", 250 | "array-flatten": "1.1.1", 251 | "body-parser": "1.19.0", 252 | "content-disposition": "0.5.3", 253 | "content-type": "~1.0.4", 254 | "cookie": "0.4.0", 255 | "cookie-signature": "1.0.6", 256 | "debug": "2.6.9", 257 | "depd": "~1.1.2", 258 | "encodeurl": "~1.0.2", 259 | "escape-html": "~1.0.3", 260 | "etag": "~1.8.1", 261 | "finalhandler": "~1.1.2", 262 | "fresh": "0.5.2", 263 | "merge-descriptors": "1.0.1", 264 | "methods": "~1.1.2", 265 | "on-finished": "~2.3.0", 266 | "parseurl": "~1.3.3", 267 | "path-to-regexp": "0.1.7", 268 | "proxy-addr": "~2.0.5", 269 | "qs": "6.7.0", 270 | "range-parser": "~1.2.1", 271 | "safe-buffer": "5.1.2", 272 | "send": "0.17.1", 273 | "serve-static": "1.14.1", 274 | "setprototypeof": "1.1.1", 275 | "statuses": "~1.5.0", 276 | "type-is": "~1.6.18", 277 | "utils-merge": "1.0.1", 278 | "vary": "~1.1.2" 279 | } 280 | }, 281 | "finalhandler": { 282 | "version": "1.1.2", 283 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 284 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 285 | "requires": { 286 | "debug": "2.6.9", 287 | "encodeurl": "~1.0.2", 288 | "escape-html": "~1.0.3", 289 | "on-finished": "~2.3.0", 290 | "parseurl": "~1.3.3", 291 | "statuses": "~1.5.0", 292 | "unpipe": "~1.0.0" 293 | } 294 | }, 295 | "follow-redirects": { 296 | "version": "1.14.1", 297 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", 298 | "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" 299 | }, 300 | "forwarded": { 301 | "version": "0.2.0", 302 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 303 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 304 | }, 305 | "fresh": { 306 | "version": "0.5.2", 307 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 308 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 309 | }, 310 | "http-errors": { 311 | "version": "1.7.2", 312 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 313 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 314 | "requires": { 315 | "depd": "~1.1.2", 316 | "inherits": "2.0.3", 317 | "setprototypeof": "1.1.1", 318 | "statuses": ">= 1.5.0 < 2", 319 | "toidentifier": "1.0.0" 320 | } 321 | }, 322 | "iconv-lite": { 323 | "version": "0.4.24", 324 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 325 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 326 | "requires": { 327 | "safer-buffer": ">= 2.1.2 < 3" 328 | } 329 | }, 330 | "inherits": { 331 | "version": "2.0.3", 332 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 333 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 334 | }, 335 | "inversify": { 336 | "version": "5.1.1", 337 | "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz", 338 | "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==" 339 | }, 340 | "ipaddr.js": { 341 | "version": "1.9.1", 342 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 343 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 344 | }, 345 | "isarray": { 346 | "version": "1.0.0", 347 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 348 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 349 | }, 350 | "make-error": { 351 | "version": "1.3.6", 352 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 353 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 354 | }, 355 | "media-typer": { 356 | "version": "0.3.0", 357 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 358 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 359 | }, 360 | "merge-descriptors": { 361 | "version": "1.0.1", 362 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 363 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 364 | }, 365 | "methods": { 366 | "version": "1.1.2", 367 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 368 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 369 | }, 370 | "mime": { 371 | "version": "1.6.0", 372 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 373 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 374 | }, 375 | "mime-db": { 376 | "version": "1.48.0", 377 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 378 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 379 | }, 380 | "mime-types": { 381 | "version": "2.1.31", 382 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 383 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 384 | "requires": { 385 | "mime-db": "1.48.0" 386 | } 387 | }, 388 | "ms": { 389 | "version": "2.0.0", 390 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 391 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 392 | }, 393 | "mysql": { 394 | "version": "2.18.1", 395 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", 396 | "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", 397 | "requires": { 398 | "bignumber.js": "9.0.0", 399 | "readable-stream": "2.3.7", 400 | "safe-buffer": "5.1.2", 401 | "sqlstring": "2.3.1" 402 | } 403 | }, 404 | "negotiator": { 405 | "version": "0.6.2", 406 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 407 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 408 | }, 409 | "on-finished": { 410 | "version": "2.3.0", 411 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 412 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 413 | "requires": { 414 | "ee-first": "1.1.1" 415 | } 416 | }, 417 | "opentracing": { 418 | "version": "0.14.5", 419 | "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.5.tgz", 420 | "integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg==", 421 | "dev": true 422 | }, 423 | "parseurl": { 424 | "version": "1.3.3", 425 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 426 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 427 | }, 428 | "path-to-regexp": { 429 | "version": "0.1.7", 430 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 431 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 432 | }, 433 | "process-nextick-args": { 434 | "version": "2.0.1", 435 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 436 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 437 | }, 438 | "prom-client": { 439 | "version": "13.1.0", 440 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", 441 | "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", 442 | "dev": true, 443 | "requires": { 444 | "tdigest": "^0.1.1" 445 | } 446 | }, 447 | "proxy-addr": { 448 | "version": "2.0.7", 449 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 450 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 451 | "requires": { 452 | "forwarded": "0.2.0", 453 | "ipaddr.js": "1.9.1" 454 | } 455 | }, 456 | "qs": { 457 | "version": "6.7.0", 458 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 459 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 460 | }, 461 | "range-parser": { 462 | "version": "1.2.1", 463 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 464 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 465 | }, 466 | "raw-body": { 467 | "version": "2.4.0", 468 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 469 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 470 | "requires": { 471 | "bytes": "3.1.0", 472 | "http-errors": "1.7.2", 473 | "iconv-lite": "0.4.24", 474 | "unpipe": "1.0.0" 475 | } 476 | }, 477 | "readable-stream": { 478 | "version": "2.3.7", 479 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 480 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 481 | "requires": { 482 | "core-util-is": "~1.0.0", 483 | "inherits": "~2.0.3", 484 | "isarray": "~1.0.0", 485 | "process-nextick-args": "~2.0.0", 486 | "safe-buffer": "~5.1.1", 487 | "string_decoder": "~1.1.1", 488 | "util-deprecate": "~1.0.1" 489 | } 490 | }, 491 | "reflect-metadata": { 492 | "version": "0.1.13", 493 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 494 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" 495 | }, 496 | "safe-buffer": { 497 | "version": "5.1.2", 498 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 499 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 500 | }, 501 | "safer-buffer": { 502 | "version": "2.1.2", 503 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 504 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 505 | }, 506 | "send": { 507 | "version": "0.17.1", 508 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 509 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 510 | "requires": { 511 | "debug": "2.6.9", 512 | "depd": "~1.1.2", 513 | "destroy": "~1.0.4", 514 | "encodeurl": "~1.0.2", 515 | "escape-html": "~1.0.3", 516 | "etag": "~1.8.1", 517 | "fresh": "0.5.2", 518 | "http-errors": "~1.7.2", 519 | "mime": "1.6.0", 520 | "ms": "2.1.1", 521 | "on-finished": "~2.3.0", 522 | "range-parser": "~1.2.1", 523 | "statuses": "~1.5.0" 524 | }, 525 | "dependencies": { 526 | "ms": { 527 | "version": "2.1.1", 528 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 529 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 530 | } 531 | } 532 | }, 533 | "serve-static": { 534 | "version": "1.14.1", 535 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 536 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 537 | "requires": { 538 | "encodeurl": "~1.0.2", 539 | "escape-html": "~1.0.3", 540 | "parseurl": "~1.3.3", 541 | "send": "0.17.1" 542 | } 543 | }, 544 | "setprototypeof": { 545 | "version": "1.1.1", 546 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 547 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 548 | }, 549 | "source-map": { 550 | "version": "0.6.1", 551 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 552 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 553 | }, 554 | "source-map-support": { 555 | "version": "0.5.19", 556 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 557 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 558 | "requires": { 559 | "buffer-from": "^1.0.0", 560 | "source-map": "^0.6.0" 561 | } 562 | }, 563 | "sqlstring": { 564 | "version": "2.3.1", 565 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", 566 | "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" 567 | }, 568 | "statuses": { 569 | "version": "1.5.0", 570 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 571 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 572 | }, 573 | "string_decoder": { 574 | "version": "1.1.1", 575 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 576 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 577 | "requires": { 578 | "safe-buffer": "~5.1.0" 579 | } 580 | }, 581 | "tdigest": { 582 | "version": "0.1.1", 583 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 584 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 585 | "dev": true, 586 | "requires": { 587 | "bintrees": "1.0.1" 588 | } 589 | }, 590 | "toidentifier": { 591 | "version": "1.0.0", 592 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 593 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 594 | }, 595 | "ts-node": { 596 | "version": "9.1.1", 597 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", 598 | "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", 599 | "requires": { 600 | "arg": "^4.1.0", 601 | "create-require": "^1.1.0", 602 | "diff": "^4.0.1", 603 | "make-error": "^1.1.1", 604 | "source-map-support": "^0.5.17", 605 | "yn": "3.1.1" 606 | } 607 | }, 608 | "type-is": { 609 | "version": "1.6.18", 610 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 611 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 612 | "requires": { 613 | "media-typer": "0.3.0", 614 | "mime-types": "~2.1.24" 615 | } 616 | }, 617 | "typescript": { 618 | "version": "4.3.2", 619 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 620 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" 621 | }, 622 | "unpipe": { 623 | "version": "1.0.0", 624 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 625 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 626 | }, 627 | "util-deprecate": { 628 | "version": "1.0.2", 629 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 630 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 631 | }, 632 | "utils-merge": { 633 | "version": "1.0.1", 634 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 635 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 636 | }, 637 | "vary": { 638 | "version": "1.1.2", 639 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 640 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 641 | }, 642 | "yn": { 643 | "version": "3.1.1", 644 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 645 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 646 | } 647 | } 648 | } 649 | -------------------------------------------------------------------------------- /clean-architecture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": { 6 | "name": "Carlos Bastos Pérez-Cuadrado", 7 | "email": "carlosbastospc@gmail.com", 8 | "url": "http://www.cbastos.com/" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.21.1", 12 | "express": "^4.17.1", 13 | "inversify": "^5.1.1", 14 | "mysql": "^2.18.1", 15 | "reflect-metadata": "^0.1.13", 16 | "ts-node": "^9.1.1", 17 | "typescript": "^4.3.2" 18 | }, 19 | "scripts": { 20 | "start": "ts-node ./main.ts" 21 | }, 22 | "devDependencies": { 23 | "@types/express": "^4.17.11", 24 | "@types/jaeger-client": "^3.15.4", 25 | "@types/mysql": "^2.15.17", 26 | "@types/node": "^14.14.16" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /clean-architecture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "lib": ["es6", "dom"], 11 | "resolveJsonModule": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "types": ["node"], 15 | "typeRoots" : ["./node_modules/@types"] 16 | }, 17 | "include": [ 18 | "**/*.ts", 19 | "node_modules/@types" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } -------------------------------------------------------------------------------- /hexagonal-architecture/Application/PaddleCourts.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubRepository } from "./ports/SportsClubRepository"; 2 | import { Weather } from "./ports/Weather"; 3 | 4 | export class PaddleCourts { 5 | constructor( 6 | private weather: Weather, 7 | private sportsClubRepository: SportsClubRepository 8 | ) { } 9 | 10 | async getAvailables(): Promise> { 11 | const sportsClubPaddleCourts = await this.sportsClubRepository.getAllPaddleCourts(); 12 | const availablePaddleCourts = []; 13 | for (let paddelCourt of sportsClubPaddleCourts) { 14 | const isRainingInPaddelCourt = await this.weather.isRainingIn(paddelCourt.city); 15 | if (!isRainingInPaddelCourt) { 16 | availablePaddleCourts.push(paddelCourt); 17 | } 18 | } 19 | return availablePaddleCourts; 20 | } 21 | } 22 | 23 | export class PaddleCourt { 24 | number: number; 25 | } 26 | -------------------------------------------------------------------------------- /hexagonal-architecture/Application/SportsClub.ts: -------------------------------------------------------------------------------- 1 | import { PaddleCourts } from "./PaddleCourts"; 2 | import { SportsClubUserInterface } from "./ports/SportsClubUserInterface"; 3 | 4 | export class SportsClub { 5 | constructor( 6 | private userInterface: SportsClubUserInterface, 7 | private paddleCourts: PaddleCourts 8 | ) { } 9 | 10 | init() { 11 | this.userInterface.installGetAvailablePaddleCourts( 12 | () => this.paddleCourts.getAvailables() 13 | ); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /hexagonal-architecture/Application/adapters/SportsClubInMemoryRepository.ts: -------------------------------------------------------------------------------- 1 | 2 | import { PaddleCourt, SportsClubRepository } from "../ports/SportsClubRepository"; 3 | 4 | export class SportsClubInMemoryRepository implements SportsClubRepository{ 5 | getAllPaddleCourts(): Promise> { 6 | return Promise.resolve([ 7 | { number: 5, city: 'Madrid' }, 8 | { number: 1, city: 'Valencia' }, 9 | { number: 2, city: 'Madrid' } 10 | ]); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /hexagonal-architecture/Application/adapters/SportsClubWebApi.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { PaddleCourt } from '../PaddleCourts'; 3 | import { SportsClubUserInterface } from '../ports/SportsClubUserInterface'; 4 | 5 | export class SportsClubWebApiUserInterface implements SportsClubUserInterface { 6 | static PORT = 3000; 7 | constructor(private api = express()) { 8 | api.listen(SportsClubWebApiUserInterface.PORT, () => { 9 | console.log(`web api listening on port ${SportsClubWebApiUserInterface.PORT}`); 10 | }); 11 | } 12 | 13 | installGetAvailablePaddleCourts(getAvailablePaddleCourts: () => Promise): void { 14 | this.api.get('/api/paddle/courts', async (req, res) => { 15 | const availablePaddleCourts = await getAvailablePaddleCourts(); 16 | res.json(availablePaddleCourts); 17 | }); 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /hexagonal-architecture/Application/adapters/WeatherWebApi.ts: -------------------------------------------------------------------------------- 1 | import { Weather } from "../ports/Weather"; 2 | import { City } from "../ports/SportsClubRepository"; 3 | // import axios from 'axios'; 4 | 5 | export class WeatherWebApi implements Weather { 6 | isRainingIn(city: City): Promise { 7 | 8 | // HTTP call logic: await axios.get('https://weather.com/api/israining') 9 | return Promise.resolve(false); 10 | } 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /hexagonal-architecture/Application/ports/SportsClubRepository.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface SportsClubRepository { 3 | getAllPaddleCourts(): Promise>; 4 | } 5 | 6 | export class PaddleCourt { 7 | number: number; 8 | city: City; 9 | } 10 | 11 | export type City = 'Madrid' | 'Valencia'; -------------------------------------------------------------------------------- /hexagonal-architecture/Application/ports/SportsClubUserInterface.ts: -------------------------------------------------------------------------------- 1 | import { PaddleCourt } from "../PaddleCourts"; 2 | 3 | export interface SportsClubUserInterface { 4 | installGetAvailablePaddleCourts(callback: () => Promise): void; 5 | } -------------------------------------------------------------------------------- /hexagonal-architecture/Application/ports/Weather.ts: -------------------------------------------------------------------------------- 1 | import { City } from "./SportsClubRepository"; 2 | 3 | export interface Weather { 4 | isRainingIn(city: City): Promise; 5 | } -------------------------------------------------------------------------------- /hexagonal-architecture/README.md: -------------------------------------------------------------------------------- 1 | [Hexagonal architecture](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)) -------------------------------------------------------------------------------- /hexagonal-architecture/main.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubInMemoryRepository } from './Application/adapters/SportsClubInMemoryRepository'; 2 | import { SportsClubWebApiUserInterface } from './Application/adapters/SportsClubWebApi'; 3 | import { WeatherWebApi } from './Application/adapters/WeatherWebApi'; 4 | import { PaddleCourts } from './Application/PaddleCourts'; 5 | import { SportsClub } from './Application/SportsClub'; 6 | 7 | const sportsClub = new SportsClub( 8 | new SportsClubWebApiUserInterface(), 9 | new PaddleCourts( 10 | new WeatherWebApi(), 11 | new SportsClubInMemoryRepository() 12 | ) 13 | ); 14 | 15 | sportsClub.init(); -------------------------------------------------------------------------------- /hexagonal-architecture/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/body-parser": { 8 | "version": "1.19.0", 9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", 10 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", 11 | "dev": true, 12 | "requires": { 13 | "@types/connect": "*", 14 | "@types/node": "*" 15 | } 16 | }, 17 | "@types/connect": { 18 | "version": "3.4.34", 19 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", 20 | "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", 21 | "dev": true, 22 | "requires": { 23 | "@types/node": "*" 24 | } 25 | }, 26 | "@types/express": { 27 | "version": "4.17.12", 28 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", 29 | "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", 30 | "dev": true, 31 | "requires": { 32 | "@types/body-parser": "*", 33 | "@types/express-serve-static-core": "^4.17.18", 34 | "@types/qs": "*", 35 | "@types/serve-static": "*" 36 | } 37 | }, 38 | "@types/express-serve-static-core": { 39 | "version": "4.17.21", 40 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", 41 | "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", 42 | "dev": true, 43 | "requires": { 44 | "@types/node": "*", 45 | "@types/qs": "*", 46 | "@types/range-parser": "*" 47 | } 48 | }, 49 | "@types/jaeger-client": { 50 | "version": "3.18.0", 51 | "resolved": "https://registry.npmjs.org/@types/jaeger-client/-/jaeger-client-3.18.0.tgz", 52 | "integrity": "sha512-RbQvsCpapGqnuC4jVycOH/AthHr9Ze5hzbjdHclVRta29rsrA/0iHVJCsNi+nQ/iGJ3r6bQSJjp7uE29Xd+EdA==", 53 | "dev": true, 54 | "requires": { 55 | "@types/node": "*", 56 | "opentracing": "~0.14.3", 57 | "prom-client": "~11.3.0 || ^12.0.0 || ^13.0.0" 58 | } 59 | }, 60 | "@types/mime": { 61 | "version": "1.3.2", 62 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 63 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 64 | "dev": true 65 | }, 66 | "@types/mysql": { 67 | "version": "2.15.18", 68 | "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz", 69 | "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==", 70 | "dev": true, 71 | "requires": { 72 | "@types/node": "*" 73 | } 74 | }, 75 | "@types/node": { 76 | "version": "14.17.2", 77 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", 78 | "integrity": "sha512-sld7b/xmFum66AAKuz/rp/CUO8+98fMpyQ3SBfzzBNGMd/1iHBTAg9oyAvcYlAj46bpc74r91jSw2iFdnx29nw==", 79 | "dev": true 80 | }, 81 | "@types/qs": { 82 | "version": "6.9.6", 83 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", 84 | "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", 85 | "dev": true 86 | }, 87 | "@types/range-parser": { 88 | "version": "1.2.3", 89 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 90 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", 91 | "dev": true 92 | }, 93 | "@types/serve-static": { 94 | "version": "1.13.9", 95 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", 96 | "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", 97 | "dev": true, 98 | "requires": { 99 | "@types/mime": "^1", 100 | "@types/node": "*" 101 | } 102 | }, 103 | "accepts": { 104 | "version": "1.3.7", 105 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 106 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 107 | "requires": { 108 | "mime-types": "~2.1.24", 109 | "negotiator": "0.6.2" 110 | } 111 | }, 112 | "arg": { 113 | "version": "4.1.3", 114 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 115 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 116 | }, 117 | "array-flatten": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 120 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 121 | }, 122 | "axios": { 123 | "version": "0.21.1", 124 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 125 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 126 | "requires": { 127 | "follow-redirects": "^1.10.0" 128 | } 129 | }, 130 | "bignumber.js": { 131 | "version": "9.0.0", 132 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", 133 | "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" 134 | }, 135 | "bintrees": { 136 | "version": "1.0.1", 137 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 138 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=", 139 | "dev": true 140 | }, 141 | "body-parser": { 142 | "version": "1.19.0", 143 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 144 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 145 | "requires": { 146 | "bytes": "3.1.0", 147 | "content-type": "~1.0.4", 148 | "debug": "2.6.9", 149 | "depd": "~1.1.2", 150 | "http-errors": "1.7.2", 151 | "iconv-lite": "0.4.24", 152 | "on-finished": "~2.3.0", 153 | "qs": "6.7.0", 154 | "raw-body": "2.4.0", 155 | "type-is": "~1.6.17" 156 | } 157 | }, 158 | "buffer-from": { 159 | "version": "1.1.1", 160 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 161 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 162 | }, 163 | "bytes": { 164 | "version": "3.1.0", 165 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 166 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 167 | }, 168 | "content-disposition": { 169 | "version": "0.5.3", 170 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 171 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 172 | "requires": { 173 | "safe-buffer": "5.1.2" 174 | } 175 | }, 176 | "content-type": { 177 | "version": "1.0.4", 178 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 179 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 180 | }, 181 | "cookie": { 182 | "version": "0.4.0", 183 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 184 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 185 | }, 186 | "cookie-signature": { 187 | "version": "1.0.6", 188 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 189 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 190 | }, 191 | "core-util-is": { 192 | "version": "1.0.2", 193 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 194 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 195 | }, 196 | "create-require": { 197 | "version": "1.1.1", 198 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 199 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 200 | }, 201 | "debug": { 202 | "version": "2.6.9", 203 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 204 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 205 | "requires": { 206 | "ms": "2.0.0" 207 | } 208 | }, 209 | "depd": { 210 | "version": "1.1.2", 211 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 212 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 213 | }, 214 | "destroy": { 215 | "version": "1.0.4", 216 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 217 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 218 | }, 219 | "diff": { 220 | "version": "4.0.2", 221 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 222 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 223 | }, 224 | "ee-first": { 225 | "version": "1.1.1", 226 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 227 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 228 | }, 229 | "encodeurl": { 230 | "version": "1.0.2", 231 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 232 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 233 | }, 234 | "escape-html": { 235 | "version": "1.0.3", 236 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 237 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 238 | }, 239 | "etag": { 240 | "version": "1.8.1", 241 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 242 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 243 | }, 244 | "express": { 245 | "version": "4.17.1", 246 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 247 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 248 | "requires": { 249 | "accepts": "~1.3.7", 250 | "array-flatten": "1.1.1", 251 | "body-parser": "1.19.0", 252 | "content-disposition": "0.5.3", 253 | "content-type": "~1.0.4", 254 | "cookie": "0.4.0", 255 | "cookie-signature": "1.0.6", 256 | "debug": "2.6.9", 257 | "depd": "~1.1.2", 258 | "encodeurl": "~1.0.2", 259 | "escape-html": "~1.0.3", 260 | "etag": "~1.8.1", 261 | "finalhandler": "~1.1.2", 262 | "fresh": "0.5.2", 263 | "merge-descriptors": "1.0.1", 264 | "methods": "~1.1.2", 265 | "on-finished": "~2.3.0", 266 | "parseurl": "~1.3.3", 267 | "path-to-regexp": "0.1.7", 268 | "proxy-addr": "~2.0.5", 269 | "qs": "6.7.0", 270 | "range-parser": "~1.2.1", 271 | "safe-buffer": "5.1.2", 272 | "send": "0.17.1", 273 | "serve-static": "1.14.1", 274 | "setprototypeof": "1.1.1", 275 | "statuses": "~1.5.0", 276 | "type-is": "~1.6.18", 277 | "utils-merge": "1.0.1", 278 | "vary": "~1.1.2" 279 | } 280 | }, 281 | "finalhandler": { 282 | "version": "1.1.2", 283 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 284 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 285 | "requires": { 286 | "debug": "2.6.9", 287 | "encodeurl": "~1.0.2", 288 | "escape-html": "~1.0.3", 289 | "on-finished": "~2.3.0", 290 | "parseurl": "~1.3.3", 291 | "statuses": "~1.5.0", 292 | "unpipe": "~1.0.0" 293 | } 294 | }, 295 | "follow-redirects": { 296 | "version": "1.14.1", 297 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", 298 | "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" 299 | }, 300 | "forwarded": { 301 | "version": "0.2.0", 302 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 303 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 304 | }, 305 | "fresh": { 306 | "version": "0.5.2", 307 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 308 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 309 | }, 310 | "http-errors": { 311 | "version": "1.7.2", 312 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 313 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 314 | "requires": { 315 | "depd": "~1.1.2", 316 | "inherits": "2.0.3", 317 | "setprototypeof": "1.1.1", 318 | "statuses": ">= 1.5.0 < 2", 319 | "toidentifier": "1.0.0" 320 | } 321 | }, 322 | "iconv-lite": { 323 | "version": "0.4.24", 324 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 325 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 326 | "requires": { 327 | "safer-buffer": ">= 2.1.2 < 3" 328 | } 329 | }, 330 | "inherits": { 331 | "version": "2.0.3", 332 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 333 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 334 | }, 335 | "ipaddr.js": { 336 | "version": "1.9.1", 337 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 338 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 339 | }, 340 | "isarray": { 341 | "version": "1.0.0", 342 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 343 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 344 | }, 345 | "make-error": { 346 | "version": "1.3.6", 347 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 348 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 349 | }, 350 | "media-typer": { 351 | "version": "0.3.0", 352 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 353 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 354 | }, 355 | "merge-descriptors": { 356 | "version": "1.0.1", 357 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 358 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 359 | }, 360 | "methods": { 361 | "version": "1.1.2", 362 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 363 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 364 | }, 365 | "mime": { 366 | "version": "1.6.0", 367 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 368 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 369 | }, 370 | "mime-db": { 371 | "version": "1.48.0", 372 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 373 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 374 | }, 375 | "mime-types": { 376 | "version": "2.1.31", 377 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 378 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 379 | "requires": { 380 | "mime-db": "1.48.0" 381 | } 382 | }, 383 | "ms": { 384 | "version": "2.0.0", 385 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 386 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 387 | }, 388 | "mysql": { 389 | "version": "2.18.1", 390 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", 391 | "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", 392 | "requires": { 393 | "bignumber.js": "9.0.0", 394 | "readable-stream": "2.3.7", 395 | "safe-buffer": "5.1.2", 396 | "sqlstring": "2.3.1" 397 | } 398 | }, 399 | "negotiator": { 400 | "version": "0.6.2", 401 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 402 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 403 | }, 404 | "on-finished": { 405 | "version": "2.3.0", 406 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 407 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 408 | "requires": { 409 | "ee-first": "1.1.1" 410 | } 411 | }, 412 | "opentracing": { 413 | "version": "0.14.5", 414 | "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.5.tgz", 415 | "integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg==", 416 | "dev": true 417 | }, 418 | "parseurl": { 419 | "version": "1.3.3", 420 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 421 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 422 | }, 423 | "path-to-regexp": { 424 | "version": "0.1.7", 425 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 426 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 427 | }, 428 | "process-nextick-args": { 429 | "version": "2.0.1", 430 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 431 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 432 | }, 433 | "prom-client": { 434 | "version": "13.1.0", 435 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", 436 | "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", 437 | "dev": true, 438 | "requires": { 439 | "tdigest": "^0.1.1" 440 | } 441 | }, 442 | "proxy-addr": { 443 | "version": "2.0.7", 444 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 445 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 446 | "requires": { 447 | "forwarded": "0.2.0", 448 | "ipaddr.js": "1.9.1" 449 | } 450 | }, 451 | "qs": { 452 | "version": "6.7.0", 453 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 454 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 455 | }, 456 | "range-parser": { 457 | "version": "1.2.1", 458 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 459 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 460 | }, 461 | "raw-body": { 462 | "version": "2.4.0", 463 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 464 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 465 | "requires": { 466 | "bytes": "3.1.0", 467 | "http-errors": "1.7.2", 468 | "iconv-lite": "0.4.24", 469 | "unpipe": "1.0.0" 470 | } 471 | }, 472 | "readable-stream": { 473 | "version": "2.3.7", 474 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 475 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 476 | "requires": { 477 | "core-util-is": "~1.0.0", 478 | "inherits": "~2.0.3", 479 | "isarray": "~1.0.0", 480 | "process-nextick-args": "~2.0.0", 481 | "safe-buffer": "~5.1.1", 482 | "string_decoder": "~1.1.1", 483 | "util-deprecate": "~1.0.1" 484 | } 485 | }, 486 | "safe-buffer": { 487 | "version": "5.1.2", 488 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 489 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 490 | }, 491 | "safer-buffer": { 492 | "version": "2.1.2", 493 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 494 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 495 | }, 496 | "send": { 497 | "version": "0.17.1", 498 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 499 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 500 | "requires": { 501 | "debug": "2.6.9", 502 | "depd": "~1.1.2", 503 | "destroy": "~1.0.4", 504 | "encodeurl": "~1.0.2", 505 | "escape-html": "~1.0.3", 506 | "etag": "~1.8.1", 507 | "fresh": "0.5.2", 508 | "http-errors": "~1.7.2", 509 | "mime": "1.6.0", 510 | "ms": "2.1.1", 511 | "on-finished": "~2.3.0", 512 | "range-parser": "~1.2.1", 513 | "statuses": "~1.5.0" 514 | }, 515 | "dependencies": { 516 | "ms": { 517 | "version": "2.1.1", 518 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 519 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 520 | } 521 | } 522 | }, 523 | "serve-static": { 524 | "version": "1.14.1", 525 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 526 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 527 | "requires": { 528 | "encodeurl": "~1.0.2", 529 | "escape-html": "~1.0.3", 530 | "parseurl": "~1.3.3", 531 | "send": "0.17.1" 532 | } 533 | }, 534 | "setprototypeof": { 535 | "version": "1.1.1", 536 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 537 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 538 | }, 539 | "source-map": { 540 | "version": "0.6.1", 541 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 542 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 543 | }, 544 | "source-map-support": { 545 | "version": "0.5.19", 546 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 547 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 548 | "requires": { 549 | "buffer-from": "^1.0.0", 550 | "source-map": "^0.6.0" 551 | } 552 | }, 553 | "sqlstring": { 554 | "version": "2.3.1", 555 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", 556 | "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" 557 | }, 558 | "statuses": { 559 | "version": "1.5.0", 560 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 561 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 562 | }, 563 | "string_decoder": { 564 | "version": "1.1.1", 565 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 566 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 567 | "requires": { 568 | "safe-buffer": "~5.1.0" 569 | } 570 | }, 571 | "tdigest": { 572 | "version": "0.1.1", 573 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 574 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 575 | "dev": true, 576 | "requires": { 577 | "bintrees": "1.0.1" 578 | } 579 | }, 580 | "toidentifier": { 581 | "version": "1.0.0", 582 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 583 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 584 | }, 585 | "ts-node": { 586 | "version": "9.1.1", 587 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", 588 | "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", 589 | "requires": { 590 | "arg": "^4.1.0", 591 | "create-require": "^1.1.0", 592 | "diff": "^4.0.1", 593 | "make-error": "^1.1.1", 594 | "source-map-support": "^0.5.17", 595 | "yn": "3.1.1" 596 | } 597 | }, 598 | "type-is": { 599 | "version": "1.6.18", 600 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 601 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 602 | "requires": { 603 | "media-typer": "0.3.0", 604 | "mime-types": "~2.1.24" 605 | } 606 | }, 607 | "typescript": { 608 | "version": "4.3.2", 609 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 610 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" 611 | }, 612 | "unpipe": { 613 | "version": "1.0.0", 614 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 615 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 616 | }, 617 | "util-deprecate": { 618 | "version": "1.0.2", 619 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 620 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 621 | }, 622 | "utils-merge": { 623 | "version": "1.0.1", 624 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 625 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 626 | }, 627 | "vary": { 628 | "version": "1.1.2", 629 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 630 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 631 | }, 632 | "yn": { 633 | "version": "3.1.1", 634 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 635 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 636 | } 637 | } 638 | } 639 | -------------------------------------------------------------------------------- /hexagonal-architecture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": { 6 | "name": "Carlos Bastos Pérez-Cuadrado", 7 | "email": "carlosbastospc@gmail.com", 8 | "url": "http://www.cbastos.com/" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.21.1", 12 | "express": "^4.17.1", 13 | "mysql": "^2.18.1", 14 | "ts-node": "^9.1.1", 15 | "typescript": "^4.3.2" 16 | }, 17 | "scripts": { 18 | "start": "ts-node ./main.ts" 19 | }, 20 | "devDependencies": { 21 | "@types/express": "^4.17.11", 22 | "@types/jaeger-client": "^3.15.4", 23 | "@types/mysql": "^2.15.17", 24 | "@types/node": "^14.14.16" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /hexagonal-architecture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "lib": ["es6", "dom"], 11 | "resolveJsonModule": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "types": ["node"], 15 | "typeRoots" : ["./node_modules/@types"] 16 | }, 17 | "include": [ 18 | "**/*.ts", 19 | "node_modules/@types" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } -------------------------------------------------------------------------------- /onion-architecture/1. DomainModel/City.ts: -------------------------------------------------------------------------------- 1 | export type City = 'Madrid' | 'Valencia'; -------------------------------------------------------------------------------- /onion-architecture/1. DomainModel/PaddleCourt.ts: -------------------------------------------------------------------------------- 1 | import { City } from "./City"; 2 | 3 | export class PaddleCourt { 4 | number: number; 5 | city: City 6 | } -------------------------------------------------------------------------------- /onion-architecture/2. DomainServices/SportsClubRepository.ts: -------------------------------------------------------------------------------- 1 | import { PaddleCourt } from "../1. DomainModel/PaddleCourt"; 2 | 3 | export interface SportsClubRepository { 4 | getAllPaddleCourts(): Promise>; 5 | } 6 | 7 | -------------------------------------------------------------------------------- /onion-architecture/3. ApplicationServices/PaddleCourts.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubRepository } from "../2. DomainServices/SportsClubRepository"; 2 | import { Weather } from "./Weather"; 3 | import { PaddleCourt } from "../1. DomainModel/PaddleCourt"; 4 | import { inject, injectable } from 'inversify'; 5 | import TYPES from "../container.types"; 6 | 7 | @injectable() 8 | export class PaddleCourts { 9 | constructor( 10 | @inject(TYPES.Weather) private weather: Weather, 11 | @inject(TYPES.SportsClubRepository) private sportsClubRepository: SportsClubRepository 12 | ) { } 13 | 14 | async getAvailables(): Promise> { 15 | const sportsClubPaddleCourts = await this.sportsClubRepository.getAllPaddleCourts(); 16 | const availablePaddleCourts = []; 17 | for (let paddelCourt of sportsClubPaddleCourts) { 18 | const isRainingInPaddelCourt = await this.weather.isRainingIn(paddelCourt.city); 19 | if (!isRainingInPaddelCourt) { 20 | availablePaddleCourts.push(paddelCourt); 21 | } 22 | } 23 | return availablePaddleCourts; 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /onion-architecture/3. ApplicationServices/Weather.ts: -------------------------------------------------------------------------------- 1 | import { City } from "../1. DomainModel/City"; 2 | 3 | export interface Weather { 4 | isRainingIn(city: City): Promise; 5 | } 6 | -------------------------------------------------------------------------------- /onion-architecture/4.A Infrastructure/SportsClubInMemoryRepository.ts: -------------------------------------------------------------------------------- 1 | 2 | import { PaddleCourt } from "../1. DomainModel/PaddleCourt"; 3 | import { SportsClubRepository } from "../2. DomainServices/SportsClubRepository"; 4 | import { injectable } from "inversify"; 5 | 6 | @injectable() 7 | export class SportsClubInMemoryRepository implements SportsClubRepository { 8 | getAllPaddleCourts(): Promise> { 9 | return Promise.resolve([ 10 | { number: 5, city: 'Madrid' }, 11 | { number: 1, city: 'Valencia' }, 12 | { number: 2, city: 'Madrid' } 13 | ]); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /onion-architecture/4.A Infrastructure/WeatherWebApiClient.ts: -------------------------------------------------------------------------------- 1 | import { Weather } from "../3. ApplicationServices/Weather"; 2 | import { City } from "../1. DomainModel/City"; 3 | // import axios from 'axios'; 4 | import { inject, injectable } from "inversify"; 5 | 6 | @injectable() 7 | export class WeatherWebApiClient implements Weather { 8 | isRainingIn(city: City): Promise { 9 | 10 | // HTTP call logic: await axios.get('https://weather.com/api/israining') 11 | return Promise.resolve(false); 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /onion-architecture/4.B UserInterface/SportsClubWebApi.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { inject, injectable } from 'inversify'; 3 | import { PaddleCourts } from '../3. ApplicationServices/PaddleCourts'; 4 | import TYPES from '../container.types'; 5 | 6 | @injectable() 7 | export class SportsClubWebApiUserInterface { 8 | static PORT = 3000; 9 | api = express(); 10 | 11 | constructor(@inject(TYPES.PaddleCourts) private paddleCourts: PaddleCourts) { } 12 | 13 | init() { 14 | this.api.get('/api/paddle/courts', async (req, res) => { 15 | const availablePaddleCourts = await this.paddleCourts.getAvailables(); 16 | res.json(availablePaddleCourts); 17 | }); 18 | this.api.listen(SportsClubWebApiUserInterface.PORT, () => { 19 | console.log(`web api listening on port ${SportsClubWebApiUserInterface.PORT}`); 20 | }); 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /onion-architecture/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbastos/web-api-microservice-architectures/27cb2ee9eb7a045c26f1a979c39c0e403c638e12/onion-architecture/README.md -------------------------------------------------------------------------------- /onion-architecture/container.ts: -------------------------------------------------------------------------------- 1 | import { Container } from 'inversify'; 2 | import { SportsClubRepository } from './2. DomainServices/SportsClubRepository'; 3 | import { PaddleCourts } from './3. ApplicationServices/PaddleCourts'; 4 | import { Weather } from './3. ApplicationServices/Weather'; 5 | import { SportsClubInMemoryRepository } from './4.A Infrastructure/SportsClubInMemoryRepository'; 6 | import { WeatherWebApiClient } from './4.A Infrastructure/WeatherWebApiClient'; 7 | import { SportsClubWebApiUserInterface } from './4.B UserInterface/SportsClubWebApi'; 8 | import TYPES from './container.types'; 9 | 10 | export const container = new Container(); 11 | container.bind(TYPES.PaddleCourts).to(PaddleCourts); 12 | container.bind(TYPES.Weather).to(WeatherWebApiClient); 13 | container.bind(TYPES.SportsClubUserInterface).to(SportsClubWebApiUserInterface); 14 | container.bind(TYPES.SportsClubRepository).to(SportsClubInMemoryRepository); 15 | -------------------------------------------------------------------------------- /onion-architecture/container.types.ts: -------------------------------------------------------------------------------- 1 | const TYPES = { 2 | PaddleCourts: Symbol('PaddleCourts'), 3 | SportsClubUserInterface: Symbol('SportsClubUserInterface'), 4 | SportsClubRepository: Symbol('SportsClubRepository'), 5 | SportsClub: Symbol('SportsClub'), 6 | Weather: Symbol('Weather') 7 | }; 8 | 9 | export default TYPES; -------------------------------------------------------------------------------- /onion-architecture/main.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import { SportsClubWebApiUserInterface } from './4.B UserInterface/SportsClubWebApi'; 3 | import { container } from './container'; 4 | import TYPES from './container.types'; 5 | 6 | container.get(TYPES.SportsClubUserInterface).init(); -------------------------------------------------------------------------------- /onion-architecture/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/body-parser": { 8 | "version": "1.19.0", 9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", 10 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", 11 | "dev": true, 12 | "requires": { 13 | "@types/connect": "*", 14 | "@types/node": "*" 15 | } 16 | }, 17 | "@types/connect": { 18 | "version": "3.4.34", 19 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", 20 | "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", 21 | "dev": true, 22 | "requires": { 23 | "@types/node": "*" 24 | } 25 | }, 26 | "@types/express": { 27 | "version": "4.17.12", 28 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", 29 | "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", 30 | "dev": true, 31 | "requires": { 32 | "@types/body-parser": "*", 33 | "@types/express-serve-static-core": "^4.17.18", 34 | "@types/qs": "*", 35 | "@types/serve-static": "*" 36 | } 37 | }, 38 | "@types/express-serve-static-core": { 39 | "version": "4.17.21", 40 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", 41 | "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", 42 | "dev": true, 43 | "requires": { 44 | "@types/node": "*", 45 | "@types/qs": "*", 46 | "@types/range-parser": "*" 47 | } 48 | }, 49 | "@types/jaeger-client": { 50 | "version": "3.18.0", 51 | "resolved": "https://registry.npmjs.org/@types/jaeger-client/-/jaeger-client-3.18.0.tgz", 52 | "integrity": "sha512-RbQvsCpapGqnuC4jVycOH/AthHr9Ze5hzbjdHclVRta29rsrA/0iHVJCsNi+nQ/iGJ3r6bQSJjp7uE29Xd+EdA==", 53 | "dev": true, 54 | "requires": { 55 | "@types/node": "*", 56 | "opentracing": "~0.14.3", 57 | "prom-client": "~11.3.0 || ^12.0.0 || ^13.0.0" 58 | } 59 | }, 60 | "@types/mime": { 61 | "version": "1.3.2", 62 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 63 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 64 | "dev": true 65 | }, 66 | "@types/mysql": { 67 | "version": "2.15.18", 68 | "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz", 69 | "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==", 70 | "dev": true, 71 | "requires": { 72 | "@types/node": "*" 73 | } 74 | }, 75 | "@types/node": { 76 | "version": "14.17.2", 77 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", 78 | "integrity": "sha512-sld7b/xmFum66AAKuz/rp/CUO8+98fMpyQ3SBfzzBNGMd/1iHBTAg9oyAvcYlAj46bpc74r91jSw2iFdnx29nw==", 79 | "dev": true 80 | }, 81 | "@types/qs": { 82 | "version": "6.9.6", 83 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", 84 | "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", 85 | "dev": true 86 | }, 87 | "@types/range-parser": { 88 | "version": "1.2.3", 89 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 90 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", 91 | "dev": true 92 | }, 93 | "@types/serve-static": { 94 | "version": "1.13.9", 95 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", 96 | "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", 97 | "dev": true, 98 | "requires": { 99 | "@types/mime": "^1", 100 | "@types/node": "*" 101 | } 102 | }, 103 | "accepts": { 104 | "version": "1.3.7", 105 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 106 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 107 | "requires": { 108 | "mime-types": "~2.1.24", 109 | "negotiator": "0.6.2" 110 | } 111 | }, 112 | "arg": { 113 | "version": "4.1.3", 114 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 115 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 116 | }, 117 | "array-flatten": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 120 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 121 | }, 122 | "axios": { 123 | "version": "0.21.1", 124 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 125 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 126 | "requires": { 127 | "follow-redirects": "^1.10.0" 128 | } 129 | }, 130 | "bignumber.js": { 131 | "version": "9.0.0", 132 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", 133 | "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" 134 | }, 135 | "bintrees": { 136 | "version": "1.0.1", 137 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 138 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=", 139 | "dev": true 140 | }, 141 | "body-parser": { 142 | "version": "1.19.0", 143 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 144 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 145 | "requires": { 146 | "bytes": "3.1.0", 147 | "content-type": "~1.0.4", 148 | "debug": "2.6.9", 149 | "depd": "~1.1.2", 150 | "http-errors": "1.7.2", 151 | "iconv-lite": "0.4.24", 152 | "on-finished": "~2.3.0", 153 | "qs": "6.7.0", 154 | "raw-body": "2.4.0", 155 | "type-is": "~1.6.17" 156 | } 157 | }, 158 | "buffer-from": { 159 | "version": "1.1.1", 160 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 161 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 162 | }, 163 | "bytes": { 164 | "version": "3.1.0", 165 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 166 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 167 | }, 168 | "content-disposition": { 169 | "version": "0.5.3", 170 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 171 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 172 | "requires": { 173 | "safe-buffer": "5.1.2" 174 | } 175 | }, 176 | "content-type": { 177 | "version": "1.0.4", 178 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 179 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 180 | }, 181 | "cookie": { 182 | "version": "0.4.0", 183 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 184 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 185 | }, 186 | "cookie-signature": { 187 | "version": "1.0.6", 188 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 189 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 190 | }, 191 | "core-util-is": { 192 | "version": "1.0.2", 193 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 194 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 195 | }, 196 | "create-require": { 197 | "version": "1.1.1", 198 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 199 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 200 | }, 201 | "debug": { 202 | "version": "2.6.9", 203 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 204 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 205 | "requires": { 206 | "ms": "2.0.0" 207 | } 208 | }, 209 | "depd": { 210 | "version": "1.1.2", 211 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 212 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 213 | }, 214 | "destroy": { 215 | "version": "1.0.4", 216 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 217 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 218 | }, 219 | "diff": { 220 | "version": "4.0.2", 221 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 222 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 223 | }, 224 | "ee-first": { 225 | "version": "1.1.1", 226 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 227 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 228 | }, 229 | "encodeurl": { 230 | "version": "1.0.2", 231 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 232 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 233 | }, 234 | "escape-html": { 235 | "version": "1.0.3", 236 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 237 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 238 | }, 239 | "etag": { 240 | "version": "1.8.1", 241 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 242 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 243 | }, 244 | "express": { 245 | "version": "4.17.1", 246 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 247 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 248 | "requires": { 249 | "accepts": "~1.3.7", 250 | "array-flatten": "1.1.1", 251 | "body-parser": "1.19.0", 252 | "content-disposition": "0.5.3", 253 | "content-type": "~1.0.4", 254 | "cookie": "0.4.0", 255 | "cookie-signature": "1.0.6", 256 | "debug": "2.6.9", 257 | "depd": "~1.1.2", 258 | "encodeurl": "~1.0.2", 259 | "escape-html": "~1.0.3", 260 | "etag": "~1.8.1", 261 | "finalhandler": "~1.1.2", 262 | "fresh": "0.5.2", 263 | "merge-descriptors": "1.0.1", 264 | "methods": "~1.1.2", 265 | "on-finished": "~2.3.0", 266 | "parseurl": "~1.3.3", 267 | "path-to-regexp": "0.1.7", 268 | "proxy-addr": "~2.0.5", 269 | "qs": "6.7.0", 270 | "range-parser": "~1.2.1", 271 | "safe-buffer": "5.1.2", 272 | "send": "0.17.1", 273 | "serve-static": "1.14.1", 274 | "setprototypeof": "1.1.1", 275 | "statuses": "~1.5.0", 276 | "type-is": "~1.6.18", 277 | "utils-merge": "1.0.1", 278 | "vary": "~1.1.2" 279 | } 280 | }, 281 | "finalhandler": { 282 | "version": "1.1.2", 283 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 284 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 285 | "requires": { 286 | "debug": "2.6.9", 287 | "encodeurl": "~1.0.2", 288 | "escape-html": "~1.0.3", 289 | "on-finished": "~2.3.0", 290 | "parseurl": "~1.3.3", 291 | "statuses": "~1.5.0", 292 | "unpipe": "~1.0.0" 293 | } 294 | }, 295 | "follow-redirects": { 296 | "version": "1.14.1", 297 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", 298 | "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" 299 | }, 300 | "forwarded": { 301 | "version": "0.2.0", 302 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 303 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 304 | }, 305 | "fresh": { 306 | "version": "0.5.2", 307 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 308 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 309 | }, 310 | "http-errors": { 311 | "version": "1.7.2", 312 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 313 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 314 | "requires": { 315 | "depd": "~1.1.2", 316 | "inherits": "2.0.3", 317 | "setprototypeof": "1.1.1", 318 | "statuses": ">= 1.5.0 < 2", 319 | "toidentifier": "1.0.0" 320 | } 321 | }, 322 | "iconv-lite": { 323 | "version": "0.4.24", 324 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 325 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 326 | "requires": { 327 | "safer-buffer": ">= 2.1.2 < 3" 328 | } 329 | }, 330 | "inherits": { 331 | "version": "2.0.3", 332 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 333 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 334 | }, 335 | "inversify": { 336 | "version": "5.1.1", 337 | "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.1.1.tgz", 338 | "integrity": "sha512-j8grHGDzv1v+8T1sAQ+3boTCntFPfvxLCkNcxB1J8qA0lUN+fAlSyYd+RXKvaPRL4AGyPxViutBEJHNXOyUdFQ==" 339 | }, 340 | "ipaddr.js": { 341 | "version": "1.9.1", 342 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 343 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 344 | }, 345 | "isarray": { 346 | "version": "1.0.0", 347 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 348 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 349 | }, 350 | "make-error": { 351 | "version": "1.3.6", 352 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 353 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 354 | }, 355 | "media-typer": { 356 | "version": "0.3.0", 357 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 358 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 359 | }, 360 | "merge-descriptors": { 361 | "version": "1.0.1", 362 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 363 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 364 | }, 365 | "methods": { 366 | "version": "1.1.2", 367 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 368 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 369 | }, 370 | "mime": { 371 | "version": "1.6.0", 372 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 373 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 374 | }, 375 | "mime-db": { 376 | "version": "1.48.0", 377 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 378 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 379 | }, 380 | "mime-types": { 381 | "version": "2.1.31", 382 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 383 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 384 | "requires": { 385 | "mime-db": "1.48.0" 386 | } 387 | }, 388 | "ms": { 389 | "version": "2.0.0", 390 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 391 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 392 | }, 393 | "mysql": { 394 | "version": "2.18.1", 395 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", 396 | "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", 397 | "requires": { 398 | "bignumber.js": "9.0.0", 399 | "readable-stream": "2.3.7", 400 | "safe-buffer": "5.1.2", 401 | "sqlstring": "2.3.1" 402 | } 403 | }, 404 | "negotiator": { 405 | "version": "0.6.2", 406 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 407 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 408 | }, 409 | "on-finished": { 410 | "version": "2.3.0", 411 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 412 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 413 | "requires": { 414 | "ee-first": "1.1.1" 415 | } 416 | }, 417 | "opentracing": { 418 | "version": "0.14.5", 419 | "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.5.tgz", 420 | "integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg==", 421 | "dev": true 422 | }, 423 | "parseurl": { 424 | "version": "1.3.3", 425 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 426 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 427 | }, 428 | "path-to-regexp": { 429 | "version": "0.1.7", 430 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 431 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 432 | }, 433 | "process-nextick-args": { 434 | "version": "2.0.1", 435 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 436 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 437 | }, 438 | "prom-client": { 439 | "version": "13.1.0", 440 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", 441 | "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", 442 | "dev": true, 443 | "requires": { 444 | "tdigest": "^0.1.1" 445 | } 446 | }, 447 | "proxy-addr": { 448 | "version": "2.0.7", 449 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 450 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 451 | "requires": { 452 | "forwarded": "0.2.0", 453 | "ipaddr.js": "1.9.1" 454 | } 455 | }, 456 | "qs": { 457 | "version": "6.7.0", 458 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 459 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 460 | }, 461 | "range-parser": { 462 | "version": "1.2.1", 463 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 464 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 465 | }, 466 | "raw-body": { 467 | "version": "2.4.0", 468 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 469 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 470 | "requires": { 471 | "bytes": "3.1.0", 472 | "http-errors": "1.7.2", 473 | "iconv-lite": "0.4.24", 474 | "unpipe": "1.0.0" 475 | } 476 | }, 477 | "readable-stream": { 478 | "version": "2.3.7", 479 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 480 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 481 | "requires": { 482 | "core-util-is": "~1.0.0", 483 | "inherits": "~2.0.3", 484 | "isarray": "~1.0.0", 485 | "process-nextick-args": "~2.0.0", 486 | "safe-buffer": "~5.1.1", 487 | "string_decoder": "~1.1.1", 488 | "util-deprecate": "~1.0.1" 489 | } 490 | }, 491 | "reflect-metadata": { 492 | "version": "0.1.13", 493 | "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", 494 | "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" 495 | }, 496 | "safe-buffer": { 497 | "version": "5.1.2", 498 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 499 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 500 | }, 501 | "safer-buffer": { 502 | "version": "2.1.2", 503 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 504 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 505 | }, 506 | "send": { 507 | "version": "0.17.1", 508 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 509 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 510 | "requires": { 511 | "debug": "2.6.9", 512 | "depd": "~1.1.2", 513 | "destroy": "~1.0.4", 514 | "encodeurl": "~1.0.2", 515 | "escape-html": "~1.0.3", 516 | "etag": "~1.8.1", 517 | "fresh": "0.5.2", 518 | "http-errors": "~1.7.2", 519 | "mime": "1.6.0", 520 | "ms": "2.1.1", 521 | "on-finished": "~2.3.0", 522 | "range-parser": "~1.2.1", 523 | "statuses": "~1.5.0" 524 | }, 525 | "dependencies": { 526 | "ms": { 527 | "version": "2.1.1", 528 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 529 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 530 | } 531 | } 532 | }, 533 | "serve-static": { 534 | "version": "1.14.1", 535 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 536 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 537 | "requires": { 538 | "encodeurl": "~1.0.2", 539 | "escape-html": "~1.0.3", 540 | "parseurl": "~1.3.3", 541 | "send": "0.17.1" 542 | } 543 | }, 544 | "setprototypeof": { 545 | "version": "1.1.1", 546 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 547 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 548 | }, 549 | "source-map": { 550 | "version": "0.6.1", 551 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 552 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 553 | }, 554 | "source-map-support": { 555 | "version": "0.5.19", 556 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 557 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 558 | "requires": { 559 | "buffer-from": "^1.0.0", 560 | "source-map": "^0.6.0" 561 | } 562 | }, 563 | "sqlstring": { 564 | "version": "2.3.1", 565 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", 566 | "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" 567 | }, 568 | "statuses": { 569 | "version": "1.5.0", 570 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 571 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 572 | }, 573 | "string_decoder": { 574 | "version": "1.1.1", 575 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 576 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 577 | "requires": { 578 | "safe-buffer": "~5.1.0" 579 | } 580 | }, 581 | "tdigest": { 582 | "version": "0.1.1", 583 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 584 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 585 | "dev": true, 586 | "requires": { 587 | "bintrees": "1.0.1" 588 | } 589 | }, 590 | "toidentifier": { 591 | "version": "1.0.0", 592 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 593 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 594 | }, 595 | "ts-node": { 596 | "version": "9.1.1", 597 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", 598 | "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", 599 | "requires": { 600 | "arg": "^4.1.0", 601 | "create-require": "^1.1.0", 602 | "diff": "^4.0.1", 603 | "make-error": "^1.1.1", 604 | "source-map-support": "^0.5.17", 605 | "yn": "3.1.1" 606 | } 607 | }, 608 | "type-is": { 609 | "version": "1.6.18", 610 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 611 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 612 | "requires": { 613 | "media-typer": "0.3.0", 614 | "mime-types": "~2.1.24" 615 | } 616 | }, 617 | "typescript": { 618 | "version": "4.3.2", 619 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 620 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" 621 | }, 622 | "unpipe": { 623 | "version": "1.0.0", 624 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 625 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 626 | }, 627 | "util-deprecate": { 628 | "version": "1.0.2", 629 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 630 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 631 | }, 632 | "utils-merge": { 633 | "version": "1.0.1", 634 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 635 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 636 | }, 637 | "vary": { 638 | "version": "1.1.2", 639 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 640 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 641 | }, 642 | "yn": { 643 | "version": "3.1.1", 644 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 645 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 646 | } 647 | } 648 | } 649 | -------------------------------------------------------------------------------- /onion-architecture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": { 6 | "name": "Carlos Bastos Pérez-Cuadrado", 7 | "email": "carlosbastospc@gmail.com", 8 | "url": "http://www.cbastos.com/" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.21.1", 12 | "express": "^4.17.1", 13 | "inversify": "^5.1.1", 14 | "mysql": "^2.18.1", 15 | "reflect-metadata": "^0.1.13", 16 | "ts-node": "^9.1.1", 17 | "typescript": "^4.3.2" 18 | }, 19 | "scripts": { 20 | "start": "ts-node ./main.ts" 21 | }, 22 | "devDependencies": { 23 | "@types/express": "^4.17.11", 24 | "@types/jaeger-client": "^3.15.4", 25 | "@types/mysql": "^2.15.17", 26 | "@types/node": "^14.14.16" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /onion-architecture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "lib": ["es6", "dom"], 11 | "resolveJsonModule": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "types": ["node"], 15 | "typeRoots" : ["./node_modules/@types"] 16 | }, 17 | "include": [ 18 | "**/*.ts", 19 | "node_modules/@types" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } -------------------------------------------------------------------------------- /three-layer-architecture/1. Presentation/SportsClubWebApi.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import { PaddleCourts } from '../2. Business Logic/PaddleCourts'; 3 | 4 | export class SportsClubWebApi { 5 | static PORT = 3000; 6 | 7 | constructor( 8 | private paddleCourts = new PaddleCourts() 9 | ) { } 10 | 11 | init(): Promise { 12 | return new Promise((resolve) => { 13 | const api = express(); 14 | 15 | api.get('/api/paddle/courts', async (req, res) => { 16 | const availablePaddleCourts = await this.paddleCourts.getAvailables(); 17 | res.json(availablePaddleCourts); 18 | }); 19 | 20 | api.listen(SportsClubWebApi.PORT, () => { 21 | console.log(`web api listening on port ${SportsClubWebApi.PORT}`); 22 | resolve(); 23 | }); 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /three-layer-architecture/2. Business Logic/PaddleCourts.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubRepository } from "../3. Data Access/SportsClubRepository"; 2 | import { Weather } from "./Weather"; 3 | 4 | export class PaddleCourts { 5 | constructor( 6 | private weather = new Weather(), 7 | private sportsClubRepository = new SportsClubRepository() 8 | ) { } 9 | 10 | async getAvailables(): Promise> { 11 | const sportsClubPaddleCourts = await this.sportsClubRepository.getAllPaddleCourts(); 12 | const availablePaddleCourts = []; 13 | for (let paddelCourt of sportsClubPaddleCourts){ 14 | const isRainingInPaddelCourt = await this.weather.isRainingIn(paddelCourt.city); 15 | if(!isRainingInPaddelCourt){ 16 | availablePaddleCourts.push(paddelCourt); 17 | } 18 | } 19 | return availablePaddleCourts; 20 | } 21 | } 22 | 23 | class PaddleCourt { 24 | number: number; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /three-layer-architecture/2. Business Logic/Weather.ts: -------------------------------------------------------------------------------- 1 | import { City } from "../3. Data Access/SportsClubRepository"; 2 | // import axios from 'axios'; 3 | 4 | export class Weather { 5 | isRainingIn(city: City): Promise { 6 | 7 | // HTTP call logic: await axios.get('https://weather.com/api/israining') 8 | return Promise.resolve(false); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /three-layer-architecture/3. Data Access/SportsClubRepository.ts: -------------------------------------------------------------------------------- 1 | export class SportsClubRepository { 2 | getAllPaddleCourts(): Promise> { 3 | return Promise.resolve([ 4 | { number: 5, city: 'Madrid' }, 5 | { number: 1, city: 'Valencia' }, 6 | { number: 2, city: 'Madrid' } 7 | ]); 8 | } 9 | } 10 | 11 | class PaddleCourt { 12 | number: number; 13 | city: City; 14 | } 15 | 16 | export type City = 'Madrid' | 'Valencia'; -------------------------------------------------------------------------------- /three-layer-architecture/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cbastos/web-api-microservice-architectures/27cb2ee9eb7a045c26f1a979c39c0e403c638e12/three-layer-architecture/README.md -------------------------------------------------------------------------------- /three-layer-architecture/main.ts: -------------------------------------------------------------------------------- 1 | import { SportsClubWebApi } from './1. Presentation/SportsClubWebApi'; 2 | 3 | const sportsClubWebApi = new SportsClubWebApi(); 4 | sportsClubWebApi.init(); -------------------------------------------------------------------------------- /three-layer-architecture/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/body-parser": { 8 | "version": "1.19.0", 9 | "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", 10 | "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", 11 | "dev": true, 12 | "requires": { 13 | "@types/connect": "*", 14 | "@types/node": "*" 15 | } 16 | }, 17 | "@types/connect": { 18 | "version": "3.4.34", 19 | "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", 20 | "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", 21 | "dev": true, 22 | "requires": { 23 | "@types/node": "*" 24 | } 25 | }, 26 | "@types/express": { 27 | "version": "4.17.12", 28 | "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", 29 | "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", 30 | "dev": true, 31 | "requires": { 32 | "@types/body-parser": "*", 33 | "@types/express-serve-static-core": "^4.17.18", 34 | "@types/qs": "*", 35 | "@types/serve-static": "*" 36 | } 37 | }, 38 | "@types/express-serve-static-core": { 39 | "version": "4.17.21", 40 | "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", 41 | "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", 42 | "dev": true, 43 | "requires": { 44 | "@types/node": "*", 45 | "@types/qs": "*", 46 | "@types/range-parser": "*" 47 | } 48 | }, 49 | "@types/jaeger-client": { 50 | "version": "3.18.0", 51 | "resolved": "https://registry.npmjs.org/@types/jaeger-client/-/jaeger-client-3.18.0.tgz", 52 | "integrity": "sha512-RbQvsCpapGqnuC4jVycOH/AthHr9Ze5hzbjdHclVRta29rsrA/0iHVJCsNi+nQ/iGJ3r6bQSJjp7uE29Xd+EdA==", 53 | "dev": true, 54 | "requires": { 55 | "@types/node": "*", 56 | "opentracing": "~0.14.3", 57 | "prom-client": "~11.3.0 || ^12.0.0 || ^13.0.0" 58 | } 59 | }, 60 | "@types/mime": { 61 | "version": "1.3.2", 62 | "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", 63 | "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", 64 | "dev": true 65 | }, 66 | "@types/mysql": { 67 | "version": "2.15.18", 68 | "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.18.tgz", 69 | "integrity": "sha512-JW74Nh3P/RDAnaP8uXe1qmRpoFBO84SiWvWoSju/F5+2S1kVBi1FbbDoqK/sTZrCCxySaOJnRATvWD+bLcJjAg==", 70 | "dev": true, 71 | "requires": { 72 | "@types/node": "*" 73 | } 74 | }, 75 | "@types/node": { 76 | "version": "14.17.2", 77 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.2.tgz", 78 | "integrity": "sha512-sld7b/xmFum66AAKuz/rp/CUO8+98fMpyQ3SBfzzBNGMd/1iHBTAg9oyAvcYlAj46bpc74r91jSw2iFdnx29nw==", 79 | "dev": true 80 | }, 81 | "@types/qs": { 82 | "version": "6.9.6", 83 | "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", 84 | "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", 85 | "dev": true 86 | }, 87 | "@types/range-parser": { 88 | "version": "1.2.3", 89 | "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", 90 | "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", 91 | "dev": true 92 | }, 93 | "@types/serve-static": { 94 | "version": "1.13.9", 95 | "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", 96 | "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", 97 | "dev": true, 98 | "requires": { 99 | "@types/mime": "^1", 100 | "@types/node": "*" 101 | } 102 | }, 103 | "accepts": { 104 | "version": "1.3.7", 105 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 106 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", 107 | "requires": { 108 | "mime-types": "~2.1.24", 109 | "negotiator": "0.6.2" 110 | } 111 | }, 112 | "arg": { 113 | "version": "4.1.3", 114 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 115 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" 116 | }, 117 | "array-flatten": { 118 | "version": "1.1.1", 119 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 120 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 121 | }, 122 | "axios": { 123 | "version": "0.21.1", 124 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", 125 | "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", 126 | "requires": { 127 | "follow-redirects": "^1.10.0" 128 | } 129 | }, 130 | "bignumber.js": { 131 | "version": "9.0.0", 132 | "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", 133 | "integrity": "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==" 134 | }, 135 | "bintrees": { 136 | "version": "1.0.1", 137 | "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", 138 | "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=", 139 | "dev": true 140 | }, 141 | "body-parser": { 142 | "version": "1.19.0", 143 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", 144 | "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", 145 | "requires": { 146 | "bytes": "3.1.0", 147 | "content-type": "~1.0.4", 148 | "debug": "2.6.9", 149 | "depd": "~1.1.2", 150 | "http-errors": "1.7.2", 151 | "iconv-lite": "0.4.24", 152 | "on-finished": "~2.3.0", 153 | "qs": "6.7.0", 154 | "raw-body": "2.4.0", 155 | "type-is": "~1.6.17" 156 | } 157 | }, 158 | "buffer-from": { 159 | "version": "1.1.1", 160 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 161 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" 162 | }, 163 | "bytes": { 164 | "version": "3.1.0", 165 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", 166 | "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" 167 | }, 168 | "content-disposition": { 169 | "version": "0.5.3", 170 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", 171 | "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", 172 | "requires": { 173 | "safe-buffer": "5.1.2" 174 | } 175 | }, 176 | "content-type": { 177 | "version": "1.0.4", 178 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 179 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 180 | }, 181 | "cookie": { 182 | "version": "0.4.0", 183 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", 184 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" 185 | }, 186 | "cookie-signature": { 187 | "version": "1.0.6", 188 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 189 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 190 | }, 191 | "core-util-is": { 192 | "version": "1.0.2", 193 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 194 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 195 | }, 196 | "create-require": { 197 | "version": "1.1.1", 198 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 199 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" 200 | }, 201 | "debug": { 202 | "version": "2.6.9", 203 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 204 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 205 | "requires": { 206 | "ms": "2.0.0" 207 | } 208 | }, 209 | "depd": { 210 | "version": "1.1.2", 211 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 212 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 213 | }, 214 | "destroy": { 215 | "version": "1.0.4", 216 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 217 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 218 | }, 219 | "diff": { 220 | "version": "4.0.2", 221 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 222 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" 223 | }, 224 | "ee-first": { 225 | "version": "1.1.1", 226 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 227 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 228 | }, 229 | "encodeurl": { 230 | "version": "1.0.2", 231 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 232 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 233 | }, 234 | "escape-html": { 235 | "version": "1.0.3", 236 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 237 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 238 | }, 239 | "etag": { 240 | "version": "1.8.1", 241 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 242 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 243 | }, 244 | "express": { 245 | "version": "4.17.1", 246 | "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", 247 | "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", 248 | "requires": { 249 | "accepts": "~1.3.7", 250 | "array-flatten": "1.1.1", 251 | "body-parser": "1.19.0", 252 | "content-disposition": "0.5.3", 253 | "content-type": "~1.0.4", 254 | "cookie": "0.4.0", 255 | "cookie-signature": "1.0.6", 256 | "debug": "2.6.9", 257 | "depd": "~1.1.2", 258 | "encodeurl": "~1.0.2", 259 | "escape-html": "~1.0.3", 260 | "etag": "~1.8.1", 261 | "finalhandler": "~1.1.2", 262 | "fresh": "0.5.2", 263 | "merge-descriptors": "1.0.1", 264 | "methods": "~1.1.2", 265 | "on-finished": "~2.3.0", 266 | "parseurl": "~1.3.3", 267 | "path-to-regexp": "0.1.7", 268 | "proxy-addr": "~2.0.5", 269 | "qs": "6.7.0", 270 | "range-parser": "~1.2.1", 271 | "safe-buffer": "5.1.2", 272 | "send": "0.17.1", 273 | "serve-static": "1.14.1", 274 | "setprototypeof": "1.1.1", 275 | "statuses": "~1.5.0", 276 | "type-is": "~1.6.18", 277 | "utils-merge": "1.0.1", 278 | "vary": "~1.1.2" 279 | } 280 | }, 281 | "finalhandler": { 282 | "version": "1.1.2", 283 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", 284 | "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", 285 | "requires": { 286 | "debug": "2.6.9", 287 | "encodeurl": "~1.0.2", 288 | "escape-html": "~1.0.3", 289 | "on-finished": "~2.3.0", 290 | "parseurl": "~1.3.3", 291 | "statuses": "~1.5.0", 292 | "unpipe": "~1.0.0" 293 | } 294 | }, 295 | "follow-redirects": { 296 | "version": "1.14.1", 297 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", 298 | "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==" 299 | }, 300 | "forwarded": { 301 | "version": "0.2.0", 302 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 303 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" 304 | }, 305 | "fresh": { 306 | "version": "0.5.2", 307 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 308 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 309 | }, 310 | "http-errors": { 311 | "version": "1.7.2", 312 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", 313 | "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", 314 | "requires": { 315 | "depd": "~1.1.2", 316 | "inherits": "2.0.3", 317 | "setprototypeof": "1.1.1", 318 | "statuses": ">= 1.5.0 < 2", 319 | "toidentifier": "1.0.0" 320 | } 321 | }, 322 | "iconv-lite": { 323 | "version": "0.4.24", 324 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 325 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 326 | "requires": { 327 | "safer-buffer": ">= 2.1.2 < 3" 328 | } 329 | }, 330 | "inherits": { 331 | "version": "2.0.3", 332 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 333 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 334 | }, 335 | "ipaddr.js": { 336 | "version": "1.9.1", 337 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 338 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" 339 | }, 340 | "isarray": { 341 | "version": "1.0.0", 342 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 343 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 344 | }, 345 | "make-error": { 346 | "version": "1.3.6", 347 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 348 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" 349 | }, 350 | "media-typer": { 351 | "version": "0.3.0", 352 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 353 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 354 | }, 355 | "merge-descriptors": { 356 | "version": "1.0.1", 357 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 358 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 359 | }, 360 | "methods": { 361 | "version": "1.1.2", 362 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 363 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 364 | }, 365 | "mime": { 366 | "version": "1.6.0", 367 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 368 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" 369 | }, 370 | "mime-db": { 371 | "version": "1.48.0", 372 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", 373 | "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" 374 | }, 375 | "mime-types": { 376 | "version": "2.1.31", 377 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", 378 | "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", 379 | "requires": { 380 | "mime-db": "1.48.0" 381 | } 382 | }, 383 | "ms": { 384 | "version": "2.0.0", 385 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 386 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 387 | }, 388 | "mysql": { 389 | "version": "2.18.1", 390 | "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.18.1.tgz", 391 | "integrity": "sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==", 392 | "requires": { 393 | "bignumber.js": "9.0.0", 394 | "readable-stream": "2.3.7", 395 | "safe-buffer": "5.1.2", 396 | "sqlstring": "2.3.1" 397 | } 398 | }, 399 | "negotiator": { 400 | "version": "0.6.2", 401 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", 402 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" 403 | }, 404 | "on-finished": { 405 | "version": "2.3.0", 406 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 407 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 408 | "requires": { 409 | "ee-first": "1.1.1" 410 | } 411 | }, 412 | "opentracing": { 413 | "version": "0.14.5", 414 | "resolved": "https://registry.npmjs.org/opentracing/-/opentracing-0.14.5.tgz", 415 | "integrity": "sha512-XLKtEfHxqrWyF1fzxznsv78w3csW41ucHnjiKnfzZLD5FN8UBDZZL1i4q0FR29zjxXhm+2Hop+5Vr/b8tKIvEg==", 416 | "dev": true 417 | }, 418 | "parseurl": { 419 | "version": "1.3.3", 420 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 421 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" 422 | }, 423 | "path-to-regexp": { 424 | "version": "0.1.7", 425 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 426 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 427 | }, 428 | "process-nextick-args": { 429 | "version": "2.0.1", 430 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 431 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 432 | }, 433 | "prom-client": { 434 | "version": "13.1.0", 435 | "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.1.0.tgz", 436 | "integrity": "sha512-jT9VccZCWrJWXdyEtQddCDszYsiuWj5T0ekrPszi/WEegj3IZy6Mm09iOOVM86A4IKMWq8hZkT2dD9MaSe+sng==", 437 | "dev": true, 438 | "requires": { 439 | "tdigest": "^0.1.1" 440 | } 441 | }, 442 | "proxy-addr": { 443 | "version": "2.0.7", 444 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 445 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 446 | "requires": { 447 | "forwarded": "0.2.0", 448 | "ipaddr.js": "1.9.1" 449 | } 450 | }, 451 | "qs": { 452 | "version": "6.7.0", 453 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", 454 | "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" 455 | }, 456 | "range-parser": { 457 | "version": "1.2.1", 458 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 459 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" 460 | }, 461 | "raw-body": { 462 | "version": "2.4.0", 463 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", 464 | "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", 465 | "requires": { 466 | "bytes": "3.1.0", 467 | "http-errors": "1.7.2", 468 | "iconv-lite": "0.4.24", 469 | "unpipe": "1.0.0" 470 | } 471 | }, 472 | "readable-stream": { 473 | "version": "2.3.7", 474 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 475 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 476 | "requires": { 477 | "core-util-is": "~1.0.0", 478 | "inherits": "~2.0.3", 479 | "isarray": "~1.0.0", 480 | "process-nextick-args": "~2.0.0", 481 | "safe-buffer": "~5.1.1", 482 | "string_decoder": "~1.1.1", 483 | "util-deprecate": "~1.0.1" 484 | } 485 | }, 486 | "safe-buffer": { 487 | "version": "5.1.2", 488 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 489 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 490 | }, 491 | "safer-buffer": { 492 | "version": "2.1.2", 493 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 494 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 495 | }, 496 | "send": { 497 | "version": "0.17.1", 498 | "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", 499 | "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", 500 | "requires": { 501 | "debug": "2.6.9", 502 | "depd": "~1.1.2", 503 | "destroy": "~1.0.4", 504 | "encodeurl": "~1.0.2", 505 | "escape-html": "~1.0.3", 506 | "etag": "~1.8.1", 507 | "fresh": "0.5.2", 508 | "http-errors": "~1.7.2", 509 | "mime": "1.6.0", 510 | "ms": "2.1.1", 511 | "on-finished": "~2.3.0", 512 | "range-parser": "~1.2.1", 513 | "statuses": "~1.5.0" 514 | }, 515 | "dependencies": { 516 | "ms": { 517 | "version": "2.1.1", 518 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 519 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 520 | } 521 | } 522 | }, 523 | "serve-static": { 524 | "version": "1.14.1", 525 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", 526 | "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", 527 | "requires": { 528 | "encodeurl": "~1.0.2", 529 | "escape-html": "~1.0.3", 530 | "parseurl": "~1.3.3", 531 | "send": "0.17.1" 532 | } 533 | }, 534 | "setprototypeof": { 535 | "version": "1.1.1", 536 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", 537 | "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" 538 | }, 539 | "source-map": { 540 | "version": "0.6.1", 541 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 542 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" 543 | }, 544 | "source-map-support": { 545 | "version": "0.5.19", 546 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", 547 | "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", 548 | "requires": { 549 | "buffer-from": "^1.0.0", 550 | "source-map": "^0.6.0" 551 | } 552 | }, 553 | "sqlstring": { 554 | "version": "2.3.1", 555 | "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", 556 | "integrity": "sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A=" 557 | }, 558 | "statuses": { 559 | "version": "1.5.0", 560 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 561 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 562 | }, 563 | "string_decoder": { 564 | "version": "1.1.1", 565 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 566 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 567 | "requires": { 568 | "safe-buffer": "~5.1.0" 569 | } 570 | }, 571 | "tdigest": { 572 | "version": "0.1.1", 573 | "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", 574 | "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", 575 | "dev": true, 576 | "requires": { 577 | "bintrees": "1.0.1" 578 | } 579 | }, 580 | "toidentifier": { 581 | "version": "1.0.0", 582 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", 583 | "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" 584 | }, 585 | "ts-node": { 586 | "version": "9.1.1", 587 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", 588 | "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", 589 | "requires": { 590 | "arg": "^4.1.0", 591 | "create-require": "^1.1.0", 592 | "diff": "^4.0.1", 593 | "make-error": "^1.1.1", 594 | "source-map-support": "^0.5.17", 595 | "yn": "3.1.1" 596 | } 597 | }, 598 | "type-is": { 599 | "version": "1.6.18", 600 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 601 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 602 | "requires": { 603 | "media-typer": "0.3.0", 604 | "mime-types": "~2.1.24" 605 | } 606 | }, 607 | "typescript": { 608 | "version": "4.3.2", 609 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", 610 | "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" 611 | }, 612 | "unpipe": { 613 | "version": "1.0.0", 614 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 615 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 616 | }, 617 | "util-deprecate": { 618 | "version": "1.0.2", 619 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 620 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 621 | }, 622 | "utils-merge": { 623 | "version": "1.0.1", 624 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 625 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 626 | }, 627 | "vary": { 628 | "version": "1.1.2", 629 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 630 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 631 | }, 632 | "yn": { 633 | "version": "3.1.1", 634 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 635 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" 636 | } 637 | } 638 | } 639 | -------------------------------------------------------------------------------- /three-layer-architecture/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threelayerapi", 3 | "version": "1.0.0", 4 | "private": true, 5 | "author": { 6 | "name": "Carlos Bastos Pérez-Cuadrado", 7 | "email": "carlosbastospc@gmail.com", 8 | "url": "http://www.cbastos.com/" 9 | }, 10 | "dependencies": { 11 | "axios": "^0.21.1", 12 | "express": "^4.17.1", 13 | "mysql": "^2.18.1", 14 | "ts-node": "^9.1.1", 15 | "typescript": "^4.3.2" 16 | }, 17 | "scripts": { 18 | "start": "ts-node ./main.ts" 19 | }, 20 | "devDependencies": { 21 | "@types/express": "^4.17.11", 22 | "@types/jaeger-client": "^3.15.4", 23 | "@types/mysql": "^2.15.17", 24 | "@types/node": "^14.14.16" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /three-layer-architecture/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "esModuleInterop": true, 5 | "moduleResolution": "node", 6 | "noImplicitAny": true, 7 | "removeComments": true, 8 | "preserveConstEnums": true, 9 | "sourceMap": true, 10 | "lib": ["es6", "dom"], 11 | "resolveJsonModule": true, 12 | "experimentalDecorators": true, 13 | "emitDecoratorMetadata": true, 14 | "types": ["node"], 15 | "typeRoots" : ["./node_modules/@types"] 16 | }, 17 | "include": [ 18 | "**/*.ts", 19 | "node_modules/@types" 20 | ], 21 | "exclude": [ 22 | "node_modules" 23 | ] 24 | } --------------------------------------------------------------------------------