diff --git a/.env b/.env index af3db56..2cd02e8 100644 --- a/.env +++ b/.env @@ -1,14 +1,20 @@ -# auth token -API_KEY=1ab2c3d4e5f61ab2c3d4e5f6 - # eoapi-server coinfigure EOAPI_SERVER_PORT=3000 +EOAPI_SERVER_PATH=/api # mysql configure TZ=Asia/Shanghai -MYSQL_HOST=localhost +MYSQL_HOST=host.docker.internal MYSQL_PORT=33066 MYSQL_USERNAME=root MYSQL_DATABASE=eoapi MYSQL_PASSWORD=123456a. MYSQL_ROOT_PASSWORD=123456a. + +# swagger +SWAGGER_PATH=swagger-docs +SWAGGER_ENABLE=true +SWAGGER_VERSION=1.0 +SWAGGER_TITLE=Eoapi-remote-server API文档 +SWAGGER_DESC=Eoapi remote server API document。 + \ No newline at end of file diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..da1387b --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +MYSQL_HOST=localhost \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 8f5aedb..4de8c5e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,13 +2,15 @@ module.exports = { parser: '@typescript-eslint/parser', parserOptions: { project: 'tsconfig.json', - tsconfigRootDir : __dirname, + tsconfigRootDir: __dirname, sourceType: 'module', }, - plugins: ['@typescript-eslint/eslint-plugin'], + plugins: ['@typescript-eslint/eslint-plugin', 'prettier', 'import'], extends: [ + 'eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended', + 'prettier', ], root: true, env: { @@ -21,5 +23,36 @@ module.exports = { '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', + + // prettier + 'prettier/prettier': 'error', + + // import + 'import/first': 'error', + 'import/no-duplicates': 'error', + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + + pathGroups: [ + { + pattern: '@nestjs/**', + group: 'external', + position: 'before', + }, + ], + pathGroupsExcludedImportTypes: ['type'], + }, + ], }, }; diff --git a/.gitignore b/.gitignore index 3da4f0f..f3186f5 100644 --- a/.gitignore +++ b/.gitignore @@ -35,4 +35,7 @@ lerna-debug.log* !.vscode/extensions.json # sample -/sample \ No newline at end of file +/sample + +# env +.env.prodction \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 37441be..ce830bb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,89 @@ { - "files.eol": "\n" + "typescript.tsdk": "./node_modules/typescript/lib", + "typescript.preferences.importModuleSpecifier": "non-relative", + "npm.packageManager": "yarn", + "editor.tabSize": 2, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "files.eol": "\n", + "eslint.probe": [ + "javascript", + "typescript", + "markdown", + "json", + "jsonc" + ], + "eslint.validate": [ + "javascript", + "typescript", + "markdown", + "json", + "jsonc" + ], + "search.exclude": { + "**/node_modules": true, + "**/*.log": true, + "**/*.log*": true, + "**/bower_components": true, + "**/dist": true, + "**/elehukouben": true, + "**/.git": true, + "**/.gitignore": true, + "**/.svn": true, + "**/.DS_Store": true, + "**/.idea": true, + "**/.vscode": false, + "**/yarn.lock": true, + "**/tmp": true, + "out": true, + "dist": true, + "node_modules": true, + "CHANGELOG.md": true, + "examples": true, + "res": true, + "screenshots": true, + "yarn-error.log": true, + "**/.yarn": true + }, + "files.exclude": { + "**/.cache": true, + "**/.editorconfig": true, + "**/.eslintcache": true, + "**/bower_components": true, + "**/.idea": true, + "**/tmp": true, + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true + }, + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, + "**/.vscode/**": true, + "**/node_modules/**": true, + "**/tmp/**": true, + "**/bower_components/**": true, + "**/dist/**": true, + "**/yarn.lock": true + }, + "path-intellisense.mappings": { + "@/": "${workspaceRoot}/src" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } + }, + "[markdown]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[jsonc]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, } \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 2ab31f7..212c66a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -9,8 +9,6 @@ services: restart: always env_file: - .env - environment: - - MYSQL_HOST=host.docker.internal extra_hosts: - 'host.docker.internal:host-gateway' ports: diff --git a/nest-cli.json b/nest-cli.json index 2566481..fb0d691 100644 --- a/nest-cli.json +++ b/nest-cli.json @@ -1,5 +1,8 @@ { "$schema": "https://json.schemastore.org/nest-cli", "collection": "@nestjs/schematics", - "sourceRoot": "src" + "sourceRoot": "src", + "compilerOptions": { + "plugins": ["@nestjs/swagger"] + } } diff --git a/package.json b/package.json index 714b7ae..4eef60d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eoapi-remote-server", - "version": "1.1.0", + "version": "1.8.0", "description": "Storage api data in remote server", "author": "eoapi", "private": true, @@ -13,60 +13,77 @@ "start:dev": "rimraf dist && cross-env NODE_ENV=development nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "cross-env NODE_ENV=production node dist/main.js", - "migration:create": "npm run typeorm migration:create -- -n createTable", - "migration:generate": "npm run typeorm migration:generate -- -n upgradeTable", - "migration:run": "npm run build&&npm run typeorm migration:run", + "migration:create": "npx typeorm-ts-node-commonjs migration:create ./src/migrations/create-table", + "migration:generate": "npx typeorm-ts-node-commonjs migration:generate ./src/migrations/update-table -d ./src/config/data-source.ts", + "migration:run": "npm run build&&npx typeorm-ts-node-commonjs migration:run -d ./src/config/data-source.ts", "migration:revert": "npm run typeorm migration:revert", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", - "typeorm": "node -r tsconfig-paths/register -r ts-node/register ./node_modules/typeorm/cli.js --config src/config/ormconfig.ts", + "typeorm": "npx typeorm-ts-node-commonjs", "test": "jest", "test:watch": "jest --watch", "test:cov": "jest --coverage", "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "test:e2e": "jest --config ./test/jest-e2e.json" + "test:e2e": "jest --config ./test/jest-e2e.json", + "docker:rmi": "docker compose stop eoapi-remote-server && docker container rm eoapi-remote-server && docker rmi eoapi-remote-server", + "docker:dev": "docker compose up --build -d", + "docker:prod": "docker compose --env-file .env.production up --build -d", + "docker:down": "docker compose down", + "docker:logs": "docker compose logs -f" }, "dependencies": { - "@nestjs/common": "^8.0.0", - "@nestjs/config": "^2.0.0", - "@nestjs/core": "^8.0.0", + "@nestjs/axios": "^0.1.0", + "@nestjs/common": "^9.1.2", + "@nestjs/config": "^2.2.0", + "@nestjs/core": "^9.1.2", + "@nestjs/jwt": "^9.0.0", "@nestjs/mapped-types": "*", - "@nestjs/passport": "^8.2.1", - "@nestjs/platform-express": "^8.0.0", - "@nestjs/typeorm": "^8.0.3", + "@nestjs/passport": "^9.0.0", + "@nestjs/platform-express": "^9.1.2", + "@nestjs/swagger": "^6.1.2", + "@nestjs/typeorm": "^9.0.1", "ajv": "^8.11.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.13.2", "cross-env": "^7.0.3", + "crypto-js": "^4.1.1", "mysql2": "^2.3.3", - "passport": "^0.5.3", + "nanoid": "^3.3.4", + "passport": "^0.6.0", "passport-headerapikey": "^1.2.2", + "passport-jwt": "^4.0.0", + "passport-local": "^1.0.0", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^7.2.0", - "typeorm": "^0.2.45" + "rxjs": "^7.5.7", + "typeorm": "^0.3.10" }, "devDependencies": { - "@nestjs/cli": "^8.0.0", - "@nestjs/schematics": "^8.0.0", - "@nestjs/testing": "^8.0.0", - "@types/express": "^4.17.13", - "@types/jest": "27.5.0", - "@types/node": "^16.0.0", - "@types/passport": "^1.0.7", + "@nestjs/cli": "^9.1.3", + "@nestjs/schematics": "^9.0.3", + "@nestjs/testing": "^9.1.2", + "@types/crypto-js": "^4.1.1", + "@types/express": "^4.17.14", + "@types/jest": "29.0.3", + "@types/node": "^18.7.23", + "@types/passport": "^1.0.11", "@types/passport-http": "^0.3.9", - "@types/supertest": "^2.0.11", - "@typescript-eslint/eslint-plugin": "^5.0.0", - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^8.0.1", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-prettier": "^4.0.0", - "jest": "28.0.3", - "prettier": "^2.3.2", - "source-map-support": "^0.5.20", - "supertest": "^6.1.3", - "ts-jest": "28.0.1", - "ts-loader": "^9.2.3", - "ts-node": "^10.0.0", - "tsconfig-paths": "4.0.0", - "typescript": "^4.3.5" + "@types/supertest": "^2.0.12", + "@typescript-eslint/eslint-plugin": "^5.38.1", + "@typescript-eslint/parser": "^5.38.1", + "dotenv": "^16.0.2", + "eslint": "^8.24.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-prettier": "^4.2.1", + "jest": "29.0.3", + "prettier": "^2.7.1", + "source-map-support": "^0.5.21", + "supertest": "^6.2.4", + "ts-jest": "29.0.2", + "ts-loader": "^9.4.1", + "ts-node": "^10.9.1", + "tsconfig-paths": "4.1.0", + "typescript": "^4.8.3" }, "jest": { "moduleFileExtensions": [ diff --git a/src/app.controller.ts b/src/app.controller.ts index 7439083..85df3c5 100644 --- a/src/app.controller.ts +++ b/src/app.controller.ts @@ -1,22 +1,20 @@ -import { Controller, Get, UseGuards } from '@nestjs/common'; -import { AuthGuard } from '@nestjs/passport'; +import { Controller, Get } from '@nestjs/common'; import { AppService } from './app.service'; +import { Public } from '@/common/decorators/public.decorator'; @Controller() export class AppController { constructor(private readonly appService: AppService) {} + @Public() @Get() getHello(): string { return this.appService.getHello(); } @Get('system/status') - @UseGuards(AuthGuard('api-key')) + @Public() status() { - return { - statusCode: 200, - data: 'success', - }; + return 'success'; } } diff --git a/src/app.module.ts b/src/app.module.ts index 1e7f49d..f3d0ae6 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -1,37 +1,42 @@ import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { ConfigModule, ConfigService } from '@nestjs/config'; import { AppController } from './app.controller'; import { AppService } from './app.service'; // 引入数据库的及配置文件 -import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthModule } from './modules/auth/auth.module'; -import { ProjectModule } from './modules/project/project.module'; -import { ApiGroupModule } from './modules/apiGroup/apiGroup.module'; -import { EnvironmentModule } from './modules/environment/environment.module'; -import { ApiDataModule } from './modules/apiData/apiData.module'; -import { ApiTestHistoryModule } from './modules/apiTestHistory/apiTestHistory.module'; -import { MockModule } from './modules/mock/mock.module'; -import { getTypeOrmModuleOptions } from './config/ormconfig'; -import { ConfigModule, ConfigService } from '@nestjs/config'; +import { getConfiguration } from './config/configuration'; +import { UserModule } from '@/modules/user/user.module'; +import { WorkspaceModule } from '@/modules/workspace/workspace.module'; +import { SharedModule } from '@/shared/shared.module'; +console.log('process.env.NODE_ENV', `.env.${process.env.NODE_ENV}`); @Module({ imports: [ ConfigModule.forRoot({ - envFilePath: ['.env'], + envFilePath: [`.env.${process.env.NODE_ENV}`, '.env'], + load: [getConfiguration], }), TypeOrmModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], - useFactory: () => ({ - ...getTypeOrmModuleOptions(), + useFactory: (configService: ConfigService) => ({ + autoLoadEntities: true, + type: configService.get('database.type'), + host: configService.get('database.host'), + port: configService.get('database.port'), + username: configService.get('database.username'), + password: configService.get('database.password'), + database: configService.get('database.database'), + synchronize: configService.get('database.synchronize'), + logging: configService.get('database.logging'), + timezone: configService.get('database.timezone'), // 时区 }), }), // 数据库 + WorkspaceModule, + SharedModule, AuthModule, // 认证 - ProjectModule, - ApiGroupModule, - EnvironmentModule, - ApiDataModule, - ApiTestHistoryModule, - MockModule, + UserModule, ], controllers: [AppController], providers: [AppService], diff --git a/src/common/class/res.class.ts b/src/common/class/res.class.ts new file mode 100644 index 0000000..39ac2fd --- /dev/null +++ b/src/common/class/res.class.ts @@ -0,0 +1,26 @@ +export class ResOp { + readonly data: any; + readonly statusCode: number; + readonly message: string; + + constructor(code: number, data?: any, message = 'success') { + this.statusCode = code; + this.data = data; + this.message = message; + } + + static success(data?: any) { + return new ResOp(200, data); + } +} + +export class Pagination { + total: number; + page: number; + size: number; +} + +export class PageResult { + list?: Array; + pagination: Pagination; +} diff --git a/src/common/contants/decorator.contants.ts b/src/common/contants/decorator.contants.ts new file mode 100644 index 0000000..5d8efd9 --- /dev/null +++ b/src/common/contants/decorator.contants.ts @@ -0,0 +1,5 @@ +// @Keep +export const TRANSFORM_KEEP_KEY_METADATA = 'common:transform_keep'; + +// @Mission +export const MISSION_KEY_METADATA = 'common:mission'; diff --git a/src/common/contants/error-code.contants.ts b/src/common/contants/error-code.contants.ts new file mode 100644 index 0000000..5c1110a --- /dev/null +++ b/src/common/contants/error-code.contants.ts @@ -0,0 +1,8 @@ +/** + * 统一错误代码定义 + */ +export const ErrorCodeMap = { + // 10000 - 99999 业务操作错误 +} as const; + +export type ErrorCodeMapType = keyof typeof ErrorCodeMap; diff --git a/src/common/contants/prefix.contants.ts b/src/common/contants/prefix.contants.ts new file mode 100644 index 0000000..7c15386 --- /dev/null +++ b/src/common/contants/prefix.contants.ts @@ -0,0 +1,5 @@ +export const WORKSPACE_ID_PREFIX = ':workspaceID'; +export const PROJECT_ID_PREFIX = ':projectID'; + +export const WORKSPACE_PROJECT_PREFIX = + `${WORKSPACE_ID_PREFIX}/${PROJECT_ID_PREFIX}` as const; diff --git a/src/common/decorators/keep.decorator.ts b/src/common/decorators/keep.decorator.ts new file mode 100644 index 0000000..b9d6edd --- /dev/null +++ b/src/common/decorators/keep.decorator.ts @@ -0,0 +1,7 @@ +import { SetMetadata } from '@nestjs/common'; +import { TRANSFORM_KEEP_KEY_METADATA } from '../contants/decorator.contants'; + +/** + * 不转化成JSON结构,保留原有返回 + */ +export const Keep = () => SetMetadata(TRANSFORM_KEEP_KEY_METADATA, true); diff --git a/src/common/decorators/public.decorator.ts b/src/common/decorators/public.decorator.ts new file mode 100644 index 0000000..b3845e1 --- /dev/null +++ b/src/common/decorators/public.decorator.ts @@ -0,0 +1,4 @@ +import { SetMetadata } from '@nestjs/common'; + +export const IS_PUBLIC_KEY = 'isPublic'; +export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); diff --git a/src/common/decorators/user.decorator.ts b/src/common/decorators/user.decorator.ts new file mode 100644 index 0000000..570b530 --- /dev/null +++ b/src/common/decorators/user.decorator.ts @@ -0,0 +1,14 @@ +import { createParamDecorator, ExecutionContext } from '@nestjs/common'; + +export type IUser = { + userId: number; + /** 密码版本 */ + pv: number; +}; + +export const User = createParamDecorator( + (_data: unknown, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + return request.currentUser as IUser; + }, +); diff --git a/src/common/dto/page.dto.ts b/src/common/dto/page.dto.ts new file mode 100644 index 0000000..412e805 --- /dev/null +++ b/src/common/dto/page.dto.ts @@ -0,0 +1,25 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { IsInt, Min } from 'class-validator'; + +export class PageOptionsDto { + @ApiProperty({ + description: '当前页包含数量', + required: false, + default: 10, + }) + @Type(() => Number) + @IsInt() + @Min(1) + readonly limit: number = 10; + + @ApiProperty({ + description: '当前页包含数量', + required: false, + default: 1, + }) + @Type(() => Number) + @IsInt() + @Min(1) + readonly page: number = 1; +} diff --git a/src/common/exceptions/api.exception.ts b/src/common/exceptions/api.exception.ts new file mode 100644 index 0000000..b95fa7b --- /dev/null +++ b/src/common/exceptions/api.exception.ts @@ -0,0 +1,24 @@ +import { HttpException } from '@nestjs/common'; +import { + ErrorCodeMap, + ErrorCodeMapType, +} from '../contants/error-code.contants'; + +/** + * Api业务异常均抛出该异常 + */ +export class ApiException extends HttpException { + /** + * 业务类型错误代码,非Http code + */ + private errorCode: ErrorCodeMapType; + + constructor(errorCode: ErrorCodeMapType) { + super(ErrorCodeMap[errorCode], 200); + this.errorCode = errorCode; + } + + getErrorCode(): ErrorCodeMapType { + return this.errorCode; + } +} diff --git a/src/common/filters/api-exception.filter.ts b/src/common/filters/api-exception.filter.ts new file mode 100644 index 0000000..3e73d2d --- /dev/null +++ b/src/common/filters/api-exception.filter.ts @@ -0,0 +1,42 @@ +import { + ArgumentsHost, + Catch, + ExceptionFilter, + HttpException, + HttpStatus, +} from '@nestjs/common'; +import { ApiException } from '../exceptions/api.exception'; +import { ResOp } from '../class/res.class'; +import { isDev } from '@/utils'; + +/** + * 异常接管,统一异常返回数据 + */ +@Catch() +export class ApiExceptionFilter implements ExceptionFilter { + catch(exception: unknown, host: ArgumentsHost) { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + + // check api exection + const status = + exception instanceof HttpException + ? exception.getStatus() + : HttpStatus.INTERNAL_SERVER_ERROR; + // set json response + response.header('Content-Type', 'application/json; charset=utf-8'); + // prod env will not return internal error message + const code = + exception instanceof ApiException + ? (exception as ApiException).getErrorCode() + : status; + let message = '服务器异常,请稍后再试'; + // 开发模式下提示500类型错误,生产模式下屏蔽500内部错误提示 + // if (isDev() || status < 500) { + message = + exception instanceof HttpException ? exception.message : `${exception}`; + // } + const result = new ResOp(code, null, message); + response.status(status).send(result); + } +} diff --git a/src/common/interceptors/api-transform.interceptor.ts b/src/common/interceptors/api-transform.interceptor.ts new file mode 100644 index 0000000..eca3336 --- /dev/null +++ b/src/common/interceptors/api-transform.interceptor.ts @@ -0,0 +1,33 @@ +import { CallHandler, ExecutionContext, NestInterceptor } from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { TRANSFORM_KEEP_KEY_METADATA } from '../contants/decorator.contants'; +import { ResOp } from '../class/res.class'; + +/** + * 统一处理返回接口结果,如果不需要则添加@Keep装饰器 + */ +export class ApiTransformInterceptor implements NestInterceptor { + constructor(private readonly reflector: Reflector) {} + intercept( + context: ExecutionContext, + next: CallHandler, + ): Observable { + return next.handle().pipe( + map((data) => { + const keep = this.reflector.get( + TRANSFORM_KEEP_KEY_METADATA, + context.getHandler(), + ); + if (keep) { + return data; + } else { + const response = context.switchToHttp().getResponse(); + response.header('Content-Type', 'application/json; charset=utf-8'); + return new ResOp(200, data); + } + }), + ); + } +} diff --git a/src/config/configuration.ts b/src/config/configuration.ts new file mode 100644 index 0000000..3215902 --- /dev/null +++ b/src/config/configuration.ts @@ -0,0 +1,37 @@ +import { DataSourceOptions } from 'typeorm'; + +export const getConfiguration = () => ({ + // jwt sign secret + jwt: { + secret: process.env.JWT_SECRET || '123456', + }, + // typeorm config + database: { + type: 'mysql', + host: process.env.MYSQL_HOST, + port: Number.parseInt(process.env.MYSQL_PORT, 10), + username: process.env.MYSQL_USERNAME, + password: process.env.MYSQL_ROOT_PASSWORD, + database: process.env.MYSQL_DATABASE, + entities: [__dirname + '/../**/entities/*.entity.{ts,js}'], + autoLoadEntities: true, + synchronize: false, + logging: false, + timezone: '+08:00', // 东八区 + migrations: ['dist/migrations/**/*.js'], + migrationsRun: true, + cli: { + migrationsDir: 'src/migrations', + }, + } as DataSourceOptions, + // swagger + swagger: { + enable: process.env.SWAGGER_ENABLE === 'true', + path: process.env.SWAGGER_PATH, + title: process.env.SWAGGER_TITLE, + desc: process.env.SWAGGER_DESC, + version: process.env.SWAGGER_VERSION, + }, +}); + +export default getConfiguration(); diff --git a/src/config/data-source.ts b/src/config/data-source.ts new file mode 100644 index 0000000..27c550c --- /dev/null +++ b/src/config/data-source.ts @@ -0,0 +1,7 @@ +import 'reflect-metadata'; +import * as dotenv from 'dotenv'; +import { DataSource } from 'typeorm'; +import { getConfiguration } from './configuration'; +dotenv.config(); + +export const AppDataSource = new DataSource(getConfiguration().database); diff --git a/src/config/ormconfig.ts b/src/config/ormconfig.ts deleted file mode 100644 index 2afab46..0000000 --- a/src/config/ormconfig.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { TypeOrmModuleOptions } from '@nestjs/typeorm'; - -export const getTypeOrmModuleOptions = (): TypeOrmModuleOptions => ({ - type: 'mysql', - host: process.env.MYSQL_HOST, - port: Number.parseInt(process.env.MYSQL_PORT, 10), - username: process.env.MYSQL_USERNAME, - password: process.env.MYSQL_ROOT_PASSWORD, - database: process.env.MYSQL_DATABASE, - entities: [__dirname + '/../**/entities/*.entity.{ts,js}'], - autoLoadEntities: true, - // logging: true, - // synchronize: true, -}); - -export const getOrmConfig = () => ({ - ...getTypeOrmModuleOptions(), - entities: ['dist/entities/**/*.js'], - migrations: ['dist/migrations/**/*.js'], - migrationsRun: true, - cli: { - migrationsDir: 'src/migrations', - }, -}); - -export default getOrmConfig(); diff --git a/src/entities/apiData.entity.ts b/src/entities/apiData.entity.ts index ed69c62..3f9c5b3 100644 --- a/src/entities/apiData.entity.ts +++ b/src/entities/apiData.entity.ts @@ -31,7 +31,7 @@ export class ApiData extends Base { @Column() requestBodyJsonType: string; - @Column({ type: 'json', nullable: true }) + @Column({ type: 'json' }) requestBody: string; @Column({ type: 'json' }) @@ -43,7 +43,7 @@ export class ApiData extends Base { @Column({ type: 'json' }) responseHeaders: string; - @Column({ type: 'json', nullable: true }) + @Column({ type: 'json' }) responseBody: string; @Column() diff --git a/src/entities/apiGroup.entity.ts b/src/entities/apiGroup.entity.ts index d11ec9b..6987665 100644 --- a/src/entities/apiGroup.entity.ts +++ b/src/entities/apiGroup.entity.ts @@ -9,6 +9,6 @@ export class ApiGroup extends Base { @Column({ default: 0 }) parentID: number; - @Column({default:0}) + @Column({ default: 0 }) weight: number; } diff --git a/src/entities/auth.entity.ts b/src/entities/auth.entity.ts new file mode 100644 index 0000000..27d3d46 --- /dev/null +++ b/src/entities/auth.entity.ts @@ -0,0 +1,40 @@ +import { + BaseEntity, + Column, + CreateDateColumn, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + UpdateDateColumn, +} from 'typeorm'; + +import { UserEntity } from './user.entity'; + +@Entity({ name: 'auth' }) +export class AuthEntity extends BaseEntity { + @PrimaryGeneratedColumn() + public id: number; + + @Column({ type: 'varchar' }) + public accessToken: string; + + @Column({ type: 'varchar' }) + public refreshToken: string; + + @Column({ type: 'bigint' }) + public refreshTokenExpiresAt: number; + + @JoinColumn() + @ManyToOne(() => UserEntity) + public user: UserEntity; + + @Column({ type: 'int' }) + public userId: number; + + @CreateDateColumn({ type: 'timestamp' }) + createdAt: Date; + + @UpdateDateColumn({ type: 'timestamp' }) + updatedAt: Date; +} diff --git a/src/entities/base.entity.ts b/src/entities/base.entity.ts index ea1193f..6eda806 100644 --- a/src/entities/base.entity.ts +++ b/src/entities/base.entity.ts @@ -1,3 +1,4 @@ +import { ApiProperty } from '@nestjs/swagger'; import { Column, CreateDateColumn, @@ -8,21 +9,29 @@ import { /** * Without name and description constructure */ -export abstract class FictitiousBase { - @PrimaryGeneratedColumn() - uuid: number; +export abstract class TimestampBase { @CreateDateColumn({ type: 'timestamp' }) + @ApiProperty() createdAt: Date; @UpdateDateColumn({ type: 'timestamp' }) + @ApiProperty() updatedAt: Date; } +export abstract class FictitiousBase extends TimestampBase { + @PrimaryGeneratedColumn() + @ApiProperty() + uuid: number; +} + export abstract class Base extends FictitiousBase { @Column() + @ApiProperty() name: string; @Column({ nullable: true }) + @ApiProperty() description: string; } diff --git a/src/entities/project.entity.ts b/src/entities/project.entity.ts index 4272dde..4961cdf 100644 --- a/src/entities/project.entity.ts +++ b/src/entities/project.entity.ts @@ -1,5 +1,13 @@ -import { Entity } from 'typeorm'; +import { ApiProperty } from '@nestjs/swagger'; +import { Entity, ManyToOne } from 'typeorm'; import { Base } from './base.entity'; +import { WorkspaceEntity } from './workspace.entity'; @Entity({ name: 'project' }) -export class Project extends Base {} +export class Project extends Base { + @ApiProperty({ description: '项目所属空间' }) + @ManyToOne(() => WorkspaceEntity, (user) => user.projects, { + onDelete: 'CASCADE', + }) + workspace: WorkspaceEntity; +} diff --git a/src/entities/user.entity.ts b/src/entities/user.entity.ts new file mode 100644 index 0000000..7d332f3 --- /dev/null +++ b/src/entities/user.entity.ts @@ -0,0 +1,49 @@ +import { ApiHideProperty, ApiProperty } from '@nestjs/swagger'; +import { Exclude } from 'class-transformer'; +import { IsEmail, IsMobilePhone, IsString } from 'class-validator'; +import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from 'typeorm'; +import { WorkspaceEntity } from './workspace.entity'; +import { TimestampBase } from './base.entity'; + +@Entity({ name: 'user' }) +export class UserEntity extends TimestampBase { + @PrimaryGeneratedColumn() + @ApiProperty() + id: number; + + @Column() + @ApiProperty({ example: '路飞', description: '用户名' }) + username: string; + + @ApiProperty({ description: '手机号码' }) + @IsMobilePhone('zh-CN') + @Column({ nullable: true }) + mobilePhone: string; + + @ApiProperty({ example: 'scar@eolink.com', description: '邮箱' }) + @Column({ nullable: true }) + @IsEmail() + email: string; + + @Exclude() + @Column({ type: 'varchar', select: false }) + @ApiHideProperty() + @ApiProperty({ example: '123456', description: '密码' }) + password: string; + + @Column({ type: 'int', nullable: true, default: 1, select: false }) + @ApiHideProperty() + @Exclude() + @ApiProperty({ example: 1, description: '密码版本' }) + passwordVersion: number; + + @Column({ nullable: true }) + @IsString() + @ApiProperty({ example: 'url', description: '用户头像' }) + avatar: string; + + @ApiHideProperty() + @Exclude() + @ManyToMany(() => WorkspaceEntity, (workspace) => workspace.users) + workspaces: WorkspaceEntity[]; +} diff --git a/src/entities/workspace.entity.ts b/src/entities/workspace.entity.ts new file mode 100644 index 0000000..ca338ea --- /dev/null +++ b/src/entities/workspace.entity.ts @@ -0,0 +1,38 @@ +import { ApiProperty, ApiHideProperty } from '@nestjs/swagger'; +import { + PrimaryGeneratedColumn, + Column, + Entity, + ManyToMany, + JoinTable, + OneToMany, +} from 'typeorm'; +import { Exclude } from 'class-transformer'; +import { UserEntity } from './user.entity'; +import { Project } from './project.entity'; +import { TimestampBase } from './base.entity'; + +@Entity({ name: 'workspace' }) +export class WorkspaceEntity extends TimestampBase { + @PrimaryGeneratedColumn() + @ApiProperty() + id: number; + + @Column() + @ApiProperty({ example: '在线空间1', description: '空间名称' }) + title: string; + + @Column() + @ApiProperty({ example: 'scar', description: '空间创建者ID' }) + creatorID: number; + + @Exclude() + @ApiHideProperty() + @ManyToMany(() => UserEntity, (user) => user.workspaces) + @JoinTable() + users: UserEntity[]; + + @ApiProperty({ description: '当前空间下的所有项目' }) + @OneToMany(() => Project, (project) => project.workspace) + projects: Project[]; +} diff --git a/src/main.ts b/src/main.ts index cc11c56..080cfb0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,26 +1,29 @@ -import { NestFactory } from '@nestjs/core'; +import { NestFactory, Reflector } from '@nestjs/core'; +import { Logger } from '@nestjs/common'; import * as bodyParser from 'body-parser'; import { AppModule } from './app.module'; -import { Logger } from '@nestjs/common'; -import { writeFileSync } from 'node:fs'; -import { getOrmConfig } from './config/ormconfig'; +import { setupSwagger } from '@/setup-swagger'; +import { ApiExceptionFilter } from '@/common/filters/api-exception.filter'; +import { ApiTransformInterceptor } from '@/common/interceptors/api-transform.interceptor'; +import { ValidationPipe } from '@/pipe/validation.pipe'; async function bootstrap() { const app = await NestFactory.create(AppModule); app.enableCors(); app.use(bodyParser.json({ limit: '50mb' })); app.use(bodyParser.urlencoded({ limit: '50mb', extended: true })); + + app.useGlobalPipes(new ValidationPipe()); + // execption + app.useGlobalFilters(new ApiExceptionFilter()); + // api interceptor + app.useGlobalInterceptors(new ApiTransformInterceptor(new Reflector())); + // swagger + setupSwagger(app); await app.listen(process.env.EOAPI_SERVER_PORT, '0.0.0.0'); - Logger.log(`api服务已经启动,请访问: ${await app.getUrl()}`); + const serverUrl = await app.getUrl(); + Logger.log(`api服务已经启动,请访问: ${serverUrl}`); + Logger.log(`API文档已生成,请访问: ${serverUrl}/${process.env.SWAGGER_PATH}/`); } -const generateOrmconfigJson = () => { - // try { - // writeFileSync('./ormconfig.json', JSON.stringify(getOrmConfig(), null, 2)); - // console.log('ormconfig.json 写入成功'); - // } catch (err) { - // console.error(err); - // } -}; - -bootstrap().then(generateOrmconfigJson); +bootstrap(); diff --git a/src/migrations/1652758382828-CreateTables.ts b/src/migrations/1652758382828-CreateTables.ts index 9b646bc..4c7d78c 100644 --- a/src/migrations/1652758382828-CreateTables.ts +++ b/src/migrations/1652758382828-CreateTables.ts @@ -4,7 +4,7 @@ export class createTable1652758382828 implements MigrationInterface { name = 'createTable1652758382828'; public async up(queryRunner: QueryRunner): Promise { await queryRunner.query( - `CREATE TABLE \`api_data\` (\`uuid\` int NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`description\` varchar(255) NULL, \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \`updatedAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE NOW(), \`uniqueID\` varchar(36) NOT NULL, \`projectID\` int NOT NULL DEFAULT '0', \`groupID\` int NOT NULL DEFAULT '0', \`uri\` varchar(255) NOT NULL, \`protocol\` varchar(255) NOT NULL, \`method\` varchar(255) NOT NULL, \`requestBodyType\` varchar(255) NOT NULL, \`requestHeaders\` json NOT NULL, \`requestBodyJsonType\` varchar(255) NOT NULL, \`requestBody\` json NULL, \`queryParams\` json NOT NULL, \`restParams\` json NOT NULL, \`responseHeaders\` json NOT NULL, \`responseBody\` json NULL, \`responseBodyType\` varchar(255) NOT NULL, \`responseBodyJsonType\` varchar(255) NOT NULL, \`weight\` int NOT NULL DEFAULT '0', PRIMARY KEY (\`uuid\`)) ENGINE=InnoDB`, + `CREATE TABLE \`api_data\` (\`uuid\` int NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`description\` varchar(255) NULL, \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \`updatedAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE NOW(), \`uniqueID\` varchar(36) NOT NULL, \`projectID\` int NOT NULL DEFAULT '0', \`groupID\` int NOT NULL DEFAULT '0', \`uri\` varchar(255) NOT NULL, \`protocol\` varchar(255) NOT NULL, \`method\` varchar(255) NOT NULL, \`requestBodyType\` varchar(255) NOT NULL, \`requestHeaders\` json NOT NULL, \`requestBodyJsonType\` varchar(255) NOT NULL, \`requestBody\` json NOT NULL, \`queryParams\` json NOT NULL, \`restParams\` json NOT NULL, \`responseHeaders\` json NOT NULL, \`responseBody\` json NOT NULL, \`responseBodyType\` varchar(255) NOT NULL, \`responseBodyJsonType\` varchar(255) NOT NULL, \`weight\` int NOT NULL DEFAULT '0', PRIMARY KEY (\`uuid\`)) ENGINE=InnoDB`, ); await queryRunner.query( `CREATE TABLE \`api_group\` (\`uuid\` int NOT NULL AUTO_INCREMENT, \`name\` varchar(255) NOT NULL, \`description\` varchar(255) NULL, \`createdAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, \`updatedAt\` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE NOW(), \`projectID\` int NOT NULL DEFAULT '0', \`parentID\` int NOT NULL DEFAULT '0', \`weight\` int NOT NULL DEFAULT '0', PRIMARY KEY (\`uuid\`)) ENGINE=InnoDB`, diff --git a/src/migrations/1652764517480-InitData.ts b/src/migrations/1652764517480-InitData.ts index e74d58b..37ad4b4 100644 --- a/src/migrations/1652764517480-InitData.ts +++ b/src/migrations/1652764517480-InitData.ts @@ -24,7 +24,7 @@ export class InitData1652764517480 implements MigrationInterface { method: 'GET', requestBodyType: 'raw', requestBodyJsonType: 'object', - requestBody: '{}', + requestBody: {}, queryParams: [], restParams: [ { @@ -124,7 +124,7 @@ export class InitData1652764517480 implements MigrationInterface { method: 'GET', requestBodyType: 'raw', requestBodyJsonType: 'object', - requestBody: '{}', + requestBody: {}, queryParams: [{ name: 'name', required: true, example: 'disease_h5' }], restParams: [], requestHeaders: [], diff --git a/src/migrations/1664727097056-update-table.ts b/src/migrations/1664727097056-update-table.ts new file mode 100644 index 0000000..2574a9f --- /dev/null +++ b/src/migrations/1664727097056-update-table.ts @@ -0,0 +1,87 @@ +import { MigrationInterface, QueryRunner } from 'typeorm'; + +export class updateTable1664727097056 implements MigrationInterface { + name = 'updateTable1664727097056'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `UPDATE api_data SET requestBody='[]' WHERE requestBody IS NULL`, + ); + await queryRunner.query( + `UPDATE api_data SET responseBody='[]' WHERE responseBody IS NULL`, + ); + await queryRunner.query( + `CREATE TABLE \`workspace\` (\`createdAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updatedAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`id\` int NOT NULL AUTO_INCREMENT, \`title\` varchar(255) NOT NULL, \`creatorID\` int NOT NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `CREATE TABLE \`user\` (\`createdAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updatedAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), \`id\` int NOT NULL AUTO_INCREMENT, \`username\` varchar(255) NOT NULL, \`mobilePhone\` varchar(255) NULL, \`email\` varchar(255) NULL, \`password\` varchar(255) NOT NULL, \`passwordVersion\` int NULL DEFAULT '1', \`avatar\` varchar(255) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `CREATE TABLE \`auth\` (\`id\` int NOT NULL AUTO_INCREMENT, \`accessToken\` varchar(255) NOT NULL, \`refreshToken\` varchar(255) NOT NULL, \`refreshTokenExpiresAt\` bigint NOT NULL, \`userId\` int NOT NULL, \`createdAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), \`updatedAt\` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), PRIMARY KEY (\`id\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `CREATE TABLE \`workspace_users_user\` (\`workspaceId\` int NOT NULL, \`userId\` int NOT NULL, INDEX \`IDX_e560bebe0dad802fbb036ba878\` (\`workspaceId\`), INDEX \`IDX_ff70af68685d8a5d6b588dfdc5\` (\`userId\`), PRIMARY KEY (\`workspaceId\`, \`userId\`)) ENGINE=InnoDB`, + ); + await queryRunner.query( + `ALTER TABLE \`project\` ADD \`workspaceId\` int NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`api_data\` CHANGE \`requestBody\` \`requestBody\` json NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`api_data\` CHANGE \`responseBody\` \`responseBody\` json NOT NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`project\` ADD CONSTRAINT \`FK_c224ab17df530651e53a398ed92\` FOREIGN KEY (\`workspaceId\`) REFERENCES \`workspace\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE \`auth\` ADD CONSTRAINT \`FK_373ead146f110f04dad60848154\` FOREIGN KEY (\`userId\`) REFERENCES \`user\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE \`workspace_users_user\` ADD CONSTRAINT \`FK_e560bebe0dad802fbb036ba8788\` FOREIGN KEY (\`workspaceId\`) REFERENCES \`workspace\`(\`id\`) ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE \`workspace_users_user\` ADD CONSTRAINT \`FK_ff70af68685d8a5d6b588dfdc5b\` FOREIGN KEY (\`userId\`) REFERENCES \`user\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `UPDATE api_data SET requestBody='[]' WHERE requestBody IS NULL`, + ); + await queryRunner.query( + `UPDATE api_data SET responseBody='[]' WHERE responseBody IS NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`workspace_users_user\` DROP FOREIGN KEY \`FK_ff70af68685d8a5d6b588dfdc5b\``, + ); + await queryRunner.query( + `ALTER TABLE \`workspace_users_user\` DROP FOREIGN KEY \`FK_e560bebe0dad802fbb036ba8788\``, + ); + await queryRunner.query( + `ALTER TABLE \`auth\` DROP FOREIGN KEY \`FK_373ead146f110f04dad60848154\``, + ); + await queryRunner.query( + `ALTER TABLE \`project\` DROP FOREIGN KEY \`FK_c224ab17df530651e53a398ed92\``, + ); + await queryRunner.query( + `ALTER TABLE \`api_data\` CHANGE \`responseBody\` \`responseBody\` json NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`api_data\` CHANGE \`requestBody\` \`requestBody\` json NULL`, + ); + await queryRunner.query( + `ALTER TABLE \`project\` DROP COLUMN \`workspaceId\``, + ); + await queryRunner.query( + `DROP INDEX \`IDX_ff70af68685d8a5d6b588dfdc5\` ON \`workspace_users_user\``, + ); + await queryRunner.query( + `DROP INDEX \`IDX_e560bebe0dad802fbb036ba878\` ON \`workspace_users_user\``, + ); + await queryRunner.query(`DROP TABLE \`workspace_users_user\``); + await queryRunner.query(`DROP TABLE \`auth\``); + await queryRunner.query(`DROP TABLE \`user\``); + await queryRunner.query(`DROP TABLE \`workspace\``); + } +} diff --git a/src/modules/apiData/apiData.controller.ts b/src/modules/apiData/apiData.controller.ts deleted file mode 100644 index 3d07423..0000000 --- a/src/modules/apiData/apiData.controller.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Put, - Param, - Delete, - Query, - UseGuards, -} from '@nestjs/common'; -import { ApiDataService } from './apiData.service'; -import { CreateDto } from './dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { ValidateQueryPipe } from 'src/pipe/query.pipe'; -import { retry } from 'rxjs'; - -@Controller('api_data') -@UseGuards(AuthGuard('api-key')) -export class ApiDataController { - private readonly NOT_FOUND = { - statusCode: 201, - message: 'Cannot find record in database', - error: 'Not Found', - }; - - private readonly JSON_FIELDS = [ - 'requestHeaders', - 'requestBody', - 'queryParams', - 'restParams', - 'responseHeaders', - 'responseBody', - ]; - - constructor(private readonly service: ApiDataService) {} - filterItem(item: any = {}) { - this.JSON_FIELDS.forEach((field) => { - item[field] = item[field] ? JSON.stringify(item[field]) : '{}'; - }); - return item; - } - @Post() - async create(@Body() createDto: CreateDto) { - createDto = this.filterItem(createDto); - const data = await this.service.create(createDto); - if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); - } - - return this.NOT_FOUND; - } - - @Post('batch') - async batchCreate(@Body() createDto: Array) { - createDto.map((val) => { - return this.filterItem(val); - }); - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; - } - - @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - return { - statusCode: 200, - data: data, - }; - } - - @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - @Put('batch') - async batchUpdate(@Body() updateDtos: Array) { - const ids = updateDtos.map((val) => val.uuid); - const array = await this.service.findByIds(ids); - const newArr = array.map((el) => { - const item = updateDtos.find((val) => Number(val.uuid) === el.uuid); - return this.filterItem({ - ...el, - groupID: Number(item.groupID), - weight: item.weight, - }); - }); - const data = await this.service.bulkUpdate(newArr); - if (data) { - return this.service.findByIds(ids); - } - return this.NOT_FOUND; - } - @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { - updateDto = this.filterItem(updateDto); - const data = await this.service.update(+uuid, updateDto); - if (data) { - return await this.findOne(uuid); - } - return this.NOT_FOUND; - } - - @Delete() - async remove(@Query(ValidateQueryPipe) query) { - const data = await this.service.remove(query.uuids); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } -} diff --git a/src/modules/apiData/apiData.module.ts b/src/modules/apiData/apiData.module.ts deleted file mode 100644 index 59b2963..0000000 --- a/src/modules/apiData/apiData.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ApiDataService } from './apiData.service'; -import { ApiDataController } from './apiData.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApiData } from '../..//entities/apiData.entity'; -import { MockModule } from '../mock/mock.module'; -import { Mock } from '../../entities/mock.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([ApiData, Mock]), MockModule], - controllers: [ApiDataController], - providers: [ApiDataService], - exports: [ApiDataService], -}) -export class ApiDataModule {} diff --git a/src/modules/apiData/dto/query.dto.ts b/src/modules/apiData/dto/query.dto.ts deleted file mode 100644 index bcadcc9..0000000 --- a/src/modules/apiData/dto/query.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class QueryDto { - name: string; - projectID: number; - groupID: number; -} diff --git a/src/modules/apiGroup/apiGroup.controller.spec.ts b/src/modules/apiGroup/apiGroup.controller.spec.ts deleted file mode 100644 index 38b37ca..0000000 --- a/src/modules/apiGroup/apiGroup.controller.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ApiGroupController } from './apiGroup.controller'; -import { ApiGroupService } from './apiGroup.service'; - -describe('ApiGroupController', () => { - let controller: ApiGroupController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [ApiGroupController], - providers: [ApiGroupService], - }).compile(); - - controller = module.get(ApiGroupController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/src/modules/apiGroup/apiGroup.controller.ts b/src/modules/apiGroup/apiGroup.controller.ts deleted file mode 100644 index af381f5..0000000 --- a/src/modules/apiGroup/apiGroup.controller.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Put, - Param, - Delete, - Query, - UseGuards, -} from '@nestjs/common'; -import { ApiGroupService } from './apiGroup.service'; -import { CreateDto } from './dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { ValidateQueryPipe } from 'src/pipe/query.pipe'; - -@Controller('group') -@UseGuards(AuthGuard('api-key')) -export class ApiGroupController { - private readonly NOT_FOUND = { - statusCode: 201, - message: 'Cannot find record in database', - error: 'Not Found', - }; - - constructor(private readonly service: ApiGroupService) {} - - @Post() - async create(@Body() createDto: CreateDto) { - const data = await this.service.create(createDto); - if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); - } - - return this.NOT_FOUND; - } - - @Post('batch') - async batchCreate(@Body() createDto: Array) { - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; - } - - @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - return { - statusCode: 200, - data: data, - }; - } - - @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - @Put('batch') - async batchUpdate(@Body() updateDtos: Array) { - let ids = updateDtos.map((val) => val.uuid); - const array = await this.service.findByIds(ids); - const newArr = array.map((el) => { - let item = updateDtos.find((val) => (val.uuid == el.uuid)); - return { - ...el, - parentID: item.parentID, - weight: item.weight, - }; - }); - const data = await this.service.bulkUpdate(newArr); - if (data) { - return this.service.findByIds(ids); - } - return this.NOT_FOUND; - } - @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { - const data = await this.service.update(+uuid, updateDto); - if (data) { - return await this.findOne(uuid); - } - - return this.NOT_FOUND; - } - - @Delete() - async remove(@Query(ValidateQueryPipe) query) { - const data = await this.service.remove(query.uuids); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } -} diff --git a/src/modules/apiGroup/apiGroup.module.ts b/src/modules/apiGroup/apiGroup.module.ts deleted file mode 100644 index f5a5b35..0000000 --- a/src/modules/apiGroup/apiGroup.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ApiGroupService } from './apiGroup.service'; -import { ApiGroupController } from './apiGroup.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApiGroup } from '../..//entities/apiGroup.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([ApiGroup])], - controllers: [ApiGroupController], - providers: [ApiGroupService], - exports: [ApiGroupService], -}) -export class ApiGroupModule {} diff --git a/src/modules/apiGroup/apiGroup.service.spec.ts b/src/modules/apiGroup/apiGroup.service.spec.ts deleted file mode 100644 index abfb6f2..0000000 --- a/src/modules/apiGroup/apiGroup.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ApiGroupService } from './apiGroup.service'; - -describe('ApiGroupService', () => { - let service: ApiGroupService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ApiGroupService], - }).compile(); - - service = module.get(ApiGroupService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/src/modules/apiTestHistory/apiTestHistory.controller.spec.ts b/src/modules/apiTestHistory/apiTestHistory.controller.spec.ts deleted file mode 100644 index 7b70e27..0000000 --- a/src/modules/apiTestHistory/apiTestHistory.controller.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ApiTestHistoryController } from './apiTestHistory.controller'; -import { ApiTestHistoryService } from './apiTestHistory.service'; - -describe('ProjectController', () => { - let controller: ApiTestHistoryController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [ApiTestHistoryController], - providers: [ApiTestHistoryService], - }).compile(); - - controller = module.get(ApiTestHistoryController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/src/modules/apiTestHistory/apiTestHistory.controller.ts b/src/modules/apiTestHistory/apiTestHistory.controller.ts deleted file mode 100644 index 78433c2..0000000 --- a/src/modules/apiTestHistory/apiTestHistory.controller.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Put, - Param, - Delete, - Query, - UseGuards, -} from '@nestjs/common'; -import { ApiTestHistoryService } from './apiTestHistory.service'; -import { CreateDto } from './dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { ValidateQueryPipe } from 'src/pipe/query.pipe'; - -@Controller('api_test_history') -@UseGuards(AuthGuard('api-key')) -export class ApiTestHistoryController { - private readonly NOT_FOUND = { - statusCode: 201, - message: 'Cannot find record in database', - error: 'Not Found', - }; - - private readonly JSON_FIELDS = ['general', 'request', 'response']; - - constructor(private readonly service: ApiTestHistoryService) {} - - @Post() - async create(@Body() createDto: CreateDto) { - const data = await this.service.create(createDto); - if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); - } - - return this.NOT_FOUND; - } - - @Post('batch') - async batchCreate(@Body() createDto: Array) { - createDto.map((val) => { - this.JSON_FIELDS.forEach((field) => { - if (val[field]) { - val[field] = JSON.stringify(val[field]); - } - }); - return val; - }); - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; - } - - @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - - return { - statusCode: 200, - data: data, - }; - } - - @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - - @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { - this.JSON_FIELDS.forEach((field) => { - if (updateDto[field]) { - updateDto[field] = JSON.stringify(updateDto[field]); - } - }); - const data = await this.service.update(+uuid, updateDto); - if (data) { - return await this.findOne(uuid); - } - - return this.NOT_FOUND; - } - - @Delete() - async remove(@Query(ValidateQueryPipe) query) { - const data = await this.service.remove(query.uuids); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } -} diff --git a/src/modules/apiTestHistory/apiTestHistory.module.ts b/src/modules/apiTestHistory/apiTestHistory.module.ts deleted file mode 100644 index 45cdb5d..0000000 --- a/src/modules/apiTestHistory/apiTestHistory.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ApiTestHistoryService } from './apiTestHistory.service'; -import { ApiTestHistoryController } from './apiTestHistory.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { ApiTestHistory } from '../..//entities/apiTestHistory.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([ApiTestHistory])], - controllers: [ApiTestHistoryController], - providers: [ApiTestHistoryService], -}) -export class ApiTestHistoryModule {} diff --git a/src/modules/apiTestHistory/apiTestHistory.service.spec.ts b/src/modules/apiTestHistory/apiTestHistory.service.spec.ts deleted file mode 100644 index 8436cd5..0000000 --- a/src/modules/apiTestHistory/apiTestHistory.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ApiTestHistoryService } from './apiTestHistory.service'; - -describe('ApiTestHistoryService', () => { - let service: ApiTestHistoryService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ApiTestHistoryService], - }).compile(); - - service = module.get(ApiTestHistoryService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/src/modules/auth/auth-header-api-key.strategy.ts b/src/modules/auth/auth-header-api-key.strategy.ts deleted file mode 100644 index 33f344f..0000000 --- a/src/modules/auth/auth-header-api-key.strategy.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable, UnauthorizedException } from '@nestjs/common'; -import { PassportStrategy } from '@nestjs/passport'; -import { ConfigService } from '@nestjs/config'; -import Strategy from 'passport-headerapikey'; - -@Injectable() -export class HeaderApiKeyStrategy extends PassportStrategy( - Strategy, - 'api-key', -) { - constructor(private readonly configService: ConfigService) { - super({ header: 'X-API-KEY', prefix: '' }, true, async (apiKey, done) => { - return this.validate(apiKey, done); - }); - } - - // eslint-disable-next-line @typescript-eslint/ban-types - public validate = (apiKey: string, done: (error: Error, data) => {}) => { - if (this.configService.get('API_KEY') === apiKey) { - done(null, true); - } - done(new UnauthorizedException(), null); - }; -} diff --git a/src/modules/auth/auth.class.ts b/src/modules/auth/auth.class.ts new file mode 100644 index 0000000..e5b467a --- /dev/null +++ b/src/modules/auth/auth.class.ts @@ -0,0 +1,15 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class LoginToken { + @ApiProperty({ description: 'JWT身份Token' }) + accessToken: string; + + @ApiProperty({ description: 'Refresh Token' }) + refreshToken: string; + + @ApiProperty() + accessTokenExpiresAt: number; + + @ApiProperty() + refreshTokenExpiresAt: number; +} diff --git a/src/modules/auth/auth.constants.ts b/src/modules/auth/auth.constants.ts new file mode 100644 index 0000000..439c5d7 --- /dev/null +++ b/src/modules/auth/auth.constants.ts @@ -0,0 +1,4 @@ +/** 7 days */ +export const accessTokenExpiresIn = 7 * 24 * 60 * 60 * 1000; +/** 30 days */ +export const refreshTokenExpiresIn = 30 * 24 * 60 * 60 * 1000; diff --git a/src/modules/auth/auth.controller.ts b/src/modules/auth/auth.controller.ts new file mode 100644 index 0000000..69888ef --- /dev/null +++ b/src/modules/auth/auth.controller.ts @@ -0,0 +1,54 @@ +import { Body, Controller, Post, Put } from '@nestjs/common'; +import { ApiOkResponse, ApiOperation, ApiTags } from '@nestjs/swagger'; +import { AuthService } from './auth.service'; +import { Public } from '@/common/decorators/public.decorator'; +import { LoginInfoDto } from '@/modules/auth/dto/login.dto'; +import { LoginToken } from '@/modules/auth/auth.class'; +import { JwtLogoutDto, JwtRefreshTokenDto } from '@/modules/auth/dto'; +import { UserService } from '@/modules/user/user.service'; + +@ApiTags('auth') +@Controller('auth') +export class AuthController { + constructor( + private readonly authService: AuthService, + private readonly userService: UserService, + ) {} + + @ApiOperation({ + summary: '用户登录/注册', + }) + @ApiOkResponse({ type: LoginToken }) + @Public() + @Post('login') + async login(@Body() userLoginDto: LoginInfoDto) { + return this.authService.login(userLoginDto); + } + + @ApiOperation({ + summary: '刷新token', + }) + @Public() + @Put('refresh') + async refreshToken(@Body() dto: JwtRefreshTokenDto): Promise { + return this.authService.refresh(dto); + } + @ApiOperation({ + summary: '用户登出', + }) + @Post('logout') + public async logout(@Body() dto: JwtLogoutDto): Promise { + await this.authService.delete(dto); + return true; + } + + // @ApiOperation({ + // summary: '用户注册', + // deprecated: true, + // }) + // @Get('signup') + // public async signup(@Body() dto: LoginInfoDto): Promise { + // const userEntity = await this.userService.getOrCreateUser(dto); + // return this.authService.loginUser(userEntity); + // } +} diff --git a/src/modules/auth/auth.module.ts b/src/modules/auth/auth.module.ts index 4c3eea1..114ac0c 100644 --- a/src/modules/auth/auth.module.ts +++ b/src/modules/auth/auth.module.ts @@ -1,10 +1,40 @@ import { Module } from '@nestjs/common'; import { PassportModule } from '@nestjs/passport'; -import { HeaderApiKeyStrategy } from './auth-header-api-key.strategy'; -import { ConfigModule } from '@nestjs/config'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { JwtModule } from '@nestjs/jwt'; +import { APP_GUARD } from '@nestjs/core'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthController } from './auth.controller'; +import { UserModule } from '@/modules/user/user.module'; +import { AuthService } from '@/modules/auth/auth.service'; +import { JwtAuthGuard } from '@/modules/auth/guards/jwt-auth.guard'; +import { AuthEntity } from '@/entities/auth.entity'; @Module({ - imports: [PassportModule, ConfigModule], - providers: [HeaderApiKeyStrategy], + imports: [ + TypeOrmModule.forFeature([AuthEntity]), + PassportModule, + ConfigModule, + UserModule, + PassportModule, + JwtModule.registerAsync({ + imports: [ConfigModule], + useFactory: (configService: ConfigService) => ({ + secret: configService.get('jwt.secret'), + signOptions: { expiresIn: '600s' }, + }), + inject: [ConfigService], + }), + ], + controllers: [AuthController], + providers: [ + AuthService, + // JwtStrategy, + { + provide: APP_GUARD, + useClass: JwtAuthGuard, + }, + ], + exports: [AuthService], }) export class AuthModule {} diff --git a/src/modules/auth/auth.service.ts b/src/modules/auth/auth.service.ts new file mode 100644 index 0000000..bc15e6f --- /dev/null +++ b/src/modules/auth/auth.service.ts @@ -0,0 +1,124 @@ +import { + forwardRef, + Inject, + Injectable, + OnModuleInit, + UnauthorizedException, +} from '@nestjs/common'; +import { JwtService } from '@nestjs/jwt'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ModuleRef } from '@nestjs/core'; +import { DeleteResult, FindOptionsWhere, Repository } from 'typeorm'; +import { nanoid } from 'nanoid'; +import { LoginInfoDto } from '@/modules/auth/dto/login.dto'; +import { UserService } from '@/modules/user/user.service'; +import { UserEntity } from '@/entities/user.entity'; +import { AuthEntity } from '@/entities/auth.entity'; +import { + accessTokenExpiresIn, + refreshTokenExpiresIn, +} from '@/modules/auth/auth.constants'; +import { LoginToken } from '@/modules/auth/auth.class'; +import { UserLoginResultDto } from '@/modules/user/user.dto'; + +@Injectable() +export class AuthService implements OnModuleInit { + private userService: UserService; + constructor( + @InjectRepository(AuthEntity) + private readonly authEntityRepository: Repository, + private readonly jwtService: JwtService, + private moduleRef: ModuleRef, + ) {} + onModuleInit() { + this.userService = this.moduleRef.get(UserService, { strict: false }); + } + // async validateUser(username: string, password: string): Promise { + // const user = await this.usersService.findOne({ username, password }); + // if (user && (await bcrypt.compare(password, user.password))) { + // Reflect.deleteProperty(user, 'password'); + // return user; + // } + // return null; + // } + + async login(dto: LoginInfoDto): Promise { + const userEntity = await this.userService.getByCredentials( + dto.username, + dto.password, + ); + + if (!userEntity) { + throw new UnauthorizedException(); + } + + return this.loginUser(userEntity); + } + + async findOne(where: FindOptionsWhere): Promise { + return this.authEntityRepository.findOne({ where }); + } + + async delete(where: FindOptionsWhere): Promise { + return this.authEntityRepository.delete(where); + } + + async refresh(where: FindOptionsWhere): Promise { + const authEntity = await this.authEntityRepository.findOne({ + where, + relations: ['user'], + select: { + user: { id: true, passwordVersion: true, password: true }, + }, + }); + + if ( + !authEntity || + authEntity.refreshTokenExpiresAt < new Date().getTime() + ) { + throw new UnauthorizedException(); + } + return this.loginUser( + { + ...authEntity.user, + isFirstLogin: false, + }, + String(where.refreshToken), + ); + } + + async loginUser( + userEntity: UserLoginResultDto, + refreshToken = '', + ): Promise { + if (refreshToken) { + const isRefresh = await this.authEntityRepository.findOne({ + where: { refreshToken }, + }); + if (isRefresh) { + await this.authEntityRepository.delete({ refreshToken }); + } + } + + const date = new Date(); + + const result = { + accessToken: this.jwtService.sign( + { userId: userEntity.id, pv: userEntity.passwordVersion }, + { expiresIn: accessTokenExpiresIn / 1000 }, + ), + refreshToken: nanoid(), + accessTokenExpiresAt: date.getTime() + accessTokenExpiresIn, + refreshTokenExpiresAt: date.getTime() + refreshTokenExpiresIn, + isFirstLogin: userEntity.isFirstLogin, + }; + await this.authEntityRepository + .create({ + ...result, + user: userEntity, + }) + .save(); + + return result; + } +} diff --git a/src/modules/auth/dto/index.ts b/src/modules/auth/dto/index.ts new file mode 100644 index 0000000..5888fb8 --- /dev/null +++ b/src/modules/auth/dto/index.ts @@ -0,0 +1,3 @@ +export * from './login.dto'; +export * from './logout.dto'; +export * from './refresh.dto'; diff --git a/src/modules/auth/dto/login.dto.ts b/src/modules/auth/dto/login.dto.ts new file mode 100644 index 0000000..be1f6db --- /dev/null +++ b/src/modules/auth/dto/login.dto.ts @@ -0,0 +1,20 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { + IsMobilePhone, + IsNotEmpty, + IsString, + MinLength, +} from 'class-validator'; + +export class LoginInfoDto { + @ApiProperty({ description: '用户名' }) + @IsString() + @IsNotEmpty({ message: '用户名不能为空' }) + username: string; + + @ApiProperty({ description: '密码' }) + @IsNotEmpty({ message: '密码不能为空' }) + @IsString() + @MinLength(6) + password: string; +} diff --git a/src/modules/auth/dto/logout.dto.ts b/src/modules/auth/dto/logout.dto.ts new file mode 100644 index 0000000..bed919c --- /dev/null +++ b/src/modules/auth/dto/logout.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString } from 'class-validator'; + +export class JwtLogoutDto { + @ApiProperty() + @IsString() + refreshToken: string; +} diff --git a/src/modules/auth/dto/refresh.dto.ts b/src/modules/auth/dto/refresh.dto.ts new file mode 100644 index 0000000..93919fd --- /dev/null +++ b/src/modules/auth/dto/refresh.dto.ts @@ -0,0 +1,8 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsString } from 'class-validator'; + +export class JwtRefreshTokenDto { + @ApiProperty() + @IsString() + refreshToken: string; +} diff --git a/src/modules/auth/guards/jwt-auth.guard.ts b/src/modules/auth/guards/jwt-auth.guard.ts new file mode 100644 index 0000000..3beca20 --- /dev/null +++ b/src/modules/auth/guards/jwt-auth.guard.ts @@ -0,0 +1,77 @@ +import { + CanActivate, + ExecutionContext, + ForbiddenException, + Injectable, + UnauthorizedException, +} from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import { JwtService } from '@nestjs/jwt'; +import { isEmpty } from 'lodash'; +import { IS_PUBLIC_KEY } from '@/common/decorators/public.decorator'; +import { AuthService } from '@/modules/auth/auth.service'; +import { IUser } from '@/common/decorators/user.decorator'; +import { UserService } from '@/modules/user/user.service'; + +/** + * admin perm check guard + */ +@Injectable() +export class JwtAuthGuard implements CanActivate { + constructor( + private reflector: Reflector, + private jwtService: JwtService, + private authService: AuthService, + private userService: UserService, + ) {} + + async canActivate(context: ExecutionContext): Promise { + // 检测是否是开放类型的,例如获取验证码类型的接口不需要校验,可以加入@Public可自动放过 + const isPublic = this.reflector.getAllAndOverride(IS_PUBLIC_KEY, [ + context.getHandler(), + context.getClass(), + ]); + if (isPublic) { + return true; + } + const request = context.switchToHttp().getRequest(); + const token = request.headers['authorization'] as string; + if (isEmpty(token)) { + throw new UnauthorizedException(); + } + try { + // 挂载对象到当前请求上 + request.currentUser = this.jwtService.verify(token); + const isExit = await this.authService.findOne({ accessToken: token }); + const { passwordVersion } = await this.userService.findOne({ + where: { id: request.currentUser.userId }, + select: ['passwordVersion'], + }); + if (!isExit || passwordVersion !== request.currentUser.pv) { + throw new UnauthorizedException(); + } + } catch (e) { + // 无法通过token校验 + throw new UnauthorizedException(); + } + if (isEmpty(request.currentUser)) { + throw new UnauthorizedException(); + } + + const workspaceID = Number(request?.params?.workspaceID); + if (!Number.isNaN(workspaceID)) { + const hasWorkspaceAuth = await this.userService.findOneBy({ + id: request.currentUser.userId, + workspaces: { + id: workspaceID, + }, + }); + if (!hasWorkspaceAuth) { + throw new ForbiddenException(); + } + } + + // pass + return true; + } +} diff --git a/src/modules/auth/strategies/jwt.strategy.ts b/src/modules/auth/strategies/jwt.strategy.ts new file mode 100644 index 0000000..b1fd112 --- /dev/null +++ b/src/modules/auth/strategies/jwt.strategy.ts @@ -0,0 +1,26 @@ +import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { PassportStrategy } from '@nestjs/passport'; +import { ExtractJwt, Strategy } from 'passport-jwt'; +import { UserEntity } from '@/entities/user.entity'; + +@Injectable() +export class JwtStrategy extends PassportStrategy(Strategy) { + constructor(configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKey: configService.get('jwt.secret'), + }); + } + + async validate(payload: any): Promise { + const { username } = payload; + const user = await this.userRepository.findOne({ username }); + + if (!user) { + throw new UnauthorizedException(); + } + return user; + } +} diff --git a/src/modules/environment/environment.controller.spec.ts b/src/modules/environment/environment.controller.spec.ts deleted file mode 100644 index 655f05e..0000000 --- a/src/modules/environment/environment.controller.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { EnvironmentController } from './environment.controller'; -import { EnvironmentService } from './environment.service'; - -describe('ProjectController', () => { - let controller: EnvironmentController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [EnvironmentController], - providers: [EnvironmentService], - }).compile(); - - controller = module.get(EnvironmentController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/src/modules/environment/environment.module.ts b/src/modules/environment/environment.module.ts deleted file mode 100644 index 362df1b..0000000 --- a/src/modules/environment/environment.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Module } from '@nestjs/common'; -import { EnvironmentService } from './environment.service'; -import { EnvironmentController } from './environment.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Environment } from '../..//entities/environment.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([Environment])], - controllers: [EnvironmentController], - providers: [EnvironmentService], - exports: [EnvironmentService], -}) -export class EnvironmentModule {} diff --git a/src/modules/environment/environment.service.spec.ts b/src/modules/environment/environment.service.spec.ts deleted file mode 100644 index cd2ad4b..0000000 --- a/src/modules/environment/environment.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { EnvironmentService } from './environment.service'; - -describe('EnvironmentService', () => { - let service: EnvironmentService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [EnvironmentService], - }).compile(); - - service = module.get(EnvironmentService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/src/modules/mock/mock.controller.ts b/src/modules/mock/mock.controller.ts deleted file mode 100644 index 2c89f53..0000000 --- a/src/modules/mock/mock.controller.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { - Controller, - Get, - Req, - Post, - Body, - Put, - Param, - Delete, - Query, -} from '@nestjs/common'; -import { MockService } from './mock.service'; -import { CreateDto } from './dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; -import { Request } from 'express'; -import { All } from '@nestjs/common'; - -@Controller('mock') -export class MockController { - private readonly NOT_FOUND = { - statusCode: 201, - message: 'Cannot find record in database', - error: 'Not Found', - }; - - constructor(private readonly service: MockService) {} - - @Post() - async create(@Body() createDto: CreateDto) { - const data = await this.service.create(createDto); - if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); - } - return this.NOT_FOUND; - } - - @Post('batch') - async batchCreate(@Body() createDto: Array) { - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; - } - - @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - return { - statusCode: 200, - data: data, - }; - } - - @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - - @All(':projectID/**') - async findMock( - @Param('projectID') projectID: string, - @Req() request: Request, - ) { - const response = await this.service.findMock(projectID, request); - - return response ?? this.NOT_FOUND; - } - - @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { - const data = await this.service.update(+uuid, updateDto); - if (data) { - return await this.findOne(uuid); - } - - return this.NOT_FOUND; - } - - @Delete(':uuid') - async remove(@Param('uuid') uuid: string) { - const mock = await this.service.findOne(+uuid); - if (mock.createWay === 'system') { - return { - statusCode: 200, - data: {}, - message: '系统自动创建的mock不能删除', - }; - } - const data = await this.service.remove(+uuid); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } -} diff --git a/src/modules/mock/mock.module.ts b/src/modules/mock/mock.module.ts deleted file mode 100644 index ebd465e..0000000 --- a/src/modules/mock/mock.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from '@nestjs/common'; -import { MockService } from './mock.service'; -import { MockController } from './mock.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Mock } from '../../entities/mock.entity'; -import { ApiData } from 'src/entities/apiData.entity'; - -@Module({ - imports: [TypeOrmModule.forFeature([Mock, ApiData])], - controllers: [MockController], - providers: [MockService], - exports: [MockService], -}) -export class MockModule {} diff --git a/src/modules/project/project.controller.ts b/src/modules/project/project.controller.ts deleted file mode 100644 index cba9649..0000000 --- a/src/modules/project/project.controller.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { - Controller, - Get, - Post, - Body, - Put, - Param, - Delete, - Query, - UseGuards, -} from '@nestjs/common'; -import { ProjectService } from './project.service'; -import { CreateDto } from './dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; -import { AuthGuard } from '@nestjs/passport'; -import { ImportDto } from './dto/import.dto'; - -@Controller('project') -@UseGuards(AuthGuard('api-key')) -export class ProjectController { - private readonly NOT_FOUND = { - statusCode: 201, - message: 'Cannot find record in database', - error: 'Not Found', - }; - - constructor(private readonly service: ProjectService) {} - - @Post() - async create(@Body() createDto: CreateDto) { - const data = await this.service.create(createDto); - if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); - } - - return this.NOT_FOUND; - } - - @Post('batch') - async batchCreate(@Body() createDto: Array) { - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; - } - - @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - return { - statusCode: 200, - data: data, - }; - } - - @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - - @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { - const data = await this.service.update(+uuid, updateDto); - if (data) { - return await this.findOne(uuid); - } - - return this.NOT_FOUND; - } - - @Delete(':uuid') - async remove(@Param('uuid') uuid: string) { - const data = await this.service.remove(+uuid); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; - } - - @Put(':uuid/import') - async import(@Param('uuid') uuid: string, @Body() importDto: ImportDto) { - // console.log('uuid', uuid, importDto); - const data = await this.service.import(Number(uuid), importDto); - return { - statusCode: 200, - data: { - errors: data, - }, - }; - } -} diff --git a/src/modules/project/project.module.ts b/src/modules/project/project.module.ts deleted file mode 100644 index ba834e0..0000000 --- a/src/modules/project/project.module.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ProjectService } from './project.service'; -import { ProjectController } from './project.controller'; -import { TypeOrmModule } from '@nestjs/typeorm'; -import { Project } from '../../entities/project.entity'; -import { ApiDataModule } from '../apiData/apiData.module'; -import { ApiGroupModule } from '../apiGroup/apiGroup.module'; -import { EnvironmentModule } from '../environment/environment.module'; - -@Module({ - imports: [ - TypeOrmModule.forFeature([Project]), - ApiDataModule, - ApiGroupModule, - EnvironmentModule, - ], - controllers: [ProjectController], - providers: [ProjectService], -}) -export class ProjectModule {} diff --git a/src/modules/user/user.controller.ts b/src/modules/user/user.controller.ts new file mode 100644 index 0000000..7053ac8 --- /dev/null +++ b/src/modules/user/user.controller.ts @@ -0,0 +1,53 @@ +import { + Body, + ClassSerializerInterceptor, + Controller, + Get, + Param, + Put, + UseInterceptors, +} from '@nestjs/common'; +import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; +import { UserService } from './user.service'; +import { UpdateUserInfoDto, UpdateUserPasswordDto } from './user.dto'; +import { UserEntity } from '@/entities/user.entity'; +import { IUser, User } from '@/common/decorators/user.decorator'; +import { LoginToken } from '@/modules/auth/auth.class'; + +@ApiBearerAuth() +@ApiTags('user') +@Controller('user') +export class UserController { + constructor(private readonly userService: UserService) {} + + @ApiOperation({ summary: '查看个人信息' }) + @Get('profile') + @UseInterceptors(ClassSerializerInterceptor) + public getUserProfile(@User() user: IUser): Promise { + return this.userService.findOneBy({ id: user.userId }); + } + + @Put('profile') + @ApiOperation({ summary: '更新个人资料' }) + async updateUserProfile( + @User() user: IUser, + @Body() updateUserDto: UpdateUserInfoDto, + ): Promise { + return this.userService.updateUserProfile(user.userId, updateUserDto); + } + + @Put('password') + @ApiOperation({ summary: '更改个人密码' }) + async updateUserPassword( + @User() user: IUser, + @Body() updateUserDto: UpdateUserPasswordDto, + ): Promise { + return this.userService.updateUserPassword(user.userId, updateUserDto); + } + + @Get(':username') + @ApiOperation({ summary: '搜索用户' }) + findOne(@Param('username') username: string) { + return this.userService.searchUsers(username); + } +} diff --git a/src/modules/user/user.dto.ts b/src/modules/user/user.dto.ts new file mode 100644 index 0000000..000a089 --- /dev/null +++ b/src/modules/user/user.dto.ts @@ -0,0 +1,54 @@ +import { OmitType, PartialType } from '@nestjs/mapped-types'; +import { ApiProperty } from '@nestjs/swagger'; +import { IsOptional, IsString, MinLength } from 'class-validator'; +import { UserEntity } from '@/entities/user.entity'; + +export class UserLoginDto { + @ApiProperty({ description: '用户名' }) + @MinLength(1) + @IsString() + readonly username: string; + + @ApiProperty({ description: '密码' }) + @MinLength(1) + @IsString() + readonly password: string; +} +export class CreateUserDto extends UserLoginDto {} + +export class UserLoginToken { + @ApiProperty({ description: 'JWT身份Token' }) + token: string; +} + +export class UpdateUserInfoDto extends PartialType( + OmitType(UserEntity, ['password', 'passwordVersion']), +) {} + +export class UpdateUserPasswordDto { + @ApiProperty({ description: '旧密码', required: false }) + @MinLength(6) + @IsString() + readonly oldPassword: string; + + @ApiProperty({ description: '新密码', required: false }) + @MinLength(6) + @IsString() + readonly newPassword: string; +} + +export class UserInfoValidator { + @ApiProperty({ description: '旧密码', required: false }) + @MinLength(6) + @IsString() + readonly oldPassword: string; + + @ApiProperty({ description: '新密码', required: false }) + @MinLength(6) + @IsString() + readonly newPassword: string; +} + +export class UserLoginResultDto extends UserEntity { + isFirstLogin: boolean; +} diff --git a/src/modules/user/user.module.ts b/src/modules/user/user.module.ts new file mode 100644 index 0000000..5dcf692 --- /dev/null +++ b/src/modules/user/user.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { UserController } from './user.controller'; +import { UserService } from './user.service'; +import { UserEntity } from '@/entities/user.entity'; + +@Module({ + imports: [TypeOrmModule.forFeature([UserEntity])], + controllers: [UserController], + providers: [UserService], + exports: [UserService], +}) +export class UserModule {} diff --git a/src/modules/user/user.service.ts b/src/modules/user/user.service.ts new file mode 100644 index 0000000..cada79f --- /dev/null +++ b/src/modules/user/user.service.ts @@ -0,0 +1,214 @@ +import { + ConflictException, + ForbiddenException, + Injectable, + OnModuleInit, +} from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ModuleRef } from '@nestjs/core'; +import { + Equal, + FindManyOptions, + FindOneOptions, + FindOptionsWhere, + Like, + Not, + Repository, +} from 'typeorm'; +import { validate } from 'class-validator'; +import { nanoid } from 'nanoid'; +import { + UpdateUserInfoDto, + UpdateUserPasswordDto, + UserLoginDto, + UserLoginResultDto, +} from './user.dto'; +import { UserEntity } from '@/entities/user.entity'; +import { UtilService } from '@/shared/services/util.service'; +import { AuthService } from '@/modules/auth/auth.service'; +import { LoginToken } from '@/modules/auth/auth.class'; +import { WorkspaceService } from '@/modules/workspace/workspace.service'; +import { ProjectService } from '@/modules/workspace/project/project.service'; + +@Injectable() +export class UserService implements OnModuleInit { + private authService: AuthService; + private workspaceService: WorkspaceService; + private projectService: ProjectService; + constructor( + private utils: UtilService, + private moduleRef: ModuleRef, + @InjectRepository(UserEntity) + private userRepository: Repository, + ) {} + + onModuleInit() { + this.authService = this.moduleRef.get(AuthService, { strict: false }); + this.workspaceService = this.moduleRef.get(WorkspaceService, { + strict: false, + }); + this.projectService = this.moduleRef.get(ProjectService, { + strict: false, + }); + } + + findOne(options: FindOneOptions): Promise { + return this.userRepository.findOne(options); + } + + findOneBy(where: FindOptionsWhere): Promise { + return this.userRepository.findOneBy(where); + } + + find(where: FindManyOptions): Promise { + return this.userRepository.find(where); + } + + findAndCount( + options: FindManyOptions, + ): Promise<[Array, number]> { + return this.userRepository.findAndCount(options); + } + + async getByCredentials( + username: string, + password: string, + ): Promise { + // return this.userRepository.findOne({ + // where: { + // username, + // password: await this.createPasswordHash(password), + // }, + // }); + return this.getOrCreateUser({ username, password }); + } + + validateUser(userDto: Partial) { + const userValidator = new UserEntity(); + userValidator.email = userDto.username; + userValidator.mobilePhone = userDto.username; + + return validate(userValidator).then((errors) => { + const result = {} as UserEntity; + const validateFields = errors.map((n) => n.property); + if (!validateFields.includes('email')) { + result.email = userDto.username; + } + if (!validateFields.includes('mobilePhone')) { + result.mobilePhone = userDto.username; + } + return result; + }); + } + + async getOrCreateUser(userDto: UserLoginDto): Promise { + const user = await this.userRepository.findOne({ + where: [ + { username: Equal(userDto.username) }, + { email: Equal(userDto.username) }, + { mobilePhone: Equal(userDto.username) }, + ], + select: ['id', 'username', 'password', 'avatar', 'passwordVersion'], + }); + if (user) { + if (this.utils.md5(userDto.password) === user.password) { + return { + ...user, + isFirstLogin: false, + }; + } else { + throw new ForbiddenException('密码错误'); + } + } else { + const other = await this.validateUser(userDto); + if (Object.keys(other).length === 0) { + throw new Error('用户名必须是手机号码或邮箱'); + } + const user = await this.userRepository.save({ + ...other, + ...userDto, + password: this.utils.md5(userDto.password), + }); + this.userRepository.update(user.id, { username: `user_${nanoid(10)}` }); + if (user.id === 1) { + const defaultProject = await this.projectService.findOneBy(1); + if (defaultProject) { + this.workspaceService.create( + user.id, + { + title: '默认空间', + }, + defaultProject, + ); + } + } + + return { + ...user, + isFirstLogin: true, + }; + } + } + + async searchUsers(username: string) { + const [result] = await this.userRepository.findAndCount({ + where: [ + { username: Like(`%${username}%`) }, + { email: Like(`%${username}%`) }, + { mobilePhone: Like(`%${username}%`) }, + ], + }); + return result; + } + + async updateUserProfile( + userId, + userInfoDto: UpdateUserInfoDto, + ): Promise { + // const other = await this.validateUser(userInfoDto); + // if (userInfoDto.username && Object.keys(other).length === 0) { + // throw new Error('用户名必须是手机号码或邮箱'); + // } + const isConflict = await this.userRepository.findOne({ + where: { username: Equal(userInfoDto.username), id: Not(userId) }, + }); + if (isConflict) { + throw new ConflictException('用户名已存在'); + } + Reflect.deleteProperty(userInfoDto, 'password'); + await this.userRepository.update(userId, { + username: userInfoDto.username, + }); + return this.userRepository.findOneBy({ id: userId }); + } + + async updateUserPassword( + userId, + userPasswordDto: UpdateUserPasswordDto, + ): Promise { + const user = await this.userRepository.findOne({ + where: { id: userId }, + select: ['password', 'passwordVersion'], + }); + if (!user) { + throw new ConflictException('用户不存在'); + } + if (!userPasswordDto.newPassword) { + throw new ConflictException('新密码不能为空'); + } + const oldPassword = this.utils.md5(userPasswordDto.oldPassword); + if (oldPassword !== user.password) { + throw new ForbiddenException('旧密码验证失败'); + } + await this.userRepository.update(userId, { + password: this.utils.md5(userPasswordDto.newPassword), + passwordVersion: user.passwordVersion + 1, + }); + const userInfo = await this.userRepository.findOneBy({ id: userId }); + userInfo.passwordVersion = user.passwordVersion + 1; + return this.authService.loginUser({ + ...userInfo, + isFirstLogin: false, + }); + } +} diff --git a/src/modules/apiData/apiData.controller.spec.ts b/src/modules/workspace/apiData/apiData.controller.spec.ts similarity index 100% rename from src/modules/apiData/apiData.controller.spec.ts rename to src/modules/workspace/apiData/apiData.controller.spec.ts diff --git a/src/modules/workspace/apiData/apiData.controller.ts b/src/modules/workspace/apiData/apiData.controller.ts new file mode 100644 index 0000000..898f50f --- /dev/null +++ b/src/modules/workspace/apiData/apiData.controller.ts @@ -0,0 +1,99 @@ +import { + Controller, + Get, + Post, + Body, + Put, + Param, + Delete, + Query, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { ValidateQueryPipe } from 'src/pipe/query.pipe'; +import { ApiDataService } from './apiData.service'; +import { CreateDto } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { WORKSPACE_PROJECT_PREFIX } from '@/common/contants/prefix.contants'; + +@ApiTags('apiData') +@Controller(`${WORKSPACE_PROJECT_PREFIX}/api_data`) +export class ApiDataController { + private readonly JSON_FIELDS = [ + 'requestHeaders', + 'requestBody', + 'queryParams', + 'restParams', + 'responseHeaders', + 'responseBody', + ]; + + constructor(private readonly service: ApiDataService) {} + filterItem(item: any = {}, projectID) { + this.JSON_FIELDS.forEach((field) => { + item[field] = item[field] ? JSON.stringify(item[field]) : '{}'; + item.projectID = projectID; + }); + return item; + } + @Post() + async create(@Body() createDto: CreateDto, @Param('projectID') projectID) { + createDto = this.filterItem(createDto, projectID); + return this.service.create({ ...createDto, projectID }); + } + + @Post('batch') + async batchCreate( + @Body() createDto: Array, + @Param('projectID') projectID, + ) { + createDto.map((val) => { + return this.filterItem(val, projectID); + }); + return this.service.batchCreate(createDto); + } + + @Get() + async findAll(@Param('projectID') projectID, @Query() query: QueryDto) { + return this.service.findAll({ ...query, projectID }); + } + + @Get(':uuid') + async findOne(@Param('uuid') uuid, @Param('projectID') projectID) { + return this.service.findOne({ where: { uuid, projectID } }); + } + @Put('batch') + async batchUpdate( + @Body() updateDtos: Array, + @Param('projectID') projectID, + ) { + const ids = updateDtos.map((val) => val.uuid); + const array = await this.service.findByIds(ids); + const newArr = array.map((el) => { + const item = updateDtos.find((val) => Number(val.uuid) === el.uuid); + return this.filterItem( + { + ...el, + groupID: Number(item.groupID), + weight: item.weight, + }, + projectID, + ); + }); + return this.service.bulkUpdate(newArr); + } + @Put(':uuid') + async update( + @Param('uuid') uuid: string, + @Param('projectID') projectID, + @Body() updateDto: UpdateDto, + ) { + updateDto = this.filterItem(updateDto, projectID); + return this.service.update(+uuid, updateDto); + } + + @Delete() + async remove(@Query(ValidateQueryPipe) query) { + return this.service.remove(query.uuids); + } +} diff --git a/src/modules/apiData/apiData.service.spec.ts b/src/modules/workspace/apiData/apiData.service.spec.ts similarity index 100% rename from src/modules/apiData/apiData.service.spec.ts rename to src/modules/workspace/apiData/apiData.service.spec.ts diff --git a/src/modules/apiData/apiData.service.ts b/src/modules/workspace/apiData/apiData.service.ts similarity index 77% rename from src/modules/apiData/apiData.service.ts rename to src/modules/workspace/apiData/apiData.service.ts index cd77ea3..6aab7c8 100644 --- a/src/modules/apiData/apiData.service.ts +++ b/src/modules/workspace/apiData/apiData.service.ts @@ -1,12 +1,12 @@ -import { ConsoleLogger, Injectable } from '@nestjs/common'; +import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { In, Repository } from 'typeorm'; -import { ApiData } from '../../entities/apiData.entity'; +import { FindOneOptions, In, Repository } from 'typeorm'; +import { MockService } from '../mock/mock.service'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; -import { MockService } from '../mock/mock.service'; -import { Mock } from '../../entities/mock.entity'; +import { ApiData } from '@/entities/apiData.entity'; +import { Mock } from '@/entities/mock.entity'; @Injectable() export class ApiDataService { @@ -38,11 +38,11 @@ export class ApiDataService { .execute(); } - async findAll(query: QueryDto) { - const apiData = await this.repository.find(query); + async findAll(query: Partial) { + const apiData = await this.repository.find({ where: query }); const mockApiDataIds = ( await this.mockRepository.find({ - apiDataID: In(apiData.map((n) => n.uuid)), + where: { apiDataID: In(apiData.map((n) => n.uuid)) }, }) ).map((n) => n.apiDataID); @@ -57,8 +57,8 @@ export class ApiDataService { return apiData; } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOne(options: FindOneOptions): Promise { + return await this.repository.findOne(options); } async update(id: number, updateDto: UpdateDto) { diff --git a/src/modules/apiData/dto/create.dto.ts b/src/modules/workspace/apiData/dto/create.dto.ts similarity index 100% rename from src/modules/apiData/dto/create.dto.ts rename to src/modules/workspace/apiData/dto/create.dto.ts diff --git a/src/modules/workspace/apiData/dto/query.dto.ts b/src/modules/workspace/apiData/dto/query.dto.ts new file mode 100644 index 0000000..72fd8c0 --- /dev/null +++ b/src/modules/workspace/apiData/dto/query.dto.ts @@ -0,0 +1,14 @@ +import { ApiParam, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsOptional } from 'class-validator'; + +export class QueryDto { + @ApiPropertyOptional({ description: 'api名称' }) + @IsOptional() + name: string; + + projectID: number; + + @ApiPropertyOptional({ description: '分组ID' }) + @IsOptional() + groupID: number; +} diff --git a/src/modules/apiData/dto/update.dto.ts b/src/modules/workspace/apiData/dto/update.dto.ts similarity index 100% rename from src/modules/apiData/dto/update.dto.ts rename to src/modules/workspace/apiData/dto/update.dto.ts diff --git a/src/modules/workspace/apiGroup/apiGroup.controller.ts b/src/modules/workspace/apiGroup/apiGroup.controller.ts new file mode 100644 index 0000000..4b25e1e --- /dev/null +++ b/src/modules/workspace/apiGroup/apiGroup.controller.ts @@ -0,0 +1,91 @@ +import { + Controller, + Get, + Post, + Body, + Put, + Param, + Delete, + Query, + ParseIntPipe, + NotFoundException, + BadRequestException, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { ValidateQueryPipe } from 'src/pipe/query.pipe'; +import { ApiGroupService } from './apiGroup.service'; +import { CreateDto } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { WORKSPACE_PROJECT_PREFIX } from '@/common/contants/prefix.contants'; + +@ApiTags('apiGroup') +@Controller(`${WORKSPACE_PROJECT_PREFIX}/group`) +export class ApiGroupController { + constructor(private readonly service: ApiGroupService) {} + + @Post() + async create(@Body() createDto: CreateDto, @Param('projectID') projectID) { + const { uuid } = await this.service.create({ ...createDto, projectID }); + return await this.findOne(uuid, projectID); + } + + @Post('batch') + async batchCreate(@Body() createDto: Array) { + return this.service.batchCreate(createDto); + } + + @Get() + async findAll(@Query() query: QueryDto, @Param('projectID') projectID) { + return this.service.findAll({ ...query, projectID }); + } + + @Get(':uuid') + async findOne( + @Param('uuid', ParseIntPipe) uuid: number, + @Param('projectID') projectID, + ) { + return this.service.findOne({ where: { uuid, projectID } }); + } + @Put('batch') + async batchUpdate(@Body() updateDtos: Array) { + const ids = updateDtos.map((val) => val.uuid); + const array = await this.service.findByIds(ids); + const newArr = array.map((el) => { + const item = updateDtos.find((val) => val.uuid == el.uuid); + return { + ...el, + parentID: item.parentID, + weight: item.weight, + }; + }); + const data = await this.service.bulkUpdate(newArr); + if (data) { + return this.service.findByIds(ids); + } + return new BadRequestException('批量修改失败!'); + } + @Put(':uuid') + async update( + @Param('uuid', ParseIntPipe) uuid: number, + @Param('projectID') projectID, + @Body() updateDto: UpdateDto, + ) { + const data = await this.service.update(+uuid, updateDto); + if (data) { + return await this.findOne(uuid, projectID); + } + + return new NotFoundException('修改失败!分组不存在'); + } + + @Delete() + async remove(@Query(ValidateQueryPipe) query) { + const data = await this.service.remove(query.uuids); + if (data && data.affected > 0) { + return data; + } + + return new NotFoundException('删除失败!该分组不存在'); + } +} diff --git a/src/modules/apiGroup/apiGroup.service.ts b/src/modules/workspace/apiGroup/apiGroup.service.ts similarity index 72% rename from src/modules/apiGroup/apiGroup.service.ts rename to src/modules/workspace/apiGroup/apiGroup.service.ts index 0804964..30d0e5f 100644 --- a/src/modules/apiGroup/apiGroup.service.ts +++ b/src/modules/workspace/apiGroup/apiGroup.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { ApiGroup } from '../../entities/apiGroup.entity'; +import { FindOneOptions, Repository } from 'typeorm'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; +import { ApiGroup } from '@/entities/apiGroup.entity'; @Injectable() export class ApiGroupService { @@ -26,21 +26,21 @@ export class ApiGroupService { .execute(); } - async findAll(query: QueryDto) { - return await this.repository.find(query); + async findAll(query: Partial) { + return await this.repository.find({ where: query }); } async findByIds(ids: number[]) { return await this.repository.findByIds(ids); } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOne(options: FindOneOptions): Promise { + return await this.repository.findOne(options); } async update(id: number, updateDto: UpdateDto) { return await this.repository.update(id, updateDto); } - async bulkUpdate(updateDto: Array){ + async bulkUpdate(updateDto: Array) { return await this.repository.save(updateDto); } async remove(id: number) { diff --git a/src/modules/apiGroup/dto/create.dto.ts b/src/modules/workspace/apiGroup/dto/create.dto.ts similarity index 100% rename from src/modules/apiGroup/dto/create.dto.ts rename to src/modules/workspace/apiGroup/dto/create.dto.ts diff --git a/src/modules/apiGroup/dto/query.dto.ts b/src/modules/workspace/apiGroup/dto/query.dto.ts similarity index 100% rename from src/modules/apiGroup/dto/query.dto.ts rename to src/modules/workspace/apiGroup/dto/query.dto.ts diff --git a/src/modules/apiGroup/dto/update.dto.ts b/src/modules/workspace/apiGroup/dto/update.dto.ts similarity index 100% rename from src/modules/apiGroup/dto/update.dto.ts rename to src/modules/workspace/apiGroup/dto/update.dto.ts diff --git a/src/modules/workspace/apiTestHistory/apiTestHistory.controller.ts b/src/modules/workspace/apiTestHistory/apiTestHistory.controller.ts new file mode 100644 index 0000000..7a5c7a1 --- /dev/null +++ b/src/modules/workspace/apiTestHistory/apiTestHistory.controller.ts @@ -0,0 +1,74 @@ +import { + Controller, + Get, + Post, + Body, + Put, + Param, + Delete, + Query, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { ValidateQueryPipe } from 'src/pipe/query.pipe'; +import { ApiTestHistoryService } from './apiTestHistory.service'; +import { CreateDto } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { WORKSPACE_PROJECT_PREFIX } from '@/common/contants/prefix.contants'; + +@ApiTags('apiTestHistory') +@Controller(`${WORKSPACE_PROJECT_PREFIX}/api_test_history`) +export class ApiTestHistoryController { + private readonly JSON_FIELDS = ['general', 'request', 'response']; + + constructor(private readonly service: ApiTestHistoryService) {} + + @Post() + async create(@Body() createDto: CreateDto, @Param('projectID') projectID) { + const data = await this.service.create({ ...createDto, projectID }); + return await this.findOne(`${data.uuid}`, projectID); + } + + @Post('batch') + async batchCreate(@Body() createDto: Array) { + createDto.map((val) => { + this.JSON_FIELDS.forEach((field) => { + if (val[field]) { + val[field] = JSON.stringify(val[field]); + } + }); + return val; + }); + return this.service.batchCreate(createDto); + } + + @Get() + async findAll(@Query() query: QueryDto, @Param('projectID') projectID) { + return this.service.findAll({ ...query, projectID }); + } + + @Get(':uuid') + async findOne(@Param('uuid') uuid: string, @Param('projectID') projectID) { + return this.service.findOne(+uuid, projectID); + } + + @Put(':uuid') + async update( + @Param('uuid') uuid: string, + @Body() updateDto: UpdateDto, + @Param('projectID') projectID, + ) { + this.JSON_FIELDS.forEach((field) => { + if (updateDto[field]) { + updateDto[field] = JSON.stringify(updateDto[field]); + } + }); + await this.service.update(+uuid, updateDto); + return await this.findOne(uuid, projectID); + } + + @Delete() + async remove(@Query(ValidateQueryPipe) query) { + return await this.service.remove(query.uuids); + } +} diff --git a/src/modules/apiTestHistory/apiTestHistory.service.ts b/src/modules/workspace/apiTestHistory/apiTestHistory.service.ts similarity index 78% rename from src/modules/apiTestHistory/apiTestHistory.service.ts rename to src/modules/workspace/apiTestHistory/apiTestHistory.service.ts index 86c2b1a..649fef0 100644 --- a/src/modules/apiTestHistory/apiTestHistory.service.ts +++ b/src/modules/workspace/apiTestHistory/apiTestHistory.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { ApiTestHistory } from '../../entities/apiTestHistory.entity'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; +import { ApiTestHistory } from '@/entities/apiTestHistory.entity'; @Injectable() export class ApiTestHistoryService { @@ -27,11 +27,11 @@ export class ApiTestHistoryService { } async findAll(query: QueryDto) { - return await this.repository.find(query); + return await this.repository.find({ where: query }); } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOne(uuid: number, projectID: number): Promise { + return await this.repository.findOne({ where: { uuid, projectID } }); } async update(id: number, updateDto: UpdateDto) { diff --git a/src/modules/apiTestHistory/dto/create.dto.ts b/src/modules/workspace/apiTestHistory/dto/create.dto.ts similarity index 100% rename from src/modules/apiTestHistory/dto/create.dto.ts rename to src/modules/workspace/apiTestHistory/dto/create.dto.ts diff --git a/src/modules/apiTestHistory/dto/query.dto.ts b/src/modules/workspace/apiTestHistory/dto/query.dto.ts similarity index 100% rename from src/modules/apiTestHistory/dto/query.dto.ts rename to src/modules/workspace/apiTestHistory/dto/query.dto.ts diff --git a/src/modules/apiTestHistory/dto/update.dto.ts b/src/modules/workspace/apiTestHistory/dto/update.dto.ts similarity index 100% rename from src/modules/apiTestHistory/dto/update.dto.ts rename to src/modules/workspace/apiTestHistory/dto/update.dto.ts diff --git a/src/modules/environment/dto/create.dto.ts b/src/modules/workspace/environment/dto/create.dto.ts similarity index 100% rename from src/modules/environment/dto/create.dto.ts rename to src/modules/workspace/environment/dto/create.dto.ts diff --git a/src/modules/environment/dto/query.dto.ts b/src/modules/workspace/environment/dto/query.dto.ts similarity index 100% rename from src/modules/environment/dto/query.dto.ts rename to src/modules/workspace/environment/dto/query.dto.ts diff --git a/src/modules/environment/dto/update.dto.ts b/src/modules/workspace/environment/dto/update.dto.ts similarity index 100% rename from src/modules/environment/dto/update.dto.ts rename to src/modules/workspace/environment/dto/update.dto.ts diff --git a/src/modules/environment/environment.controller.ts b/src/modules/workspace/environment/environment.controller.ts similarity index 55% rename from src/modules/environment/environment.controller.ts rename to src/modules/workspace/environment/environment.controller.ts index 459714d..19c6fe4 100644 --- a/src/modules/environment/environment.controller.ts +++ b/src/modules/workspace/environment/environment.controller.ts @@ -7,16 +7,16 @@ import { Param, Delete, Query, - UseGuards, } from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; import { EnvironmentService } from './environment.service'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; -import { AuthGuard } from '@nestjs/passport'; +import { WORKSPACE_PROJECT_PREFIX } from '@/common/contants/prefix.contants'; -@Controller('environment') -@UseGuards(AuthGuard('api-key')) +@ApiTags('Environment') +@Controller(`${WORKSPACE_PROJECT_PREFIX}/environment`) export class EnvironmentController { private readonly NOT_FOUND = { statusCode: 201, @@ -29,62 +29,53 @@ export class EnvironmentController { constructor(private readonly service: EnvironmentService) {} @Post() - async create(@Body() createDto: CreateDto) { + async create(@Body() createDto: CreateDto, @Param('projectID') projectID) { this.JSON_FIELDS.forEach((field) => { if (createDto[field]) { createDto[field] = JSON.stringify(createDto[field]); } }); - const data = await this.service.create(createDto); + const data = await this.service.create({ ...createDto, projectID }); if (data && data.uuid) { - return await this.findOne(`${data.uuid}`); + return await this.findOne(data.uuid, projectID); } return this.NOT_FOUND; } @Post('batch') - async batchCreate(@Body() createDto: Array) { + async batchCreate( + @Body() createDto: Array, + @Param('projectID') projectID, + ) { createDto.map((val) => { this.JSON_FIELDS.forEach((field) => { if (val[field]) { val[field] = JSON.stringify(val[field]); } + val['projectID'] = projectID; }); return val; }); - const data = await this.service.batchCreate(createDto); - return { - statusCode: 200, - data: data, - }; + return this.service.batchCreate(createDto); } @Get() - async findAll(@Query() query: QueryDto) { - const data = await this.service.findAll(query); - - return { - statusCode: 200, - data: data, - }; + async findAll(@Query() query: QueryDto, @Param('projectID') projectID) { + return this.service.findAll({ where: { ...query, projectID } }); } @Get(':uuid') - async findOne(@Param('uuid') uuid: string) { - const data = await this.service.findOne(+uuid); - if (data) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; + async findOne(@Param('uuid') uuid, @Param('projectID') projectID) { + return this.service.findOne({ where: { uuid, projectID } }); } @Put(':uuid') - async update(@Param('uuid') uuid: string, @Body() updateDto: UpdateDto) { + async update( + @Param('uuid') uuid: string, + @Param('projectID') projectID, + @Body() updateDto: UpdateDto, + ) { this.JSON_FIELDS.forEach((field) => { if (updateDto[field]) { updateDto[field] = JSON.stringify(updateDto[field]); @@ -92,7 +83,7 @@ export class EnvironmentController { }); const data = await this.service.update(+uuid, updateDto); if (data) { - return await this.findOne(uuid); + return await this.findOne(uuid, projectID); } return this.NOT_FOUND; @@ -100,14 +91,6 @@ export class EnvironmentController { @Delete(':uuid') async remove(@Param('uuid') uuid: string) { - const data = await this.service.remove(+uuid); - if (data && data.affected > 0) { - return { - statusCode: 200, - data: data, - }; - } - - return this.NOT_FOUND; + return this.service.remove(+uuid); } } diff --git a/src/modules/environment/environment.service.ts b/src/modules/workspace/environment/environment.service.ts similarity index 70% rename from src/modules/environment/environment.service.ts rename to src/modules/workspace/environment/environment.service.ts index d4348fc..c8e4f27 100644 --- a/src/modules/environment/environment.service.ts +++ b/src/modules/workspace/environment/environment.service.ts @@ -1,10 +1,10 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { Environment } from '../../entities/environment.entity'; +import { FindManyOptions, FindOneOptions, Repository } from 'typeorm'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; +import { Environment } from '@/entities/environment.entity'; @Injectable() export class EnvironmentService { @@ -26,12 +26,12 @@ export class EnvironmentService { .execute(); } - async findAll(query: QueryDto) { - return await this.repository.find(query); + async findAll(options: FindManyOptions) { + return await this.repository.find(options); } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOne(options: FindOneOptions): Promise { + return await this.repository.findOne(options); } async update(id: number, updateDto: UpdateDto) { diff --git a/src/modules/mock/dto/create.dto.ts b/src/modules/workspace/mock/dto/create.dto.ts similarity index 100% rename from src/modules/mock/dto/create.dto.ts rename to src/modules/workspace/mock/dto/create.dto.ts diff --git a/src/modules/mock/dto/query.dto.ts b/src/modules/workspace/mock/dto/query.dto.ts similarity index 100% rename from src/modules/mock/dto/query.dto.ts rename to src/modules/workspace/mock/dto/query.dto.ts diff --git a/src/modules/mock/dto/update.dto.ts b/src/modules/workspace/mock/dto/update.dto.ts similarity index 100% rename from src/modules/mock/dto/update.dto.ts rename to src/modules/workspace/mock/dto/update.dto.ts diff --git a/src/modules/mock/mock.controller.spec.ts b/src/modules/workspace/mock/mock.controller.spec.ts similarity index 100% rename from src/modules/mock/mock.controller.spec.ts rename to src/modules/workspace/mock/mock.controller.spec.ts diff --git a/src/modules/workspace/mock/mock.controller.ts b/src/modules/workspace/mock/mock.controller.ts new file mode 100644 index 0000000..1ecd2b1 --- /dev/null +++ b/src/modules/workspace/mock/mock.controller.ts @@ -0,0 +1,78 @@ +import { + Controller, + Get, + Req, + Post, + Body, + Put, + Param, + Delete, + Query, + All, + BadRequestException, + ParseIntPipe, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { Request } from 'express'; +import { MockService } from './mock.service'; +import { CreateDto } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { WORKSPACE_PROJECT_PREFIX } from '@/common/contants/prefix.contants'; + +@ApiTags('Mock') +@Controller(`${WORKSPACE_PROJECT_PREFIX}/mock`) +export class MockController { + constructor(private readonly service: MockService) {} + + @Post() + async create(@Body() createDto: CreateDto, @Param('projectID') projectID) { + const data = await this.service.create({ ...createDto, projectID }); + return this.findOne(data.uuid, projectID); + } + + @Post('batch') + async batchCreate(@Body() createDto: Array) { + return this.service.batchCreate(createDto); + } + + @Get() + async findAll(@Query() query: QueryDto, @Param('projectID') projectID) { + return this.service.findAll({ ...query, projectID }); + } + + @Get(':uuid') + async findOne(@Param('uuid') uuid, @Param('projectID') projectID) { + return this.service.findOne({ where: { uuid, projectID } }); + } + + @All(':projectID/**') + async findMock( + @Param('projectID') projectID: string, + @Req() request: Request, + ) { + return this.service.findMock(projectID, request); + } + + @Put(':uuid') + async update( + @Param('uuid') uuid: string, + @Param('projectID') projectID, + @Body() updateDto: UpdateDto, + ) { + await this.service.update(+uuid, updateDto); + return await this.findOne(uuid, projectID); + } + + @Delete(':uuid') + async remove( + @Param('uuid', ParseIntPipe) uuid: number, + @Param('projectID') projectID, + ) { + const mock = await this.service.findOne({ where: { uuid, projectID } }); + if (mock.createWay === 'system') { + return new BadRequestException('系统自动创建的mock不能删除'); + } + return this.service.remove(+uuid); + } +} diff --git a/src/modules/mock/mock.service.spec.ts b/src/modules/workspace/mock/mock.service.spec.ts similarity index 100% rename from src/modules/mock/mock.service.spec.ts rename to src/modules/workspace/mock/mock.service.spec.ts diff --git a/src/modules/mock/mock.service.ts b/src/modules/workspace/mock/mock.service.ts similarity index 83% rename from src/modules/mock/mock.service.ts rename to src/modules/workspace/mock/mock.service.ts index 41bc93d..8e07aa0 100644 --- a/src/modules/mock/mock.service.ts +++ b/src/modules/workspace/mock/mock.service.ts @@ -1,14 +1,14 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, NotFoundException } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { Mock } from '../../entities/mock.entity'; -import { CreateDto, CreateWay } from './dto/create.dto'; -import { CreateDto as ApiDataCreateDto } from '../apiData/dto/create.dto'; -import { UpdateDto } from './dto/update.dto'; -import { QueryDto } from './dto/query.dto'; +import { Repository, FindOneOptions } from 'typeorm'; import { ApiData } from 'src/entities/apiData.entity'; import { Request } from 'express'; import { tree2obj } from 'src/utils'; +import { CreateDto as ApiDataCreateDto } from '../apiData/dto/create.dto'; +import { CreateDto, CreateWay } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { Mock } from '@/entities/mock.entity'; @Injectable() export class MockService { @@ -34,14 +34,14 @@ export class MockService { } async findAll(query: QueryDto) { - return await this.repository.find(query); + return await this.repository.find({ where: query }); } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOne(options: FindOneOptions): Promise { + return await this.repository.findOne(options); } - async findMock(projectID: string, request: Request): Promise { + async findMock(projectID: string, request: Request) { const { path, method, query, body, protocol } = request; const pathName = path.replace(`/mock/${projectID}`, ''); const pathReg = new RegExp(`/?${pathName}/?`); @@ -73,10 +73,9 @@ export class MockService { }); if (!apiData) { - return JSON.stringify({ - statusCode: 404, - message: '没有匹配到该mock,请检查请求方法或路径是否正确。', - }); + return new NotFoundException( + '没有匹配到该mock,请检查请求方法或路径是否正确。', + ); } console.log('apiData', apiData); if (apiData.responseBodyType === 'raw') { @@ -92,7 +91,9 @@ export class MockService { return '{}'; } } else { - const mock = await this.repository.findOne(+query.mockID); + const mock = await this.repository.findOne({ + where: { uuid: Number(query.mockID) }, + }); return mock?.response || '{}'; } } diff --git a/src/modules/project/dto/create.dto.ts b/src/modules/workspace/project/dto/create.dto.ts similarity index 73% rename from src/modules/project/dto/create.dto.ts rename to src/modules/workspace/project/dto/create.dto.ts index 156fa57..ec587c7 100644 --- a/src/modules/project/dto/create.dto.ts +++ b/src/modules/workspace/project/dto/create.dto.ts @@ -1,4 +1,5 @@ export class CreateDto { name: string; description?: string; + workspaceID?: number; } diff --git a/src/modules/project/dto/import.dto.ts b/src/modules/workspace/project/dto/import.dto.ts similarity index 100% rename from src/modules/project/dto/import.dto.ts rename to src/modules/workspace/project/dto/import.dto.ts diff --git a/src/modules/project/dto/query.dto.ts b/src/modules/workspace/project/dto/query.dto.ts similarity index 100% rename from src/modules/project/dto/query.dto.ts rename to src/modules/workspace/project/dto/query.dto.ts diff --git a/src/modules/project/dto/update.dto.ts b/src/modules/workspace/project/dto/update.dto.ts similarity index 100% rename from src/modules/project/dto/update.dto.ts rename to src/modules/workspace/project/dto/update.dto.ts diff --git a/src/modules/project/project.controller.spec.ts b/src/modules/workspace/project/project.controller.spec.ts similarity index 100% rename from src/modules/project/project.controller.spec.ts rename to src/modules/workspace/project/project.controller.spec.ts diff --git a/src/modules/workspace/project/project.controller.ts b/src/modules/workspace/project/project.controller.ts new file mode 100644 index 0000000..3dc1138 --- /dev/null +++ b/src/modules/workspace/project/project.controller.ts @@ -0,0 +1,105 @@ +import { + Controller, + Get, + Post, + Body, + Put, + Param, + Delete, + Query, + ParseIntPipe, + NotFoundException, +} from '@nestjs/common'; +import { ApiTags } from '@nestjs/swagger'; +import { ProjectService } from './project.service'; +import { CreateDto } from './dto/create.dto'; +import { UpdateDto } from './dto/update.dto'; +import { QueryDto } from './dto/query.dto'; +import { ImportDto } from './dto/import.dto'; +import { WORKSPACE_ID_PREFIX } from '@/common/contants/prefix.contants'; + +@ApiTags('Project') +@Controller(`${WORKSPACE_ID_PREFIX}/project`) +export class ProjectController { + constructor(private readonly service: ProjectService) {} + + @Post() + async create( + @Param('workspaceID', ParseIntPipe) workspaceID, + @Body() createDto: CreateDto, + ) { + const data = await this.service.create(createDto); + return this.findOne(workspaceID, `${data.uuid}`); + } + + @Post('batch') + async batchCreate(@Body() createDto: Array) { + return this.service.batchCreate(createDto); + } + + @Get() + async findAll( + @Query() query: QueryDto, + @Param('workspaceID', ParseIntPipe) workspaceID, + ) { + return this.service.findAll(query, workspaceID); + } + + @Get(':uuid') + async findOne( + @Param('uuid', ParseIntPipe) uuid, + @Param('workspaceID', ParseIntPipe) workspaceID, + ) { + return this.service.findOne(workspaceID, uuid); + } + + @Put(':uuid') + async update( + @Param('uuid') uuid: string, + @Param('workspaceID', ParseIntPipe) workspaceID, + @Body() updateDto: UpdateDto, + ) { + const data = await this.service.update(+uuid, updateDto); + if (data) { + return await this.findOne(workspaceID, uuid); + } + + return new NotFoundException('更新失败!项目不存在'); + } + + @Delete(':uuid') + async remove(@Param('uuid') uuid: string) { + const data = await this.service.remove(+uuid); + if (data && data.affected > 0) { + return data; + } + + return new NotFoundException('删除失败!项目不存在'); + } + + @Put(':uuid/import') + async import( + @Param('uuid') uuid: string, + @Param('workspaceID', ParseIntPipe) workspaceID, + @Body() importDto: ImportDto, + ) { + // console.log('uuid', uuid, importDto); + const data = await this.service.import( + workspaceID, + Number(uuid), + importDto, + ); + return { + errors: data, + }; + } + + @Get(':uuid/export') + async export( + @Param('uuid') uuid: string, + @Param('workspaceID', ParseIntPipe) workspaceID, + ) { + // console.log('uuid', uuid, importDto); + return this.service.export(workspaceID, Number(uuid)); + } +} diff --git a/src/modules/project/project.service.spec.ts b/src/modules/workspace/project/project.service.spec.ts similarity index 100% rename from src/modules/project/project.service.spec.ts rename to src/modules/workspace/project/project.service.spec.ts diff --git a/src/modules/project/project.service.ts b/src/modules/workspace/project/project.service.ts similarity index 59% rename from src/modules/project/project.service.ts rename to src/modules/workspace/project/project.service.ts index 149c2d3..165b703 100644 --- a/src/modules/project/project.service.ts +++ b/src/modules/workspace/project/project.service.ts @@ -1,15 +1,15 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { Project } from '../../entities/project.entity'; +import { ApiGroupService } from '../apiGroup/apiGroup.service'; +import { ApiDataService } from '../apiData/apiData.service'; +import { EnvironmentService } from '../environment/environment.service'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; import { Child, Collections, Environment, ImportDto } from './dto/import.dto'; -import { ApiGroupService } from '../apiGroup/apiGroup.service'; -import { ApiDataService } from '../apiData/apiData.service'; import { parseAndCheckApiData, parseAndCheckEnv } from './validate'; -import { EnvironmentService } from '../environment/environment.service'; +import { Project } from '@/entities/project.entity'; type Errors = { apiData: any[]; @@ -40,12 +40,25 @@ export class ProjectService { .execute(); } - async findAll(query: QueryDto) { - return await this.repository.find(query); + async findAll(query: QueryDto, workspaceID: number) { + return await this.repository.find({ + where: { + ...query, + workspace: { id: workspaceID }, + }, + }); } - async findOne(id: number): Promise { - return await this.repository.findOne(id); + async findOneBy(uuid: number): Promise { + return await this.repository.findOneBy({ + uuid: Number(uuid), + }); + } + + async findOne(workspaceID: number, uuid: number): Promise { + return await this.repository.findOne({ + where: { uuid: Number(uuid), workspace: { id: workspaceID } }, + }); } async update(id: number, updateDto: UpdateDto) { @@ -56,15 +69,54 @@ export class ProjectService { return await this.repository.delete(id); } - async import(uuid: number, importDto: Collections) { - const { collections, enviroments } = importDto; - const errors = { - apiData: [], - group: [], - enviroments: [], - }; - this.importEnv(enviroments, uuid, errors); - return this.importCollects(collections, uuid, 0, errors); + async import(workspaceID: number, uuid: number, importDto: Collections) { + const project = await this.findOne(workspaceID, uuid); + if (project) { + const { collections, enviroments } = importDto; + const errors = { + apiData: [], + group: [], + enviroments: [], + }; + this.importEnv(enviroments, uuid, errors); + return this.importCollects(collections, uuid, 0, errors); + } + return '导入失败,项目不存在'; + } + + exportCollects(apiGroup: any[], apiData: any[], parentID = 0) { + const apiGroupFilters = apiGroup.filter( + (child) => child.parentID === parentID, + ); + const apiDataFilters = apiData.filter( + (child) => child.groupID === parentID, + ); + return apiGroupFilters + .map((item) => { + return { + name: item.name, + children: this.exportCollects(apiGroup, apiData, item.uuid), + }; + }) + .concat(apiDataFilters); + } + + async export(workspaceID: number, uuid: number) { + const project = await this.findOne(workspaceID, uuid); + if (project) { + const apiData = await this.apiDataService.findAll({ projectID: uuid }); + const apiGroup = await this.apiGroupService.findAll({ projectID: uuid }); + const enviroments = await this.environmentService.findAll({ + where: { + projectID: uuid, + }, + }); + return { + collections: this.exportCollects(apiGroup, apiData), + enviroments, + }; + } + return '导出失败,项目不存在'; } async importEnv( @@ -94,6 +146,7 @@ export class ProjectService { errors: Errors, ): Promise { return collections.reduce(async (prev: any, curr: any) => { + Reflect.deleteProperty(curr, 'uuid'); if (curr.uri || curr.method || curr.protocol) { const result = parseAndCheckApiData(curr); if (!result.validate) { diff --git a/src/modules/project/schema/README.md b/src/modules/workspace/project/schema/README.md similarity index 100% rename from src/modules/project/schema/README.md rename to src/modules/workspace/project/schema/README.md diff --git a/src/modules/project/schema/apiData.json b/src/modules/workspace/project/schema/apiData.json similarity index 100% rename from src/modules/project/schema/apiData.json rename to src/modules/workspace/project/schema/apiData.json diff --git a/src/modules/project/schema/env.json b/src/modules/workspace/project/schema/env.json similarity index 100% rename from src/modules/project/schema/env.json rename to src/modules/workspace/project/schema/env.json diff --git a/src/modules/project/validate.ts b/src/modules/workspace/project/validate.ts similarity index 100% rename from src/modules/project/validate.ts rename to src/modules/workspace/project/validate.ts diff --git a/src/modules/workspace/workspace.controller.ts b/src/modules/workspace/workspace.controller.ts new file mode 100644 index 0000000..ea663ce --- /dev/null +++ b/src/modules/workspace/workspace.controller.ts @@ -0,0 +1,169 @@ +import { + Body, + Controller, + Delete, + ForbiddenException, + Get, + NotFoundException, + Param, + ParseIntPipe, + Post, + Put, + UnauthorizedException, +} from '@nestjs/common'; +import { + ApiBearerAuth, + ApiOperation, + ApiResponse, + ApiTags, +} from '@nestjs/swagger'; +import { DeleteResult } from 'typeorm'; +import { WorkspaceService } from './workspace.service'; +import { + CreateWorkspaceDto, + UpdateWorkspaceDto, + WorkspaceMemberAddDto, + WorkspaceMemberRemoveDto, + WorkspaceUser, +} from './workspace.dto'; +import { WorkspaceEntity } from '@/entities/workspace.entity'; +import { IUser, User } from '@/common/decorators/user.decorator'; +import { UserEntity } from '@/entities/user.entity'; +import { Collections } from '@/modules/workspace/project/dto/import.dto'; +import { ProjectService } from '@/modules/workspace/project/project.service'; + +@ApiBearerAuth() +@ApiTags('workspace') +@Controller('workspace') +export class WorkspaceController { + constructor( + private readonly workspaceService: WorkspaceService, + private readonly projectService: ProjectService, + ) {} + + @Post() + @ApiOperation({ summary: '创建空间' }) + @ApiResponse({ status: 403, description: 'Forbidden.' }) + async create( + @User() user: IUser, + @Body() createDto: CreateWorkspaceDto, + ): Promise { + return this.workspaceService.create(user.userId, createDto); + } + + @Post('upload') + @ApiOperation({ summary: '导入本地数据并创建空间' }) + async importLocalData(@User() user: IUser, @Body() collections: Collections) { + const workspace = await this.workspaceService.create(user.userId, { + title: '默认空间', + }); + const exportResult = await this.projectService.import( + workspace.id, + workspace.projects.at(0).uuid, + collections, + ); + if (typeof exportResult === 'string') { + return new Error(exportResult); + } else { + return { + ...exportResult, + workspace, + }; + } + } + + @Put(':workspaceID') + @ApiOperation({ summary: '修改空间名称' }) + async update( + @Param('workspaceID', ParseIntPipe) id, + @Body() updateDto: UpdateWorkspaceDto, + ): Promise { + return this.workspaceService.update(id, updateDto); + } + + @Delete(':workspaceID') + @ApiOperation({ summary: '删除空间' }) + @ApiResponse({ status: 403, description: 'Forbidden.' }) + async deleteWorkspace( + @User() user: IUser, + @Param('workspaceID', ParseIntPipe) id, + ): Promise { + const workspace = await this.workspaceService.findOne({ where: { id } }); + if (!workspace) { + throw new NotFoundException('删除失败,空间不存在'); + } + if (user.userId !== workspace.creatorID) { + throw new UnauthorizedException('无删除该空间权限,请联系空间创建者'); + } + return this.workspaceService.delete(id); + } + + @Get('list') + @ApiOperation({ summary: '获取空间列表' }) + list(@User() user: IUser): Promise { + return this.workspaceService.list(user.userId); + } + + @Get(':workspaceID') + @ApiOperation({ summary: '获取空间信息' }) + async info(@Param('workspaceID') id): Promise { + const workspace = await this.workspaceService.findOne({ + where: { id }, + relations: ['projects'], + }); + + return workspace; + } + + @Get(':workspaceID/member/list') + @ApiOperation({ summary: '获取空间成员列表' }) + async getMemberList(@Param('workspaceID') id): Promise { + return this.workspaceService.getMemberList(id); + } + + @Get(':workspaceID/member/list/:username') + @ApiOperation({ summary: '搜索空间成员' }) + @ApiResponse({ + type: [UserEntity], + }) + async searchMemberByName( + @Param('workspaceID') id, + @Param('username') username, + ): Promise { + return this.workspaceService.getMemberList(id, username); + } + + @Post(':workspaceID/member/add') + @ApiOperation({ summary: '添加空间成员' }) + async memberAdd( + @User() user: IUser, + @Param('workspaceID') id, + @Body() createCatDto: WorkspaceMemberAddDto, + ) { + const workspace = await this.workspaceService.findOne({ where: { id } }); + if (user.userId !== workspace.creatorID) { + throw new UnauthorizedException('无该空间添加成员权限,请联系空间创建者'); + } + return this.workspaceService.addMembers(id, createCatDto.userIDs); + } + + @Delete(':workspaceID/member/remove') + @ApiOperation({ summary: '移除空间成员' }) + async memberRemove( + @User() user: IUser, + @Param('workspaceID') id, + @Body() createCatDto: WorkspaceMemberRemoveDto, + ): Promise { + const workspace = await this.workspaceService.findOne({ where: { id } }); + if (!workspace) { + throw new UnauthorizedException('空间不存在'); + } + if (user.userId !== workspace.creatorID) { + throw new UnauthorizedException('无移除该空间成员权限,请联系空间创建者'); + } + if (createCatDto.userIDs.includes(user.userId)) { + throw new ForbiddenException('空间创建者不能移除自己'); + } + return this.workspaceService.removeMembers(id, createCatDto.userIDs); + } +} diff --git a/src/modules/workspace/workspace.dto.ts b/src/modules/workspace/workspace.dto.ts new file mode 100644 index 0000000..497e09f --- /dev/null +++ b/src/modules/workspace/workspace.dto.ts @@ -0,0 +1,34 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { ArrayNotEmpty, IsArray, IsString, MinLength } from 'class-validator'; +import { UserEntity } from '@/entities/user.entity'; + +export class CreateWorkspaceDto { + @ApiProperty({ description: '空间名称' }) + @MinLength(1) + @IsString() + readonly title: string; +} +export class UpdateWorkspaceDto extends CreateWorkspaceDto {} + +export class WorkspaceListDto { + @ApiProperty({ description: '空间名称' }) + @MinLength(1) + @IsString() + readonly title: string; +} + +export class WorkspaceMemberAddDto { + @ApiProperty({ description: '用户id数组', type: [Number] }) + @IsArray() + @ArrayNotEmpty() + readonly userIDs: number[]; +} + +export class WorkspaceMemberRemoveDto extends WorkspaceMemberAddDto {} + +export class WorkspaceUser extends UserEntity { + @ApiProperty({ description: '成员身份' }) + @MinLength(1) + @IsString() + readonly roleName: string = 'member'; +} diff --git a/src/modules/workspace/workspace.module.ts b/src/modules/workspace/workspace.module.ts new file mode 100644 index 0000000..7f02849 --- /dev/null +++ b/src/modules/workspace/workspace.module.ts @@ -0,0 +1,64 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { WorkspaceController } from './workspace.controller'; +import { WorkspaceService } from './workspace.service'; +import { WorkspaceEntity } from '@/entities/workspace.entity'; +import { UserEntity } from '@/entities/user.entity'; +import { Project } from '@/entities/project.entity'; +import { ApiData } from '@/entities/apiData.entity'; +import { Mock } from '@/entities/mock.entity'; +import { ApiTestHistory } from '@/entities/apiTestHistory.entity'; +import { ApiGroup } from '@/entities/apiGroup.entity'; +import { Environment } from '@/entities/environment.entity'; +import { ApiDataController } from '@/modules/workspace/apiData/apiData.controller'; +import { EnvironmentController } from '@/modules/workspace/environment/environment.controller'; +import { ApiTestHistoryController } from '@/modules/workspace/apiTestHistory/apiTestHistory.controller'; +import { MockController } from '@/modules/workspace/mock/mock.controller'; +import { ProjectController } from '@/modules/workspace/project/project.controller'; +import { ApiDataService } from '@/modules/workspace/apiData/apiData.service'; +import { ApiTestHistoryService } from '@/modules/workspace/apiTestHistory/apiTestHistory.service'; +import { ProjectService } from '@/modules/workspace/project/project.service'; +import { MockService } from '@/modules/workspace/mock/mock.service'; +import { EnvironmentService } from '@/modules/workspace/environment/environment.service'; +import { ApiGroupService } from '@/modules/workspace/apiGroup/apiGroup.service'; +import { ApiGroupController } from '@/modules/workspace/apiGroup/apiGroup.controller'; +import { UserModule } from '@/modules/user/user.module'; +import { AuthModule } from '@/modules/auth/auth.module'; + +const commonProviders = [ + WorkspaceService, + ApiDataService, + ApiGroupService, + ApiTestHistoryService, + ProjectService, + MockService, + EnvironmentService, +]; +@Module({ + imports: [ + TypeOrmModule.forFeature([ + WorkspaceEntity, + UserEntity, + Project, + ApiData, + Mock, + ApiTestHistory, + ApiGroup, + Environment, + ]), + UserModule, + AuthModule, + ], + controllers: [ + WorkspaceController, + ApiDataController, + ApiGroupController, + EnvironmentController, + ApiTestHistoryController, + MockController, + ProjectController, + ], + providers: [...commonProviders], + exports: [...commonProviders], +}) +export class WorkspaceModule {} diff --git a/src/modules/workspace/workspace.service.ts b/src/modules/workspace/workspace.service.ts new file mode 100644 index 0000000..57ae8d9 --- /dev/null +++ b/src/modules/workspace/workspace.service.ts @@ -0,0 +1,130 @@ +import { Injectable, OnModuleInit } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { ModuleRef } from '@nestjs/core'; +import { DeleteResult, FindOneOptions, In, Like, Repository } from 'typeorm'; +import { + CreateWorkspaceDto, + UpdateWorkspaceDto, + WorkspaceUser, +} from './workspace.dto'; +import { WorkspaceEntity } from '@/entities/workspace.entity'; +import { UserService } from '@/modules/user/user.service'; +import { ProjectService } from '@/modules/workspace/project/project.service'; +import { Project } from '@/entities/project.entity'; +import { CreateDto as ProjectCreateDto } from '@/modules/workspace/project/dto/create.dto'; + +@Injectable() +export class WorkspaceService implements OnModuleInit { + private userService: UserService; + constructor( + private moduleRef: ModuleRef, + @InjectRepository(WorkspaceEntity) + private workspaceRepository: Repository, + private projectService: ProjectService, + ) {} + + onModuleInit() { + this.userService = this.moduleRef.get(UserService, { strict: false }); + } + + findOne(options: FindOneOptions) { + return this.workspaceRepository.findOne(options); + } + + async create( + creatorID: number, + createWorkspaceDto: CreateWorkspaceDto, + project?: ProjectCreateDto & Project, + ): Promise { + const creator = await this.userService.findOneBy({ id: creatorID }); + project ??= await this.projectService.create({ + name: '默认项目', + description: createWorkspaceDto.title + '默认项目', + }); + return this.workspaceRepository.save({ + ...createWorkspaceDto, + creatorID, + users: [creator], + projects: [project], + }); + } + + async update( + id: number, + updateDto: UpdateWorkspaceDto, + ): Promise { + await this.workspaceRepository.update(id, { title: updateDto.title }); + return this.workspaceRepository.findOneBy({ id }); + } + + delete(id: number): Promise { + return this.workspaceRepository.delete(id); + } + + list(userId: number): Promise { + return this.workspaceRepository.find({ + where: { + users: { + id: userId, + }, + }, + }); + } + + async getMemberList( + workspaceId: number, + username = '', + ): Promise { + const [result] = await this.userService.findAndCount({ + where: { + workspaces: { + id: workspaceId, + }, + username: Like(`%${username}%`), + }, + }); + const workspace = await this.workspaceRepository.findOneBy({ + id: workspaceId, + }); + return result.map((item) => ({ + ...item, + roleName: item.id === workspace.creatorID ? 'Owner' : 'Member', + })); + } + + async addMembers(workspaceId: number, userIDs: number[]) { + const workspace = await this.workspaceRepository.findOne({ + where: { id: workspaceId }, + relations: { + users: true, + }, + }); + const users = await this.userService.find({ + where: { id: In(userIDs) }, + relations: { + workspaces: true, + }, + }); + users.forEach((user) => { + user.workspaces.push({ + ...workspace, + users: [], + }); + }); + workspace.users.push(...users); + return this.workspaceRepository.save(workspace); + } + + async removeMembers(workspaceId: number, userIDs: number[]) { + const workspace = await this.workspaceRepository.findOne({ + where: { id: workspaceId }, + relations: { + users: true, + }, + }); + workspace.users = workspace.users.filter( + (user) => !userIDs.includes(user.id), + ); + return this.workspaceRepository.save(workspace); + } +} diff --git a/src/pipe/validation.pipe.ts b/src/pipe/validation.pipe.ts new file mode 100644 index 0000000..3df69cf --- /dev/null +++ b/src/pipe/validation.pipe.ts @@ -0,0 +1,31 @@ +import { + ArgumentMetadata, + PipeTransform, + BadRequestException, + Logger, +} from '@nestjs/common'; +import { validate } from 'class-validator'; +import { plainToClass } from 'class-transformer'; + +export class ValidationPipe implements PipeTransform { + async transform(value: any, { metatype }: ArgumentMetadata) { + // console.log(`value:`, value, 'metatype: ', metatype); + if (!metatype || !this.toValidate(metatype)) { + // 如果没有传入验证规则,则不验证,直接返回数据 + return value; + } + // 将对象转换为 Class 来验证 + const object = plainToClass(metatype, value); + const errors = await validate(object); + if (errors.length > 0) { + const msg = Object.values(errors[0].constraints)[0]; // 只需要取第一个错误信息并返回即可 + // Logger.error(`Validation failed: ${msg}`); + throw new BadRequestException(`Validation failed: ${msg}`); + } + return value; + } + private toValidate(metatype: any): boolean { + const types: any[] = [String, Boolean, Number, Array, Object]; + return !types.includes(metatype); + } +} diff --git a/src/setup-swagger.ts b/src/setup-swagger.ts new file mode 100644 index 0000000..2bb4699 --- /dev/null +++ b/src/setup-swagger.ts @@ -0,0 +1,33 @@ +import { INestApplication } from '@nestjs/common'; +import { ConfigService } from '@nestjs/config'; +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; + +export function setupSwagger(app: INestApplication): void { + const configService: ConfigService = app.get(ConfigService); + + // 默认为启用 + const enable = configService.get('swagger.enable', true); + + // 判断是否需要启用 + if (!enable) { + return; + } + + const swaggerPath = configService.get('swagger.path', '/swagger-api'); + const swaggerConfig = new DocumentBuilder() + .setTitle(configService.get('swagger.title')) + .setDescription(configService.get('swagger.desc')) + .setLicense('MIT', 'https://github.com/eolinker/eoapi-remote-server') + .setExternalDoc('JSON Schema', `/${swaggerPath}-json`) + // JWT鉴权 + .addSecurity('', { + description: '接口授权', + type: 'apiKey', + in: 'header', + name: 'Authorization', + }) + .build(); + const document = SwaggerModule.createDocument(app, swaggerConfig); + + SwaggerModule.setup(swaggerPath, app, document); +} diff --git a/src/shared/services/util.service.ts b/src/shared/services/util.service.ts new file mode 100644 index 0000000..0e422a7 --- /dev/null +++ b/src/shared/services/util.service.ts @@ -0,0 +1,45 @@ +import { Injectable } from '@nestjs/common'; +import { customAlphabet, nanoid } from 'nanoid'; +import * as CryptoJS from 'crypto-js'; + +@Injectable() +export class UtilService { + /** + * AES加密 + */ + public aesEncrypt(msg: string, secret: string): string { + return CryptoJS.AES.encrypt(msg, secret).toString(); + } + + /** + * AES解密 + */ + public aesDecrypt(encrypted: string, secret: string): string { + return CryptoJS.AES.decrypt(encrypted, secret).toString(CryptoJS.enc.Utf8); + } + + /** + * md5加密 + */ + public md5(msg: string): string { + return CryptoJS.MD5(msg).toString(); + } + + /** + * 生成一个UUID + */ + public generateUUID(): string { + return nanoid(); + } + + /** + * 生成一个随机的值 + */ + public generateRandomValue( + length: number, + placeholder = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM', + ): string { + const customNanoid = customAlphabet(placeholder, length); + return customNanoid(); + } +} diff --git a/src/shared/shared.module.ts b/src/shared/shared.module.ts new file mode 100644 index 0000000..5db9907 --- /dev/null +++ b/src/shared/shared.module.ts @@ -0,0 +1,22 @@ +import { HttpModule } from '@nestjs/axios'; +import { Global, Module } from '@nestjs/common'; +import { UtilService } from '@/shared/services/util.service'; + +// common provider list +const providers = [UtilService]; + +/** + * 全局共享模块 + */ +@Global() +@Module({ + imports: [ + HttpModule.register({ + timeout: 5000, + maxRedirects: 5, + }), + ], + providers: [...providers], + exports: [HttpModule, ...providers], +}) +export class SharedModule {} diff --git a/src/utils/index.ts b/src/utils/index.ts index 857e267..2066558 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -44,3 +44,11 @@ export const tree2obj = ( return prev; }, initObj); }; + +/** + * check dev env + * @returns boolean true is dev + */ +export function isDev(): boolean { + return process.env.NODE_ENV === 'development'; +} diff --git a/tsconfig.json b/tsconfig.json index 45a5e66..4153f1b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,31 @@ { "compilerOptions": { "module": "NodeNext", + "moduleResolution": "Node", "declaration": true, "removeComments": true, + "resolveJsonModule": true, + "esModuleInterop": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, - "resolveJsonModule": true, "allowSyntheticDefaultImports": true, - "target": "es2017", + "target": "ESNext", "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true, - "skipLibCheck": true, - "strictNullChecks": false, - "noImplicitAny": false, - "strictBindCallApply": false, - "forceConsistentCasingInFileNames": false, - "noFallthroughCasesInSwitch": false - } + "lib": [ + "ESNext" + ], + "paths": { + /*定义别名*/ + "@/*": [ + "src/*" + ] + } + }, + "exclude": [ + "node_modules", + "dist" + ] } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 356f07f..99ddac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,61 +10,59 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@angular-devkit/core@13.3.5": - version "13.3.5" - resolved "https://registry.npmmirror.com/@angular-devkit/core/-/core-13.3.5.tgz#c5f32f4f99b5cad8df9cf3cf4da9c4b1335c1155" - integrity sha512-w7vzK4VoYP9rLgxJ2SwEfrkpKybdD+QgQZlsDBzT0C6Ebp7b4gkNcNVFo8EiZvfDl6Yplw2IAP7g7fs3STn0hQ== +"@angular-devkit/core@14.2.1": + version "14.2.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-14.2.1.tgz#7ce14efdb5fce687bb4f13bef03d4b67e971b22e" + integrity sha512-lW8oNGuJqr4r31FWBjfWQYkSXdiOHBGOThIEtHvUVBKfPF/oVrupLueCUgBPel+NvxENXdo93uPsqHN7bZbmsQ== dependencies: - ajv "8.9.0" + ajv "8.11.0" ajv-formats "2.1.1" - fast-json-stable-stringify "2.1.0" - magic-string "0.25.7" + jsonc-parser "3.1.0" rxjs "6.6.7" - source-map "0.7.3" + source-map "0.7.4" -"@angular-devkit/core@13.3.6": - version "13.3.6" - resolved "https://registry.npmmirror.com/@angular-devkit/core/-/core-13.3.6.tgz#656284327d6f84a866a8d3cc8625895fe740602d" - integrity sha512-ZmD586B+RnM2CG5+jbXh2NVfIydTc/yKSjppYDDOv4I530YBm6vpfZMwClpiNk6XLbMv7KqX4Tlr4wfxlPYYbA== +"@angular-devkit/core@14.2.2": + version "14.2.2" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-14.2.2.tgz#d616ada7c9a0610454da47445e64520a0b34e400" + integrity sha512-ofDhTmJqoAkmkJP0duwUaCxDBMxPlc+AWYwgs3rKKZeJBb0d+tchEXHXevD5bYbbRfXtnwM+Vye2XYHhA4nWAA== dependencies: - ajv "8.9.0" + ajv "8.11.0" ajv-formats "2.1.1" - fast-json-stable-stringify "2.1.0" - magic-string "0.25.7" + jsonc-parser "3.1.0" rxjs "6.6.7" - source-map "0.7.3" - -"@angular-devkit/schematics-cli@13.3.6": - version "13.3.6" - resolved "https://registry.npmmirror.com/@angular-devkit/schematics-cli/-/schematics-cli-13.3.6.tgz#5246c112b6b837a9d0a348cb6b79a8c4948e90c8" - integrity sha512-5tTuu9gbXM0bMk0sin4phmWA3U1Qz53zT/rpEfzQ/+c/s8CoqZ5N1qOnYtemRct3Jxsz1kn4TBpHeriR4r5hHg== - dependencies: - "@angular-devkit/core" "13.3.6" - "@angular-devkit/schematics" "13.3.6" - ansi-colors "4.1.1" - inquirer "8.2.0" - minimist "1.2.6" + source-map "0.7.4" + +"@angular-devkit/schematics-cli@14.2.2": + version "14.2.2" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics-cli/-/schematics-cli-14.2.2.tgz#0f3779e1ea066e8bff015208a7dc2a8c2dba9d67" + integrity sha512-timCty5tO1A5VOcy8nVJ+jL98i6+ct5/Hg+4rQxc3J6agmmNL9fALboJBEz1ckTt7MewlGtrpohMMy+YGhuWOg== + dependencies: + "@angular-devkit/core" "14.2.2" + "@angular-devkit/schematics" "14.2.2" + ansi-colors "4.1.3" + inquirer "8.2.4" symbol-observable "4.0.0" + yargs-parser "21.1.1" -"@angular-devkit/schematics@13.3.5": - version "13.3.5" - resolved "https://registry.npmmirror.com/@angular-devkit/schematics/-/schematics-13.3.5.tgz#9cb03ac99ee14173a6fa00fd7ca94fa42600c163" - integrity sha512-0N/kL/Vfx0yVAEwa3HYxNx9wYb+G9r1JrLjJQQzDp+z9LtcojNf7j3oey6NXrDUs1WjVZOa/AIdRl3/DuaoG5w== +"@angular-devkit/schematics@14.2.1": + version "14.2.1" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-14.2.1.tgz#9d66080e60ab32d1b44c854cabc8f5cbb421d877" + integrity sha512-0U18FwDYt4zROBPrvewH6iBTkf2ozVHN4/gxUb9jWrqVw8mPU5AWc/iYxQLHBSinkr2Egjo1H/i9aBqgJSeh3g== dependencies: - "@angular-devkit/core" "13.3.5" - jsonc-parser "3.0.0" - magic-string "0.25.7" + "@angular-devkit/core" "14.2.1" + jsonc-parser "3.1.0" + magic-string "0.26.2" ora "5.4.1" rxjs "6.6.7" -"@angular-devkit/schematics@13.3.6": - version "13.3.6" - resolved "https://registry.npmmirror.com/@angular-devkit/schematics/-/schematics-13.3.6.tgz#b02e1eff714c2cf44a54de92410d07cc8cefbb0e" - integrity sha512-yLh5xc92C/FiaAp27coPiKWpSUmwoXF7vMxbJYJTyOXlt0mUITAEAwtrZQNr4yAxW/yvgTdyg7PhXaveQNTUuQ== +"@angular-devkit/schematics@14.2.2": + version "14.2.2" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-14.2.2.tgz#ceb024214aee56f0c61e26e768775f69045b4f4c" + integrity sha512-90hseNg1yQ2AR+lVr/NByZRHnYAlzCL6hr9p9q1KPHxA3Owo04yX6n6dvR/xf27hCopXInXKPsasR59XCx5ZOQ== dependencies: - "@angular-devkit/core" "13.3.6" - jsonc-parser "3.0.0" - magic-string "0.25.7" + "@angular-devkit/core" "14.2.2" + jsonc-parser "3.1.0" + magic-string "0.26.2" ora "5.4.1" rxjs "6.6.7" @@ -253,6 +251,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.npmmirror.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -360,14 +365,14 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@eslint/eslintrc@^1.3.0": - version "1.3.0" - resolved "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" - integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== +"@eslint/eslintrc@^1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" + integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.2" + espree "^9.4.0" globals "^13.15.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -375,10 +380,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.10.4": - version "0.10.4" - resolved "https://registry.npmmirror.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" - integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== +"@humanwhocodes/config-array@^0.10.5": + version "0.10.5" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.5.tgz#bb679745224745fff1e9a41961c1d45a49f81c04" + integrity sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -389,6 +394,11 @@ resolved "https://registry.npmmirror.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -410,110 +420,110 @@ resolved "https://registry.npmmirror.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" - integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== +"@jest/console@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.0.3.tgz#a222ab87e399317a89db88a58eaec289519e807a" + integrity sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + jest-message-util "^29.0.3" + jest-util "^29.0.3" slash "^3.0.0" -"@jest/core@^28.0.3", "@jest/core@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" - integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== +"@jest/core@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.0.3.tgz#ba22a9cbd0c7ba36e04292e2093c547bf53ec1fd" + integrity sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ== dependencies: - "@jest/console" "^28.1.3" - "@jest/reporters" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.0.3" + "@jest/reporters" "^29.0.3" + "@jest/test-result" "^29.0.3" + "@jest/transform" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^28.1.3" - jest-config "^28.1.3" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-resolve-dependencies "^28.1.3" - jest-runner "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - jest-watcher "^28.1.3" + jest-changed-files "^29.0.0" + jest-config "^29.0.3" + jest-haste-map "^29.0.3" + jest-message-util "^29.0.3" + jest-regex-util "^29.0.0" + jest-resolve "^29.0.3" + jest-resolve-dependencies "^29.0.3" + jest-runner "^29.0.3" + jest-runtime "^29.0.3" + jest-snapshot "^29.0.3" + jest-util "^29.0.3" + jest-validate "^29.0.3" + jest-watcher "^29.0.3" micromatch "^4.0.4" - pretty-format "^28.1.3" - rimraf "^3.0.0" + pretty-format "^29.0.3" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" - integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== +"@jest/environment@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.0.3.tgz#7745ec30a954e828e8cc6df6a13280d3b51d8f35" + integrity sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA== dependencies: - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/fake-timers" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" - jest-mock "^28.1.3" + jest-mock "^29.0.3" -"@jest/expect-utils@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" - integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== +"@jest/expect-utils@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.0.3.tgz#f5bb86f5565bf2dacfca31ccbd887684936045b2" + integrity sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q== dependencies: - jest-get-type "^28.0.2" + jest-get-type "^29.0.0" -"@jest/expect@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" - integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== +"@jest/expect@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.0.3.tgz#9dc7c46354eeb7a348d73881fba6402f5fdb2c30" + integrity sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ== dependencies: - expect "^28.1.3" - jest-snapshot "^28.1.3" + expect "^29.0.3" + jest-snapshot "^29.0.3" -"@jest/fake-timers@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" - integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== +"@jest/fake-timers@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.0.3.tgz#ad5432639b715d45a86a75c47fd75019bc36b22c" + integrity sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@sinonjs/fake-timers" "^9.1.2" "@types/node" "*" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-util "^28.1.3" + jest-message-util "^29.0.3" + jest-mock "^29.0.3" + jest-util "^29.0.3" -"@jest/globals@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" - integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== +"@jest/globals@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.0.3.tgz#681950c430fdc13ff9aa89b2d8d572ac0e4a1bf5" + integrity sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w== dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.0.3" + "@jest/expect" "^29.0.3" + "@jest/types" "^29.0.3" + jest-mock "^29.0.3" -"@jest/reporters@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" - integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== +"@jest/reporters@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.0.3.tgz#735f110e08b44b38729d8dbbb74063bdf5aba8a5" + integrity sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" + "@jest/console" "^29.0.3" + "@jest/test-result" "^29.0.3" + "@jest/transform" "^29.0.3" + "@jest/types" "^29.0.3" + "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" collect-v8-coverage "^1.0.0" @@ -525,78 +535,78 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - jest-worker "^28.1.3" + jest-message-util "^29.0.3" + jest-util "^29.0.3" + jest-worker "^29.0.3" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" terminal-link "^2.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" - integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== +"@jest/schemas@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" + integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== dependencies: "@sinclair/typebox" "^0.24.1" -"@jest/source-map@^28.1.2": - version "28.1.2" - resolved "https://registry.npmmirror.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" - integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== +"@jest/source-map@^29.0.0": + version "29.0.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.0.0.tgz#f8d1518298089f8ae624e442bbb6eb870ee7783c" + integrity sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ== dependencies: - "@jridgewell/trace-mapping" "^0.3.13" + "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" - integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== +"@jest/test-result@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.0.3.tgz#b03d8ef4c58be84cd5d5d3b24d4b4c8cabbf2746" + integrity sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg== dependencies: - "@jest/console" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.0.3" + "@jest/types" "^29.0.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" - integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== +"@jest/test-sequencer@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz#0681061ad21fb8e293b49c4fdf7e631ca79240ba" + integrity sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ== dependencies: - "@jest/test-result" "^28.1.3" + "@jest/test-result" "^29.0.3" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" + jest-haste-map "^29.0.3" slash "^3.0.0" -"@jest/transform@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" - integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== +"@jest/transform@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.0.3.tgz#9eb1fed2072a0354f190569807d1250572fb0970" + integrity sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" + "@jest/types" "^29.0.3" + "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" + fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" + jest-haste-map "^29.0.3" + jest-regex-util "^29.0.0" + jest-util "^29.0.3" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" write-file-atomic "^4.0.1" -"@jest/types@^28.1.3": - version "28.1.3" - resolved "https://registry.npmmirror.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" - integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== +"@jest/types@^29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.0.3.tgz#0be78fdddb1a35aeb2041074e55b860561c8ef63" + integrity sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A== dependencies: - "@jest/schemas" "^28.1.3" + "@jest/schemas" "^29.0.0" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" @@ -651,7 +661,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== @@ -659,20 +669,35 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@nestjs/cli@^8.0.0": - version "8.2.8" - resolved "https://registry.npmmirror.com/@nestjs/cli/-/cli-8.2.8.tgz#63e5b477f90e6d0238365dcc6236b95bf4f0c807" - integrity sha512-y5Imcw1EY0OxD3POAM7SLUB1rFdn5FjbfSsyJrokjKmXY+i6KcBdbRrv3Ox7aeJ4W7wXuckIXZEUlK6lC52dnA== +"@jridgewell/trace-mapping@^0.3.15": + version "0.3.15" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@nestjs/axios@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@nestjs/axios/-/axios-0.1.0.tgz#6cf93df11ef93b598b3c7411adb980eedd13b3e3" + integrity sha512-b2TT2X6BFbnNoeteiaxCIiHaFcSbVW+S5yygYqiIq5i6H77yIU3IVuLdpQkHq8/EqOWFwMopLN8jdkUT71Am9w== dependencies: - "@angular-devkit/core" "13.3.6" - "@angular-devkit/schematics" "13.3.6" - "@angular-devkit/schematics-cli" "13.3.6" - "@nestjs/schematics" "^8.0.3" + axios "0.27.2" + +"@nestjs/cli@^9.1.3": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@nestjs/cli/-/cli-9.1.3.tgz#b1891268e20ecc1b55d730ec3013f1a3683fca64" + integrity sha512-ILACqDDrplvOb7HwCFJCvghMyXSHPwhqzxzant4AwYzu3BGsZVQG7TRNPxu+qfHZH6o4EBglpBwkb+8vbnVBKA== + dependencies: + "@angular-devkit/core" "14.2.2" + "@angular-devkit/schematics" "14.2.2" + "@angular-devkit/schematics-cli" "14.2.2" + "@nestjs/schematics" "^9.0.0" chalk "3.0.0" chokidar "3.5.3" cli-table3 "0.6.2" commander "4.1.1" - fork-ts-checker-webpack-plugin "7.2.11" + fork-ts-checker-webpack-plugin "7.2.13" inquirer "7.3.3" node-emoji "1.11.0" ora "5.4.1" @@ -681,25 +706,24 @@ shelljs "0.8.5" source-map-support "0.5.21" tree-kill "1.2.2" - tsconfig-paths "3.14.1" - tsconfig-paths-webpack-plugin "3.5.2" - typescript "4.7.4" - webpack "5.73.0" + tsconfig-paths "4.1.0" + tsconfig-paths-webpack-plugin "4.0.0" + typescript "4.8.3" + webpack "5.74.0" webpack-node-externals "3.0.0" -"@nestjs/common@^8.0.0": - version "8.4.7" - resolved "https://registry.npmmirror.com/@nestjs/common/-/common-8.4.7.tgz#fc4a575b797e230bb5a0bcab6da8b796aa88d605" - integrity sha512-m/YsbcBal+gA5CFrDpqXqsSfylo+DIQrkFY3qhVIltsYRfu8ct8J9pqsTO6OPf3mvqdOpFGrV5sBjoyAzOBvsw== +"@nestjs/common@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-9.1.2.tgz#a808edb196d13a6e003a07883b4163493ed5346c" + integrity sha512-zpF4DaLvvsCVqfrf9LJfSeYP+SBCWCFbOCTOmEZ5Gs6Hralia6s2kS+CSicJKx8IpnyC6ZReuqdTbjcPl4yunA== dependencies: - axios "0.27.2" iterare "1.2.1" tslib "2.4.0" - uuid "8.3.2" + uuid "9.0.0" -"@nestjs/config@^2.0.0": +"@nestjs/config@^2.2.0": version "2.2.0" - resolved "https://registry.npmmirror.com/@nestjs/config/-/config-2.2.0.tgz#9f3da35f7c4a58724c0a0817d6f04b66e6703430" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-2.2.0.tgz#9f3da35f7c4a58724c0a0817d6f04b66e6703430" integrity sha512-78Eg6oMbCy3D/YvqeiGBTOWei1Jwi3f2pSIZcZ1QxY67kYsJzTRTkwRT8Iv30DbK0sGKc1mcloDLD5UXgZAZtg== dependencies: dotenv "16.0.1" @@ -707,10 +731,10 @@ lodash "4.17.21" uuid "8.3.2" -"@nestjs/core@^8.0.0": - version "8.4.7" - resolved "https://registry.npmmirror.com/@nestjs/core/-/core-8.4.7.tgz#fbec7fa744ac8749a4b966f759a6656c1cf43883" - integrity sha512-XB9uexHqzr2xkPo6QSiQWJJttyYYLmvQ5My64cFvWFi7Wk2NIus0/xUNInwX3kmFWB6pF1ab5Y2ZBvWdPwGBhw== +"@nestjs/core@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-9.1.2.tgz#53eeeb8730d7fbe049387bdee6053d513abd4ee2" + integrity sha512-wrb/U8PN50K9wEHOLifR9bFKDH8+Dr37rXBB5J+9v3tSWEHkT4o2OiJ8qFmfX5B9GwGE/YRKaJqxw/ScvYvPFw== dependencies: "@nuxtjs/opencollective" "0.3.2" fast-safe-stringify "2.1.1" @@ -718,22 +742,30 @@ object-hash "3.0.0" path-to-regexp "3.2.0" tslib "2.4.0" - uuid "8.3.2" + uuid "9.0.0" + +"@nestjs/jwt@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@nestjs/jwt/-/jwt-9.0.0.tgz#73e01338d2853a55033528b540cfd92c7996bae9" + integrity sha512-ZsXGY/wMYKzEhymw2+dxiwrHTRKIKrGszx6r2EjQqNLypdXMQu0QrujwZJ8k3+XQV4snmuJwwNakQoA2ILfq8w== + dependencies: + "@types/jsonwebtoken" "8.5.8" + jsonwebtoken "8.5.1" -"@nestjs/mapped-types@*": +"@nestjs/mapped-types@*", "@nestjs/mapped-types@1.1.0": version "1.1.0" resolved "https://registry.npmmirror.com/@nestjs/mapped-types/-/mapped-types-1.1.0.tgz#54a9fa61079635dd6c3c75fd9593f20b2302a55b" integrity sha512-+2kSly4P1QI+9eGt+/uGyPdEG1hVz7nbpqPHWZVYgoqz8eOHljpXPag+UCVRw9zo2XCu4sgNUIGe8Uk0+OvUQg== -"@nestjs/passport@^8.2.1": - version "8.2.2" - resolved "https://registry.npmmirror.com/@nestjs/passport/-/passport-8.2.2.tgz#32b3932b83740895f037eabaf812c44f5ec18b3a" - integrity sha512-Ytbn8j7WZ4INmEntOpdJY1isTgdQqZkx5ADz8zsZ5wAp0t8tc5GF/A+GlXlmn9/yRPwZHSbmHpv7Qt2EIiNnrw== +"@nestjs/passport@^9.0.0": + version "9.0.0" + resolved "https://registry.yarnpkg.com/@nestjs/passport/-/passport-9.0.0.tgz#0571bb08f8043456bc6df44cd4f59ca5f10c9b9f" + integrity sha512-Gnh8n1wzFPOLSS/94X1sUP4IRAoXTgG4odl7/AO5h+uwscEGXxJFercrZfqdAwkWhqkKWbsntM3j5mRy/6ZQDA== -"@nestjs/platform-express@^8.0.0": - version "8.4.7" - resolved "https://registry.npmmirror.com/@nestjs/platform-express/-/platform-express-8.4.7.tgz#402a3d3c47327a164bb3867615f423c29d1a6cd9" - integrity sha512-lPE5Ltg2NbQGRQIwXWY+4cNrXhJdycbxFDQ8mNxSIuv+LbrJBIdEB/NONk+LLn9N/8d2+I2LsIETGQrPvsejBg== +"@nestjs/platform-express@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-9.1.2.tgz#985307b074be4dcf04c2ba7bdf5f2f97407861e7" + integrity sha512-SlAG6nfEVSk+lQL1Z4kjLip2jJ+w4mc8cG5ccM3mN06gREYfJVayNuydPUYtoxP/QmzugQfO5+cNEdqdhCmSQw== dependencies: body-parser "1.20.0" cors "2.8.5" @@ -741,28 +773,39 @@ multer "1.4.4-lts.1" tslib "2.4.0" -"@nestjs/schematics@^8.0.0", "@nestjs/schematics@^8.0.3": - version "8.0.11" - resolved "https://registry.npmmirror.com/@nestjs/schematics/-/schematics-8.0.11.tgz#5d0c56184826660a2c01b1c326dbdbb12880e864" - integrity sha512-W/WzaxgH5aE01AiIErE9QrQJ73VR/M/8p8pq0LZmjmNcjZqU5kQyOWUxZg13WYfSpJdOa62t6TZRtFDmgZPoIg== +"@nestjs/schematics@^9.0.0", "@nestjs/schematics@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@nestjs/schematics/-/schematics-9.0.3.tgz#175218350fb3829c9a903e980046a11950310e24" + integrity sha512-kZrU/lrpVd2cnK8I3ibDb3Wi1ppl3wX3U3lVWoL+DzRRoezWKkh8upEL4q0koKmuXnsmLiu3UPxFeMOrJV7TSA== dependencies: - "@angular-devkit/core" "13.3.5" - "@angular-devkit/schematics" "13.3.5" + "@angular-devkit/core" "14.2.1" + "@angular-devkit/schematics" "14.2.1" fs-extra "10.1.0" - jsonc-parser "3.0.0" + jsonc-parser "3.2.0" pluralize "8.0.0" -"@nestjs/testing@^8.0.0": - version "8.4.7" - resolved "https://registry.npmmirror.com/@nestjs/testing/-/testing-8.4.7.tgz#fe4f356c0e081e25fe8c899a65e91dd88947fd13" - integrity sha512-aedpeJFicTBeiTCvJWUG45WMMS53f5eu8t2fXsfjsU1t+WdDJqYcZyrlCzA4dL1B7MfbqaTURdvuVVHTmJO8ag== +"@nestjs/swagger@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-6.1.2.tgz#5eb9c134fc976f16c139ecaf80a7f02a5d33da46" + integrity sha512-RU1DeTDyuN/lRXKFWaf7I9LYF34/ale3IIGeY3romAcXL/N9W0+50Ek3ou+Ajd5FqpLqzt7saYhnaQegVuU4UQ== + dependencies: + "@nestjs/mapped-types" "1.1.0" + js-yaml "4.1.0" + lodash "4.17.21" + path-to-regexp "3.2.0" + swagger-ui-dist "4.14.0" + +"@nestjs/testing@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-9.1.2.tgz#98925cafab0cc92e0492d37ec17a6a7739b46a21" + integrity sha512-BfwERdTppE4oz6qxCNJVo0kaRH2FO7mipooedT2nDtYW3krGZ8978odmGdpVgNz1xwqKDH3Y/68frs5oW2CTZw== dependencies: tslib "2.4.0" -"@nestjs/typeorm@^8.0.3": - version "8.1.4" - resolved "https://registry.npmmirror.com/@nestjs/typeorm/-/typeorm-8.1.4.tgz#ab2286b39b69d1ce74e039d1847708d56c2c3e60" - integrity sha512-hKv0Y9PG7YkHQfjsrNqM1s/VajlT7Mla8gaoblmuLzgMKsOQFsZXSHlXNxXZ8CA4aCPeDUiXtvqc4zocadGiIQ== +"@nestjs/typeorm@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@nestjs/typeorm/-/typeorm-9.0.1.tgz#f78bfc00e71731ea860288e4a03830107daf3d9c" + integrity sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g== dependencies: uuid "8.3.2" @@ -893,6 +936,11 @@ resolved "https://registry.npmmirror.com/@types/cookiejar/-/cookiejar-2.1.2.tgz#66ad9331f63fe8a3d3d9d8c6e3906dd10f6446e8" integrity sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog== +"@types/crypto-js@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.1.tgz#602859584cecc91894eb23a4892f38cfa927890d" + integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== + "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.npmmirror.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -928,7 +976,7 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@^4.17.13": +"@types/express@*": version "4.17.13" resolved "https://registry.npmmirror.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== @@ -938,6 +986,16 @@ "@types/qs" "*" "@types/serve-static" "*" +"@types/express@^4.17.14": + version "4.17.14" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" + integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/graceful-fs@^4.1.3": version "4.1.5" resolved "https://registry.npmmirror.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" @@ -964,13 +1022,13 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@27.5.0": - version "27.5.0" - resolved "https://registry.npmmirror.com/@types/jest/-/jest-27.5.0.tgz#e04ed1824ca6b1dd0438997ba60f99a7405d4c7b" - integrity sha512-9RBFx7r4k+msyj/arpfaa0WOOEcaAZNmN+j80KFbFCoSqCJGHTz7YMAMGQW9Xmqm5w6l5c25vbSjMwlikJi5+g== +"@types/jest@29.0.3": + version "29.0.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.0.3.tgz#b61a5ed100850686b8d3c5e28e3a1926b2001b59" + integrity sha512-F6ukyCTwbfsEX5F2YmVYmM5TcTHy1q9P5rWlRbrk56KyMh3v9xRGUO3aa8+SkvMi0SHXtASJv1283enXimC0Og== dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" + expect "^29.0.0" + pretty-format "^29.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" @@ -979,9 +1037,16 @@ "@types/json5@^0.0.29": version "0.0.29" - resolved "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/jsonwebtoken@8.5.8": + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz#01b39711eb844777b7af1d1f2b4cf22fda1c0c44" + integrity sha512-zm6xBQpFDIDM6o9r6HSgDeIcLy82TKWctCXEPbJJcXb5AKmi5BNNdLXneixK4lplX3PqIVcwLBCGE/kAGnlD4A== + dependencies: + "@types/node" "*" + "@types/mime@*": version "3.0.1" resolved "https://registry.npmmirror.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" @@ -992,10 +1057,10 @@ resolved "https://registry.npmmirror.com/@types/node/-/node-18.6.4.tgz#fd26723a8a3f8f46729812a7f9b4fc2d1608ed39" integrity sha512-I4BD3L+6AWiUobfxZ49DlU43gtI+FTHSv9pE2Zekg6KjMpre4ByusaljW3vYSLJrvQ1ck1hUaeVu8HVlY3vzHg== -"@types/node@^16.0.0": - version "16.11.47" - resolved "https://registry.npmmirror.com/@types/node/-/node-16.11.47.tgz#efa9e3e0f72e7aa6a138055dace7437a83d9f91c" - integrity sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g== +"@types/node@^18.7.23": + version "18.7.23" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f" + integrity sha512-DWNcCHolDq0ZKGizjx2DZjR/PqsYwAcYUJmfMWqtVU2MBMG5Mo+xFZrhGId5r/O5HOuMPyQEcM6KUBp5lBZZBg== "@types/parse-json@^4.0.0": version "4.0.0" @@ -1010,13 +1075,20 @@ "@types/express" "*" "@types/passport" "*" -"@types/passport@*", "@types/passport@^1.0.7": +"@types/passport@*": version "1.0.9" resolved "https://registry.npmmirror.com/@types/passport/-/passport-1.0.9.tgz#b32fa8f7485dace77a9b58e82d0c92908f6e8387" integrity sha512-9+ilzUhmZQR4JP49GdC2O4UdDE3POPLwpmaTC/iLkW7l0TZCXOo1zsTnnlXPq6rP1UsUZPfbAV4IUdiwiXyC7g== dependencies: "@types/express" "*" +"@types/passport@^1.0.11": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.11.tgz#d046b41e28b280f4e7994614fb976e9b449cb7c6" + integrity sha512-pz1cx9ptZvozyGKKKIPLcVDVHwae4hrH5d6g5J+DkMRRjR3cVETb4jMabhXAUbg3Ov7T22nFHEgaK2jj+5CBpw== + dependencies: + "@types/express" "*" + "@types/prettier@^2.1.5": version "2.7.0" resolved "https://registry.npmmirror.com/@types/prettier/-/prettier-2.7.0.tgz#ea03e9f0376a4446f44797ca19d9c46c36e352dc" @@ -1053,9 +1125,9 @@ "@types/cookiejar" "*" "@types/node" "*" -"@types/supertest@^2.0.11": +"@types/supertest@^2.0.12": version "2.0.12" - resolved "https://registry.npmmirror.com/@types/supertest/-/supertest-2.0.12.tgz#ddb4a0568597c9aadff8dbec5b2e8fddbe8692fc" + resolved "https://registry.yarnpkg.com/@types/supertest/-/supertest-2.0.12.tgz#ddb4a0568597c9aadff8dbec5b2e8fddbe8692fc" integrity sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ== dependencies: "@types/superagent" "*" @@ -1072,89 +1144,84 @@ dependencies: "@types/yargs-parser" "*" -"@types/zen-observable@0.8.3": - version "0.8.3" - resolved "https://registry.npmmirror.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" - integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== - -"@typescript-eslint/eslint-plugin@^5.0.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.32.0.tgz#e27e38cffa4a61226327c874a7be965e9a861624" - integrity sha512-CHLuz5Uz7bHP2WgVlvoZGhf0BvFakBJKAD/43Ty0emn4wXWv5k01ND0C0fHcl/Im8Td2y/7h44E9pca9qAu2ew== +"@typescript-eslint/eslint-plugin@^5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.38.1.tgz#9f05d42fa8fb9f62304cc2f5c2805e03c01c2620" + integrity sha512-ky7EFzPhqz3XlhS7vPOoMDaQnQMn+9o5ICR9CPr/6bw8HrFkzhMSxuA3gRfiJVvs7geYrSeawGJjZoZQKCOglQ== dependencies: - "@typescript-eslint/scope-manager" "5.32.0" - "@typescript-eslint/type-utils" "5.32.0" - "@typescript-eslint/utils" "5.32.0" + "@typescript-eslint/scope-manager" "5.38.1" + "@typescript-eslint/type-utils" "5.38.1" + "@typescript-eslint/utils" "5.38.1" debug "^4.3.4" - functional-red-black-tree "^1.0.1" ignore "^5.2.0" regexpp "^3.2.0" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.0.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/parser/-/parser-5.32.0.tgz#1de243443bc6186fb153b9e395b842e46877ca5d" - integrity sha512-IxRtsehdGV9GFQ35IGm5oKKR2OGcazUoiNBxhRV160iF9FoyuXxjY+rIqs1gfnd+4eL98OjeGnMpE7RF/NBb3A== +"@typescript-eslint/parser@^5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.38.1.tgz#c577f429f2c32071b92dff4af4f5fbbbd2414bd0" + integrity sha512-LDqxZBVFFQnQRz9rUZJhLmox+Ep5kdUmLatLQnCRR6523YV+XhRjfYzStQ4MheFA8kMAfUlclHSbu+RKdRwQKw== dependencies: - "@typescript-eslint/scope-manager" "5.32.0" - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/typescript-estree" "5.32.0" + "@typescript-eslint/scope-manager" "5.38.1" + "@typescript-eslint/types" "5.38.1" + "@typescript-eslint/typescript-estree" "5.38.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/scope-manager/-/scope-manager-5.32.0.tgz#763386e963a8def470580cc36cf9228864190b95" - integrity sha512-KyAE+tUON0D7tNz92p1uetRqVJiiAkeluvwvZOqBmW9z2XApmk5WSMV9FrzOroAcVxJZB3GfUwVKr98Dr/OjOg== +"@typescript-eslint/scope-manager@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz#f87b289ef8819b47189351814ad183e8801d5764" + integrity sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ== dependencies: - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/visitor-keys" "5.32.0" + "@typescript-eslint/types" "5.38.1" + "@typescript-eslint/visitor-keys" "5.38.1" -"@typescript-eslint/type-utils@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/type-utils/-/type-utils-5.32.0.tgz#45a14506fe3fb908600b4cef2f70778f7b5cdc79" - integrity sha512-0gSsIhFDduBz3QcHJIp3qRCvVYbqzHg8D6bHFsDMrm0rURYDj+skBK2zmYebdCp+4nrd9VWd13egvhYFJj/wZg== +"@typescript-eslint/type-utils@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.38.1.tgz#7f038fcfcc4ade4ea76c7c69b2aa25e6b261f4c1" + integrity sha512-UU3j43TM66gYtzo15ivK2ZFoDFKKP0k03MItzLdq0zV92CeGCXRfXlfQX5ILdd4/DSpHkSjIgLLLh1NtkOJOAw== dependencies: - "@typescript-eslint/utils" "5.32.0" + "@typescript-eslint/typescript-estree" "5.38.1" + "@typescript-eslint/utils" "5.38.1" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/types/-/types-5.32.0.tgz#484273021eeeae87ddb288f39586ef5efeb6dcd8" - integrity sha512-EBUKs68DOcT/EjGfzywp+f8wG9Zw6gj6BjWu7KV/IYllqKJFPlZlLSYw/PTvVyiRw50t6wVbgv4p9uE2h6sZrQ== +"@typescript-eslint/types@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.38.1.tgz#74f9d6dcb8dc7c58c51e9fbc6653ded39e2e225c" + integrity sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg== -"@typescript-eslint/typescript-estree@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.32.0.tgz#282943f34babf07a4afa7b0ff347a8e7b6030d12" - integrity sha512-ZVAUkvPk3ITGtCLU5J4atCw9RTxK+SRc6hXqLtllC2sGSeMFWN+YwbiJR9CFrSFJ3w4SJfcWtDwNb/DmUIHdhg== +"@typescript-eslint/typescript-estree@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz#657d858d5d6087f96b638ee383ee1cff52605a1e" + integrity sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g== dependencies: - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/visitor-keys" "5.32.0" + "@typescript-eslint/types" "5.38.1" + "@typescript-eslint/visitor-keys" "5.38.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/utils/-/utils-5.32.0.tgz#eccb6b672b94516f1afc6508d05173c45924840c" - integrity sha512-W7lYIAI5Zlc5K082dGR27Fczjb3Q57ECcXefKU/f0ajM5ToM0P+N9NmJWip8GmGu/g6QISNT+K6KYB+iSHjXCQ== +"@typescript-eslint/utils@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.38.1.tgz#e3ac37d7b33d1362bb5adf4acdbe00372fb813ef" + integrity sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.32.0" - "@typescript-eslint/types" "5.32.0" - "@typescript-eslint/typescript-estree" "5.32.0" + "@typescript-eslint/scope-manager" "5.38.1" + "@typescript-eslint/types" "5.38.1" + "@typescript-eslint/typescript-estree" "5.38.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.32.0": - version "5.32.0" - resolved "https://registry.npmmirror.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.32.0.tgz#b9715d0b11fdb5dd10fd0c42ff13987470525394" - integrity sha512-S54xOHZgfThiZ38/ZGTgB2rqx51CMJ5MCfVT2IplK4Q7hgzGfe0nLzLCcenDnc/cSjP568hdeKfeDcBgqNHD/g== +"@typescript-eslint/visitor-keys@5.38.1": + version "5.38.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz#508071bfc6b96d194c0afe6a65ad47029059edbc" + integrity sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA== dependencies: - "@typescript-eslint/types" "5.32.0" + "@typescript-eslint/types" "5.38.1" eslint-visitor-keys "^3.3.0" "@webassemblyjs/ast@1.11.1": @@ -1311,7 +1378,7 @@ acorn-walk@^8.1.1: resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.4.1, acorn@^8.5.0, acorn@^8.8.0: +acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: version "8.8.0" resolved "https://registry.npmmirror.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== @@ -1328,10 +1395,10 @@ ajv-keywords@^3.5.2: resolved "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@8.9.0: - version "8.9.0" - resolved "https://registry.npmmirror.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" - integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== +ajv@8.11.0, ajv@^8.0.0, ajv@^8.11.0: + version "8.11.0" + resolved "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -1348,20 +1415,10 @@ ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.11.0: - version "8.11.0" - resolved "https://registry.npmmirror.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.npmmirror.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-colors@4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== ansi-escapes@^4.2.1: version "4.3.2" @@ -1439,11 +1496,32 @@ array-flatten@1.1.1: resolved "https://registry.npmmirror.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== +array-includes@^3.1.4: + version "3.1.5" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" + integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + array-union@^2.1.0: version "2.1.0" resolved "https://registry.npmmirror.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array.prototype.flat@^1.2.5: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" + integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" + asap@^2.0.0: version "2.0.6" resolved "https://registry.npmmirror.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -1456,21 +1534,21 @@ asynckit@^0.4.0: axios@0.27.2: version "0.27.2" - resolved "https://registry.npmmirror.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== dependencies: follow-redirects "^1.14.9" form-data "^4.0.0" -babel-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" - integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== +babel-jest@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.0.3.tgz#64e156a47a77588db6a669a88dedff27ed6e260f" + integrity sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg== dependencies: - "@jest/transform" "^28.1.3" + "@jest/transform" "^29.0.3" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^28.1.3" + babel-preset-jest "^29.0.2" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -1486,10 +1564,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" - integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== +babel-plugin-jest-hoist@^29.0.2: + version "29.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.2.tgz#ae61483a829a021b146c016c6ad39b8bcc37c2c8" + integrity sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -1514,12 +1592,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" - integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== +babel-preset-jest@^29.0.2: + version "29.0.2" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.0.2.tgz#e14a7124e22b161551818d89e5bdcfb3b2b0eac7" + integrity sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA== dependencies: - babel-plugin-jest-hoist "^28.1.3" + babel-plugin-jest-hoist "^29.0.2" babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: @@ -1603,6 +1681,11 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" @@ -1636,7 +1719,7 @@ bytes@3.1.2: resolved "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -call-bind@^1.0.0: +call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -1729,6 +1812,19 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.npmmirror.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.13.2.tgz#64b031e9f3f81a1e1dcd04a5d604734608b24143" + integrity sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw== + dependencies: + libphonenumber-js "^1.9.43" + validator "^13.7.0" + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -1936,16 +2032,33 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -debug@2.6.9: +crypto-js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" + integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== + +date-fns@^2.28.0: + version "2.29.3" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" + integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA== + +debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" - resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -1972,6 +2085,14 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -2005,15 +2126,10 @@ dezalgo@1.0.3: asap "^2.0.0" wrappy "1" -diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - -diff-sequences@^28.1.1: - version "28.1.1" - resolved "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" - integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== +diff-sequences@^29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.0.0.tgz#bae49972ef3933556bcb0800b72e8579d19d9e4f" + integrity sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA== diff@^4.0.1: version "4.0.2" @@ -2027,6 +2143,13 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.npmmirror.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -2044,10 +2167,17 @@ dotenv@16.0.1: resolved "https://registry.npmmirror.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== -dotenv@^8.2.0: - version "8.6.0" - resolved "https://registry.npmmirror.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" - integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== +dotenv@^16.0.0, dotenv@^16.0.2: + version "16.0.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf" + integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" ee-first@1.1.1: version "1.1.1" @@ -2081,7 +2211,7 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.7.0, enhanced-resolve@^5.9.3: +enhanced-resolve@^5.0.0, enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0: version "5.10.0" resolved "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== @@ -2096,11 +2226,57 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5: + version "1.20.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.3.tgz#90b143ff7aedc8b3d189bcfac7f1e3e3f81e9da1" + integrity sha512-AyrnaKVpMzljIdwjzrj+LxGmj8ik2LckwXacHqrJJ/jxz6dDDBcZ7I7nlHM0FvEW8MfbWJwOd+yT2XzYW49Frw== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.3" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.6" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.2" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.4.3" + safe-regex-test "^1.0.0" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + es-module-lexer@^0.9.0: version "0.9.3" resolved "https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2126,14 +2302,48 @@ escape-string-regexp@^4.0.0: resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-config-prettier@^8.3.0: +eslint-config-prettier@^8.5.0: version "8.5.0" - resolved "https://registry.npmmirror.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== -eslint-plugin-prettier@^4.0.0: +eslint-import-resolver-node@^0.3.6: + version "0.3.6" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" + integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== + dependencies: + debug "^3.2.7" + resolve "^1.20.0" + +eslint-module-utils@^2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" + integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + dependencies: + debug "^3.2.7" + +eslint-plugin-import@^2.26.0: + version "2.26.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" + integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== + dependencies: + array-includes "^3.1.4" + array.prototype.flat "^1.2.5" + debug "^2.6.9" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.6" + eslint-module-utils "^2.7.3" + has "^1.0.3" + is-core-module "^2.8.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.values "^1.1.5" + resolve "^1.22.0" + tsconfig-paths "^3.14.1" + +eslint-plugin-prettier@^4.2.1: version "4.2.1" - resolved "https://registry.npmmirror.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== dependencies: prettier-linter-helpers "^1.0.0" @@ -2171,14 +2381,15 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@^8.0.1: - version "8.21.0" - resolved "https://registry.npmmirror.com/eslint/-/eslint-8.21.0.tgz#1940a68d7e0573cef6f50037addee295ff9be9ef" - integrity sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA== +eslint@^8.24.0: + version "8.24.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.24.0.tgz#489516c927a5da11b3979dbfb2679394523383c8" + integrity sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ== dependencies: - "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.10.4" + "@eslint/eslintrc" "^1.3.2" + "@humanwhocodes/config-array" "^0.10.5" "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + "@humanwhocodes/module-importer" "^1.0.1" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -2188,13 +2399,12 @@ eslint@^8.0.1: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.3" + espree "^9.4.0" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" find-up "^5.0.0" - functional-red-black-tree "^1.0.1" glob-parent "^6.0.1" globals "^13.15.0" globby "^11.1.0" @@ -2203,6 +2413,7 @@ eslint@^8.0.1: import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" + js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" @@ -2214,12 +2425,11 @@ eslint@^8.0.1: strip-ansi "^6.0.1" strip-json-comments "^3.1.0" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^9.3.2, espree@^9.3.3: - version "9.3.3" - resolved "https://registry.npmmirror.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" - integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== +espree@^9.4.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: acorn "^8.8.0" acorn-jsx "^5.3.2" @@ -2304,16 +2514,16 @@ exit@^0.1.2: resolved "https://registry.npmmirror.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expect@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" - integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== +expect@^29.0.0, expect@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.0.3.tgz#6be65ddb945202f143c4e07c083f4f39f3bd326f" + integrity sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q== dependencies: - "@jest/expect-utils" "^28.1.3" - jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + "@jest/expect-utils" "^29.0.3" + jest-get-type "^29.0.0" + jest-matcher-utils "^29.0.3" + jest-message-util "^29.0.3" + jest-util "^29.0.3" express@4.18.1: version "4.18.1" @@ -2382,7 +2592,7 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -2475,14 +2685,14 @@ flatted@^3.1.0: integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== follow-redirects@^1.14.9: - version "1.15.1" - resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" - integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -fork-ts-checker-webpack-plugin@7.2.11: - version "7.2.11" - resolved "https://registry.npmmirror.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.11.tgz#aff3febbc11544ba3ad0ae4d5aa4055bd15cd26d" - integrity sha512-2e5+NyTUTE1Xq4fWo7KFEQblCaIvvINQwUX3jRmEGlgCTc1Ecqw/975EfQrQ0GEraxJTnp8KB9d/c8hlCHUMJA== +fork-ts-checker-webpack-plugin@7.2.13: + version "7.2.13" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz#51ffd6a2f96f03ab64b92f8aedf305dbf3dee0f1" + integrity sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg== dependencies: "@babel/code-frame" "^7.16.7" chalk "^4.1.2" @@ -2492,6 +2702,7 @@ fork-ts-checker-webpack-plugin@7.2.11: fs-extra "^10.0.0" memfs "^3.4.1" minimatch "^3.0.4" + node-abort-controller "^3.0.1" schema-utils "^3.1.1" semver "^7.3.5" tapable "^2.2.1" @@ -2554,10 +2765,20 @@ function-bind@^1.1.1: resolved "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.npmmirror.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== generate-function@^2.3.1: version "2.3.1" @@ -2585,6 +2806,15 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" + integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.npmmirror.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -2602,6 +2832,14 @@ get-stream@^6.0.0: resolved "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2621,7 +2859,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmmirror.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: +glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: version "7.2.3" resolved "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -2667,6 +2905,11 @@ grapheme-splitter@^1.0.4: resolved "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2677,11 +2920,25 @@ has-flag@^4.0.0: resolved "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.3: +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has@^1.0.3: version "1.0.3" resolved "https://registry.npmmirror.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -2802,10 +3059,10 @@ inquirer@7.3.3: strip-ansi "^6.0.0" through "^2.3.6" -inquirer@8.2.0: - version "8.2.0" - resolved "https://registry.npmmirror.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" - integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== +inquirer@8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" + integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -2817,10 +3074,20 @@ inquirer@8.2.0: mute-stream "0.0.8" ora "^5.4.1" run-async "^2.4.0" - rxjs "^7.2.0" + rxjs "^7.5.5" string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" + wrap-ansi "^7.0.0" + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" interpret@^1.0.0: version "1.4.0" @@ -2837,6 +3104,13 @@ is-arrayish@^0.2.1: resolved "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -2844,13 +3118,33 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-core-module@^2.9.0: +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-callable@^1.1.4, is-callable@^1.2.6: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + +is-core-module@^2.8.1, is-core-module@^2.9.0: version "2.10.0" resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== dependencies: has "^1.0.3" +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -2878,6 +3172,18 @@ is-interactive@^1.0.0: resolved "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -2888,16 +3194,52 @@ is-property@^1.0.2: resolved "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + isarray@~1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2955,213 +3297,188 @@ iterare@1.2.1: resolved "https://registry.npmmirror.com/iterare/-/iterare-1.2.1.tgz#139c400ff7363690e33abffa33cbba8920f00042" integrity sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q== -jest-changed-files@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" - integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== +jest-changed-files@^29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.0.0.tgz#aa238eae42d9372a413dd9a8dadc91ca1806dce0" + integrity sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" - integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== +jest-circus@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.0.3.tgz#90faebc90295291cfc636b27dbd82e3bfb9e7a48" + integrity sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg== dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/environment" "^29.0.3" + "@jest/expect" "^29.0.3" + "@jest/test-result" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" + jest-each "^29.0.3" + jest-matcher-utils "^29.0.3" + jest-message-util "^29.0.3" + jest-runtime "^29.0.3" + jest-snapshot "^29.0.3" + jest-util "^29.0.3" p-limit "^3.1.0" - pretty-format "^28.1.3" + pretty-format "^29.0.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^28.0.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" - integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== +jest-cli@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.0.3.tgz#fd8f0ef363a7a3d9c53ef62e0651f18eeffa77b9" + integrity sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ== dependencies: - "@jest/core" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/core" "^29.0.3" + "@jest/test-result" "^29.0.3" + "@jest/types" "^29.0.3" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-config "^29.0.3" + jest-util "^29.0.3" + jest-validate "^29.0.3" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" - integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== +jest-config@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.0.3.tgz#c2e52a8f5adbd18de79f99532d8332a19e232f13" + integrity sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.1.3" - "@jest/types" "^28.1.3" - babel-jest "^28.1.3" + "@jest/test-sequencer" "^29.0.3" + "@jest/types" "^29.0.3" + babel-jest "^29.0.3" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^28.1.3" - jest-environment-node "^28.1.3" - jest-get-type "^28.0.2" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-runner "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-circus "^29.0.3" + jest-environment-node "^29.0.3" + jest-get-type "^29.0.0" + jest-regex-util "^29.0.0" + jest-resolve "^29.0.3" + jest-runner "^29.0.3" + jest-util "^29.0.3" + jest-validate "^29.0.3" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^28.1.3" + pretty-format "^29.0.3" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.npmmirror.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== +jest-diff@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.0.3.tgz#41cc02409ad1458ae1bf7684129a3da2856341ac" + integrity sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg== dependencies: chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" + diff-sequences "^29.0.0" + jest-get-type "^29.0.0" + pretty-format "^29.0.3" -jest-diff@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" - integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== - dependencies: - chalk "^4.0.0" - diff-sequences "^28.1.1" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - -jest-docblock@^28.1.1: - version "28.1.1" - resolved "https://registry.npmmirror.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" - integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== +jest-docblock@^29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.0.0.tgz#3151bcc45ed7f5a8af4884dcc049aee699b4ceae" + integrity sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw== dependencies: detect-newline "^3.0.0" -jest-each@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" - integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== +jest-each@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.0.3.tgz#7ef3157580b15a609d7ef663dd4fc9b07f4e1299" + integrity sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" chalk "^4.0.0" - jest-get-type "^28.0.2" - jest-util "^28.1.3" - pretty-format "^28.1.3" - -jest-environment-node@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" - integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" + jest-get-type "^29.0.0" + jest-util "^29.0.3" + pretty-format "^29.0.3" + +jest-environment-node@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.0.3.tgz#293804b1e0fa5f0e354dacbe510655caa478a3b2" + integrity sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg== + dependencies: + "@jest/environment" "^29.0.3" + "@jest/fake-timers" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" - jest-mock "^28.1.3" - jest-util "^28.1.3" + jest-mock "^29.0.3" + jest-util "^29.0.3" -jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== +jest-get-type@^29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.0.0.tgz#843f6c50a1b778f7325df1129a0fd7aa713aef80" + integrity sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw== -jest-get-type@^28.0.2: - version "28.0.2" - resolved "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" - integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== - -jest-haste-map@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" - integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== +jest-haste-map@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.0.3.tgz#d7f3f7180f558d760eacc5184aac5a67f20ef939" + integrity sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - jest-worker "^28.1.3" + jest-regex-util "^29.0.0" + jest-util "^29.0.3" + jest-worker "^29.0.3" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" - integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== +jest-leak-detector@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz#e85cf3391106a7a250850b6766b508bfe9c7bc6f" + integrity sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ== dependencies: - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - -jest-matcher-utils@^27.0.0: - version "27.5.1" - resolved "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" + jest-get-type "^29.0.0" + pretty-format "^29.0.3" -jest-matcher-utils@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" - integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== +jest-matcher-utils@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz#b8305fd3f9e27cdbc210b21fc7dbba92d4e54560" + integrity sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w== dependencies: chalk "^4.0.0" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" + jest-diff "^29.0.3" + jest-get-type "^29.0.0" + pretty-format "^29.0.3" -jest-message-util@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" - integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== +jest-message-util@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.0.3.tgz#f0254e1ffad21890c78355726202cc91d0a40ea8" + integrity sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^28.1.3" + pretty-format "^29.0.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" - integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== +jest-mock@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.0.3.tgz#4f0093f6a9cb2ffdb9c44a07a3912f0c098c8de9" + integrity sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -3169,154 +3486,155 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.npmmirror.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^28.0.2: - version "28.0.2" - resolved "https://registry.npmmirror.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" - integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== +jest-regex-util@^29.0.0: + version "29.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.0.0.tgz#b442987f688289df8eb6c16fa8df488b4cd007de" + integrity sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug== -jest-resolve-dependencies@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" - integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== +jest-resolve-dependencies@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz#f23a54295efc6374b86b198cf8efed5606d6b762" + integrity sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw== dependencies: - jest-regex-util "^28.0.2" - jest-snapshot "^28.1.3" + jest-regex-util "^29.0.0" + jest-snapshot "^29.0.3" -jest-resolve@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" - integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== +jest-resolve@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.0.3.tgz#329a3431e3b9eb6629a2cd483e9bed95b26827b9" + integrity sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" + jest-haste-map "^29.0.3" jest-pnp-resolver "^1.2.2" - jest-util "^28.1.3" - jest-validate "^28.1.3" + jest-util "^29.0.3" + jest-validate "^29.0.3" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" - integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== +jest-runner@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.0.3.tgz#2e47fe1e8777aea9b8970f37e8f83630b508fb87" + integrity sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw== dependencies: - "@jest/console" "^28.1.3" - "@jest/environment" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/console" "^29.0.3" + "@jest/environment" "^29.0.3" + "@jest/test-result" "^29.0.3" + "@jest/transform" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.10.2" graceful-fs "^4.2.9" - jest-docblock "^28.1.1" - jest-environment-node "^28.1.3" - jest-haste-map "^28.1.3" - jest-leak-detector "^28.1.3" - jest-message-util "^28.1.3" - jest-resolve "^28.1.3" - jest-runtime "^28.1.3" - jest-util "^28.1.3" - jest-watcher "^28.1.3" - jest-worker "^28.1.3" + jest-docblock "^29.0.0" + jest-environment-node "^29.0.3" + jest-haste-map "^29.0.3" + jest-leak-detector "^29.0.3" + jest-message-util "^29.0.3" + jest-resolve "^29.0.3" + jest-runtime "^29.0.3" + jest-util "^29.0.3" + jest-watcher "^29.0.3" + jest-worker "^29.0.3" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" - integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/globals" "^28.1.3" - "@jest/source-map" "^28.1.2" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" +jest-runtime@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.0.3.tgz#5a823ec5902257519556a4e5a71a868e8fd788aa" + integrity sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ== + dependencies: + "@jest/environment" "^29.0.3" + "@jest/fake-timers" "^29.0.3" + "@jest/globals" "^29.0.3" + "@jest/source-map" "^29.0.0" + "@jest/test-result" "^29.0.3" + "@jest/transform" "^29.0.3" + "@jest/types" "^29.0.3" + "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" - execa "^5.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" + jest-haste-map "^29.0.3" + jest-message-util "^29.0.3" + jest-mock "^29.0.3" + jest-regex-util "^29.0.0" + jest-resolve "^29.0.3" + jest-snapshot "^29.0.3" + jest-util "^29.0.3" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" - integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== +jest-snapshot@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.0.3.tgz#0a024706986a915a6eefae74d7343069d2fc8eef" + integrity sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/expect-utils" "^29.0.3" + "@jest/transform" "^29.0.3" + "@jest/types" "^29.0.3" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^28.1.3" + expect "^29.0.3" graceful-fs "^4.2.9" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - jest-haste-map "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" + jest-diff "^29.0.3" + jest-get-type "^29.0.0" + jest-haste-map "^29.0.3" + jest-matcher-utils "^29.0.3" + jest-message-util "^29.0.3" + jest-util "^29.0.3" natural-compare "^1.4.0" - pretty-format "^28.1.3" + pretty-format "^29.0.3" semver "^7.3.5" -jest-util@^28.0.0, jest-util@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" - integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== +jest-util@^29.0.0, jest-util@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.0.3.tgz#06d1d77f9a1bea380f121897d78695902959fbc0" + integrity sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" - integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== +jest-validate@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.0.3.tgz#f9521581d7344685428afa0a4d110e9c519aeeb6" + integrity sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw== dependencies: - "@jest/types" "^28.1.3" + "@jest/types" "^29.0.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^28.0.2" + jest-get-type "^29.0.0" leven "^3.1.0" - pretty-format "^28.1.3" + pretty-format "^29.0.3" -jest-watcher@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" - integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== +jest-watcher@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.0.3.tgz#8e220d1cc4f8029875e82015d084cab20f33d57f" + integrity sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw== dependencies: - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" + "@jest/test-result" "^29.0.3" + "@jest/types" "^29.0.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.10.2" - jest-util "^28.1.3" + jest-util "^29.0.3" string-length "^4.0.1" jest-worker@^27.4.5: @@ -3328,29 +3646,42 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" - integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== +jest-worker@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.0.3.tgz#c2ba0aa7e41eec9eb0be8e8a322ae6518df72647" + integrity sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" -jest@28.0.3: - version "28.0.3" - resolved "https://registry.npmmirror.com/jest/-/jest-28.0.3.tgz#92a7d6ee097b61de4ba2db7f3ab723e81a99b32d" - integrity sha512-uS+T5J3w5xyzd1KSJCGKhCo8WTJXbNl86f5SW11wgssbandJOVLRKKUxmhdFfmKxhPeksl1hHZ0HaA8VBzp7xA== +jest@29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.0.3.tgz#5227a0596d30791b2649eea347e4aa97f734944d" + integrity sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ== dependencies: - "@jest/core" "^28.0.3" + "@jest/core" "^29.0.3" + "@jest/types" "^29.0.3" import-local "^3.0.2" - jest-cli "^28.0.3" + jest-cli "^29.0.3" + +js-sdsl@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.4.tgz#78793c90f80e8430b7d8dc94515b6c77d98a26a6" + integrity sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw== js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" @@ -3359,13 +3690,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^4.0.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - jsesc@^2.5.1: version "2.5.2" resolved "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -3391,22 +3715,27 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.npmmirror.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json5@2.x, json5@^2.2.1: - version "2.2.1" - resolved "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== - json5@^1.0.1: version "1.0.1" - resolved "https://registry.npmmirror.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== dependencies: minimist "^1.2.0" -jsonc-parser@3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" - integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== +json5@^2.2.1: + version "2.2.1" + resolved "https://registry.npmmirror.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + +jsonc-parser@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d" + integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg== + +jsonc-parser@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== jsonfile@^6.0.1: version "6.1.0" @@ -3417,6 +3746,39 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonwebtoken@8.5.1, jsonwebtoken@^8.2.0: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + kleur@^3.0.3: version "3.0.3" resolved "https://registry.npmmirror.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" @@ -3435,6 +3797,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libphonenumber-js@^1.9.43: + version "1.10.13" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.13.tgz#0b5833c7fdbf671140530d83531c6753f7e0ea3c" + integrity sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -3459,6 +3826,36 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + lodash.memoize@4.x: version "4.1.2" resolved "https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -3469,6 +3866,11 @@ lodash.merge@^4.6.2: resolved "https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + lodash@4.17.21, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" @@ -3507,12 +3909,12 @@ macos-release@^2.5.0: resolved "https://registry.npmmirror.com/macos-release/-/macos-release-2.5.0.tgz#067c2c88b5f3fb3c56a375b2ec93826220fa1ff2" integrity sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g== -magic-string@0.25.7: - version "0.25.7" - resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" - integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== +magic-string@0.26.2: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== dependencies: - sourcemap-codec "^1.4.4" + sourcemap-codec "^1.4.8" make-dir@^3.0.0: version "3.1.0" @@ -3607,7 +4009,7 @@ minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimist@1.2.6, minimist@^1.2.0, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.6" resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== @@ -3634,7 +4036,7 @@ ms@2.1.2: resolved "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.1: version "2.1.3" resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -3687,6 +4089,11 @@ named-placeholders@^1.1.2: dependencies: lru-cache "^4.1.3" +nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmmirror.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -3702,6 +4109,11 @@ neo-async@^2.6.2: resolved "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-abort-controller@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.0.1.tgz#f91fa50b1dee3f909afabb7e261b1e1d6b0cb74e" + integrity sha512-/ujIVxthRs+7q6hsdjHMaj8hRG9NuWmwrz+JdRwZ14jdFoKSkm+vDsCbF9PLpnSqjaWQJuTmVtcWHNLr+vrOFw== + node-emoji@1.11.0: version "1.11.0" resolved "https://registry.npmmirror.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -3748,11 +4160,35 @@ object-hash@3.0.0: resolved "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== -object-inspect@^1.9.0: +object-inspect@^1.12.2, object-inspect@^1.9.0: version "1.12.2" resolved "https://registry.npmmirror.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + +object.values@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -3894,18 +4330,34 @@ passport-headerapikey@^1.2.2: lodash "^4.17.15" passport-strategy "^1.0.0" +passport-jwt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-local@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" + integrity sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow== + dependencies: + passport-strategy "1.x.x" + passport-strategy@1.x.x, passport-strategy@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" integrity sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA== -passport@^0.5.3: - version "0.5.3" - resolved "https://registry.npmmirror.com/passport/-/passport-0.5.3.tgz#e69b46c9bb3290660bc2b3299330d78710b198cc" - integrity sha512-gGc+70h4gGdBWNsR3FuV3byLDY6KBTJAIExGFXTpQaYfbbcHCBlRRKx7RBQSpqEqc5Hh2qVzRs7ssvSfOpkUEA== +passport@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.6.0.tgz#e869579fab465b5c0b291e841e6cc95c005fac9d" + integrity sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug== dependencies: passport-strategy "1.x.x" pause "0.0.1" + utils-merge "^1.0.1" path-exists@^4.0.0: version "4.0.0" @@ -3986,27 +4438,17 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.3.2: +prettier@^2.7.1: version "2.7.1" - resolved "https://registry.npmmirror.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== -pretty-format@^27.0.0, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.npmmirror.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -pretty-format@^28.1.3: - version "28.1.3" - resolved "https://registry.npmmirror.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" - integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== +pretty-format@^29.0.0, pretty-format@^29.0.3: + version "29.0.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.0.3.tgz#23d5f8cabc9cbf209a77d49409d093d61166a811" + integrity sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q== dependencies: - "@jest/schemas" "^28.1.3" - ansi-regex "^5.0.1" + "@jest/schemas" "^29.0.0" ansi-styles "^5.0.0" react-is "^18.0.0" @@ -4095,11 +4537,6 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmmirror.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - react-is@^18.0.0: version "18.2.0" resolved "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -4146,6 +4583,15 @@ reflect-metadata@^0.1.13: resolved "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.npmmirror.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -4183,7 +4629,7 @@ resolve.exports@^1.1.0: resolved "https://registry.npmmirror.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== -resolve@^1.1.6, resolve@^1.20.0: +resolve@^1.1.6, resolve@^1.20.0, resolve@^1.22.0: version "1.22.1" resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -4205,7 +4651,7 @@ reusify@^1.0.4: resolved "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -4231,13 +4677,20 @@ rxjs@6.6.7, rxjs@^6.6.0: dependencies: tslib "^1.9.0" -rxjs@^7.2.0: +rxjs@^7.5.5: version "7.5.6" - resolved "https://registry.npmmirror.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== dependencies: tslib "^2.1.0" +rxjs@^7.5.7: + version "7.5.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" + integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== + dependencies: + tslib "^2.1.0" + safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -4248,6 +4701,15 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -4274,6 +4736,11 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" +semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@^6.0.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -4386,7 +4853,7 @@ source-map-support@0.5.13: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@0.5.21, source-map-support@^0.5.20, source-map-support@~0.5.20: +source-map-support@0.5.21, source-map-support@^0.5.21, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== @@ -4394,19 +4861,19 @@ source-map-support@0.5.21, source-map-support@^0.5.20, source-map-support@~0.5.2 buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.7.3: - version "0.7.3" - resolved "https://registry.npmmirror.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +source-map@0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" resolved "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sourcemap-codec@^1.4.4: +sourcemap-codec@^1.4.8: version "1.4.8" - resolved "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== sprintf-js@~1.0.2: @@ -4453,6 +4920,24 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -4511,9 +4996,9 @@ superagent@^8.0.0: readable-stream "^3.6.0" semver "^7.3.7" -supertest@^6.1.3: +supertest@^6.2.4: version "6.2.4" - resolved "https://registry.npmmirror.com/supertest/-/supertest-6.2.4.tgz#3dcebe42f7fd6f28dd7ac74c6cba881f7101b2f0" + resolved "https://registry.yarnpkg.com/supertest/-/supertest-6.2.4.tgz#3dcebe42f7fd6f28dd7ac74c6cba881f7101b2f0" integrity sha512-M8xVnCNv+q2T2WXVzxDECvL2695Uv2uUj2O0utxsld/HRyJvOU8W9f1gvsYxSNU4wmIe0/L/ItnpU4iKq0emDA== dependencies: methods "^1.1.2" @@ -4553,6 +5038,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swagger-ui-dist@4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.14.0.tgz#e34d807464eb84578c43902e393084a1a6fbda52" + integrity sha512-TBzhheU15s+o54Cgk9qxuYcZMiqSm/SkvKnapoGHOF66kz0Y5aGjpzj5BT/vpBbn6rTPJ9tUYXQxuDWfsjiGMw== + symbol-observable@4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" @@ -4664,33 +5154,33 @@ tree-kill@1.2.2: resolved "https://registry.npmmirror.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -ts-jest@28.0.1: - version "28.0.1" - resolved "https://registry.npmmirror.com/ts-jest/-/ts-jest-28.0.1.tgz#626b4d7d5c386f88f4813d959ffc4ca0a8ffef96" - integrity sha512-PbkbitaT/9ZYAqqzk3UYTvCq080Seo46T3m/AdwcZ0D8WH2uBhG6PvA8oOAWsZIknzPQU66fYobvFCL8IqIhmg== +ts-jest@29.0.2: + version "29.0.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.0.2.tgz#0c45a1ac45d14f8b3bf89bca9048a2840c7bd5ad" + integrity sha512-P03IUItnAjG6RkJXtjjD5pu0TryQFOwcb1YKmW63rO19V0UFqL3wiXZrmR5D7qYjI98btzIOAcYafLZ0GHAcQg== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" - jest-util "^28.0.0" - json5 "2.x" + jest-util "^29.0.0" + json5 "^2.2.1" lodash.memoize "4.x" make-error "1.x" semver "7.x" - yargs-parser "^20.x" + yargs-parser "^21.0.1" -ts-loader@^9.2.3: - version "9.3.1" - resolved "https://registry.npmmirror.com/ts-loader/-/ts-loader-9.3.1.tgz#fe25cca56e3e71c1087fe48dc67f4df8c59b22d4" - integrity sha512-OkyShkcZTsTwyS3Kt7a4rsT/t2qvEVQuKCTg4LJmpj9fhFR7ukGdZwV6Qq3tRUkqcXtfGpPR7+hFKHCG/0d3Lw== +ts-loader@^9.4.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.1.tgz#b6f3d82db0eac5a8295994f8cb5e4940ff6b1060" + integrity sha512-384TYAqGs70rn9F0VBnh6BPTfhga7yFNdC5gXbQpDrBj9/KsT4iRkGqKXhziofHOlE2j6YEaiTYVGKKvPhGWvw== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" micromatch "^4.0.0" semver "^7.3.4" -ts-node@^10.0.0: +ts-node@^10.9.1: version "10.9.1" - resolved "https://registry.npmmirror.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: "@cspotcode/source-map-support" "^0.8.0" @@ -4707,35 +5197,35 @@ ts-node@^10.0.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths-webpack-plugin@3.5.2: - version "3.5.2" - resolved "https://registry.npmmirror.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz#01aafff59130c04a8c4ebc96a3045c43c376449a" - integrity sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw== +tsconfig-paths-webpack-plugin@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz#84008fc3e3e0658fdb0262758b07b4da6265ff1a" + integrity sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ== dependencies: chalk "^4.1.0" enhanced-resolve "^5.7.0" - tsconfig-paths "^3.9.0" + tsconfig-paths "^4.0.0" -tsconfig-paths@3.14.1, tsconfig-paths@^3.9.0: - version "3.14.1" - resolved "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== +tsconfig-paths@4.1.0, tsconfig-paths@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz#f8ef7d467f08ae3a695335bf1ece088c5538d2c1" + integrity sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow== dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" + json5 "^2.2.1" minimist "^1.2.6" strip-bom "^3.0.0" -tsconfig-paths@4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/tsconfig-paths/-/tsconfig-paths-4.0.0.tgz#1082f5d99fd127b72397eef4809e4dd06d229b64" - integrity sha512-SLBg2GBKlR6bVtMgJJlud/o3waplKtL7skmLkExomIiaAtLGtVsoXIqP3SYdjbcH9lq/KVv7pMZeCBpLYOit6Q== +tsconfig-paths@^3.14.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== dependencies: - json5 "^2.2.1" + "@types/json5" "^0.0.29" + json5 "^1.0.1" minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.4.0, tslib@^2.1.0: +tslib@2.4.0, tslib@^2.1.0, tslib@^2.3.1: version "2.4.0" resolved "https://registry.npmmirror.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== @@ -4787,33 +5277,43 @@ typedarray@^0.0.6: resolved "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typeorm@^0.2.45: - version "0.2.45" - resolved "https://registry.npmmirror.com/typeorm/-/typeorm-0.2.45.tgz#e5bbb3af822dc4646bad96cfa48cd22fa4687cea" - integrity sha512-c0rCO8VMJ3ER7JQ73xfk0zDnVv0WDjpsP6Q1m6CVKul7DB9iVdWLRjPzc8v2eaeBuomsbZ2+gTaYr8k1gm3bYA== +typeorm@^0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.10.tgz#aa2857fd4b078c912ca693b7eee01b6535704458" + integrity sha512-VMKiM84EpJQ+Mz9xDIPqnfplWhyUy1d8ccaKdMY9obifxJOTFnv8GYVyPsGwG8Lk7Nb8MlttHyHWENGAhBA3WA== dependencies: "@sqltools/formatter" "^1.2.2" app-root-path "^3.0.0" buffer "^6.0.3" chalk "^4.1.0" cli-highlight "^2.1.11" - debug "^4.3.1" - dotenv "^8.2.0" - glob "^7.1.6" - js-yaml "^4.0.0" + date-fns "^2.28.0" + debug "^4.3.3" + dotenv "^16.0.0" + glob "^7.2.0" + js-yaml "^4.1.0" mkdirp "^1.0.4" reflect-metadata "^0.1.13" sha.js "^2.4.11" - tslib "^2.1.0" + tslib "^2.3.1" uuid "^8.3.2" xml2js "^0.4.23" - yargs "^17.0.1" - zen-observable-ts "^1.0.0" + yargs "^17.3.1" -typescript@4.7.4, typescript@^4.3.5: - version "4.7.4" - resolved "https://registry.npmmirror.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" - integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@4.8.3, typescript@^4.8.3: + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" universalify@^2.0.0: version "2.0.0" @@ -4845,7 +5345,7 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -utils-merge@1.0.1: +utils-merge@1.0.1, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.npmmirror.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== @@ -4855,16 +5355,16 @@ uuid@8.3.2, uuid@^8.3.2: resolved "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.npmmirror.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - v8-to-istanbul@^9.0.1: version "9.0.1" resolved "https://registry.npmmirror.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" @@ -4874,6 +5374,11 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmmirror.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -4886,9 +5391,9 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -watchpack@^2.3.1: +watchpack@^2.4.0: version "2.4.0" - resolved "https://registry.npmmirror.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== dependencies: glob-to-regexp "^0.4.1" @@ -4916,21 +5421,21 @@ webpack-sources@^3.2.3: resolved "https://registry.npmmirror.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.73.0: - version "5.73.0" - resolved "https://registry.npmmirror.com/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== +webpack@5.74.0: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" + acorn "^8.7.1" acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" + enhanced-resolve "^5.10.0" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" @@ -4943,7 +5448,7 @@ webpack@5.73.0: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" + watchpack "^2.4.0" webpack-sources "^3.2.3" whatwg-url@^5.0.0: @@ -4954,6 +5459,17 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which@^2.0.1: version "2.0.2" resolved "https://registry.npmmirror.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -5033,16 +5549,16 @@ yaml@^1.10.0: resolved "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^20.2.2, yargs-parser@^20.x: - version "20.2.9" - resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.0.0: +yargs-parser@21.1.1, yargs-parser@^21.0.0, yargs-parser@^21.0.1: version "21.1.1" resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs@^16.0.0: version "16.2.0" resolved "https://registry.npmmirror.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" @@ -5056,7 +5572,7 @@ yargs@^16.0.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.0.1, yargs@^17.3.1: +yargs@^17.3.1: version "17.5.1" resolved "https://registry.npmmirror.com/yargs/-/yargs-17.5.1.tgz#e109900cab6fcb7fd44b1d8249166feb0b36e58e" integrity sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA== @@ -5078,16 +5594,3 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zen-observable-ts@^1.0.0: - version "1.1.0" - resolved "https://registry.npmmirror.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83" - integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA== - dependencies: - "@types/zen-observable" "0.8.3" - zen-observable "0.8.15" - -zen-observable@0.8.15: - version "0.8.15" - resolved "https://registry.npmmirror.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" - integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==