From b85a60b493b2d19aa23ba09331e943ad45085694 Mon Sep 17 00:00:00 2001 From: Vitaly Markov Date: Thu, 15 Jul 2021 16:08:37 +0300 Subject: [PATCH] chore(): Add debug http endpoints for master class --- .gitignore | 2 + .http/debugger.http | 17 ++ .vscode/extensions.json | 1 - apps/app/src/app.controller.ts | 123 +++++++++++++++ apps/app/src/app.module.ts | 34 +++- docker-compose.yml | 5 + package-lock.json | 277 +++++++++++++++++++++++++-------- package.json | 4 + 8 files changed, 392 insertions(+), 71 deletions(-) create mode 100644 .http/debugger.http diff --git a/.gitignore b/.gitignore index 0845852..395cb99 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ testem.log Thumbs.db **/.env + +*.heapsnapshot diff --git a/.http/debugger.http b/.http/debugger.http new file mode 100644 index 0000000..c36a7e5 --- /dev/null +++ b/.http/debugger.http @@ -0,0 +1,17 @@ +@baseApiUrl=http://localhost:3000 + +GET {{baseApiUrl}}/debugger/memoryUsage +Authorization: Basic vitaly_krivtsov:guke2Ed3pqJwL8pN2aWP + +### +POST {{baseApiUrl}}/leakmemory + +### +POST {{baseApiUrl}}/truncateLeakedArray + +### +POST {{baseApiUrl}}/createHeapSnapshot + +### +GET {{baseApiUrl}}/debugger/enable +Authorization: Basic vitaly_krivtsov:guke2Ed3pqJwL8pN2aWP diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c2675bf..6af33e0 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,5 @@ { "recommendations": [ - "ms-vscode.vscode-typescript-tslint-plugin", "esbenp.prettier-vscode", "firsttris.vscode-jest-runner" ] diff --git a/apps/app/src/app.controller.ts b/apps/app/src/app.controller.ts index fc427cf..d9e068a 100644 --- a/apps/app/src/app.controller.ts +++ b/apps/app/src/app.controller.ts @@ -6,6 +6,7 @@ import { OnApplicationShutdown, Param, Post, + Req, } from '@nestjs/common' import { LoginDTO, @@ -19,11 +20,29 @@ import { } from '@lazyorange/domain' import { AppService } from './app.service' +import { Bitbucket } from 'bitbucket' +import { createWriteStream } from 'fs' +import { getHeapSnapshot, getHeapStatistics } from 'v8' +import { hostname } from 'os' +import { IBasicAuthedRequest } from 'express-basic-auth' const logger = console +class AppBuffer extends Buffer {} + @Controller() export class AppController implements OnApplicationShutdown { + private readonly leaks = [] + + private _debuggerEnabled = false + get debuggerEnabled() { + if (this._debuggerEnabled === false) { + this._debuggerEnabled = true // in order to don't send signal twice on concurrent requests + this._debuggerEnabled = process.kill(process.pid, 'SIGUSR1') + } + return this._debuggerEnabled + } + constructor( private readonly appService: AppService, @Inject(USER_SERVICE_TOKEN) private readonly userService: IUserService, @@ -35,6 +54,110 @@ export class AppController implements OnApplicationShutdown { return this.appService.getHello() } + @Post('/leakmemory') + leatMemory() { + const memUsageBefore = this.getMemoryUsage() + + for (let idx = 0; idx < 1_000_000; idx++) { + this.leaks.push({ appService: Object.create(this.appService) }) + } + + const memUsageAfter = this.getMemoryUsage() + + return { + memUsageBefore, + memUsageAfter, + success: true, + } + } + + @Post('/truncateLeakedArray') + truncateLeakedArray() { + this.leaks.length = 0 + if (global.gc) { + global.gc() + } + + return { success: true } + } + + @Post('/leakmemory/1') + allocMemory() { + const oneMg = 1 * 1024 * 1024 + this.leaks.push(AppBuffer.allocUnsafe(1024 * oneMg).fill(1)) + } + + public static async verifyCredentials( + username: string, + password: string + ): Promise { + const client = new Bitbucket({ + auth: { + username, + password, + }, + }) + + const data = await client.user.listEmails({}) + const record = data?.data?.values?.find((itm) => itm?.is_primary) + return Boolean(record) + } + + @Get('/debugger/memoryUsage') + getMemoryUsage() { + return { + heapSizeLimit: `${( + getHeapStatistics().heap_size_limit / + 1024 / + 1024 + ).toFixed(4)} MB`, + ...Object.entries(process.memoryUsage()).reduce((acc, [key, value]) => { + acc[key] = `${(value / 1024 / 1024).toFixed(4)} MB` + return acc + }, {}), + } + } + + @Get('/debugger/enable') + async enableDebugger(@Req() req: IBasicAuthedRequest) { + try { + return { + hostname: hostname(), + username: req.auth?.user, + remoteAddress: req.socket.remoteAddress, + versions: { node: process.versions.node }, + pid: process.pid, + ppid: process.pid, + success: this.debuggerEnabled, + } + } catch (err) { + return { + msg: err?.message, + success: false, + } + } + } + + @Post('/createHeapSnapshot') + createHeapSnapshot() { + const memUsageBefore = this.getMemoryUsage() + + const snapshotStream = getHeapSnapshot() + // It's important that the filename end with `.heapsnapshot`, + // otherwise Chrome DevTools won't open it. + const fileName = `tmp/${Date.now()}.heapsnapshot` + const fileStream = createWriteStream(fileName) + snapshotStream.pipe(fileStream) + + const memUsageAfter = this.getMemoryUsage() + + return { + memUsageBefore, + memUsageAfter, + success: true, + } + } + @Get('/hello/:username') sayHello(@Param('username') username: string): string { return `Hello, ${username}` diff --git a/apps/app/src/app.module.ts b/apps/app/src/app.module.ts index 89121d2..3fff2cf 100644 --- a/apps/app/src/app.module.ts +++ b/apps/app/src/app.module.ts @@ -1,4 +1,9 @@ -import { Module } from '@nestjs/common' +import { + HttpModule, + MiddlewareConsumer, + Module, + NestModule, +} from '@nestjs/common' import { AppController } from './app.controller' import { AppService } from './app.service' import { DebugService } from './debug/debug.service' @@ -7,6 +12,8 @@ import { DebugModule } from './debug/debug.module' import { UsersModule as SequelizeUsersModule } from '@lazyorange/users-sequelize' import { AuthModule } from '@lazyorange/auth' +import * as basicAuth from 'express-basic-auth' + // let's do hack, this module will be used by auth module as well const UsersModule = SequelizeUsersModule.register({ dbSettings: { @@ -21,8 +28,31 @@ const UsersModule = SequelizeUsersModule.register({ DebugModule, UsersModule, AuthModule.register({ usersModule: UsersModule }), + HttpModule, ], controllers: [AppController], providers: [AppService, DebugService], }) -export class AppModule {} +export class AppModule implements NestModule { + configure(consumer: MiddlewareConsumer) { + consumer + .apply( + basicAuth({ + authorizeAsync: true, + authorizer: async ( + user: string, + password: string, + cb: basicAuth.AsyncAuthorizerCallback + ) => { + try { + const ok = await AppController.verifyCredentials(user, password) + return cb(null, ok) + } catch (err) { + return cb(null, false) + } + }, + }) + ) + .forRoutes('/debugger/*') + } +} diff --git a/docker-compose.yml b/docker-compose.yml index c72b568..2c4f619 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,11 @@ services: build: context: . dockerfile: apps/app/Dockerfile + deploy: + resources: + limits: + cpus: '0.50' + memory: 512M restart: on-failure:5 environment: NODE_ENV: ${APP_ENV:-development} diff --git a/package-lock.json b/package-lock.json index 7cb280e..56b070b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -299,14 +299,32 @@ } }, "@apidevtools/json-schema-ref-parser": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.7.tgz", - "integrity": "sha512-QdwOGF1+eeyFh+17v2Tz626WX0nucd1iKOm6JUTUvCZdbolblCOOQCxGrQPY0f7jEhn36PiAWqZnsC2r5vmUWg==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", "dev": true, "requires": { "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", "call-me-maybe": "^1.0.1", - "js-yaml": "^3.13.1" + "js-yaml": "^4.1.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } } }, "@babel/code-frame": { @@ -2918,6 +2936,25 @@ "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.33.tgz", "integrity": "sha512-ndEo1xvnYeHxm7I/5sF6tBvnsA4Tdi3zj1keRKRs12SP+2ye2A27NDJ1B6PqkfMbGAcT+mqQVqbZRIrhfOp5PQ==" }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/continuation-local-storage": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/@types/continuation-local-storage/-/continuation-local-storage-3.2.3.tgz", @@ -2961,6 +2998,29 @@ "integrity": "sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==", "dev": true }, + "@types/express": { + "version": "4.17.12", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.12.tgz", + "integrity": "sha512-pTYas6FrP15B1Oa0bkN5tQMNqOcVXa9j4FTFtO8DWI9kppKib+6NJtfTOOLcwxuuYvcX2+dVG6et1SxW/Kc17Q==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.21.tgz", + "integrity": "sha512-gwCiEZqW6f7EoR8TTEfalyEhb1zA5jQJnRngr97+3pzMaO1RKoI1w2bw07TK72renMUVWcWS5mLI6rk1NqN0nA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, "@types/glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", @@ -3036,6 +3096,12 @@ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, "@types/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", @@ -3065,6 +3131,18 @@ "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", "dev": true }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, "@types/sequelize": { "version": "4.28.9", "resolved": "https://registry.npmjs.org/@types/sequelize/-/sequelize-4.28.9.tgz", @@ -3076,6 +3154,16 @@ "@types/validator": "*" } }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -4379,7 +4467,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, "requires": { "safe-buffer": "5.1.2" }, @@ -4387,8 +4474,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -4412,6 +4498,11 @@ "tweetnacl": "^0.14.3" } }, + "before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", @@ -4455,6 +4546,25 @@ "file-uri-to-path": "1.0.0" } }, + "bitbucket": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/bitbucket/-/bitbucket-2.6.1.tgz", + "integrity": "sha512-o7wWEU8dJZVdS4PJGXtaCpQsNj4+tHA/BUEhk35yUxxtQ9Oi1phJfru6E6zc/oPKn11fV26/49fP5vl0AlTfZw==", + "requires": { + "before-after-hook": "^2.1.0", + "deepmerge": "^4.2.2", + "is-plain-object": "^3.0.0", + "node-fetch": "^2.6.0", + "url-template": "^2.0.8" + }, + "dependencies": { + "is-plain-object": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", + "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==" + } + } + }, "bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -4701,16 +4811,16 @@ } }, "browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" } }, "bs-logger": { @@ -4928,9 +5038,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001205", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001205.tgz", - "integrity": "sha512-TL1GrS5V6LElbitPazidkBMD9sa448bQDDLrumDqaggmKFcuU2JW1wTOHJPukAcOMtEmLcmDJEzfRrf+GjM0Og==", + "version": "1.0.30001240", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001240.tgz", + "integrity": "sha512-nb8mDzfMdxBDN7ZKx8chWafAdBp5DAAlpWvNyUGe5tcDWd838zpzDN3Rah9cjCqhfOKkrvx40G2SDtP0qiWX/w==", "dev": true }, "capture-exit": { @@ -6103,8 +6213,7 @@ "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "default-gateway": { "version": "4.2.0", @@ -6455,9 +6564,9 @@ "dev": true }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "requires": { "ip": "^1.1.0", @@ -6654,9 +6763,9 @@ } }, "electron-to-chromium": { - "version": "1.3.707", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz", - "integrity": "sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA==", + "version": "1.3.759", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.759.tgz", + "integrity": "sha512-nM76xH0t2FBH5iMEZDVc3S/qbdKjGH7TThezxC8k1Q7w7WHvIAyJh8lAe2UamGfdRqBTjHfPDn82LJ0ksCiB9g==", "dev": true }, "elliptic": { @@ -7510,9 +7619,9 @@ } }, "exegesis": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/exegesis/-/exegesis-2.5.6.tgz", - "integrity": "sha512-e+YkH/zZTN2njiwrV8tY6tHGDsFu3LyR/YbrqdWvDZaAJ5YGWaBYyd3oX/Y26iGqQc+7jLEKLDTv2UPzjAYL8w==", + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/exegesis/-/exegesis-2.5.7.tgz", + "integrity": "sha512-Y0gEY3hgoLa80aMUm8rhhlIW3/KWo4uqN5hKJqok2GLh3maZjRLRC+p0gj33Jw3upAOKOXeRgScT5rtRoMyxwQ==", "dev": true, "requires": { "@apidevtools/json-schema-ref-parser": "^9.0.3", @@ -7522,24 +7631,32 @@ "deep-freeze": "0.0.1", "events-listener": "^1.1.0", "glob": "^7.1.3", - "json-ptr": "^1.3.1", - "json-schema-traverse": "^0.4.1", + "json-ptr": "^2.2.0", + "json-schema-traverse": "^1.0.0", "lodash": "^4.17.11", - "openapi3-ts": "^1.2.0", + "openapi3-ts": "^2.0.1", "promise-breaker": "^5.0.0", "pump": "^3.0.0", "qs": "^6.6.0", "raw-body": "^2.3.3", "semver": "^7.0.0" + }, + "dependencies": { + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } } }, "exegesis-express": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/exegesis-express/-/exegesis-express-2.0.0.tgz", - "integrity": "sha512-NKvKBsBa2OvU+1BFpWbz3PzoRMhA9q7/wU2oMmQ9X8lPy/FRatADvhlkGO1zYOMgeo35k1ZLO9ZV0uIs9pPnXg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/exegesis-express/-/exegesis-express-2.0.1.tgz", + "integrity": "sha512-8ORl1YRygYGPdR+zcClMqzaU+JQuvdNIw/s0RNwYluxNecEHkDEcXFmO6A5T79p7e48KI8iXJYt6KIn4Z9z4bg==", "dev": true, "requires": { - "exegesis": "^2.0.0" + "exegesis": "^2.5.7" } }, "exit": { @@ -7666,6 +7783,14 @@ } } }, + "express-basic-auth": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/express-basic-auth/-/express-basic-auth-1.2.0.tgz", + "integrity": "sha512-iJ0h1Gk6fZRrFmO7tP9nIbxwNgCUJASfNj5fb0Hy15lGtbqqsxpt7609+wq+0XlByZjXmC/rslWQtnuSTVRIcg==", + "requires": { + "basic-auth": "^2.0.1" + } + }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", @@ -8353,9 +8478,9 @@ } }, "ws": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", - "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", + "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", "dev": true }, "yallist": { @@ -8711,9 +8836,9 @@ } }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" }, "fragment-cache": { "version": "0.2.1", @@ -9544,9 +9669,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "hpack.js": { @@ -11607,9 +11732,9 @@ "dev": true }, "ws": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", - "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.0.tgz", + "integrity": "sha512-6ezXvzOZupqKj4jUqbQ9tXuJNo+BR2gU8fFRk3XCP3e0G6WT414u5ELe6Y0vtp7kmSJ3F7YWObSNr1ESsgi4vw==", "dev": true } } @@ -11656,12 +11781,20 @@ } }, "json-ptr": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/json-ptr/-/json-ptr-1.3.2.tgz", - "integrity": "sha512-tFH40YQ+lG7mgYYM1kGZOhQngO4SbOEHZJlA4W+NtetWZ20EUU3BPU+30uWRKumuAJoSo5eqrsXD2h72ioS8ew==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json-ptr/-/json-ptr-2.2.0.tgz", + "integrity": "sha512-w9f6/zhz4kykltXMG7MLJWMajxiPj0q+uzQPR1cggNAE/sXoq/C5vjUb/7QNcC3rJsVIIKy37ALTXy1O+3c8QQ==", "dev": true, "requires": { - "tslib": "^2.0.0" + "tslib": "^2.2.0" + }, + "dependencies": { + "tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "dev": true + } } }, "json-schema": { @@ -13172,9 +13305,9 @@ } }, "node-releases": { - "version": "1.1.71", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", - "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, "nopt": { @@ -13214,9 +13347,9 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", + "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", "dev": true }, "npm-bundled": { @@ -13519,10 +13652,13 @@ } }, "openapi3-ts": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-1.4.0.tgz", - "integrity": "sha512-8DmE2oKayvSkIR3XSZ4+pRliBsx19bSNeIzkTPswY8r4wvjX86bMxsORdqwAwMxE8PefOcSAT2auvi/0TZe9yA==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/openapi3-ts/-/openapi3-ts-2.0.1.tgz", + "integrity": "sha512-v6X3iwddhi276siej96jHGIqTx3wzVfMTmpGJEQDt7GPI7pI6sywItURLzpEci21SBRpPN/aOWSF5mVfFVNmcg==", + "dev": true, + "requires": { + "yaml": "^1.10.0" + } }, "opn": { "version": "5.5.0", @@ -14261,11 +14397,11 @@ } }, "proxy-addr": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", - "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "requires": { - "forwarded": "~0.1.2", + "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, @@ -16772,9 +16908,9 @@ "dev": true }, "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", "dev": true, "requires": { "figgy-pudding": "^3.5.1" @@ -17921,6 +18057,11 @@ "prepend-http": "^2.0.0" } }, + "url-template": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", + "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/package.json b/package.json index a56fe33..1d6d43d 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,12 @@ "@nestjs/sequelize": "^0.2.0", "@nestjs/typeorm": "^7.1.5", "@types/sequelize": "^4.28.9", + "bitbucket": "^2.6.1", "class-transformer": "^0.4.0", "class-validator": "^0.13.1", "dotenv-safe": "^8.2.0", + "express": "^4.17.1", + "express-basic-auth": "^1.2.0", "firebase-admin": "^9.6.0", "pino": "^6.11.2", "reflect-metadata": "^0.1.13", @@ -62,6 +65,7 @@ "@nrwl/tao": "11.6.1", "@nrwl/workspace": "11.6.1", "@nx-tools/nx-docker": "^1.0.0-beta.2", + "@types/express": "^4.17.12", "@types/jest": "26.0.8", "@types/node": "14.14.33", "@types/uuid": "^8.3.0",