perf: reduce memory usage (#1436)

* chore!: remove `qaqdmin` route

Signed-off-by: Innei <i@innei.in>

* chore!: remove node-pty

Signed-off-by: Innei <i@innei.in>

* chore!: remove cpp bcrypt

Signed-off-by: Innei <i@innei.in>

* perf: reduce memory usage

Signed-off-by: Innei <i@innei.in>

---------

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei
2024-02-07 15:06:31 +08:00
committed by GitHub
parent 9addf450c4
commit ed11374a97
12 changed files with 160 additions and 321 deletions

View File

@@ -20,7 +20,7 @@
"build:webpack": "nest build --webpack --webpackPath ./configs/webpack.config.js -c ./configs/nest-cli.webpack.json",
"dev": "npm run start",
"repl": "npm run start -- --entryFile repl",
"bundle": "rimraf out && npm run build && cd dist/src && npx ncc build main.js -o ../../out -s -t && cd ../.. && chmod +x out/index.js",
"bundle": "rimraf out && npm run build && cd dist/src && npx ncc build main.js -o ../../out --minify -s && cd ../.. && chmod +x out/index.js && node scripts/after-bundle.js",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"packages/**/*.ts\"",
"start": "cross-env NODE_ENV=development nest start -w --path tsconfig.json -- ",
"start:debug": "cross-env NODE_ENV=development nest start --debug --watch",
@@ -78,7 +78,7 @@
"algoliasearch": "4.22.1",
"axios": "^1.6.7",
"axios-retry": "4.0.0",
"bcrypt": "5.1.1",
"bcryptjs": "^2.4.3",
"cache-manager": "5.4.0",
"cache-manager-ioredis-yet": "1.2.2",
"class-transformer": "0.5.1",
@@ -111,7 +111,6 @@
"mongoose-paginate-v2": "1.8.0",
"nestjs-pretty-logger": "0.2.1",
"node-machine-id": "1.1.12",
"node-pty": "1.0.0",
"nodemailer": "6.9.9",
"pluralize": "^8.0.0",
"qs": "6.11.2",
@@ -122,6 +121,7 @@
"semver": "7.5.4",
"slugify": "1.6.6",
"snakecase-keys": "6.0.0",
"source-map-support": "^0.5.21",
"ua-parser-js": "1.0.37",
"vm2": "3.9.19",
"wildcard-match": "5.1.2",
@@ -134,7 +134,7 @@
"@nestjs/testing": "10.3.1",
"@swc/core": "1.4.0",
"@types/babel__core": "7.20.5",
"@types/bcrypt": "5.0.2",
"@types/bcryptjs": "^2.4.6",
"@types/cache-manager": "4.0.6",
"@types/cls-hooked": "^4.3.8",
"@types/ejs": "3.1.5",
@@ -165,4 +165,4 @@
"mongodb-memory-server": "^9.1.5",
"redis-memory-server": "^0.10.0"
}
}
}

View File

