From cf334ada0e41415fb966f9acbc4c33f7a58b93bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20M?= Date: Fri, 8 Dec 2023 10:18:50 +0100 Subject: [PATCH] feat: exceptions handlers (#2855) * feat: wip exception handlers * feat: exception capturer * fix: rename exception-capturer into exception-handler * fix: remove unused variable --- server/.env.example | 1 + server/package.json | 1 + server/src/app.module.ts | 17 +- server/src/filters/exception.filter.ts | 56 --- server/src/filters/global-exception.filter.ts | 18 + server/src/filters/http-exception.filter.ts | 42 ++ .../src/filters/typeorm-exception.filter.ts | 24 ++ .../environment/environment.service.ts | 32 +- .../environment/environment.validation.ts | 27 +- .../interfaces/logger.interface.ts | 4 - .../interfaces/memory-storage.interface.ts | 3 - .../interfaces/message-queue.interface.ts | 4 - .../interfaces/storage.interface.ts | 4 - .../drivers/console.driver.ts | 17 + .../drivers/sentry.driver.ts | 40 ++ .../exception-handler.constants.ts | 1 + .../exception-handler.module-definition.ts | 25 ++ .../exception-handler.module-factory.ts | 39 ++ .../exception-handler.module.ts | 60 +++ .../exception-handler.service.spec.ts | 27 ++ .../exception-handler.service.ts | 17 + .../exception-handler-driver.interface.ts | 4 + .../interfaces/exception-handler.interface.ts | 23 + .../exception-handler/interfaces/index.ts | 2 + .../file-storage.module-factory.ts | 53 +++ .../interfaces/file-storage.interface.ts | 11 +- .../src/integrations/integrations.module.ts | 133 +----- .../logger/drivers/sentry.driver.ts | 53 --- .../logger/interfaces/logger.interface.ts | 16 +- .../logger/logger.module-factory.ts | 28 ++ .../src/integrations/logger/logger.module.ts | 50 ++- .../interfaces/memory-storage.interface.ts | 7 +- .../memory-storage/memory-storage.module.ts | 5 +- .../interfaces/message-queue.interface.ts | 11 +- .../message-queue.module-factory.ts | 47 ++ .../message-queue/message-queue.module.ts | 8 +- .../workspace-schema-storage.module.ts | 11 +- server/yarn.lock | 402 +++++++++++++++++- 38 files changed, 983 insertions(+), 340 deletions(-) delete mode 100644 server/src/filters/exception.filter.ts create mode 100644 server/src/filters/global-exception.filter.ts create mode 100644 server/src/filters/http-exception.filter.ts create mode 100644 server/src/filters/typeorm-exception.filter.ts delete mode 100644 server/src/integrations/environment/interfaces/logger.interface.ts delete mode 100644 server/src/integrations/environment/interfaces/memory-storage.interface.ts delete mode 100644 server/src/integrations/environment/interfaces/message-queue.interface.ts delete mode 100644 server/src/integrations/environment/interfaces/storage.interface.ts create mode 100644 server/src/integrations/exception-handler/drivers/console.driver.ts create mode 100644 server/src/integrations/exception-handler/drivers/sentry.driver.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.constants.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.module-definition.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.module-factory.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.module.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.service.spec.ts create mode 100644 server/src/integrations/exception-handler/exception-handler.service.ts create mode 100644 server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts create mode 100644 server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts create mode 100644 server/src/integrations/exception-handler/interfaces/index.ts create mode 100644 server/src/integrations/file-storage/file-storage.module-factory.ts delete mode 100644 server/src/integrations/logger/drivers/sentry.driver.ts create mode 100644 server/src/integrations/logger/logger.module-factory.ts create mode 100644 server/src/integrations/message-queue/message-queue.module-factory.ts diff --git a/server/.env.example b/server/.env.example index c48ee9a04..612b89a64 100644 --- a/server/.env.example +++ b/server/.env.example @@ -24,6 +24,7 @@ SIGN_IN_PREFILLED=true # SUPPORT_FRONT_HMAC_KEY=replace_me_with_front_chat_verification_secret # SUPPORT_FRONT_CHAT_ID=replace_me_with_front_chat_id # LOGGER_DRIVER=console +# EXCEPTION_HANDLER_DRIVER=sentry # SENTRY_DSN=https://xxx@xxx.ingest.sentry.io/xxx # LOG_LEVEL=error,warn # MESSAGE_QUEUE_TYPE=pg-boss diff --git a/server/package.json b/server/package.json index acc533b79..a7b92736e 100644 --- a/server/package.json +++ b/server/package.json @@ -52,6 +52,7 @@ "@ptc-org/nestjs-query-graphql": "4.2.0", "@ptc-org/nestjs-query-typeorm": "4.2.1-alpha.2", "@sentry/node": "^7.66.0", + "@sentry/profiling-node": "^1.2.6", "@sentry/tracing": "^7.66.0", "@types/lodash.camelcase": "^4.3.7", "@types/lodash.merge": "^4.6.7", diff --git a/server/src/app.module.ts b/server/src/app.module.ts index f6439d0b6..813eeebf0 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -10,6 +10,9 @@ import { ExtractJwt } from 'passport-jwt'; import { TokenExpiredError, JsonWebTokenError, verify } from 'jsonwebtoken'; import { WorkspaceFactory } from 'src/workspace/workspace.factory'; +import { TypeOrmExceptionFilter } from 'src/filters/typeorm-exception.filter'; +import { HttpExceptionFilter } from 'src/filters/http-exception.filter'; +import { GlobalExceptionFilter } from 'src/filters/global-exception.filter'; import { AppService } from './app.service'; @@ -22,7 +25,6 @@ import { JwtAuthStrategy, JwtPayload, } from './core/auth/strategies/jwt.auth.strategy'; -import { ExceptionFilter } from './filters/exception.filter'; @Module({ imports: [ @@ -111,9 +113,20 @@ import { ExceptionFilter } from './filters/exception.filter'; ], providers: [ AppService, + // Exceptions filters must be ordered from the least specific to the most specific + // If TypeOrmExceptionFilter handle something, HttpExceptionFilter will not handle it + // GlobalExceptionFilter will handle the rest of the exceptions { provide: APP_FILTER, - useClass: ExceptionFilter, + useClass: GlobalExceptionFilter, + }, + { + provide: APP_FILTER, + useClass: HttpExceptionFilter, + }, + { + provide: APP_FILTER, + useClass: TypeOrmExceptionFilter, }, ], }) diff --git a/server/src/filters/exception.filter.ts b/server/src/filters/exception.filter.ts deleted file mode 100644 index a91ca4188..000000000 --- a/server/src/filters/exception.filter.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { ArgumentsHost, Catch, HttpException } from '@nestjs/common'; -import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql'; - -import { TypeORMError } from 'typeorm'; - -import { - AuthenticationError, - BaseGraphQLError, - ForbiddenError, -} from 'src/filters/utils/graphql-errors.util'; - -const graphQLPredefinedExceptions = { - 401: AuthenticationError, - 403: ForbiddenError, -}; - -@Catch() -export class ExceptionFilter implements GqlExceptionFilter { - catch(exception: HttpException | TypeORMError, host: ArgumentsHost) { - if (host.getType() !== 'graphql') { - return null; - } - - if (exception instanceof TypeORMError) { - const error = new BaseGraphQLError( - exception.name, - 'INTERNAL_SERVER_ERROR', - ); - - error.stack = exception.stack; - error.extensions['response'] = exception.message; - - return error; - } else if (exception instanceof HttpException) { - let error: BaseGraphQLError; - - if (exception.getStatus() in graphQLPredefinedExceptions) { - error = new graphQLPredefinedExceptions[exception.getStatus()]( - exception.message, - ); - } else { - error = new BaseGraphQLError( - exception.message, - exception.getStatus().toString(), - ); - } - - error.stack = exception.stack; - error.extensions['response'] = exception.getResponse(); - - return error; - } - - return exception; - } -} diff --git a/server/src/filters/global-exception.filter.ts b/server/src/filters/global-exception.filter.ts new file mode 100644 index 000000000..1879c9aee --- /dev/null +++ b/server/src/filters/global-exception.filter.ts @@ -0,0 +1,18 @@ +import { Catch, Injectable } from '@nestjs/common'; +import { GqlExceptionFilter } from '@nestjs/graphql'; + +import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; + +@Catch() +@Injectable() +export class GlobalExceptionFilter implements GqlExceptionFilter { + constructor( + private readonly exceptionHandlerService: ExceptionHandlerService, + ) {} + + catch(exception: unknown) { + this.exceptionHandlerService.captureException(exception); + + return exception; + } +} diff --git a/server/src/filters/http-exception.filter.ts b/server/src/filters/http-exception.filter.ts new file mode 100644 index 000000000..4a33e7dda --- /dev/null +++ b/server/src/filters/http-exception.filter.ts @@ -0,0 +1,42 @@ +import { ArgumentsHost, Catch, HttpException } from '@nestjs/common'; +import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql'; + +import { + AuthenticationError, + BaseGraphQLError, + ForbiddenError, +} from 'src/filters/utils/graphql-errors.util'; + +const graphQLPredefinedExceptions = { + 401: AuthenticationError, + 403: ForbiddenError, +}; + +@Catch(HttpException) +export class HttpExceptionFilter + implements GqlExceptionFilter +{ + catch(exception: HttpException, host: ArgumentsHost) { + if (host.getType() !== 'graphql') { + return null; + } + + let error: BaseGraphQLError; + + if (exception.getStatus() in graphQLPredefinedExceptions) { + error = new graphQLPredefinedExceptions[exception.getStatus()]( + exception.message, + ); + } else { + error = new BaseGraphQLError( + exception.message, + exception.getStatus().toString(), + ); + } + + error.stack = exception.stack; + error.extensions['response'] = exception.getResponse(); + + return error; + } +} diff --git a/server/src/filters/typeorm-exception.filter.ts b/server/src/filters/typeorm-exception.filter.ts new file mode 100644 index 000000000..06f4c5bf7 --- /dev/null +++ b/server/src/filters/typeorm-exception.filter.ts @@ -0,0 +1,24 @@ +import { ArgumentsHost, Catch } from '@nestjs/common'; +import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql'; + +import { TypeORMError } from 'typeorm'; + +import { BaseGraphQLError } from 'src/filters/utils/graphql-errors.util'; + +@Catch(TypeORMError) +export class TypeOrmExceptionFilter + implements GqlExceptionFilter +{ + catch(exception: TypeORMError, host: ArgumentsHost) { + if (host.getType() !== 'graphql') { + return null; + } + + const error = new BaseGraphQLError(exception.name, 'INTERNAL_SERVER_ERROR'); + + error.stack = exception.stack; + error.extensions['response'] = exception.message; + + return error; + } +} diff --git a/server/src/integrations/environment/environment.service.ts b/server/src/integrations/environment/environment.service.ts index cc3868fb6..80cee928e 100644 --- a/server/src/integrations/environment/environment.service.ts +++ b/server/src/integrations/environment/environment.service.ts @@ -2,11 +2,13 @@ import { Injectable, LogLevel } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; +import { LoggerDriverType } from 'src/integrations/logger/interfaces'; +import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; +import { StorageDriverType } from 'src/integrations/file-storage/interfaces'; +import { MessageQueueDriverType } from 'src/integrations/message-queue/interfaces'; + import { AwsRegion } from './interfaces/aws-region.interface'; -import { StorageType } from './interfaces/storage.interface'; import { SupportDriver } from './interfaces/support.interface'; -import { LoggerDriver } from './interfaces/logger.interface'; -import { MessageQueueType } from './interfaces/message-queue.interface'; @Injectable() export class EnvironmentService { @@ -109,16 +111,17 @@ export class EnvironmentService { return this.configService.get('AUTH_GOOGLE_CALLBACK_URL'); } - getStorageType(): StorageType { + getStorageDriverType(): StorageDriverType { return ( - this.configService.get('STORAGE_TYPE') ?? StorageType.Local + this.configService.get('STORAGE_TYPE') ?? + StorageDriverType.Local ); } - getMessageQueueType(): MessageQueueType { + getMessageQueueDriverType(): MessageQueueDriverType { return ( - this.configService.get('MESSAGE_QUEUE_TYPE') ?? - MessageQueueType.PgBoss + this.configService.get('MESSAGE_QUEUE_TYPE') ?? + MessageQueueDriverType.PgBoss ); } @@ -154,9 +157,18 @@ export class EnvironmentService { return this.configService.get('SUPPORT_FRONT_HMAC_KEY'); } - getLoggerDriver(): string { + getLoggerDriverType(): LoggerDriverType { return ( - this.configService.get('LOGGER_DRIVER') ?? LoggerDriver.Console + this.configService.get('LOGGER_DRIVER') ?? + LoggerDriverType.Console + ); + } + + getExceptionHandlerDriverType(): ExceptionHandlerDriver { + return ( + this.configService.get( + 'EXCEPTION_HANDLER_DRIVER', + ) ?? ExceptionHandlerDriver.Console ); } diff --git a/server/src/integrations/environment/environment.validation.ts b/server/src/integrations/environment/environment.validation.ts index c82ce4d56..9e8705bb5 100644 --- a/server/src/integrations/environment/environment.validation.ts +++ b/server/src/integrations/environment/environment.validation.ts @@ -14,15 +14,16 @@ import { import { assert } from 'src/utils/assert'; import { CastToStringArray } from 'src/integrations/environment/decorators/cast-to-string-array.decorator'; +import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; +import { StorageDriverType } from 'src/integrations/file-storage/interfaces'; +import { LoggerDriverType } from 'src/integrations/logger/interfaces'; import { IsDuration } from './decorators/is-duration.decorator'; -import { StorageType } from './interfaces/storage.interface'; import { AwsRegion } from './interfaces/aws-region.interface'; import { IsAWSRegion } from './decorators/is-aws-region.decorator'; import { CastToBoolean } from './decorators/cast-to-boolean.decorator'; import { SupportDriver } from './interfaces/support.interface'; import { CastToPositiveNumber } from './decorators/cast-to-positive-number.decorator'; -import { LoggerDriver } from './interfaces/logger.interface'; import { CastToLogLevelArray } from './decorators/cast-to-log-level-array.decorator'; export class EnvironmentVariables { @@ -110,20 +111,20 @@ export class EnvironmentVariables { AUTH_GOOGLE_CALLBACK_URL?: string; // Storage - @IsEnum(StorageType) + @IsEnum(StorageDriverType) @IsOptional() - STORAGE_TYPE?: StorageType; + STORAGE_TYPE?: StorageDriverType; - @ValidateIf((env) => env.STORAGE_TYPE === StorageType.S3) + @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3) @IsAWSRegion() STORAGE_S3_REGION?: AwsRegion; - @ValidateIf((env) => env.STORAGE_TYPE === StorageType.S3) + @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.S3) @IsString() STORAGE_S3_NAME?: string; @IsString() - @ValidateIf((env) => env.STORAGE_TYPE === StorageType.Local) + @ValidateIf((env) => env.STORAGE_TYPE === StorageDriverType.Local) STORAGE_LOCAL_PATH?: string; // Support @@ -139,9 +140,13 @@ export class EnvironmentVariables { @IsString() SUPPORT_FRONT_HMAC_KEY?: string; - @IsEnum(LoggerDriver) + @IsEnum(LoggerDriverType) @IsOptional() - LOGGER_DRIVER?: LoggerDriver; + LOGGER_DRIVER?: LoggerDriverType; + + @IsEnum(ExceptionHandlerDriver) + @IsOptional() + EXCEPTION_HANDLER_DRIVER?: ExceptionHandlerDriver; @CastToLogLevelArray() @IsOptional() @@ -151,7 +156,9 @@ export class EnvironmentVariables { @IsOptional() DEMO_WORKSPACE_IDS?: string[]; - @ValidateIf((env) => env.LOGGER_DRIVER === LoggerDriver.Sentry) + @ValidateIf( + (env) => env.EXCEPTION_HANDLER_DRIVER === ExceptionHandlerDriver.Sentry, + ) @IsString() SENTRY_DSN?: string; } diff --git a/server/src/integrations/environment/interfaces/logger.interface.ts b/server/src/integrations/environment/interfaces/logger.interface.ts deleted file mode 100644 index 3692f062b..000000000 --- a/server/src/integrations/environment/interfaces/logger.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum LoggerDriver { - Console = 'console', - Sentry = 'sentry', -} diff --git a/server/src/integrations/environment/interfaces/memory-storage.interface.ts b/server/src/integrations/environment/interfaces/memory-storage.interface.ts deleted file mode 100644 index bf906df15..000000000 --- a/server/src/integrations/environment/interfaces/memory-storage.interface.ts +++ /dev/null @@ -1,3 +0,0 @@ -export enum MemoryStorageType { - Local = 'local', -} diff --git a/server/src/integrations/environment/interfaces/message-queue.interface.ts b/server/src/integrations/environment/interfaces/message-queue.interface.ts deleted file mode 100644 index ff37f2c36..000000000 --- a/server/src/integrations/environment/interfaces/message-queue.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum MessageQueueType { - PgBoss = 'pg-boss', - BullMQ = 'bull-mq', -} diff --git a/server/src/integrations/environment/interfaces/storage.interface.ts b/server/src/integrations/environment/interfaces/storage.interface.ts deleted file mode 100644 index 78433a2d1..000000000 --- a/server/src/integrations/environment/interfaces/storage.interface.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum StorageType { - S3 = 's3', - Local = 'local', -} diff --git a/server/src/integrations/exception-handler/drivers/console.driver.ts b/server/src/integrations/exception-handler/drivers/console.driver.ts new file mode 100644 index 000000000..4dfbf4d17 --- /dev/null +++ b/server/src/integrations/exception-handler/drivers/console.driver.ts @@ -0,0 +1,17 @@ +import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces'; + +export class ExceptionHandlerConsoleDriver + implements ExceptionHandlerDriverInterface +{ + captureException(exception: unknown) { + console.group('Exception Captured'); + console.error(exception); + console.groupEnd(); + } + + captureMessage(message: string): void { + console.group('Message Captured'); + console.info(message); + console.groupEnd(); + } +} diff --git a/server/src/integrations/exception-handler/drivers/sentry.driver.ts b/server/src/integrations/exception-handler/drivers/sentry.driver.ts new file mode 100644 index 000000000..71d1bdaa8 --- /dev/null +++ b/server/src/integrations/exception-handler/drivers/sentry.driver.ts @@ -0,0 +1,40 @@ +import * as Sentry from '@sentry/node'; +import { ProfilingIntegration } from '@sentry/profiling-node'; + +import { + ExceptionHandlerDriverInterface, + ExceptionHandlerSentryDriverFactoryOptions, +} from 'src/integrations/exception-handler/interfaces'; + +export class ExceptionHandlerSentryDriver + implements ExceptionHandlerDriverInterface +{ + constructor(options: ExceptionHandlerSentryDriverFactoryOptions['options']) { + Sentry.init({ + dsn: options.dns, + integrations: [ + // enable HTTP calls tracing + new Sentry.Integrations.Http({ tracing: true }), + // enable Express.js middleware tracing + new Sentry.Integrations.Express({ app: options.serverInstance }), + new Sentry.Integrations.GraphQL(), + new Sentry.Integrations.Postgres({ + usePgNative: true, + }), + new ProfilingIntegration(), + ], + tracesSampleRate: 1.0, + profilesSampleRate: 1.0, + environment: options.debug ? 'development' : 'production', + debug: options.debug, + }); + } + + captureException(exception: Error) { + Sentry.captureException(exception); + } + + captureMessage(message: string) { + Sentry.captureMessage(message); + } +} diff --git a/server/src/integrations/exception-handler/exception-handler.constants.ts b/server/src/integrations/exception-handler/exception-handler.constants.ts new file mode 100644 index 000000000..cbe7f2a12 --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.constants.ts @@ -0,0 +1 @@ +export const EXCEPTION_HANDLER_DRIVER = Symbol('EXCEPTION_HANDLER_DRIVER'); diff --git a/server/src/integrations/exception-handler/exception-handler.module-definition.ts b/server/src/integrations/exception-handler/exception-handler.module-definition.ts new file mode 100644 index 000000000..72e3d9a5a --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.module-definition.ts @@ -0,0 +1,25 @@ +import { + ConfigurableModuleBuilder, + FactoryProvider, + ModuleMetadata, +} from '@nestjs/common'; + +import { ExceptionHandlerModuleOptions } from './interfaces'; + +export const { + ConfigurableModuleClass, + MODULE_OPTIONS_TOKEN, + OPTIONS_TYPE, + ASYNC_OPTIONS_TYPE, +} = new ConfigurableModuleBuilder({ + moduleName: 'ExceptionHandlerModule', +}) + .setClassMethodName('forRoot') + .build(); + +export type ExceptionHandlerModuleAsyncOptions = { + useFactory: ( + ...args: any[] + ) => ExceptionHandlerModuleOptions | Promise; +} & Pick & + Pick; diff --git a/server/src/integrations/exception-handler/exception-handler.module-factory.ts b/server/src/integrations/exception-handler/exception-handler.module-factory.ts new file mode 100644 index 000000000..c40346958 --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.module-factory.ts @@ -0,0 +1,39 @@ +import { HttpAdapterHost } from '@nestjs/core'; + +import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { OPTIONS_TYPE } from 'src/integrations/exception-handler/exception-handler.module-definition'; +import { ExceptionHandlerDriver } from 'src/integrations/exception-handler/interfaces'; + +/** + * ExceptionHandler Module factory + * @param environment + * @returns ExceptionHandlerModuleOptions + */ +export const exceptionHandlerModuleFactory = async ( + environmentService: EnvironmentService, + adapterHost: HttpAdapterHost, +): Promise => { + const driverType = environmentService.getExceptionHandlerDriverType(); + + switch (driverType) { + case ExceptionHandlerDriver.Console: { + return { + type: ExceptionHandlerDriver.Console, + }; + } + case ExceptionHandlerDriver.Sentry: { + return { + type: ExceptionHandlerDriver.Sentry, + options: { + dns: environmentService.getSentryDSN() ?? '', + serverInstance: adapterHost.httpAdapter.getInstance(), + debug: environmentService.isDebugMode(), + }, + }; + } + default: + throw new Error( + `Invalid exception capturer driver type (${driverType}), check your .env file`, + ); + } +}; diff --git a/server/src/integrations/exception-handler/exception-handler.module.ts b/server/src/integrations/exception-handler/exception-handler.module.ts new file mode 100644 index 000000000..e1221bcd2 --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.module.ts @@ -0,0 +1,60 @@ +import { DynamicModule, Global, Module } from '@nestjs/common'; + +import { ExceptionHandlerSentryDriver } from 'src/integrations/exception-handler/drivers/sentry.driver'; +import { ExceptionHandlerConsoleDriver } from 'src/integrations/exception-handler/drivers/console.driver'; + +import { ExceptionHandlerService } from './exception-handler.service'; +import { ExceptionHandlerDriver } from './interfaces'; +import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants'; +import { + ConfigurableModuleClass, + OPTIONS_TYPE, + ASYNC_OPTIONS_TYPE, +} from './exception-handler.module-definition'; + +@Global() +@Module({ + providers: [ExceptionHandlerService], + exports: [ExceptionHandlerService], +}) +export class ExceptionHandlerModule extends ConfigurableModuleClass { + static forRoot(options: typeof OPTIONS_TYPE): DynamicModule { + const provider = { + provide: EXCEPTION_HANDLER_DRIVER, + useValue: + options.type === ExceptionHandlerDriver.Console + ? new ExceptionHandlerConsoleDriver() + : new ExceptionHandlerSentryDriver(options.options), + }; + const dynamicModule = super.forRoot(options); + + return { + ...dynamicModule, + providers: [...(dynamicModule.providers ?? []), provider], + }; + } + + static forRootAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule { + const provider = { + provide: EXCEPTION_HANDLER_DRIVER, + useFactory: async (...args: any[]) => { + const config = await options?.useFactory?.(...args); + + if (!config) { + return null; + } + + return config.type === ExceptionHandlerDriver.Console + ? new ExceptionHandlerConsoleDriver() + : new ExceptionHandlerSentryDriver(config.options); + }, + inject: options.inject || [], + }; + const dynamicModule = super.forRootAsync(options); + + return { + ...dynamicModule, + providers: [...(dynamicModule.providers ?? []), provider], + }; + } +} diff --git a/server/src/integrations/exception-handler/exception-handler.service.spec.ts b/server/src/integrations/exception-handler/exception-handler.service.spec.ts new file mode 100644 index 000000000..f9d1e19b9 --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.service.spec.ts @@ -0,0 +1,27 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service'; + +import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants'; + +describe('ExceptionHandlerService', () => { + let service: ExceptionHandlerService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + ExceptionHandlerService, + { + provide: EXCEPTION_HANDLER_DRIVER, + useValue: {}, + }, + ], + }).compile(); + + service = module.get(ExceptionHandlerService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/server/src/integrations/exception-handler/exception-handler.service.ts b/server/src/integrations/exception-handler/exception-handler.service.ts new file mode 100644 index 000000000..d1a14e3c4 --- /dev/null +++ b/server/src/integrations/exception-handler/exception-handler.service.ts @@ -0,0 +1,17 @@ +import { Inject, Injectable } from '@nestjs/common'; + +import { ExceptionHandlerDriverInterface } from 'src/integrations/exception-handler/interfaces'; + +import { EXCEPTION_HANDLER_DRIVER } from './exception-handler.constants'; + +@Injectable() +export class ExceptionHandlerService { + constructor( + @Inject(EXCEPTION_HANDLER_DRIVER) + private driver: ExceptionHandlerDriverInterface, + ) {} + + captureException(exception: unknown) { + this.driver.captureException(exception); + } +} diff --git a/server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts b/server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts new file mode 100644 index 000000000..f1e23ac28 --- /dev/null +++ b/server/src/integrations/exception-handler/interfaces/exception-handler-driver.interface.ts @@ -0,0 +1,4 @@ +export interface ExceptionHandlerDriverInterface { + captureException(exception: unknown): void; + captureMessage(message: string): void; +} diff --git a/server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts b/server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts new file mode 100644 index 000000000..f3dbcc248 --- /dev/null +++ b/server/src/integrations/exception-handler/interfaces/exception-handler.interface.ts @@ -0,0 +1,23 @@ +import { Router } from 'express'; + +export enum ExceptionHandlerDriver { + Sentry = 'sentry', + Console = 'console', +} + +export interface ExceptionHandlerSentryDriverFactoryOptions { + type: ExceptionHandlerDriver.Sentry; + options: { + dns: string; + serverInstance: Router; + debug?: boolean; + }; +} + +export interface ExceptionHandlerDriverFactoryOptions { + type: ExceptionHandlerDriver.Console; +} + +export type ExceptionHandlerModuleOptions = + | ExceptionHandlerSentryDriverFactoryOptions + | ExceptionHandlerDriverFactoryOptions; diff --git a/server/src/integrations/exception-handler/interfaces/index.ts b/server/src/integrations/exception-handler/interfaces/index.ts new file mode 100644 index 000000000..f3c1acc40 --- /dev/null +++ b/server/src/integrations/exception-handler/interfaces/index.ts @@ -0,0 +1,2 @@ +export * from './exception-handler.interface'; +export * from './exception-handler-driver.interface'; diff --git a/server/src/integrations/file-storage/file-storage.module-factory.ts b/server/src/integrations/file-storage/file-storage.module-factory.ts new file mode 100644 index 000000000..c4a8e266e --- /dev/null +++ b/server/src/integrations/file-storage/file-storage.module-factory.ts @@ -0,0 +1,53 @@ +import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; + +import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { + FileStorageModuleOptions, + StorageDriverType, +} from 'src/integrations/file-storage/interfaces'; + +/** + * FileStorage Module factory + * @param environment + * @returns FileStorageModuleOptions + */ +export const fileStorageModuleFactory = async ( + environmentService: EnvironmentService, +): Promise => { + const driverType = environmentService.getStorageDriverType(); + + switch (driverType) { + case StorageDriverType.Local: { + const storagePath = environmentService.getStorageLocalPath(); + + return { + type: StorageDriverType.Local, + options: { + storagePath: process.cwd() + '/' + storagePath, + }, + }; + } + case StorageDriverType.S3: { + const bucketName = environmentService.getStorageS3Name(); + const endpoint = environmentService.getStorageS3Endpoint(); + const region = environmentService.getStorageS3Region(); + + return { + type: StorageDriverType.S3, + options: { + bucketName: bucketName ?? '', + endpoint: endpoint, + credentials: fromNodeProviderChain({ + clientConfig: { region }, + }), + forcePathStyle: true, + region: region ?? '', + }, + }; + } + default: + throw new Error( + `Invalid storage driver type (${driverType}), check your .env file`, + ); + } +}; diff --git a/server/src/integrations/file-storage/interfaces/file-storage.interface.ts b/server/src/integrations/file-storage/interfaces/file-storage.interface.ts index d02869db5..81151323a 100644 --- a/server/src/integrations/file-storage/interfaces/file-storage.interface.ts +++ b/server/src/integrations/file-storage/interfaces/file-storage.interface.ts @@ -1,17 +1,20 @@ import { FactoryProvider, ModuleMetadata } from '@nestjs/common'; -import { StorageType } from 'src/integrations/environment/interfaces/storage.interface'; - import { S3DriverOptions } from 'src/integrations/file-storage/drivers/s3.driver'; import { LocalDriverOptions } from 'src/integrations/file-storage/drivers/local.driver'; +export enum StorageDriverType { + S3 = 's3', + Local = 'local', +} + export interface S3DriverFactoryOptions { - type: StorageType.S3; + type: StorageDriverType.S3; options: S3DriverOptions; } export interface LocalDriverFactoryOptions { - type: StorageType.Local; + type: StorageDriverType.Local; options: LocalDriverOptions; } diff --git a/server/src/integrations/integrations.module.ts b/server/src/integrations/integrations.module.ts index 4e2a8f6c6..5624bca09 100644 --- a/server/src/integrations/integrations.module.ts +++ b/server/src/integrations/integrations.module.ts @@ -1,134 +1,17 @@ import { Module } from '@nestjs/common'; +import { HttpAdapterHost } from '@nestjs/core'; -import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; +import { ExceptionHandlerModule } from 'src/integrations/exception-handler/exception-handler.module'; +import { exceptionHandlerModuleFactory } from 'src/integrations/exception-handler/exception-handler.module-factory'; +import { fileStorageModuleFactory } from 'src/integrations/file-storage/file-storage.module-factory'; +import { loggerModuleFactory } from 'src/integrations/logger/logger.module-factory'; +import { messageQueueModuleFactory } from 'src/integrations/message-queue/message-queue.module-factory'; import { EnvironmentModule } from './environment/environment.module'; import { EnvironmentService } from './environment/environment.service'; import { FileStorageModule } from './file-storage/file-storage.module'; -import { FileStorageModuleOptions } from './file-storage/interfaces'; -import { StorageType } from './environment/interfaces/storage.interface'; import { LoggerModule } from './logger/logger.module'; -import { LoggerModuleOptions } from './logger/interfaces'; -import { LoggerDriver } from './environment/interfaces/logger.interface'; import { MessageQueueModule } from './message-queue/message-queue.module'; -import { MessageQueueModuleOptions } from './message-queue/interfaces'; -import { MessageQueueType } from './environment/interfaces/message-queue.interface'; - -/** - * FileStorage Module factory - * @param environment - * @returns FileStorageModuleOptions - */ -const fileStorageModuleFactory = async ( - environmentService: EnvironmentService, -): Promise => { - const type = environmentService.getStorageType(); - - switch (type) { - case StorageType.Local: { - const storagePath = environmentService.getStorageLocalPath(); - - return { - type: StorageType.Local, - options: { - storagePath: process.cwd() + '/' + storagePath, - }, - }; - } - case StorageType.S3: { - const bucketName = environmentService.getStorageS3Name(); - const endpoint = environmentService.getStorageS3Endpoint(); - const region = environmentService.getStorageS3Region(); - - return { - type: StorageType.S3, - options: { - bucketName: bucketName ?? '', - endpoint: endpoint, - credentials: fromNodeProviderChain({ - clientConfig: { region }, - }), - forcePathStyle: true, - region: region ?? '', - }, - }; - } - default: - throw new Error(`Invalid storage type (${type}), check your .env file`); - } -}; - -/** - * Logger Module factory - * @param environment - * @returns LoggerModuleOptions - */ -const loggerModuleFactory = async ( - environmentService: EnvironmentService, -): Promise => { - const type = environmentService.getLoggerDriver(); - - switch (type) { - case LoggerDriver.Console: { - return { - type: LoggerDriver.Console, - options: null, - }; - } - case LoggerDriver.Sentry: { - return { - type: LoggerDriver.Sentry, - options: { - sentryDNS: environmentService.getSentryDSN() ?? '', - }, - }; - } - default: - throw new Error(`Invalid logger type (${type}), check your .env file`); - } -}; - -/** - * MessageQueue Module factory - * @param environment - * @returns MessageQueueModuleOptions - */ -const messageQueueModuleFactory = async ( - environmentService: EnvironmentService, -): Promise => { - const type = environmentService.getMessageQueueType(); - - switch (type) { - case MessageQueueType.PgBoss: { - const connectionString = environmentService.getPGDatabaseUrl(); - - return { - type: MessageQueueType.PgBoss, - options: { - connectionString, - }, - }; - } - case MessageQueueType.BullMQ: { - const host = environmentService.getRedisHost(); - const port = environmentService.getRedisPort(); - - return { - type: MessageQueueType.BullMQ, - options: { - connection: { - host, - port, - }, - }, - }; - } - default: - throw new Error( - `Invalid message queue type (${type}), check your .env file`, - ); - } -}; @Module({ imports: [ @@ -145,6 +28,10 @@ const messageQueueModuleFactory = async ( useFactory: messageQueueModuleFactory, inject: [EnvironmentService], }), + ExceptionHandlerModule.forRootAsync({ + useFactory: exceptionHandlerModuleFactory, + inject: [EnvironmentService, HttpAdapterHost], + }), ], exports: [], providers: [], diff --git a/server/src/integrations/logger/drivers/sentry.driver.ts b/server/src/integrations/logger/drivers/sentry.driver.ts deleted file mode 100644 index ddad9fdea..000000000 --- a/server/src/integrations/logger/drivers/sentry.driver.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { LoggerService } from '@nestjs/common'; - -import * as Sentry from '@sentry/node'; - -export interface SentryDriverOptions { - sentryDNS: string; -} - -export class SentryDriver implements LoggerService { - constructor(options: SentryDriverOptions) { - Sentry.init({ - dsn: options.sentryDNS, - tracesSampleRate: 1.0, - profilesSampleRate: 1.0, - }); - } - - private logLevels = ['log', 'error', 'warning', 'debug', 'info']; - - setLogLevels(levels: string[]) { - this.logLevels = levels; - } - - log(message: any) { - if (this.logLevels.includes('log')) { - Sentry.captureMessage(message, { level: 'log' }); - } - } - - error(message: any) { - if (this.logLevels.includes('error')) { - Sentry.captureMessage(message, { level: 'error' }); - } - } - - warn(message: any) { - if (this.logLevels.includes('warn')) { - Sentry.captureMessage(message, { level: 'warning' }); - } - } - - debug?(message: any) { - if (this.logLevels.includes('debug')) { - Sentry.captureMessage(message, { level: 'debug' }); - } - } - - verbose?(message: any) { - if (this.logLevels.includes('verbose')) { - Sentry.captureMessage(message, { level: 'info' }); - } - } -} diff --git a/server/src/integrations/logger/interfaces/logger.interface.ts b/server/src/integrations/logger/interfaces/logger.interface.ts index 88985257d..09a76383a 100644 --- a/server/src/integrations/logger/interfaces/logger.interface.ts +++ b/server/src/integrations/logger/interfaces/logger.interface.ts @@ -1,17 +1,9 @@ -import { LoggerDriver } from 'src/integrations/environment/interfaces/logger.interface'; - -export interface SentryDriverFactoryOptions { - type: LoggerDriver.Sentry; - options: { - sentryDNS: string; - }; +export enum LoggerDriverType { + Console = 'console', } export interface ConsoleDriverFactoryOptions { - type: LoggerDriver.Console; - options: null; + type: LoggerDriverType.Console; } -export type LoggerModuleOptions = - | SentryDriverFactoryOptions - | ConsoleDriverFactoryOptions; +export type LoggerModuleOptions = ConsoleDriverFactoryOptions; diff --git a/server/src/integrations/logger/logger.module-factory.ts b/server/src/integrations/logger/logger.module-factory.ts new file mode 100644 index 000000000..683f77b44 --- /dev/null +++ b/server/src/integrations/logger/logger.module-factory.ts @@ -0,0 +1,28 @@ +import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { + LoggerModuleOptions, + LoggerDriverType, +} from 'src/integrations/logger/interfaces'; + +/** + * Logger Module factory + * @param environment + * @returns LoggerModuleOptions + */ +export const loggerModuleFactory = async ( + environmentService: EnvironmentService, +): Promise => { + const driverType = environmentService.getLoggerDriverType(); + + switch (driverType) { + case LoggerDriverType.Console: { + return { + type: LoggerDriverType.Console, + }; + } + default: + throw new Error( + `Invalid logger driver type (${driverType}), check your .env file`, + ); + } +}; diff --git a/server/src/integrations/logger/logger.module.ts b/server/src/integrations/logger/logger.module.ts index 6e2c8c5d5..0a60e44f1 100644 --- a/server/src/integrations/logger/logger.module.ts +++ b/server/src/integrations/logger/logger.module.ts @@ -1,50 +1,58 @@ -import { DynamicModule, Global, ConsoleLogger } from '@nestjs/common'; +import { DynamicModule, Global, ConsoleLogger, Module } from '@nestjs/common'; -import { LoggerDriver } from 'src/integrations/environment/interfaces/logger.interface'; +import { LoggerDriverType } from 'src/integrations/logger/interfaces'; import { LoggerService } from './logger.service'; -import { LoggerModuleOptions } from './interfaces'; import { LOGGER_DRIVER } from './logger.constants'; -import { LoggerModuleAsyncOptions } from './logger.module-definition'; - -import { SentryDriver } from './drivers/sentry.driver'; +import { + ASYNC_OPTIONS_TYPE, + ConfigurableModuleClass, + OPTIONS_TYPE, +} from './logger.module-definition'; @Global() -export class LoggerModule { - static forRoot(options: LoggerModuleOptions): DynamicModule { +@Module({ + providers: [LoggerService], + exports: [LoggerService], +}) +export class LoggerModule extends ConfigurableModuleClass { + static forRoot(options: typeof OPTIONS_TYPE): DynamicModule { const provider = { provide: LOGGER_DRIVER, useValue: - options.type === LoggerDriver.Console + options.type === LoggerDriverType.Console ? new ConsoleLogger() - : new SentryDriver(options.options), + : undefined, }; + const dynamicModule = super.forRoot(options); return { - module: LoggerModule, - providers: [LoggerService, provider], - exports: [LoggerService], + ...dynamicModule, + providers: [...(dynamicModule.providers ?? []), provider], }; } - static forRootAsync(options: LoggerModuleAsyncOptions): DynamicModule { + static forRootAsync(options: typeof ASYNC_OPTIONS_TYPE): DynamicModule { const provider = { provide: LOGGER_DRIVER, useFactory: async (...args: any[]) => { - const config = await options.useFactory(...args); + const config = await options?.useFactory?.(...args); - return config?.type === LoggerDriver.Console + if (!config) { + return null; + } + + return config?.type === LoggerDriverType.Console ? new ConsoleLogger() - : new SentryDriver(config.options); + : undefined; }, inject: options.inject || [], }; + const dynamicModule = super.forRootAsync(options); return { - module: LoggerModule, - imports: options.imports || [], - providers: [LoggerService, provider], - exports: [LoggerService], + ...dynamicModule, + providers: [...(dynamicModule.providers ?? []), provider], }; } } diff --git a/server/src/integrations/memory-storage/interfaces/memory-storage.interface.ts b/server/src/integrations/memory-storage/interfaces/memory-storage.interface.ts index a8e4553b0..eca29d1d2 100644 --- a/server/src/integrations/memory-storage/interfaces/memory-storage.interface.ts +++ b/server/src/integrations/memory-storage/interfaces/memory-storage.interface.ts @@ -1,12 +1,15 @@ import { FactoryProvider, ModuleMetadata } from '@nestjs/common'; -import { MemoryStorageType } from 'src/integrations/environment/interfaces/memory-storage.interface'; import { MemoryStorageSerializer } from 'src/integrations/memory-storage/serializers/interfaces/memory-storage-serializer.interface'; import { LocalMemoryDriverOptions } from 'src/integrations/memory-storage/drivers/local.driver'; +export enum MemoryStorageDriverType { + Local = 'local', +} + export interface LocalMemoryDriverFactoryOptions { - type: MemoryStorageType.Local; + type: MemoryStorageDriverType.Local; options: LocalMemoryDriverOptions; } diff --git a/server/src/integrations/memory-storage/memory-storage.module.ts b/server/src/integrations/memory-storage/memory-storage.module.ts index bd9108d73..74e994452 100644 --- a/server/src/integrations/memory-storage/memory-storage.module.ts +++ b/server/src/integrations/memory-storage/memory-storage.module.ts @@ -1,11 +1,10 @@ import { DynamicModule, Global } from '@nestjs/common'; -import { MemoryStorageType } from 'src/integrations/environment/interfaces/memory-storage.interface'; - import { MemoryStorageDefaultSerializer } from 'src/integrations/memory-storage/serializers/default.serializer'; import { createMemoryStorageInjectionToken } from 'src/integrations/memory-storage/memory-storage.util'; import { + MemoryStorageDriverType, MemoryStorageModuleAsyncOptions, MemoryStorageModuleOptions, } from './interfaces'; @@ -59,7 +58,7 @@ export class MemoryStorageModule { private static createStorageDriver(options: MemoryStorageModuleOptions) { switch (options.type) { - case MemoryStorageType.Local: + case MemoryStorageDriverType.Local: return new LocalMemoryDriver( options.identifier, options.options, diff --git a/server/src/integrations/message-queue/interfaces/message-queue.interface.ts b/server/src/integrations/message-queue/interfaces/message-queue.interface.ts index da1bf0993..4ebe536db 100644 --- a/server/src/integrations/message-queue/interfaces/message-queue.interface.ts +++ b/server/src/integrations/message-queue/interfaces/message-queue.interface.ts @@ -1,17 +1,20 @@ import { FactoryProvider, ModuleMetadata } from '@nestjs/common'; -import { MessageQueueType } from 'src/integrations/environment/interfaces/message-queue.interface'; - import { BullMQDriverOptions } from 'src/integrations/message-queue/drivers/bullmq.driver'; import { PgBossDriverOptions } from 'src/integrations/message-queue/drivers/pg-boss.driver'; +export enum MessageQueueDriverType { + PgBoss = 'pg-boss', + BullMQ = 'bull-mq', +} + export interface PgBossDriverFactoryOptions { - type: MessageQueueType.PgBoss; + type: MessageQueueDriverType.PgBoss; options: PgBossDriverOptions; } export interface BullMQDriverFactoryOptions { - type: MessageQueueType.BullMQ; + type: MessageQueueDriverType.BullMQ; options: BullMQDriverOptions; } diff --git a/server/src/integrations/message-queue/message-queue.module-factory.ts b/server/src/integrations/message-queue/message-queue.module-factory.ts new file mode 100644 index 000000000..d98d38a89 --- /dev/null +++ b/server/src/integrations/message-queue/message-queue.module-factory.ts @@ -0,0 +1,47 @@ +import { EnvironmentService } from 'src/integrations/environment/environment.service'; +import { + MessageQueueDriverType, + MessageQueueModuleOptions, +} from 'src/integrations/message-queue/interfaces'; + +/** + * MessageQueue Module factory + * @param environment + * @returns MessageQueueModuleOptions + */ +export const messageQueueModuleFactory = async ( + environmentService: EnvironmentService, +): Promise => { + const driverType = environmentService.getMessageQueueDriverType(); + + switch (driverType) { + case MessageQueueDriverType.PgBoss: { + const connectionString = environmentService.getPGDatabaseUrl(); + + return { + type: MessageQueueDriverType.PgBoss, + options: { + connectionString, + }, + }; + } + case MessageQueueDriverType.BullMQ: { + const host = environmentService.getRedisHost(); + const port = environmentService.getRedisPort(); + + return { + type: MessageQueueDriverType.BullMQ, + options: { + connection: { + host, + port, + }, + }, + }; + } + default: + throw new Error( + `Invalid message queue driver type (${driverType}), check your .env file`, + ); + } +}; diff --git a/server/src/integrations/message-queue/message-queue.module.ts b/server/src/integrations/message-queue/message-queue.module.ts index dce9da800..a0f4d5a72 100644 --- a/server/src/integrations/message-queue/message-queue.module.ts +++ b/server/src/integrations/message-queue/message-queue.module.ts @@ -1,9 +1,11 @@ import { DynamicModule, Global } from '@nestjs/common'; import { MessageQueueDriver } from 'src/integrations/message-queue/drivers/interfaces/message-queue-driver.interface'; -import { MessageQueueType } from 'src/integrations/environment/interfaces/message-queue.interface'; -import { MessageQueueModuleAsyncOptions } from 'src/integrations/message-queue/interfaces'; +import { + MessageQueueDriverType, + MessageQueueModuleAsyncOptions, +} from 'src/integrations/message-queue/interfaces'; import { QUEUE_DRIVER, MessageQueues, @@ -31,7 +33,7 @@ export class MessageQueueModule { useFactory: async (...args: any[]) => { const config = await options.useFactory(...args); - if (config.type === MessageQueueType.PgBoss) { + if (config.type === MessageQueueDriverType.PgBoss) { const boss = new PgBossDriver(config.options); await boss.init(); diff --git a/server/src/workspace/workspace-schema-storage/workspace-schema-storage.module.ts b/server/src/workspace/workspace-schema-storage/workspace-schema-storage.module.ts index 5c307b5fe..dd3f7b6e7 100644 --- a/server/src/workspace/workspace-schema-storage/workspace-schema-storage.module.ts +++ b/server/src/workspace/workspace-schema-storage/workspace-schema-storage.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; -import { MemoryStorageType } from 'src/integrations/environment/interfaces/memory-storage.interface'; - +import { MemoryStorageDriverType } from 'src/integrations/memory-storage/interfaces'; import { MemoryStorageModule } from 'src/integrations/memory-storage/memory-storage.module'; import { MemoryStorageJsonSerializer } from 'src/integrations/memory-storage/serializers/json.serializer'; import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity'; @@ -15,24 +14,24 @@ import { WorkspaceSchemaStorageService } from 'src/workspace/workspace-schema-st WorkspaceCacheVersionModule, MemoryStorageModule.forRoot({ identifier: 'objectMetadataCollection', - type: MemoryStorageType.Local, + type: MemoryStorageDriverType.Local, options: {}, serializer: new MemoryStorageJsonSerializer(), }), MemoryStorageModule.forRoot({ identifier: 'typeDefs', - type: MemoryStorageType.Local, + type: MemoryStorageDriverType.Local, options: {}, }), MemoryStorageModule.forRoot({ identifier: 'usedScalarNames', - type: MemoryStorageType.Local, + type: MemoryStorageDriverType.Local, options: {}, serializer: new MemoryStorageJsonSerializer(), }), MemoryStorageModule.forRoot({ identifier: 'cacheVersion', - type: MemoryStorageType.Local, + type: MemoryStorageDriverType.Local, options: {}, }), ], diff --git a/server/yarn.lock b/server/yarn.lock index c25bf43e2..301af71a4 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -1309,6 +1309,11 @@ dependencies: prettier "^3.1.0" +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@golevelup/nestjs-discovery@4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@golevelup/nestjs-discovery/-/nestjs-discovery-4.0.0.tgz#3428f0b620b51e4d425bc9e41cc8f2f338472dc1" @@ -1991,6 +1996,22 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@nuxtjs/opencollective@0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz#620ce1044f7ac77185e825e1936115bb38e2681c" @@ -2113,6 +2134,15 @@ "@sentry/types" "7.84.0" "@sentry/utils" "7.84.0" +"@sentry-internal/tracing@7.86.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.86.0.tgz#657e80eb7d08d1030393902c1a7bc47fc39ccb2d" + integrity sha512-b4dUsNWlPWRwakGwR7bhOkqiFlqQszH1hhVFwrm/8s3kqEBZ+E4CeIfCvuHBHQ1cM/fx55xpXX/BU163cy+3iQ== + dependencies: + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + "@sentry/core@7.84.0": version "7.84.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.84.0.tgz#01d33fc452044ffd8ea57b20f60304b9cfa2b9e1" @@ -2121,6 +2151,23 @@ "@sentry/types" "7.84.0" "@sentry/utils" "7.84.0" +"@sentry/core@7.86.0", "@sentry/core@^7.76.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.86.0.tgz#d01f538783dee9a0d79141a63145392ad2c1cb89" + integrity sha512-SbLvqd1bRYzhDS42u7GMnmbDMfth/zRiLElQWbLK/shmuZzTcfQSwNNdF4Yj+VfjOkqPFgGmICHSHVUc9dh01g== + dependencies: + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + +"@sentry/hub@^7.76.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-7.86.0.tgz#58f157a8b4dad8ba5b9f70004c5b8368c2a0b676" + integrity sha512-tS9g+yoD/Zs4OS/gCO4/ccT0m90o3brkCIm/gRzPqI5dq2hEE1qn8bF7HM/vLQARM+bsmTEzPzZy19104U5Btg== + dependencies: + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + "@sentry/node@^7.66.0": version "7.84.0" resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.84.0.tgz#c06167106796b2b83c0a9b52fa56f8ca820034ca" @@ -2132,6 +2179,31 @@ "@sentry/utils" "7.84.0" https-proxy-agent "^5.0.0" +"@sentry/node@^7.76.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-7.86.0.tgz#416db178aeb64f7895a23ae1c3d4d65ce51ed50a" + integrity sha512-cB1bn/LMn2Km97Y3hv63xwWxT50/G5ixGuSxTZ3dCQM6VDhmZoCuC5NGT3itVvaRd6upQXRZa5W0Zgyh0HXKig== + dependencies: + "@sentry-internal/tracing" "7.86.0" + "@sentry/core" "7.86.0" + "@sentry/types" "7.86.0" + "@sentry/utils" "7.86.0" + https-proxy-agent "^5.0.0" + +"@sentry/profiling-node@^1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@sentry/profiling-node/-/profiling-node-1.2.6.tgz#e43494896657bcfd11e75480ed6def4172e86c21" + integrity sha512-WsXO7VmLze5wPWHpvoRZFTtN+wHw9lYWKZs4T2FwPmvfNVaScGJey/+Wp51aM47Yy12Gj9n/BpqFYDsUXRLMvw== + dependencies: + "@sentry/core" "^7.76.0" + "@sentry/hub" "^7.76.0" + "@sentry/node" "^7.76.0" + "@sentry/types" "^7.76.0" + "@sentry/utils" "^7.76.0" + detect-libc "^2.0.2" + node-abi "^3.47.0" + node-gyp "^9.4.0" + "@sentry/tracing@^7.66.0": version "7.84.0" resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.84.0.tgz#64fbd93ed771f8e19fb60b06968cc133e3c82ea0" @@ -2144,6 +2216,11 @@ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.84.0.tgz#e8db86c36c61659c3b2558f0aa8b6a073a756117" integrity sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA== +"@sentry/types@7.86.0", "@sentry/types@^7.76.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.86.0.tgz#56ed2f5b15e8130ea5ecfbbc4102d88eaa3b3a67" + integrity sha512-pGAt0+bMfWgo0KG2epthfNV4Wae03tURpoxNjGo5Fr4cXxvLTSijSAQ6rmmO4bXBJ7+rErEjX30g30o/eEdP9g== + "@sentry/utils@7.84.0": version "7.84.0" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.84.0.tgz#32861d922fa31e86dd2863a1d9dfc5a369e98952" @@ -2151,6 +2228,13 @@ dependencies: "@sentry/types" "7.84.0" +"@sentry/utils@7.86.0", "@sentry/utils@^7.76.0": + version "7.86.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.86.0.tgz#356ec19bf1e3e5c40935dd987fd15bee8c6b37ba" + integrity sha512-6PejFtw9VTFFy5vu0ks+U7Ozkqz+eMt+HN8AZKBKErYzX5/xs0kpkOcSRpu3ETdTYcZf8VAmLVgFgE2BE+3WuQ== + dependencies: + "@sentry/types" "7.86.0" + "@sinclair/typebox@^0.24.1": version "0.24.51" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" @@ -2672,6 +2756,11 @@ resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + "@tsconfig/node10@^1.0.7": version "1.0.9" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" @@ -3499,7 +3588,7 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -abbrev@1: +abbrev@1, abbrev@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== @@ -3537,13 +3626,20 @@ add@^2.0.6: resolved "https://registry.yarnpkg.com/add/-/add-2.0.6.tgz#248f0a9f6e5a528ef2295dbeec30532130ae2235" integrity sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q== -agent-base@6: +agent-base@6, agent-base@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== dependencies: debug "4" +agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -3753,6 +3849,14 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -4152,6 +4256,30 @@ bytes@3.1.2, bytes@^3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" @@ -4393,7 +4521,7 @@ color-string@^1.9.0: color-name "^1.0.0" simple-swizzle "^0.2.2" -color-support@^1.1.2: +color-support@^1.1.2, color-support@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== @@ -4581,7 +4709,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: +debug@4, 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.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4790,6 +4918,13 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -4805,6 +4940,16 @@ enhanced-resolve@^5.0.0, enhanced-resolve@^5.14.0, enhanced-resolve@^5.7.0: graceful-fs "^4.2.4" tapable "^2.2.0" +env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + +err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -5149,6 +5294,11 @@ expect@^28.0.0, expect@^28.1.3: jest-message-util "^28.1.3" jest-util "^28.1.3" +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + express@4.18.2, express@^4.17.1: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" @@ -5460,7 +5610,7 @@ fs-extra@^9.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -5517,6 +5667,20 @@ gauge@^3.0.0: strip-ansi "^6.0.1" wide-align "^1.1.2" +gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -5598,7 +5762,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^8.0.3, glob@^8.1.0: +glob@^8.0.1, glob@^8.0.3, glob@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== @@ -5657,7 +5821,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -5794,6 +5958,11 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== +http-cache-semantics@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -5816,6 +5985,15 @@ http-errors@^1.8.1: statuses ">= 1.5.0 < 2" toidentifier "1.0.1" +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -5834,6 +6012,13 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5841,6 +6026,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -5877,6 +6069,11 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -5987,6 +6184,11 @@ ioredis@^5.3.2: redis-parser "^3.0.0" standard-as-callback "^2.1.0" +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -6084,6 +6286,11 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + 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" @@ -6963,7 +7170,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.10.1, lru-cache@^7.14.1: +lru-cache@^7.10.1, lru-cache@^7.14.1, lru-cache@^7.7.1: version "7.18.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== @@ -7004,6 +7211,28 @@ make-error@1.x, make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + makeerror@1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" @@ -7114,7 +7343,46 @@ minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass@^3.0.0: +minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + +minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + +minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + +minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -7136,7 +7404,7 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== -minizlib@^2.1.1: +minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -7156,7 +7424,7 @@ mkdirp@^0.5.4: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -7176,7 +7444,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -7280,6 +7548,13 @@ node-abi@^3.3.0: dependencies: semver "^7.3.5" +node-abi@^3.47.0: + version "3.52.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.52.0.tgz#ffba0a85f54e552547e5849015f40f9514d5ba7c" + integrity sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ== + dependencies: + semver "^7.3.5" + node-abort-controller@^3.0.1, node-abort-controller@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" @@ -7314,6 +7589,23 @@ node-gyp-build-optional-packages@5.0.7: resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz#5d2632bbde0ab2f6e22f1bbac2199b07244ae0b3" integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== +node-gyp@^9.4.0: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -7331,6 +7623,13 @@ nopt@^5.0.0: dependencies: abbrev "1" +nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + normalize-path@3.0.0, normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" @@ -7353,6 +7652,16 @@ npmlog@^5.0.1: gauge "^3.0.0" set-blocking "^2.0.0" +npmlog@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + oauth@0.9.x: version "0.9.15" resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" @@ -7883,6 +8192,19 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + +promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + prompts@^2.0.1: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -8121,6 +8443,11 @@ retry@0.13.1: resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== +retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -8195,7 +8522,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -8386,6 +8713,28 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + +socks@^2.6.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" @@ -8422,6 +8771,13 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" @@ -8688,7 +9044,7 @@ tar-stream@^3.1.5: fast-fifo "^1.2.0" streamx "^2.15.0" -tar@^6.1.11: +tar@^6.1.11, tar@^6.1.2: version "6.2.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== @@ -9071,6 +9427,20 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + universalify@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" @@ -9269,14 +9639,14 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13: gopd "^1.0.1" has-tostringtag "^1.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.2: +wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==