@@ -19,7 +19,6 @@
现有的比较有意思的一些小玩意的实现:
- 实时日志输出。通过 Socket.IO + 劫持 `process.stdout` 实现。
- [云函数](./src/modules/serverless/serverless.readme.md)
三方服务集成:
@@ -63,6 +62,9 @@ node index.js
所有的依赖都打包进了产物,无需黑洞一般的 node_modules
> [!NOTE]
> 编译之后的产物错误堆栈是被压缩过的,如果你遇到任何问题,请使用 `node index.debug.js` 启动,复现问题并提供完整堆栈,然后提交 issue。
## 开发环境
```
@@ -94,7 +96,7 @@ pnpm dev
├── processors # 核心辅助模块
│ ├── cache # Redis 缓存相关
│ ├── database # Mongo 数据库相关
│ ├── gateway # Socket.IO 相关
│ ├── gateway # WebSocket 相关
│ ├── helper # 辅助类
│ └── logger # 自定义 Logger
├── shared # 通用模型
@@ -193,7 +195,6 @@ Since 2021-08-31
Thanks
# 许可
This project is licensed under AGPLv3 licensed. 2021 Innei

View File

@@ -0,0 +1,40 @@
const fs = require('node:fs')
const path = require('node:path')
const buildDir = path.resolve(__dirname, '../out')
const hasBuild = fs.existsSync(buildDir)
if (!hasBuild) {
throw new Error('No build folder found')
}
const originalIndexFilePath = path.resolve(buildDir, 'index.js')
const code = fs.readFileSync(originalIndexFilePath, 'utf8')
const replaced = code
.replace(`require('./sourcemap-register.js');`, '')
.replace(
`//# sourceMappingURL=index.js.map`,
`//# sourceMappingURL=entrypoints.js.map`,
)
fs.writeFileSync(originalIndexFilePath, replaced)
fs.renameSync(originalIndexFilePath, path.resolve(buildDir, 'entrypoints.js'))
fs.renameSync(
path.resolve(buildDir, 'index.js.map'),
path.resolve(buildDir, 'entrypoints.js.map'),
)
fs.writeFileSync(
path.resolve(buildDir, 'index.debug.js'),
`#!env node
require('./sourcemap-register.js');require('./entrypoints.js');`,
)
fs.writeFileSync(
originalIndexFilePath,
`#!env node
require('./entrypoints.js');`,
)
fs.chmodSync(path.resolve(buildDir, 'index.debug.js'), '755')
fs.chmodSync(originalIndexFilePath, '755')

View File

@@ -95,7 +95,6 @@ export async function bootstrap() {
}
logger.success(`[${prefix + pid}] Server listen on: ${url}`)
logger.success(`[${prefix + pid}] Admin Dashboard: ${url}/qaqdmin`)
logger.success(
`[${prefix + pid}] Admin Local Dashboard: ${url}/proxy/qaqdmin`,
)

View File

@@ -3,32 +3,18 @@ import fs from 'fs/promises'
import { extname, join } from 'path'
import { render } from 'ejs'
import { FastifyReply, FastifyRequest } from 'fastify'
import { isNull } from 'lodash'
import { lookup } from 'mime-types'
import PKG from 'package.json'
import type { Observable } from 'rxjs'
import {
Controller,
Get,
InternalServerErrorException,
Query,
Req,
Res,
} from '@nestjs/common'
import { Controller, Get, Query, Req, Res } from '@nestjs/common'
import { SkipThrottle } from '@nestjs/throttler'
import { Cookies } from '~/common/decorators/cookie.decorator'
import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { RedisKeys } from '~/constants/cache.constant'
import { LOCAL_ADMIN_ASSET_PATH } from '~/constants/path.constant'
import { AssetService } from '~/processors/helper/helper.asset.service'
import { CacheService } from '~/processors/redis/cache.service'
import { getRedisKey } from '~/utils/redis.util'
import { dashboard } from '../../../package.json'
import { UpdateService } from '../update/update.service'
import { PageProxyDebugDto } from './pageproxy.dto'
import { PageProxyService } from './pageproxy.service'
@Controller('/')
@@ -41,123 +27,6 @@ export class PageProxyController {
private readonly assetService: AssetService,
) {}
@Get('/qaqdmin')
@HTTPDecorators.Bypass
async proxyAdmin(
@Cookies() cookies: KV<string>,
@Query() query: PageProxyDebugDto,
@Res() reply: FastifyReply,
) {
// if want to access local, skip this route logic
if (query.__local) {
reply.redirect('/proxy/qaqdmin')
return
}
if ((await this.service.checkCanAccessAdminProxy()) === false) {
return reply.type('application/json').status(403).send({
message: 'admin proxy not enabled',
})
}
const {
__apiUrl: apiUrl,
__gatewayUrl: gatewayUrl,
__onlyGithub: onlyGithub,
__debug: debug,
__version: adminVersion = dashboard.version,
__purge,
} = query
if (__purge) {
await this.cacheService.getClient().del(getRedisKey(RedisKeys.AdminPage))
}
if (apiUrl) {
reply.setCookie('__apiUrl', apiUrl, { maxAge: 1000 * 60 * 10 })
}
if (gatewayUrl) {
reply.setCookie('__gatewayUrl', gatewayUrl, { maxAge: 1000 * 60 * 10 })
}
if (debug === false) {
reply.clearCookie('__apiUrl')
reply.clearCookie('__gatewayUrl')
}
const source: { text: string; from: string } = await (async () => {
// adminVersion 如果传入 latest 会被转换 null, 这里要判断 undefined
if (!onlyGithub && typeof adminVersion == 'undefined') {
const fromRedis = await this.cacheService.get<string>(
getRedisKey(RedisKeys.AdminPage),
)
if (fromRedis) {
return {
text: fromRedis,
from: 'redis',
}
}
}
let latestVersion = ''
if (isNull(adminVersion)) {
try {
latestVersion =
await this.service.getAdminLastestVersionFromGHRelease()
} catch (e) {
reply.type('application/json').status(500).send({
message: '从获取 GitHub 获取数据失败,连接超时',
})
throw e
}
}
const v = adminVersion || latestVersion
const indexEntryUrl = `https://raw.githubusercontent.com/${PKG.dashboard.repo}/page_v${v}/index.html`
const indexEntryCdnUrl = `https://fastly.jsdelivr.net/gh/${PKG.dashboard.repo}@page_v${v}/index.html`
const tasks = [
// eslint-disable-next-line @typescript-eslint/no-empty-function
fetch(indexEntryUrl)
.then((res) => res.text())
.then((text) => ({ text, from: 'github' })),
]
if (!onlyGithub) {
tasks.push(
fetch(indexEntryCdnUrl)
.then((res) => res.text())
.then((text) => ({ text, from: 'jsdelivr' })),
)
}
return await Promise.any(tasks).catch((e) => {
const err = '网络连接异常,所有请求均失败,无法获取后台入口文件'
reply.type('application/json').status(500).send({ message: err })
throw new InternalServerErrorException(err)
})
})()
await this.cacheService.set(
getRedisKey(RedisKeys.AdminPage),
source.text,
10 * 60 * 1000,
)
const sessionInjectableData =
debug === false
? {}
: {
BASE_API: apiUrl ?? cookies['__apiUrl'],
GATEWAY: gatewayUrl ?? cookies['__gatewayUrl'],
}
const entry = await this.service.injectAdminEnv(source.text, {
BASE_API: sessionInjectableData.BASE_API,
GATEWAY: sessionInjectableData.GATEWAY,
from: source.from,
})
return reply.type('text/html').send(entry)
}
private fetchObserver$: Observable<string> | null
private fetchLogs: string[] | null
private fetchErrorMsg: string | null

View File

@@ -36,7 +36,12 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { HttpService } from '~/processors/helper/helper.http.service'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getRedisKey, safePathJoin, scheduleManager } from '~/utils'
import {
getRedisKey,
safePathJoin,
safeProcessEnv,
scheduleManager,
} from '~/utils'
import { EncryptUtil } from '~/utils/encrypt.util'
import { safeEval } from '~/utils/safe-eval.util'
@@ -559,7 +564,7 @@ export class ServerlessService implements OnModuleInit {
},
process: {
env: {},
env: safeProcessEnv(),
nextTick: scheduleManager.schedule.bind(null),
},
}

View File

@@ -1,7 +1,6 @@
import { appendFile, rm, writeFile } from 'fs/promises'
import { inspect } from 'util'
import axios from 'axios'
import { spawn } from 'node-pty'
import { catchError, Observable } from 'rxjs'
import type { Subscriber } from 'rxjs'
@@ -10,6 +9,7 @@ import { Injectable } from '@nestjs/common'
import { dashboard } from '~/../package.json'
import { LOCAL_ADMIN_ASSET_PATH } from '~/constants/path.constant'
import { HttpService } from '~/processors/helper/helper.http.service'
import { spawnShell } from '~/utils'
const { repo } = dashboard
@@ -143,7 +143,7 @@ export class UpdateService {
return new Promise((resolve, reject) => {
subscriber.next(`${chalk.yellow(`$`)} ${command} ${args.join(' ')}\n`)
const pty = spawn(command, args, {})
const pty = spawnShell(command, args, {})
pty.onData((data) => {
subscriber.next(data.toString())
})

View File

@@ -1,4 +1,4 @@
import { hashSync } from 'bcrypt'
import { hashSync } from 'bcryptjs'
import { omit } from 'lodash'
import { Schema } from 'mongoose'
import type { DocumentType } from '@typegoose/typegoose'

View File

@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { compareSync } from 'bcrypt'
import { compareSync } from 'bcryptjs'
import type { UserDocument } from './user.model'
import {

View File

@@ -1,7 +1,6 @@
import { exec } from 'child_process'
import cdp, { exec } from 'child_process'
import { builtinModules } from 'module'
import { promisify } from 'util'
import { spawn } from 'node-pty'
export async function getFolderSize(folderPath: string) {
try {
@@ -89,7 +88,7 @@ export const installPKG = async (name: string, cwd: string) => {
cd(cwd)
// await $`${manager} ${INSTALL_COMMANDS[manager]} ${name}`
const shell = os.platform() === 'win32' ? 'powershell.exe' : 'bash'
const pty = spawn(
const pty = spawnShell(
shell,
['-c', `${manager} ${INSTALL_COMMANDS[manager]} ${name}`],
{},
@@ -97,3 +96,75 @@ export const installPKG = async (name: string, cwd: string) => {
return pty
}
const noop = () => {}
export const safeProcessEnv = () => {
const safeKeys = [
'_',
'PATH',
'HOME',
'SHELL',
'TMPDIR',
'PWD',
'EDITOR',
'VISUAL',
'LANG',
'LESS',
'N_PREFIX',
'N_PRESERVE_NPM',
'STARSHIP_SHELL',
'PNPM_HOME',
'COLORTERM',
'TZ',
]
const env: Record<string, string> = {}
for (const key of safeKeys) {
const value = process.env[key]
if (value) {
env[key] = value
}
}
return env
}
export const spawnShell = (
cmd: string,
args?: string[],
options?: cdp.SpawnOptionsWithoutStdio,
) => {
type DataHandler = (string: string, code: 0 | 1) => any
type ExitHandler = (e: { exitCode: number }) => any
let onDataHandler: DataHandler = noop
let onExitHandler: ExitHandler = noop
const returnObject = {
onData(callback: DataHandler) {
onDataHandler = callback
},
onExit(callback: ExitHandler) {
onExitHandler = callback
},
}
const child = cdp.spawn(cmd, args, {
env: {
...safeProcessEnv(),
FORCE_COLOR: '1',
...options?.env,
},
...options,
})
child.stdout.on('data', (data) => {
onDataHandler(data.toString(), 0)
})
child.stderr.on('data', (data) => {
onDataHandler(data.toString(), 1)
})
child.on('close', (code) => {
onExitHandler({ exitCode: code || 0 })
})
return returnObject
}

190
pnpm-lock.yaml generated
View File

@@ -163,9 +163,9 @@ importers:
axios-retry:
specifier: 4.0.0
version: 4.0.0(axios@1.6.7)
bcrypt:
specifier: 5.1.1
version: 5.1.1
bcryptjs:
specifier: ^2.4.3
version: 2.4.3
cache-manager:
specifier: 5.4.0
version: 5.4.0
@@ -262,9 +262,6 @@ importers:
node-machine-id:
specifier: 1.1.12
version: 1.1.12
node-pty:
specifier: 1.0.0
version: 1.0.0
nodemailer:
specifier: 6.9.9
version: 6.9.9
@@ -295,6 +292,9 @@ importers:
snakecase-keys:
specifier: 6.0.0
version: 6.0.0
source-map-support:
specifier: ^0.5.21
version: 0.5.21
ua-parser-js:
specifier: 1.0.37
version: 1.0.37
@@ -333,9 +333,9 @@ importers:
'@types/babel__core':
specifier: 7.20.5
version: 7.20.5
'@types/bcrypt':
specifier: 5.0.2
version: 5.0.2
'@types/bcryptjs':
specifier: ^2.4.6
version: 2.4.6
'@types/cache-manager':
specifier: 4.0.6
version: 4.0.6
@@ -1784,24 +1784,6 @@ packages:
engines: {node: '>=8'}
dev: false
/@mapbox/node-pre-gyp@1.0.11:
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
hasBin: true
dependencies:
detect-libc: 2.0.2
https-proxy-agent: 5.0.1
make-dir: 3.1.0
node-fetch: 2.6.13
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
semver: 7.5.4
tar: 6.2.0
transitivePeerDependencies:
- encoding
- supports-color
dev: false
/@mongodb-js/saslprep@1.1.4:
resolution: {integrity: sha512-8zJ8N1x51xo9hwPh6AWnKdLGEC5N3lDa6kms1YHmFBoRhTpJR6HG8wWk0td1MVCu9cD4YBrvjZEtd5Obw0Fbnw==}
dependencies:
@@ -2641,10 +2623,8 @@ packages:
'@babel/types': 7.23.9
dev: true
/@types/bcrypt@5.0.2:
resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==}
dependencies:
'@types/node': 20.11.16
/@types/bcryptjs@2.4.6:
resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
dev: true
/@types/body-parser@1.19.5:
@@ -3276,10 +3256,6 @@ packages:
resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==}
dev: true
/abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
/abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
@@ -3340,16 +3316,6 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
/agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
requiresBuild: true
dependencies:
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
@@ -3474,22 +3440,10 @@ packages:
picomatch: 2.3.1
dev: true
/aproba@2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
dev: false
/archy@1.0.0:
resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==}
dev: false
/are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
dev: false
/arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
dev: true
@@ -3723,16 +3677,8 @@ packages:
resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==}
engines: {node: ^4.5.0 || >= 5.9}
/bcrypt@5.1.1:
resolution: {integrity: sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==}
engines: {node: '>= 10.0.0'}
requiresBuild: true
dependencies:
'@mapbox/node-pre-gyp': 1.0.11
node-addon-api: 5.1.0
transitivePeerDependencies:
- encoding
- supports-color
/bcryptjs@2.4.3:
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
dev: false
/binary-extensions@2.2.0:
@@ -3822,7 +3768,6 @@ packages:
/buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
@@ -4029,6 +3974,7 @@ packages:
engines: {node: '>=10'}
requiresBuild: true
dev: false
optional: true
/chroma-js@2.4.2:
resolution: {integrity: sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==}
@@ -4125,11 +4071,6 @@ packages:
/color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
/color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
dev: false
/colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
dev: true
@@ -4175,10 +4116,6 @@ packages:
/consola@2.15.3:
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
/console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: false
/content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -4442,10 +4379,6 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
/delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
dev: false
/denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
@@ -4462,7 +4395,9 @@ packages:
/detect-libc@2.0.2:
resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==}
engines: {node: '>=8'}
requiresBuild: true
dev: false
optional: true
/diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
@@ -5529,6 +5464,7 @@ packages:
dependencies:
minipass: 3.1.3
dev: false
optional: true
/fs-monkey@1.0.5:
resolution: {integrity: sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==}
@@ -5579,21 +5515,6 @@ packages:
hasBin: true
dev: true
/gauge@3.0.2:
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
engines: {node: '>=10'}
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
dev: false
/gensync@1.0.0-beta.2:
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
engines: {node: '>=6.9.0'}
@@ -5841,10 +5762,6 @@ packages:
dependencies:
has-symbols: 1.0.3
/has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
dev: false
/has@1.0.3:
resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
engines: {node: '>= 0.4.0'}
@@ -5892,16 +5809,6 @@ packages:
statuses: 2.0.1
toidentifier: 1.0.1
/https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: false
/https-proxy-agent@7.0.2:
resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
engines: {node: '>= 14'}
@@ -6768,9 +6675,11 @@ packages:
/make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
requiresBuild: true
dependencies:
semver: 7.5.4
dev: false
optional: true
/make-error@1.3.6:
resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
@@ -6906,6 +6815,7 @@ packages:
dependencies:
yallist: 4.0.0
dev: false
optional: true
/minipass@4.2.8:
resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==}
@@ -6917,6 +6827,7 @@ packages:
engines: {node: '>=8'}
requiresBuild: true
dev: false
optional: true
/minipass@7.0.4:
resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==}
@@ -6930,6 +6841,7 @@ packages:
minipass: 3.1.3
yallist: 4.0.0
dev: false
optional: true
/mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
@@ -6937,6 +6849,7 @@ packages:
hasBin: true
requiresBuild: true
dev: false
optional: true
/mkdirp@3.0.1:
resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
@@ -7186,10 +7099,6 @@ packages:
thenify-all: 1.6.0
dev: true
/nan@2.17.0:
resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==}
dev: false
/nanoid@3.3.7:
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -7263,10 +7172,6 @@ packages:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
dev: true
/node-addon-api@5.1.0:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
dev: false
/node-bitmap@0.0.1:
resolution: {integrity: sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE=}
engines: {node: '>=v0.6.5'}
@@ -7294,18 +7199,6 @@ packages:
is-stream: 1.1.0
dev: true
/node-fetch@2.6.13:
resolution: {integrity: sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: false
/node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
@@ -7339,13 +7232,6 @@ packages:
resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==}
dev: false
/node-pty@1.0.0:
resolution: {integrity: sha512-wtBMWWS7dFZm/VgqElrTvtfMq4GzJ6+edFI0Y0zyzygUSZMgZdraDUMUhCIvkjhJjme15qWmbyJbtAx4ot4uZA==}
requiresBuild: true
dependencies:
nan: 2.17.0
dev: false
/node-releases@2.0.14:
resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
@@ -7354,14 +7240,6 @@ packages:
engines: {node: '>=6.0.0'}
dev: false
/nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
hasBin: true
dependencies:
abbrev: 1.1.1
dev: false
/normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -7385,15 +7263,6 @@ packages:
path-key: 4.0.0
dev: true
/npmlog@5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
dependencies:
are-we-there-yet: 2.0.0
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
dev: false
/nth-check@1.0.2:
resolution: {integrity: sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==}
dependencies:
@@ -8348,10 +8217,6 @@ packages:
- supports-color
dev: true
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: false
/set-cookie-parser@2.6.0:
resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==}
dev: false
@@ -8566,13 +8431,11 @@ packages:
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
requiresBuild: true
dev: true
/source-map@0.7.4:
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
@@ -8837,6 +8700,7 @@ packages:
mkdirp: 1.0.4
yallist: 4.0.0
dev: false
optional: true
/terser-webpack-plugin@5.3.10(@swc/core@1.4.0)(esbuild@0.19.9)(webpack@5.90.1):
resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==}
@@ -9752,12 +9616,6 @@ packages:
stackback: 0.0.2
dev: true
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 4.2.3
dev: false
/wildcard-match@5.1.2:
resolution: {integrity: sha512-qNXwI591Z88c8bWxp+yjV60Ch4F8Riawe3iGxbzquhy8Xs9m+0+SLFBGb/0yCTIDElawtaImC37fYZ+dr32KqQ==}
dev: false

View File

@@ -18,12 +18,8 @@
}
],
"ignoreDeps": [
"nanoid",
"camelcase-keys",
"class-validator",
"class-transformer",
"@socket.io/redis-emitter",
"@socket.io/redis-adapter"
"class-transformer"
],
"enabled": true
}