diff --git a/.github/workflows/e2e-test.yml b/.github/workflows/e2e-test.yml index 97a356196..8915b1a2a 100644 --- a/.github/workflows/e2e-test.yml +++ b/.github/workflows/e2e-test.yml @@ -10,7 +10,7 @@ jobs: services: mysql: - image: mysql:9.0.0 + image: mysql:9.0.1 env: MYSQL_ROOT_PASSWORD: userfeedback MYSQL_DATABASE: e2e @@ -39,7 +39,7 @@ jobs: - name: Build and run run: | - docker-compose -f "./docker/docker-compose.e2e.yml" up -d + docker compose -f "./docker/docker-compose.e2e.yml" up -d - name: Setup e2e test run: | diff --git a/.nvmrc b/.nvmrc index 119f15a0a..593cb75bc 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.15.1 \ No newline at end of file +20.16.0 \ No newline at end of file diff --git a/apps/api/eslint.config.js b/apps/api/eslint.config.js new file mode 100644 index 000000000..48a0da817 --- /dev/null +++ b/apps/api/eslint.config.js @@ -0,0 +1,25 @@ +const baseConfig = require('@ufb/eslint-config/base'); +const nestjsConfig = require('@ufb/eslint-config/nestjs'); + +const tsParser = require('@typescript-eslint/parser'); +const globals = require('globals'); + +module.exports = [ + { + ignores: ['dist/**', '**/*.js'], + }, + ...baseConfig, + ...nestjsConfig, + { + languageOptions: { + globals: { ...globals.node, ...globals.jest }, + parser: tsParser, + ecmaVersion: 5, + sourceType: 'module', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: __dirname, + }, + }, + }, +]; diff --git a/apps/api/jest.setup.js b/apps/api/jest.setup.js index 1a8f57944..f44cc2d02 100644 --- a/apps/api/jest.setup.js +++ b/apps/api/jest.setup.js @@ -1,3 +1,18 @@ +/** + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ jest.mock('typeorm-transactional', () => ({ Transactional: () => () => ({}), initializeTransactionalContext: () => {}, diff --git a/apps/api/nest-cli.json b/apps/api/nest-cli.json index 9f2d92b86..1b2931f03 100644 --- a/apps/api/nest-cli.json +++ b/apps/api/nest-cli.json @@ -3,6 +3,7 @@ "collection": "@nestjs/schematics", "sourceRoot": "src", "compilerOptions": { + "builder": "swc", "deleteOutDir": true, "assets": ["**/*.hbs"], "watchAssets": true diff --git a/apps/api/package.json b/apps/api/package.json index bc04c411e..b835d7e23 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -1,7 +1,6 @@ { "name": "api", "version": "0.0.1", - "private": true, "scripts": { "build": "nest build", "clean": "git clean -xdf dist .turbo node_modules", @@ -28,7 +27,7 @@ "dependencies": { "@aws-sdk/client-s3": "^3.556.0", "@aws-sdk/s3-request-presigner": "^3.556.0", - "@fastify/multipart": "^8.2.0", + "@fastify/multipart": "^8.3.0", "@fastify/static": "^7.0.3", "@nestjs-modules/mailer": "^2.0.0", "@nestjs/axios": "^3.0.2", @@ -45,7 +44,10 @@ "@nestjs/terminus": "^10.2.3", "@nestjs/typeorm": "^10.0.2", "@opensearch-project/opensearch": "^2.7.0", + "@swc/cli": "^0.4.0", "@swc/helpers": "^0.5.10", + "@types/passport-jwt": "^4.0.1", + "@types/passport-local": "^1.0.38", "@ufb/shared": "workspace:*", "@willsoto/nestjs-prometheus": "^6.0.0", "aws-sdk": "^2.1604.0", @@ -62,7 +64,7 @@ "luxon": "^3.4.4", "magic-bytes.js": "^1.10.0", "mysql2": "^3.9.7", - "nestjs-cls": "^3.6.0", + "nestjs-cls": "^4.0.0", "nestjs-pino": "^4.0.0", "nestjs-typeorm-paginate": "^4.0.4", "nodemailer": "^6.9.13", @@ -92,13 +94,15 @@ "@types/express": "^4.17.21", "@types/jest": "^29.5.12", "@types/luxon": "^3.4.2", - "@types/node": "20.14.11", + "@types/node": "20.14.14", "@types/nodemailer": "^6.4.15", + "@types/passport-jwt": "*", "@types/supertest": "^6.0.2", - "@ufb/prettier-config": "workspace:*", - "@ufb/tsconfig": "workspace:*", "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", + "@ufb/eslint-config": "workspace:*", + "@ufb/prettier-config": "workspace:*", + "@ufb/tsconfig": "workspace:*", "eslint": "^9.0.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", diff --git a/apps/api/src/app.module.ts b/apps/api/src/app.module.ts index 64a39b2f3..8a80db030 100644 --- a/apps/api/src/app.module.ts +++ b/apps/api/src/app.module.ts @@ -18,6 +18,7 @@ import { ConfigModule } from '@nestjs/config'; import { EventEmitterModule } from '@nestjs/event-emitter'; import { ScheduleModule } from '@nestjs/schedule'; import { PrometheusModule } from '@willsoto/nestjs-prometheus'; +import { Request } from 'express'; import { ClsModule } from 'nestjs-cls'; import { LoggerModule } from 'nestjs-pino'; @@ -80,7 +81,7 @@ export const domainModules = [ FeedbackIssueStatisticsModule, APIModule, SchedulerLockModule, -] as any[]; +] as (typeof AuthModule)[]; @Module({ imports: [ @@ -102,7 +103,7 @@ export const domainModules = [ pinoHttp: { transport: { target: 'pino-pretty', options: { singleLine: true } }, autoLogging: { - ignore: (req: any) => req.originalUrl === '/api/health', + ignore: (req: Request) => req.originalUrl === '/api/health', }, customLogLevel: (req, res, err) => { if (res.statusCode === 401) { @@ -110,7 +111,9 @@ export const domainModules = [ } if (res.statusCode >= 400 && res.statusCode < 500) { return 'warn'; - } else if (res.statusCode >= 500 || err) { + } else if (res.statusCode >= 500) { + return 'error'; + } else if (err != null) { return 'error'; } return 'info'; diff --git a/apps/api/src/common/decorators/dto-validator.spec.ts b/apps/api/src/common/decorators/dto-validator.spec.ts index 1ac260fe2..8f7c9d565 100644 --- a/apps/api/src/common/decorators/dto-validator.spec.ts +++ b/apps/api/src/common/decorators/dto-validator.spec.ts @@ -25,16 +25,24 @@ class Dto { class TestClass { @DtoValidator() - noParam() {} + noParam() { + return; + } @DtoValidator() - dtoParam(_dto: Dto) {} + dtoParam(_dto: Dto) { + return; + } @DtoValidator() - dtosParam(_dtos: Dto[]) {} + dtosParam(_dtos: Dto[]) { + return; + } @DtoValidator() - compositionParam(_a: any, _dtos: Dto) {} + compositionParam(_a: any, _dtos: Dto) { + return; + } } describe('dto validator', () => { let instance: TestClass; @@ -49,14 +57,14 @@ describe('dto validator', () => { dto.str = 'test'; instance.dtoParam(dto); const dto2 = new Dto(); - expect(instance.dtoParam(dto2)).rejects.toThrow(); + void expect(instance.dtoParam(dto2)).rejects.toThrow(); }); it('method call with no params', () => { const dto = new Dto(); dto.str = 'test'; instance.dtosParam([dto]); const dto2 = new Dto(); - expect(instance.dtosParam([dto2])).rejects.toThrow(); + void expect(instance.dtosParam([dto2])).rejects.toThrow(); }); it('method call with no params', () => { const dto = new Dto(); diff --git a/apps/api/src/common/decorators/dto-validator.ts b/apps/api/src/common/decorators/dto-validator.ts index 2c39fcdff..db5402a90 100644 --- a/apps/api/src/common/decorators/dto-validator.ts +++ b/apps/api/src/common/decorators/dto-validator.ts @@ -14,15 +14,23 @@ * under the License. */ import { InternalServerErrorException } from '@nestjs/common'; +import type { ValidationError } from 'class-validator'; import { validate } from 'class-validator'; +type Method = (...args: object[]) => any; + const DtoValidator = - () => (target: unknown, propName: string, descriptor: any) => { - const methodRef = (descriptor as any).value; + () => + ( + target: unknown, + propName: string, + descriptor: TypedPropertyDescriptor, + ) => { + const methodRef = descriptor.value as Method; - (descriptor as any).value = async function (...args) { + descriptor.value = async function (...args: object[]): Promise { for (const arg of args) { - let errors = []; + let errors: ValidationError[] = []; if (!Array.isArray(arg) && typeof arg === 'object') { errors = await validate(arg); @@ -32,14 +40,16 @@ const DtoValidator = typeof arg[0] === 'object' ) { errors = ( - await Promise.all(arg.map(async (item) => await validate(item))) + await Promise.all( + arg.map(async (item: object) => await validate(item)), + ) ).flat(); } if (errors.length > 0) { throw new InternalServerErrorException(errors); } } - return await methodRef.call(this, ...args); + return (await methodRef.call(this, ...args)) as object; }; return descriptor; }; diff --git a/apps/api/src/common/decorators/is-password.spec.ts b/apps/api/src/common/decorators/is-password.spec.ts index d3fccb2a2..0d912b138 100644 --- a/apps/api/src/common/decorators/is-password.spec.ts +++ b/apps/api/src/common/decorators/is-password.spec.ts @@ -14,7 +14,7 @@ * under the License. */ import { faker } from '@faker-js/faker'; -import { Validator } from 'class-validator'; +import { ValidationError, Validator } from 'class-validator'; import { IsPassword } from './is-password'; @@ -30,7 +30,7 @@ describe('IsPassword decorator', () => { faker.number.int({ min: 8, max: 15 }), ); const validator = new Validator(); - validator.validate(instance).then((errors) => { + void validator.validate(instance).then((errors) => { expect(errors).toHaveLength(0); }); }); @@ -40,9 +40,9 @@ describe('IsPassword decorator', () => { faker.number.int({ min: 0, max: 7 }), ); const validator = new Validator(); - validator.validate(instance).then((errors) => { + void validator.validate(instance).then((errors: ValidationError[]) => { expect(errors.length).toEqual(1); - expect(Object.keys(errors[0].constraints)[0]).toEqual('minLength'); + expect(Object.keys(errors[0].constraints ?? {})[0]).toEqual('minLength'); }); }); @@ -51,9 +51,9 @@ describe('IsPassword decorator', () => { instance.password = faker.number.int({ min: 10000000, max: 99999999 }); const validator = new Validator(); - validator.validate(instance).then((errors) => { + void validator.validate(instance).then((errors: ValidationError[]) => { expect(errors.length).toEqual(1); - expect(Object.keys(errors[0].constraints)[0]).toEqual('isString'); + expect(Object.keys(errors[0].constraints ?? {})[0]).toEqual('isString'); }); }); @@ -61,10 +61,10 @@ describe('IsPassword decorator', () => { const instance = new IsPasswordTest(); instance.password = faker.number.int({ min: 0, max: 9999999 }); const validator = new Validator(); - validator.validate(instance).then((errors) => { + void validator.validate(instance).then((errors: ValidationError[]) => { expect(errors.length).toEqual(1); - expect(Object.keys(errors[0].constraints)[0]).toEqual('isString'); - expect(Object.keys(errors[0].constraints)[1]).toEqual('minLength'); + expect(Object.keys(errors[0].constraints ?? {})[0]).toEqual('isString'); + expect(Object.keys(errors[0].constraints ?? {})[1]).toEqual('minLength'); }); }); }); diff --git a/apps/api/src/common/dtos/pagination-request.dto.ts b/apps/api/src/common/dtos/pagination-request.dto.ts index ac7a410a1..573d65987 100644 --- a/apps/api/src/common/dtos/pagination-request.dto.ts +++ b/apps/api/src/common/dtos/pagination-request.dto.ts @@ -20,14 +20,18 @@ import { IsNumber, IsOptional, Min } from 'class-validator'; import { toNumber } from '@/common/helper/cast.helper'; export class PaginationRequestDto { - @Transform(({ value }) => toNumber(value, { default: 10, min: 1 })) + @Transform(({ value }: { value: string }) => + toNumber(value, { default: 10, min: 1 }), + ) @ApiProperty({ required: false, minimum: 1, default: 10, example: 10 }) @IsOptional() @IsNumber() @Min(1) limit: number; - @Transform(({ value }) => toNumber(value, { default: 1, min: 1 })) + @Transform(({ value }: { value: string }) => + toNumber(value, { default: 1, min: 1 }), + ) @ApiProperty({ required: false, minimum: 1, default: 1, example: 1 }) @IsOptional() @IsNumber() diff --git a/apps/api/src/common/entities/common.entity.ts b/apps/api/src/common/entities/common.entity.ts index b1d20f9b4..83e23ee6e 100644 --- a/apps/api/src/common/entities/common.entity.ts +++ b/apps/api/src/common/entities/common.entity.ts @@ -38,6 +38,7 @@ export abstract class CommonEntity { @BeforeInsert() beforeInsertHook() { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!this.createdAt) { this.createdAt = DateTime.utc().toJSDate(); } diff --git a/apps/api/src/common/filters/http-exception.filter.ts b/apps/api/src/common/filters/http-exception.filter.ts index f0b681fae..6e2279d7d 100644 --- a/apps/api/src/common/filters/http-exception.filter.ts +++ b/apps/api/src/common/filters/http-exception.filter.ts @@ -30,12 +30,12 @@ export class HttpExceptionFilter implements ExceptionFilter { const exceptionResponse = exception.getResponse(); if (typeof exceptionResponse === 'string') { - response.status(statusCode).send({ + void response.status(statusCode).send({ response: exceptionResponse, path: request.url, }); } else { - response.status(statusCode).send({ + void response.status(statusCode).send({ ...exceptionResponse, statusCode, path: request.url, diff --git a/apps/api/src/common/helper/cast.helper.ts b/apps/api/src/common/helper/cast.helper.ts index e127dde92..5a299bdba 100644 --- a/apps/api/src/common/helper/cast.helper.ts +++ b/apps/api/src/common/helper/cast.helper.ts @@ -41,7 +41,7 @@ export function toNumber(value: string, opts: ToNumberOptions = {}): number { let newValue: number = Number.parseInt(value || String(opts.default), 10); if (Number.isNaN(newValue)) { - newValue = opts.default; + newValue = opts.default ?? 0; } if (opts.min) { @@ -49,7 +49,7 @@ export function toNumber(value: string, opts: ToNumberOptions = {}): number { newValue = opts.min; } - if (newValue > opts.max) { + if (opts.max && newValue > opts.max) { newValue = opts.max; } } diff --git a/apps/api/src/common/repositories/opensearch.repository.spec.ts b/apps/api/src/common/repositories/opensearch.repository.spec.ts index 537699d03..c7d2209ee 100644 --- a/apps/api/src/common/repositories/opensearch.repository.spec.ts +++ b/apps/api/src/common/repositories/opensearch.repository.spec.ts @@ -258,15 +258,27 @@ describe('Opensearch Repository Test suite', () => { }); }); - describe('getData', () => {}); + describe('getData', () => { + return; + }); - describe('scroll', () => {}); + describe('scroll', () => { + return; + }); - describe('updateData', () => {}); + describe('updateData', () => { + return; + }); - describe('deleteBulkData', () => {}); + describe('deleteBulkData', () => { + return; + }); - describe('deleteIndex', () => {}); + describe('deleteIndex', () => { + return; + }); - describe('getTotal', () => {}); + describe('getTotal', () => { + return; + }); }); diff --git a/apps/api/src/common/repositories/opensearch.repository.ts b/apps/api/src/common/repositories/opensearch.repository.ts index fd89eed06..e705786ff 100644 --- a/apps/api/src/common/repositories/opensearch.repository.ts +++ b/apps/api/src/common/repositories/opensearch.repository.ts @@ -32,6 +32,23 @@ import type { } from './dtos'; import { LargeWindowException } from './large-window.exception'; +interface OpenSearchResponse { + hits: { + hits: { _source: Record }[]; + total: { value: number }; + }; + _scroll_id: number; +} + +type OpenSearchMappingResponse = Record< + string, + { + mappings: { + properties: Record; + }; + } +>; + @Injectable() export class OpensearchRepository { private opensearchClient: Client; @@ -88,12 +105,15 @@ export class OpensearchRepository { }); if (!existence.body) throw new NotFoundException('index is not found'); - const response = await this.opensearchClient.indices.getMapping({ - index: indexName, - }); + const response = + await this.opensearchClient.indices.getMapping( + { + index: indexName, + }, + ); const mappingKeys = Object.keys( - response.body[indexName].mappings.properties, + response.body[indexName].mappings.properties as object, ); const dataKeys = Object.keys(data); if (!dataKeys.every((v) => mappingKeys.includes(v))) { @@ -107,7 +127,7 @@ export class OpensearchRepository { refresh: true, }); - return { id: body._id }; + return { id: body._id as number }; } async getData(dto: GetDataDto) { @@ -117,7 +137,7 @@ export class OpensearchRepository { sort.push('_id:desc'); } try { - const { body } = await this.opensearchClient.search({ + const { body } = await this.opensearchClient.search({ index, from: (page - 1) * limit, size: limit, @@ -147,14 +167,14 @@ export class OpensearchRepository { if (sort.length === 0) sort.push('_id:desc'); if (scrollId) { - const { body } = await this.opensearchClient.scroll({ + const { body } = await this.opensearchClient.scroll({ scroll_id: scrollId, scroll: '1m', }); return this.convertToScrollData(body); } - const { body } = await this.opensearchClient.search({ + const { body } = await this.opensearchClient.search({ index, size, sort, @@ -164,7 +184,7 @@ export class OpensearchRepository { return this.convertToScrollData(body); } - private convertToScrollData(body: Record) { + private convertToScrollData(body: OpenSearchResponse) { return { data: body.hits.hits.map((v) => ({ ...v._source, @@ -194,12 +214,12 @@ export class OpensearchRepository { await this.opensearchClient.indices.delete({ index: 'channel_' + index }); } - async getTotal(index: string, query: any) { + async getTotal(index: string, query: object): Promise { const { body } = await this.opensearchClient.count({ index, body: { query }, }); - return body.count; + return body.count as number; } } diff --git a/apps/api/src/common/validators/token-validator.decorator.spec.ts b/apps/api/src/common/validators/token-validator.decorator.spec.ts new file mode 100644 index 000000000..5753e7d85 --- /dev/null +++ b/apps/api/src/common/validators/token-validator.decorator.spec.ts @@ -0,0 +1,61 @@ +/** + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +import { IsNotEmpty, validate } from 'class-validator'; + +import { TokenValidator } from './token-validator'; + +class TokenDto { + @IsNotEmpty() + @TokenValidator({ message: 'Invalid token format' }) + token: string; +} + +describe('TokenValidator', () => { + it('should validate a correct token', async () => { + const dto = new TokenDto(); + dto.token = 'validToken123456'; + + const errors = await validate(dto); + expect(errors.length).toBe(0); + }); + + it('should invalidate a token with invalid characters', async () => { + const dto = new TokenDto(); + dto.token = 'invalidToken$123'; + + const errors = await validate(dto); + expect(errors.length).toBeGreaterThan(0); + expect(errors[0].constraints).toHaveProperty('TokenValidatorConstraint'); + }); + + it('should invalidate a token that is too short', async () => { + const dto = new TokenDto(); + dto.token = 'short'; + + const errors = await validate(dto); + expect(errors.length).toBeGreaterThan(0); + expect(errors[0].constraints).toHaveProperty('TokenValidatorConstraint'); + }); + + it('should invalidate an empty token', async () => { + const dto = new TokenDto(); + dto.token = ''; + + const errors = await validate(dto); + expect(errors.length).toBeGreaterThan(0); + expect(errors[0].constraints).toHaveProperty('isNotEmpty'); + }); +}); diff --git a/apps/api/src/common/validators/token-validator.ts b/apps/api/src/common/validators/token-validator.ts new file mode 100644 index 000000000..f4ea434a9 --- /dev/null +++ b/apps/api/src/common/validators/token-validator.ts @@ -0,0 +1,48 @@ +/** + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +import { + registerDecorator, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from 'class-validator'; + +@ValidatorConstraint({ async: false }) +export class TokenValidatorConstraint implements ValidatorConstraintInterface { + validate(token: string | null) { + const regex = /^[a-zA-Z0-9._-]+$/; + return ( + !token || + (typeof token === 'string' && regex.test(token) && token.length >= 16) + ); + } + + defaultMessage() { + return 'Token must be at least 16 characters long and contain only alphanumeric characters, dots, hyphens, and underscores.'; + } +} + +export function TokenValidator(validationOptions?: ValidationOptions) { + return function (object: object, propertyName: string) { + registerDecorator({ + target: object.constructor, + propertyName: propertyName, + options: validationOptions, + constraints: [], + validator: TokenValidatorConstraint, + }); + }; +} diff --git a/apps/api/src/configs/modules/mailer-config/mailer-config.module.ts b/apps/api/src/configs/modules/mailer-config/mailer-config.module.ts index bfbbcf39e..83df6b1a0 100644 --- a/apps/api/src/configs/modules/mailer-config/mailer-config.module.ts +++ b/apps/api/src/configs/modules/mailer-config/mailer-config.module.ts @@ -25,17 +25,19 @@ import type { ConfigServiceType } from '@/types/config-service.type'; MailerModule.forRootAsync({ inject: [ConfigService], useFactory: (configService: ConfigService) => { - const { host, password, port, username, sender } = configService.get( - 'smtp', - { infer: true }, - ); + const { host, password, port, username, sender } = + configService.get('smtp', { infer: true }) ?? {}; return { transport: { host, port, tls: { ciphers: 'SSLv3' }, - auth: username && password && { user: username, pass: password }, + auth: + username && password ? + { user: username, pass: password } + : undefined, secure: port === 465, + pool: true, }, defaults: { from: `"User feedback" <${sender}>` }, template: { diff --git a/apps/api/src/configs/modules/opensearch-config/opensearch-config.module.ts b/apps/api/src/configs/modules/opensearch-config/opensearch-config.module.ts index 8c39053ae..424f07404 100644 --- a/apps/api/src/configs/modules/opensearch-config/opensearch-config.module.ts +++ b/apps/api/src/configs/modules/opensearch-config/opensearch-config.module.ts @@ -15,7 +15,7 @@ */ import { Global, Module } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; -import { Client } from '@opensearch-project/opensearch'; +import { Client, NodeOptions } from '@opensearch-project/opensearch'; import type { ConfigServiceType } from '@/types/config-service.type'; @@ -24,13 +24,22 @@ import type { ConfigServiceType } from '@/types/config-service.type'; providers: [ { provide: 'OPENSEARCH_CLIENT', - useFactory: (configService: ConfigService): Client => { - const { use, node, password, username } = configService.get( - 'opensearch', - { - infer: true, - }, - ); + useFactory: ( + configService: ConfigService, + ): Client | undefined => { + const { + use, + node, + password, + username, + }: { + use: boolean; + node: string | string[] | NodeOptions | NodeOptions[]; + password: string; + username: string; + } = configService.get('opensearch', { + infer: true, + }) ?? { use: false, node: '', password: '', username: '' }; return use ? new Client({ node, auth: { username, password } }) : undefined; diff --git a/apps/api/src/configs/modules/typeorm-config/migrations/1720760282371-add-token-on-webhook.ts b/apps/api/src/configs/modules/typeorm-config/migrations/1720760282371-add-token-on-webhook.ts new file mode 100644 index 000000000..64e2c50c0 --- /dev/null +++ b/apps/api/src/configs/modules/typeorm-config/migrations/1720760282371-add-token-on-webhook.ts @@ -0,0 +1,30 @@ +/** + * Copyright 2023 LINE Corporation + * + * LINE Corporation licenses this file to you under the Apache License, + * version 2.0 (the "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at: + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ +import type { MigrationInterface, QueryRunner } from 'typeorm'; + +export class AddTokenOnWebhook1720760282371 implements MigrationInterface { + name = 'AddTokenOnWebhook1720760282371'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE \`webhooks\` ADD \`token\` varchar(255) NULL DEFAULT NULL AFTER \`url\``, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE \`webhooks\` DROP COLUMN \`token\``); + } +} diff --git a/apps/api/src/configs/modules/typeorm-config/typeorm-config.datasource.ts b/apps/api/src/configs/modules/typeorm-config/typeorm-config.datasource.ts index 4747a3815..15e86b075 100644 --- a/apps/api/src/configs/modules/typeorm-config/typeorm-config.datasource.ts +++ b/apps/api/src/configs/modules/typeorm-config/typeorm-config.datasource.ts @@ -18,12 +18,15 @@ import type { DataSourceOptions } from 'typeorm'; import { DataSource } from 'typeorm'; import { mysqlConfig } from '@/configs/mysql.config'; +import type { ConfigServiceType } from '@/types/config-service.type'; import { TypeOrmConfigService } from './typeorm-config.service'; const env = mysqlConfig(); console.log('env: ', env); const configService = new ConfigService({ mysql: env }); -const typeormConfigService = new TypeOrmConfigService(configService as any); +const typeormConfigService = new TypeOrmConfigService( + configService as unknown as ConfigService, +); const typeormConfig = typeormConfigService.createTypeOrmOptions() as DataSourceOptions; diff --git a/apps/api/src/configs/modules/typeorm-config/typeorm-config.module.ts b/apps/api/src/configs/modules/typeorm-config/typeorm-config.module.ts index d09a001ba..985a82432 100644 --- a/apps/api/src/configs/modules/typeorm-config/typeorm-config.module.ts +++ b/apps/api/src/configs/modules/typeorm-config/typeorm-config.module.ts @@ -15,7 +15,7 @@ */ import { Logger, Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { DataSource } from 'typeorm'; +import { DataSource, DataSourceOptions } from 'typeorm'; import { addTransactionalDataSource } from 'typeorm-transactional'; import { TypeOrmConfigService } from './typeorm-config.service'; @@ -24,7 +24,7 @@ import { TypeOrmConfigService } from './typeorm-config.service'; imports: [ TypeOrmModule.forRootAsync({ useClass: TypeOrmConfigService, - dataSourceFactory: async (options) => { + dataSourceFactory: async (options: DataSourceOptions) => { Logger.log('start data source initalized'); const datasource = await new DataSource(options).initialize(); Logger.log('end data source initalized'); diff --git a/apps/api/src/configs/modules/typeorm-config/typeorm-config.service.ts b/apps/api/src/configs/modules/typeorm-config/typeorm-config.service.ts index 1d77132ee..3b1a2023d 100644 --- a/apps/api/src/configs/modules/typeorm-config/typeorm-config.service.ts +++ b/apps/api/src/configs/modules/typeorm-config/typeorm-config.service.ts @@ -30,12 +30,14 @@ export class TypeOrmConfigService implements TypeOrmOptionsFactory { private readonly configService: ConfigService, ) {} createTypeOrmOptions(): TypeOrmModuleOptions { - const { main_url, sub_urls, auto_migration } = this.configService.get( - 'mysql', - { + const { + main_url, + sub_urls, + auto_migration, + }: { main_url: string; sub_urls: string[]; auto_migration: boolean } = + this.configService.get('mysql', { infer: true, - }, - ); + }) ?? { main_url: '', sub_urls: [], auto_migration: false }; return { type: 'mysql', diff --git a/apps/api/src/configs/smtp.config.ts b/apps/api/src/configs/smtp.config.ts index 2b33bf0a9..7a0259889 100644 --- a/apps/api/src/configs/smtp.config.ts +++ b/apps/api/src/configs/smtp.config.ts @@ -45,7 +45,7 @@ export const smtpConfigSchema = Joi.object({ export const smtpConfig = registerAs('smtp', () => ({ use: process.env.SMTP_USE === 'true', host: process.env.SMTP_HOST, - port: +process.env.SMTP_PORT, + port: parseInt(process.env.SMTP_PORT || '25'), username: process.env.SMTP_USERNAME, password: process.env.SMTP_PASSWORD, sender: process.env.SMTP_SENDER, diff --git a/apps/api/src/domains/admin/auth/auth.controller.spec.ts b/apps/api/src/domains/admin/auth/auth.controller.spec.ts index 91521ded3..65ac47c44 100644 --- a/apps/api/src/domains/admin/auth/auth.controller.spec.ts +++ b/apps/api/src/domains/admin/auth/auth.controller.spec.ts @@ -72,7 +72,7 @@ describe('AuthController', () => { const dto = new EmailVerificationCodeRequestDto(); dto.code = faker.string.sample(); dto.email = faker.internet.email(); - authController.verifyEmailCode(dto); + void authController.verifyEmailCode(dto); expect(MockAuthService.verifyEmailCode).toHaveBeenCalledTimes(1); }); @@ -80,7 +80,7 @@ describe('AuthController', () => { const dto = new EmailUserSignUpRequestDto(); dto.email = faker.internet.email(); dto.password = faker.internet.password(); - authController.signUpEmailUser(dto); + void authController.signUpEmailUser(dto); expect(MockAuthService.signUpEmailUser).toHaveBeenCalledTimes(1); }); it('signUpInvitationUser', () => { @@ -88,17 +88,17 @@ describe('AuthController', () => { dto.code = faker.string.sample(); dto.email = faker.internet.email(); dto.password = faker.internet.password(); - authController.signUpInvitationUser(dto); + void authController.signUpInvitationUser(dto); expect(MockAuthService.signUpInvitationUser).toHaveBeenCalledTimes(1); }); it('signInEmail', () => { const dto = new UserDto(); - authController.signInEmail(dto); + void authController.signInEmail(dto); expect(MockAuthService.signIn).toHaveBeenCalledTimes(1); }); it('refreshToken', () => { const dto = new UserDto(); - authController.refreshToken(dto); + void authController.refreshToken(dto); expect(MockAuthService.refreshToken).toHaveBeenCalledTimes(1); }); }); diff --git a/apps/api/src/domains/admin/auth/auth.module.ts b/apps/api/src/domains/admin/auth/auth.module.ts index 9ba58c7f3..930f20d7e 100644 --- a/apps/api/src/domains/admin/auth/auth.module.ts +++ b/apps/api/src/domains/admin/auth/auth.module.ts @@ -51,7 +51,7 @@ import { LocalStrategy } from './strategies/local.strategy'; global: true, inject: [ConfigService], useFactory: (configService: ConfigService) => { - const { secret } = configService.get('jwt', { infer: true }); + const { secret } = configService.get('jwt', { infer: true }) ?? {}; return { secret }; }, }), diff --git a/apps/api/src/domains/admin/auth/auth.service.spec.ts b/apps/api/src/domains/admin/auth/auth.service.spec.ts index 1c739d81f..5ed2e8991 100644 --- a/apps/api/src/domains/admin/auth/auth.service.spec.ts +++ b/apps/api/src/domains/admin/auth/auth.service.spec.ts @@ -81,7 +81,7 @@ describe('auth service ', () => { it('sending a code by email succeeds with a valid email', async () => { const validEmail = faker.internet.email(); dto.email = validEmail; - jest.spyOn(userRepo, 'findOne').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOne').mockResolvedValue(null); tenantRepo.setIsRestrictDomain(false); jest.spyOn(MockEmailVerificationMailingService, 'send'); @@ -104,7 +104,9 @@ describe('auth service ', () => { }); }); - describe('verifyEmailCode', () => {}); + describe('verifyEmailCode', () => { + return; + }); describe('validateEmailUser', () => { it('validating a user succeeds with valid inputs', async () => { @@ -120,7 +122,7 @@ describe('auth service ', () => { }); }); it('validating a user fails with a nonexistent user', async () => { - jest.spyOn(userRepo, 'findOne').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOne').mockResolvedValue(null); const dto = new ValidateEmailUserDto(); dto.email = faker.internet.email(); dto.password = passwordFixture; @@ -149,7 +151,7 @@ describe('auth service ', () => { tenantRepo.setIsRestrictDomain(false); tenantRepo.setIsPrivate(false); codeRepo.setIsVerified(true); - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await authService.signUpEmailUser(dto); @@ -162,7 +164,7 @@ describe('auth service ', () => { tenantRepo.setIsRestrictDomain(false); tenantRepo.setIsPrivate(false); codeRepo.setIsVerified(false); - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); jest.spyOn(userRepo, 'save'); await expect(authService.signUpEmailUser(dto)).rejects.toThrowError( @@ -178,7 +180,7 @@ describe('auth service ', () => { tenantRepo.setIsRestrictDomain(false); tenantRepo.setIsPrivate(false); codeRepo.setNull(); - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); jest.spyOn(userRepo, 'save'); await expect(authService.signUpEmailUser(dto)).rejects.toThrowError( @@ -189,9 +191,13 @@ describe('auth service ', () => { }); }); - describe('signUpInvitationUser', () => {}); + describe('signUpInvitationUser', () => { + return; + }); - describe('signUpOAuthUser', () => {}); + describe('signUpOAuthUser', () => { + return; + }); describe('signIn', () => { it('signing in succeeds with a valid user', async () => { @@ -223,7 +229,9 @@ describe('auth service ', () => { }); }); - describe('refreshToken', () => {}); + describe('refreshToken', () => { + return; + }); describe('validateApiKey', () => { it('validating an api key succeeds with a valid api key', async () => { @@ -278,5 +286,7 @@ describe('auth service ', () => { }); }); - describe('signInByOAuth', () => {}); + describe('signInByOAuth', () => { + return; + }); }); diff --git a/apps/api/src/domains/admin/auth/auth.service.ts b/apps/api/src/domains/admin/auth/auth.service.ts index 32b42af94..52e633779 100644 --- a/apps/api/src/domains/admin/auth/auth.service.ts +++ b/apps/api/src/domains/admin/auth/auth.service.ts @@ -22,7 +22,7 @@ import { } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { JwtService } from '@nestjs/jwt'; -import { AxiosError } from 'axios'; +import { AxiosError, AxiosResponse } from 'axios'; import * as bcrypt from 'bcrypt'; import { DateTime } from 'luxon'; import { catchError, lastValueFrom, map } from 'rxjs'; @@ -56,6 +56,16 @@ import type { import { SignUpEmailUserDto, SignUpOauthUserDto } from './dtos'; import { PasswordNotMatchException, UserBlockedException } from './exceptions'; +interface AccessTokenResponse { + access_token: string; + token_type: string; + expires_in: number; + refresh_token: string; + scope: string; +} + +type UserProfileResponse = Record; + @Injectable() export class AuthService { private REDIRECT_URI = `${process.env.BASE_URL}/auth/oauth-callback`; @@ -146,9 +156,6 @@ export class AuthService { code, ); - if (!data?.userType) { - throw new InternalServerErrorException('no user type'); - } return await this.createUserService.createInvitationUser({ ...rest, type: data.userType, @@ -176,7 +183,7 @@ export class AuthService { if (state === UserStateEnum.Blocked) throw new UserBlockedException(); const { accessTokenExpiredTime, refreshTokenExpiredTime } = - this.configService.get('jwt', { infer: true }); + this.configService.get('jwt', { infer: true }) ?? {}; return { accessToken: this.jwtService.sign( @@ -221,10 +228,10 @@ export class AuthService { response_type: 'code', state: crypto.randomBytes(10).toString('hex'), scope: oauthConfig.scopeString, - callback_url: encodeURIComponent(callback_url), + callback_url: encodeURIComponent(callback_url ?? ''), }); - return `${oauthConfig.authCodeRequestURL}?${params}`; + return `${oauthConfig.authCodeRequestURL}?${params.toString()}`; } private async getAccessToken(code: string): Promise { @@ -238,9 +245,9 @@ export class AuthService { } const { accessTokenRequestURL, clientId, clientSecret } = oauthConfig; - return await lastValueFrom( + return await lastValueFrom( this.httpService - .post( + .post( accessTokenRequestURL, { grant_type: 'authorization_code', @@ -256,15 +263,19 @@ export class AuthService { }, }, ) - .pipe(map((res) => res.data?.access_token)) + .pipe( + map, string>( + (res) => res.data.access_token, + ), + ) .pipe( - catchError((error) => { + catchError((error: Error) => { if (error instanceof AxiosError) { throw new InternalServerErrorException({ axiosError: { - ...error.response.data, - status: error.response.status, - }, + ...error.response?.data, + status: error.response?.status, + } as object, }); } throw error; @@ -279,20 +290,20 @@ export class AuthService { if (!oauthConfig) { throw new BadRequestException('OAuth Config is required.'); } - return await lastValueFrom( + return await lastValueFrom( this.httpService - .get(oauthConfig.userProfileRequestURL, { + .get(oauthConfig.userProfileRequestURL, { headers: { Authorization: `Bearer ${accessToken}` }, }) - .pipe(map((res) => res.data?.[oauthConfig.emailKey])) + .pipe(map((res) => res.data[oauthConfig.emailKey])) .pipe( - catchError((error) => { + catchError((error: Error) => { if (error instanceof AxiosError) { throw new InternalServerErrorException({ axiosError: { - ...error.response.data, - status: error.response.status, - }, + ...error.response?.data, + status: error.response?.status, + } as object, }); } throw error; diff --git a/apps/api/src/domains/admin/auth/dtos/requests/email-user-sign-in-request.dto.ts b/apps/api/src/domains/admin/auth/dtos/requests/email-user-sign-in-request.dto.ts index bfc9022bb..4dbbe69c0 100644 --- a/apps/api/src/domains/admin/auth/dtos/requests/email-user-sign-in-request.dto.ts +++ b/apps/api/src/domains/admin/auth/dtos/requests/email-user-sign-in-request.dto.ts @@ -21,7 +21,7 @@ import { IsPassword } from '@/common/decorators/is-password'; export class EmailUserSignInRequestDto { @ApiProperty() @IsEmail() - email: string; + email: string | null; @ApiProperty() @IsPassword() diff --git a/apps/api/src/domains/admin/auth/guards/api-key.guard.ts b/apps/api/src/domains/admin/auth/guards/api-key.guard.ts index ce191d65c..145582deb 100644 --- a/apps/api/src/domains/admin/auth/guards/api-key.guard.ts +++ b/apps/api/src/domains/admin/auth/guards/api-key.guard.ts @@ -15,6 +15,7 @@ */ import type { CanActivate, ExecutionContext } from '@nestjs/common'; import { Injectable } from '@nestjs/common'; +import { Request } from 'express'; import { AuthService } from '../auth.service'; @@ -23,8 +24,8 @@ export class ApiKeyAuthGuard implements CanActivate { constructor(private readonly authService: AuthService) {} canActivate(context: ExecutionContext) { - const request = context.switchToHttp().getRequest(); - const apiKey = request.headers['x-api-key']; + const request = context.switchToHttp().getRequest(); + const apiKey = request.headers['x-api-key'] as string | undefined; if (!apiKey) return false; if (apiKey === process.env.MASTER_API_KEY) return true; const projectId = parseInt(request.params.projectId); diff --git a/apps/api/src/domains/admin/auth/guards/jwt-auth.guard.ts b/apps/api/src/domains/admin/auth/guards/jwt-auth.guard.ts index d9f351788..66d4d356b 100644 --- a/apps/api/src/domains/admin/auth/guards/jwt-auth.guard.ts +++ b/apps/api/src/domains/admin/auth/guards/jwt-auth.guard.ts @@ -21,6 +21,9 @@ import type { Observable } from 'rxjs'; import type { ClsServiceType } from '@/types/cls-service.type'; +interface User { + id: number; +} @Injectable() export class JwtAuthGuard extends AuthGuard('jwt') { constructor(private readonly clsService: ClsService) { @@ -31,13 +34,13 @@ export class JwtAuthGuard extends AuthGuard('jwt') { ): boolean | Promise | Observable { return super.canActivate(context); } - handleRequest(err: any, user: any) { + handleRequest(err: any, user: any): any { // You can throw an exception based on either "info" or "err" arguments if (err || !user) { throw err || new UnauthorizedException('Invalid jwt'); } - this.clsService.set('userId', user.id); + this.clsService.set('userId', (user as User).id); return user; } } diff --git a/apps/api/src/domains/admin/auth/strategies/jwt.strategy.ts b/apps/api/src/domains/admin/auth/strategies/jwt.strategy.ts index b174dff6a..2a7e00c0a 100644 --- a/apps/api/src/domains/admin/auth/strategies/jwt.strategy.ts +++ b/apps/api/src/domains/admin/auth/strategies/jwt.strategy.ts @@ -16,7 +16,7 @@ import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { PassportStrategy } from '@nestjs/passport'; -import { ExtractJwt, Strategy } from 'passport-jwt'; +import { ExtractJwt, JwtFromRequestFunction, Strategy } from 'passport-jwt'; import type { UserTypeEnum } from '@/domains/admin/user/entities/enums'; import type { ConfigServiceType } from '@/types/config-service.type'; @@ -29,19 +29,25 @@ interface IPayload { exp: number; } +interface StrategyOptions { + jwtFromRequest: JwtFromRequestFunction; + ignoreExpiration: boolean; + secretOrKey: string; +} + @Injectable() export class JwtStrategy extends PassportStrategy(Strategy) { constructor(configService: ConfigService) { - const { secret } = configService.get('jwt', { infer: true }); + const { secret } = configService.get('jwt', { infer: true }) ?? {}; super({ jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), ignoreExpiration: false, secretOrKey: secret, - }); + } as StrategyOptions); } - async validate(payload: IPayload) { + validate(payload: IPayload) { const { email, sub, type } = payload; return { id: sub, email, type }; } diff --git a/apps/api/src/domains/admin/channel/channel/channel.entity.ts b/apps/api/src/domains/admin/channel/channel/channel.entity.ts index dc0f95918..9e3234149 100644 --- a/apps/api/src/domains/admin/channel/channel/channel.entity.ts +++ b/apps/api/src/domains/admin/channel/channel/channel.entity.ts @@ -48,7 +48,7 @@ export class ChannelEntity extends CommonEntity { name: string; @Column('varchar', { nullable: true }) - description: string; + description: string | null; @Column({ type: 'json', nullable: true }) imageConfig: ImageConfig | null; @@ -84,7 +84,7 @@ export class ChannelEntity extends CommonEntity { static from( name: string, - description: string, + description: string | null, projectId: number, imageConfig: ImageConfig | null, ) { diff --git a/apps/api/src/domains/admin/channel/channel/channel.service.spec.ts b/apps/api/src/domains/admin/channel/channel/channel.service.spec.ts index 0ecfffa4b..df907ff11 100644 --- a/apps/api/src/domains/admin/channel/channel/channel.service.spec.ts +++ b/apps/api/src/domains/admin/channel/channel/channel.service.spec.ts @@ -89,9 +89,7 @@ describe('ChannelService', () => { it('finding by an id fails with a nonexistent id', async () => { const dto = new FindByChannelIdDto(); dto.channelId = faker.number.int(); - jest - .spyOn(channelRepo, 'findOne') - .mockResolvedValue(null as ChannelEntity); + jest.spyOn(channelRepo, 'findOne').mockResolvedValue(null); await expect(channelService.findById(dto)).rejects.toThrow( ChannelNotFoundException, diff --git a/apps/api/src/domains/admin/channel/channel/dtos/create-channel.dto.ts b/apps/api/src/domains/admin/channel/channel/dtos/create-channel.dto.ts index f049d0139..620fababc 100644 --- a/apps/api/src/domains/admin/channel/channel/dtos/create-channel.dto.ts +++ b/apps/api/src/domains/admin/channel/channel/dtos/create-channel.dto.ts @@ -27,7 +27,7 @@ export class CreateChannelDto { name: string; @Expose() - description: string; + description: string | null; @Expose() imageConfig: ImageConfigDto | null; diff --git a/apps/api/src/domains/admin/channel/channel/dtos/update-channel.dto.ts b/apps/api/src/domains/admin/channel/channel/dtos/update-channel.dto.ts index 89cfa3a4e..f8f435b9f 100644 --- a/apps/api/src/domains/admin/channel/channel/dtos/update-channel.dto.ts +++ b/apps/api/src/domains/admin/channel/channel/dtos/update-channel.dto.ts @@ -22,7 +22,7 @@ export class UpdateChannelDto { name: string; @Expose() - description: string; + description: string | null; @Expose() imageConfig: ImageConfigDto | null; diff --git a/apps/api/src/domains/admin/channel/field/dtos/create-field.dto.ts b/apps/api/src/domains/admin/channel/field/dtos/create-field.dto.ts index f8c73d8cb..1b3fb36cc 100644 --- a/apps/api/src/domains/admin/channel/field/dtos/create-field.dto.ts +++ b/apps/api/src/domains/admin/channel/field/dtos/create-field.dto.ts @@ -29,7 +29,7 @@ export class CreateFieldDto { key: string; @Expose() - description: string; + description: string | null; @Expose() format: FieldFormatEnum; diff --git a/apps/api/src/domains/admin/channel/field/dtos/replace-field.dto.ts b/apps/api/src/domains/admin/channel/field/dtos/replace-field.dto.ts index 9ac39e708..095d042c6 100644 --- a/apps/api/src/domains/admin/channel/field/dtos/replace-field.dto.ts +++ b/apps/api/src/domains/admin/channel/field/dtos/replace-field.dto.ts @@ -32,7 +32,7 @@ export class ReplaceFieldDto { key: string; @Expose() - description: string; + description: string | null; @Expose() format: FieldFormatEnum; diff --git a/apps/api/src/domains/admin/channel/field/field.entity.ts b/apps/api/src/domains/admin/channel/field/field.entity.ts index 90f487c59..592b8910e 100644 --- a/apps/api/src/domains/admin/channel/field/field.entity.ts +++ b/apps/api/src/domains/admin/channel/field/field.entity.ts @@ -44,7 +44,7 @@ export class FieldEntity extends CommonEntity { key: string; @Column('varchar', { nullable: true }) - description: string; + description: string | null; @Column('enum', { enum: FieldFormatEnum }) format: FieldFormatEnum; @@ -65,7 +65,7 @@ export class FieldEntity extends CommonEntity { nullable: true, cascade: true, }) - options: Relation[]; + options: Relation[] | undefined; static from({ channelId, @@ -79,7 +79,7 @@ export class FieldEntity extends CommonEntity { channelId: number; name: string; key: string; - description: string; + description: string | null; format: FieldFormatEnum; property: FieldPropertyEnum; status: FieldStatusEnum; diff --git a/apps/api/src/domains/admin/channel/field/field.mysql.service.ts b/apps/api/src/domains/admin/channel/field/field.mysql.service.ts index 40c40e337..02cff31bb 100644 --- a/apps/api/src/domains/admin/channel/field/field.mysql.service.ts +++ b/apps/api/src/domains/admin/channel/field/field.mysql.service.ts @@ -51,7 +51,7 @@ export class FieldMySQLService { throw new FieldKeyDuplicatedException(); } fields.forEach(({ format, options }) => { - if (!this.isValidField(format, options)) { + if (!this.isValidField(format, options ?? [])) { throw new BadRequestException('only select format field has options'); } }); @@ -78,9 +78,9 @@ export class FieldMySQLService { options: { id?: number; name: string }[], ) { if (isSelectFieldFormat(type)) { - return !options || Array.isArray(options); + return options.length === 0 || Array.isArray(options); } else { - return !options || !Array.isArray(options); + return options.length === 0 || !Array.isArray(options); } } @@ -126,14 +126,14 @@ export class FieldMySQLService { ...fields, ]; - const fieldEntities = []; + const fieldEntities: FieldEntity[] = []; for (const field of fieldsToCreate) { - const { format, options } = field; + const { format, options = [] } = field; const newField = FieldEntity.from({ channelId, ...field }); const { id } = await this.repository.save(newField); fieldEntities.push(newField); - if (isSelectFieldFormat(format) && options?.length > 0) { + if (isSelectFieldFormat(format) && options.length > 0) { await this.optionService.createMany({ fieldId: id, options, @@ -169,7 +169,7 @@ export class FieldMySQLService { channel: { id: channelId }, }); - for (const { id, format, key, options, ...rest } of updatingFieldDtos) { + for (const { id = 0, format, key, options, ...rest } of updatingFieldDtos) { const fieldEntity = fieldEntities.find((v) => v.id === id); if (!fieldEntity) { throw new BadRequestException('field must be included'); @@ -186,9 +186,9 @@ export class FieldMySQLService { } } - const createdFields = []; + const createdFields: FieldEntity[] = []; for (const field of creatingFieldDtos) { - const { format, options } = field; + const { format, options = [] } = field; const newField = FieldEntity.from({ channelId, ...field }); const createdField = await this.repository.save(newField); createdFields.push(createdField); @@ -210,6 +210,6 @@ export class FieldMySQLService { withDeleted: true, }); const fieldMap = new Map(fields.map((field) => [field.id, field])); - return ids.map((id) => fieldMap.get(id)); + return ids.map((id) => fieldMap.get(id) ?? new FieldEntity()); } } diff --git a/apps/api/src/domains/admin/channel/field/field.service.spec.ts b/apps/api/src/domains/admin/channel/field/field.service.spec.ts index 7e85b8fa3..a6c8c2f5b 100644 --- a/apps/api/src/domains/admin/channel/field/field.service.spec.ts +++ b/apps/api/src/domains/admin/channel/field/field.service.spec.ts @@ -24,6 +24,7 @@ import { createFieldDto, updateFieldDto } from '@/test-utils/fixtures'; import { TestConfig } from '@/test-utils/util-functions'; import { FieldServiceProviders } from '../../../../test-utils/providers/field.service.providers'; import { OptionEntity } from '../option/option.entity'; +import type { CreateFieldDto, ReplaceFieldDto } from './dtos'; import { CreateManyFieldsDto, ReplaceManyFieldsDto } from './dtos'; import { FieldKeyDuplicatedException, @@ -32,8 +33,12 @@ import { import { FieldEntity } from './field.entity'; import { FieldService } from './field.service'; -const countSelect = (prev, curr) => { - return isSelectFieldFormat(curr.format) && curr.options.length > 0 ? +const countSelect = (prev: number, curr: CreateFieldDto): number => { + return ( + isSelectFieldFormat(curr.format) && + curr.options && + curr.options.length > 0 + ) ? prev + 1 : prev; }; @@ -68,6 +73,7 @@ describe('FieldService suite', () => { const fields = await fieldService.createMany(dto); expect(fields.length).toBe(fieldCount + 4); + expect(optionRepo.save).toBeCalledTimes(selectFieldCount); }); it('creating many fields fails with duplicate names', async () => { @@ -221,7 +227,9 @@ describe('FieldService suite', () => { }).map(() => updateFieldDto({ format: FieldFormatEnum.keyword })); const dto = new ReplaceManyFieldsDto(); dto.channelId = channelId; - dto.fields = JSON.parse(JSON.stringify(updatingFieldDtos)); + dto.fields = JSON.parse( + JSON.stringify(updatingFieldDtos), + ) as ReplaceFieldDto[]; jest.spyOn(fieldRepo, 'findBy').mockResolvedValue( updatingFieldDtos.map((field) => { field.format = FieldFormatEnum.text; @@ -241,7 +249,9 @@ describe('FieldService suite', () => { }).map(updateFieldDto); const dto = new ReplaceManyFieldsDto(); dto.channelId = channelId; - dto.fields = JSON.parse(JSON.stringify(updatingFieldDtos)); + dto.fields = JSON.parse( + JSON.stringify(updatingFieldDtos), + ) as ReplaceFieldDto[]; jest.spyOn(fieldRepo, 'findBy').mockResolvedValue( updatingFieldDtos.map((field) => { field.key = faker.string.sample(); diff --git a/apps/api/src/domains/admin/channel/option/dtos/replace-select-options.dto.ts b/apps/api/src/domains/admin/channel/option/dtos/replace-select-options.dto.ts index 64447f9d6..3d777e5e8 100644 --- a/apps/api/src/domains/admin/channel/option/dtos/replace-select-options.dto.ts +++ b/apps/api/src/domains/admin/channel/option/dtos/replace-select-options.dto.ts @@ -15,5 +15,5 @@ */ export class ReplaceManyOptionsDto { fieldId: number; - options: { id?: number; name: string; key: string }[]; + options: { id?: number; name: string; key: string }[] | undefined; } diff --git a/apps/api/src/domains/admin/channel/option/option.service.spec.ts b/apps/api/src/domains/admin/channel/option/option.service.spec.ts index b34262869..f998dd381 100644 --- a/apps/api/src/domains/admin/channel/option/option.service.spec.ts +++ b/apps/api/src/domains/admin/channel/option/option.service.spec.ts @@ -187,7 +187,7 @@ describe('Option Test suite', () => { key: faker.string.sample(), name: faker.string.sample(), deletedAt: null, - })) as OptionEntity[], + })) as unknown as OptionEntity[], ); jest.spyOn(optionRepo, 'query'); jest.spyOn(optionRepo, 'save'); diff --git a/apps/api/src/domains/admin/channel/option/option.service.ts b/apps/api/src/domains/admin/channel/option/option.service.ts index 2a77d0bb1..27ddc4f49 100644 --- a/apps/api/src/domains/admin/channel/option/option.service.ts +++ b/apps/api/src/domains/admin/channel/option/option.service.ts @@ -107,8 +107,9 @@ export class OptionService { }); const deletingOptionIds = optionEntities + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition .filter((option) => option.deletedAt === null) - .filter((option) => options.every((dto) => dto.id !== option.id)) + .filter((option) => (options ?? []).every((dto) => dto.id !== option.id)) .map((v) => v.id); if (deletingOptionIds.length > 0) { @@ -129,7 +130,7 @@ export class OptionService { ); } - for (const option of options) { + for (const option of options ?? []) { const inactiveOption = this.getInactiveOption( optionEntities, option.key, diff --git a/apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id.dto.ts b/apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id.dto.ts index a2a94632c..20096248a 100644 --- a/apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id.dto.ts +++ b/apps/api/src/domains/admin/feedback/dtos/find-feedbacks-by-channel-id.dto.ts @@ -26,10 +26,14 @@ export class FindFeedbacksByChannelIdDto extends PaginationDto { createdAt?: TimeRange; updatedAt?: TimeRange; ids?: number[]; - [key: string]: string | string[] | TimeRange | number | number[]; - }; - sort?: { - [key: string]: SortMethodEnum; + [key: string]: + | string + | string[] + | TimeRange + | number + | number[] + | undefined; }; + sort?: Record; fields?: FieldEntity[]; } diff --git a/apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts b/apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts index 74e347566..30d768ffd 100644 --- a/apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts +++ b/apps/api/src/domains/admin/feedback/dtos/generate-excel.dto.ts @@ -23,11 +23,15 @@ export class GenerateExcelDto { createdAt?: TimeRange; updatedAt?: TimeRange; ids?: number[]; - [key: string]: string | string[] | TimeRange | number | number[]; - }; - sort?: { - [key: string]: SortMethodEnum; + [key: string]: + | string + | string[] + | TimeRange + | number + | number[] + | undefined; }; + sort?: Record; type: 'xlsx' | 'csv'; fieldIds?: number[]; } diff --git a/apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request.dto.ts b/apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request.dto.ts index 7bee95f7e..1a7836baa 100644 --- a/apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request.dto.ts +++ b/apps/api/src/domains/admin/feedback/dtos/requests/find-feedbacks-by-channel-id-request.dto.ts @@ -44,7 +44,7 @@ class Query { @IsOptional() updatedAt?: TimeRange; - [key: string]: string | string[] | TimeRange | number | number[]; + [key: string]: string | string[] | TimeRange | number | number[] | undefined; } export class FindFeedbacksByChannelIdRequestDto extends PaginationRequestDto { @@ -63,11 +63,9 @@ export class FindFeedbacksByChannelIdRequestDto extends PaginationRequestDto { example: { createdAt: 'ASC' }, }) @IsOptional() - sort?: { - [key: string]: SortMethodEnum; - }; + sort?: Record; - constructor(limit = 10, page = 1, query) { + constructor(limit = 10, page = 1, query?: Query) { super(limit, page); this.query = query; } diff --git a/apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks.dto.ts b/apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks.dto.ts index 67826bef6..0e8c58c57 100644 --- a/apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks.dto.ts +++ b/apps/api/src/domains/admin/feedback/dtos/scroll-feedbacks.dto.ts @@ -24,11 +24,15 @@ export class ScrollFeedbacksDto { createdAt?: TimeRange; updatedAt?: TimeRange; ids?: number[]; - [key: string]: string | string[] | TimeRange | number | number[]; - }; - sort?: { - [key: string]: SortMethodEnum; + [key: string]: + | string + | string[] + | TimeRange + | number + | number[] + | undefined; }; + sort?: Record; fields: FieldEntity[]; size: number; scrollId: string | null; diff --git a/apps/api/src/domains/admin/feedback/feedback.common.ts b/apps/api/src/domains/admin/feedback/feedback.common.ts index 2b20916ae..c77d6fae1 100644 --- a/apps/api/src/domains/admin/feedback/feedback.common.ts +++ b/apps/api/src/domains/admin/feedback/feedback.common.ts @@ -32,22 +32,25 @@ export function validateValue(field: FieldEntity, value: any) { return ( value === null || (typeof value === 'string' && - !!field.options.find((v) => v.key === value)) + !!(field.options ?? []).find((v) => v.key === value)) ); case FieldFormatEnum.multiSelect: if (Array.isArray(value)) { for (const option of value) { - if (!field.options.find((v) => v.key === option)) return false; + if (!(field.options ?? []).find((v) => v.key === option)) + return false; } return true; } else { return false; } case FieldFormatEnum.date: - return !isNaN(Date.parse(value)) && typeof value !== 'number'; + return !isNaN(Date.parse(value as string)) && typeof value !== 'number'; case FieldFormatEnum.images: return Array.isArray(value); default: - throw new Error(`${field.key}: ${field.format} is error ${value}`); + throw new Error( + `${field.key}: ${field.format as string} is error ${value}`, + ); } } diff --git a/apps/api/src/domains/admin/feedback/feedback.controller.spec.ts b/apps/api/src/domains/admin/feedback/feedback.controller.spec.ts index c02f58706..6ff4456c1 100644 --- a/apps/api/src/domains/admin/feedback/feedback.controller.spec.ts +++ b/apps/api/src/domains/admin/feedback/feedback.controller.spec.ts @@ -103,7 +103,6 @@ describe('FeedbackController', () => { const dto = new ExportFeedbacksRequestDto( faker.number.int(), faker.number.int(), - 'csv', ); const userDto = new UserDto(); jest.spyOn(MockFeedbackService, 'generateFile').mockResolvedValue({ diff --git a/apps/api/src/domains/admin/feedback/feedback.controller.ts b/apps/api/src/domains/admin/feedback/feedback.controller.ts index 419e8d587..92703a4c3 100644 --- a/apps/api/src/domains/admin/feedback/feedback.controller.ts +++ b/apps/api/src/domains/admin/feedback/feedback.controller.ts @@ -156,19 +156,25 @@ export class FeedbackController { const filename = `UFB_${projectName}_${channelName}_Feedback_${DateTime.utc().toFormat( 'yyyy-MM-dd', )}.${type}`; - res.header('Content-Disposition', `attachment; filename="${filename}"`); + void res.header( + 'Content-Disposition', + `attachment; filename="${filename}"`, + ); - if (type === 'xlsx') { - res.type( - 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - ); - } else if (type === 'csv') { - res.type('text/csv'); + switch (type) { + case 'xlsx': + void res.type( + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + ); + break; + case 'csv': + void res.type('text/csv'); + break; } - res.send(stream); + void res.send(stream); - this.historyService.createHistory({ + void this.historyService.createHistory({ action: HistoryActionEnum.Download, entity: { feedbackIds }, entityName: EntityNameEnum.Channel, diff --git a/apps/api/src/domains/admin/feedback/feedback.mysql.service.ts b/apps/api/src/domains/admin/feedback/feedback.mysql.service.ts index 96f936e4f..064f4dc48 100644 --- a/apps/api/src/domains/admin/feedback/feedback.mysql.service.ts +++ b/apps/api/src/domains/admin/feedback/feedback.mysql.service.ts @@ -25,7 +25,7 @@ import type { TimeRange } from '@/common/dtos'; import { FieldFormatEnum, SortMethodEnum } from '@/common/enums'; import type { ClsServiceType } from '@/types/cls-service.type'; import { ChannelEntity } from '../channel/channel/channel.entity'; -import type { FieldEntity } from '../channel/field/field.entity'; +import { FieldEntity } from '../channel/field/field.entity'; import { OptionEntity } from '../channel/option/option.entity'; import { IssueEntity } from '../project/issue/issue.entity'; import { FeedbackIssueStatisticsService } from '../statistics/feedback-issue/feedback-issue-statistics.service'; @@ -38,10 +38,14 @@ import { RemoveIssueDto, UpdateFeedbackMySQLDto, } from './dtos'; -import type { Feedback } from './dtos/responses/find-feedbacks-by-channel-id-response.dto'; +import { Feedback } from './dtos/responses/find-feedbacks-by-channel-id-response.dto'; import { isInvalidSortMethod } from './feedback.common'; import { FeedbackEntity } from './feedback.entity'; +interface QueryFailedDriverError { + code: string; +} + @Injectable() export class FeedbackMySQLService { private logger = new Logger(FeedbackMySQLService.name); @@ -63,7 +67,7 @@ export class FeedbackMySQLService { feedback.channel = new ChannelEntity(); feedback.channel.id = channelId; if (data.createdAt) { - feedback.createdAt = data.createdAt; + feedback.createdAt = data.createdAt as Date; delete data.createdAt; } feedback.data = data; @@ -80,7 +84,14 @@ export class FeedbackMySQLService { async findByChannelId( dto: FindFeedbacksByChannelIdDto, ): Promise> { - const { page, limit, channelId, query = {}, sort = {}, fields } = dto; + const { + page, + limit, + channelId, + query = {}, + sort = {}, + fields = [new FieldEntity()], + } = dto; const queryBuilder = this.feedbackRepository .createQueryBuilder('feedbacks') @@ -127,12 +138,12 @@ export class FeedbackMySQLService { if (i === 0) { qb.where( `JSON_EXTRACT(feedbacks.data, '$."${stringFields[i].id}"') like :likeValue`, - { likeValue: `%${value}%` }, + { likeValue: `%${value as string | number}%` }, ); } else { qb.orWhere( `JSON_EXTRACT(feedbacks.data, '$."${stringFields[i].id}"') like :likeValue`, - { likeValue: `%${value}%` }, + { likeValue: `%${value as string | number}%` }, ); } } @@ -156,13 +167,19 @@ export class FeedbackMySQLService { queryBuilder.andWhere('feedbacks.updated_at >= :gte', { gte }); queryBuilder.andWhere('feedbacks.updated_at < :lt', { lt }); } else { - const { id, format } = fields.find((v) => v.key === fieldKey); + const { id, format }: { id: number; format: FieldFormatEnum } = + fields.find((v) => v.key === fieldKey) ?? { + id: 0, + format: FieldFormatEnum.date, + }; if (format === FieldFormatEnum.select) { const options = await this.optionRepository.find({ where: { field: { id } }, }); - const option = options.find((option) => option.key === value); + const option = + options.find((option) => option.key === value) ?? + new OptionEntity(); queryBuilder.andWhere( `JSON_EXTRACT(feedbacks.data, '$."${fieldKey}"') = :optionId`, @@ -174,7 +191,9 @@ export class FeedbackMySQLService { }); for (const optionKey of value as string[]) { - const option = options.find((option) => option.key === optionKey); + const option = + options.find((option) => option.key === optionKey) ?? + new OptionEntity(); queryBuilder.andWhere( `JSON_CONTAINS( JSON_EXTRACT(feedbacks.data, '$."${fieldKey}"'), @@ -187,7 +206,7 @@ export class FeedbackMySQLService { ) { queryBuilder.andWhere( `JSON_EXTRACT(feedbacks.data, '$."${fieldKey}"') like :value`, - { value: `%${value}%` }, + { value: `%${value as string | number}%` }, ); } else if (format === FieldFormatEnum.date) { const { gte, lt } = value as TimeRange; @@ -300,10 +319,11 @@ export class FeedbackMySQLService { try { const { issueId, feedbackId, channelId } = dto; - const feedback = await this.feedbackRepository.findOne({ - relations: { issues: true }, - where: { id: feedbackId, channel: { id: channelId } }, - }); + const feedback = + (await this.feedbackRepository.findOne({ + relations: { issues: true }, + where: { id: feedbackId, channel: { id: channelId } }, + })) ?? new FeedbackEntity(); const issue = new IssueEntity(); issue.id = issueId; @@ -329,9 +349,14 @@ export class FeedbackMySQLService { }); } catch (e) { if (e instanceof QueryFailedError) { - if (e.driverError.code === 'ER_NO_REFERENCED_ROW_2') { + if ( + (e.driverError as QueryFailedDriverError).code === + 'ER_NO_REFERENCED_ROW_2' + ) { throw new BadRequestException('unknown id'); - } else if (e.driverError.code === 'ER_DUP_ENTRY') { + } else if ( + (e.driverError as QueryFailedDriverError).code === 'ER_DUP_ENTRY' + ) { throw new BadRequestException('already issueed'); } else { this.logger.error(e); @@ -348,10 +373,11 @@ export class FeedbackMySQLService { try { const { channelId, issueId, feedbackId } = dto; - const feedback = await this.feedbackRepository.findOne({ - relations: { issues: true }, - where: { id: feedbackId, channel: { id: channelId } }, - }); + const feedback = + (await this.feedbackRepository.findOne({ + relations: { issues: true }, + where: { id: feedbackId, channel: { id: channelId } }, + })) ?? new FeedbackEntity(); feedback.issues = feedback.issues.filter((issue) => issue.id !== issueId); this.cls.set('removeIssueInFeedback', { feedbackId, issueId }); diff --git a/apps/api/src/domains/admin/feedback/feedback.os.service.ts b/apps/api/src/domains/admin/feedback/feedback.os.service.ts index 5bca1adff..84e25844b 100644 --- a/apps/api/src/domains/admin/feedback/feedback.os.service.ts +++ b/apps/api/src/domains/admin/feedback/feedback.os.service.ts @@ -35,6 +35,12 @@ import type { Feedback } from './dtos/responses/find-feedbacks-by-channel-id-res import { isInvalidSortMethod } from './feedback.common'; import { FeedbackEntity } from './feedback.entity'; +interface OpenSearchQuery { + bool: { + must: any[]; + }; +} + @Injectable() export class FeedbackOSService { private logger = new Logger(FeedbackOSService.name); @@ -62,22 +68,28 @@ export class FeedbackOSService { } private getMultiFieldQuery( - query: any, + query: string, fields: FieldEntity[], fieldFormats: FieldFormatEnum[], ) { + type FieldFormatCondition = { + match_phrase: Record; + }[]; return { bool: { - should: fields.reduce((prev, field) => { - if (fieldFormats.includes(field.format)) { - prev.push({ - match_phrase: { - [field.id]: query, - }, - }); - } - return prev; - }, []), + should: fields.reduce( + (prev: FieldFormatCondition, field: FieldEntity) => { + if (fieldFormats.includes(field.format)) { + prev.push({ + match_phrase: { + [field.id]: query, + }, + }); + } + return prev; + }, + [], + ), }, }; } @@ -99,11 +111,11 @@ export class FeedbackOSService { query: query ? Object.keys(query).reduce( - (osQuery, fieldKey) => { + (osQuery: OpenSearchQuery, fieldKey) => { if (fieldKey === 'ids') { osQuery.bool.must.push({ ids: { - values: query[fieldKey].map((id) => id.toString()), + values: (query[fieldKey] ?? []).map((id) => id.toString()), }, }); @@ -149,16 +161,18 @@ export class FeedbackOSService { if (format === FieldFormatEnum.select) { osQuery.bool.must.push({ match_phrase: { - [key]: options.find( + [key]: (options ?? []).find( (option) => option.key === query[fieldKey], - ).key, + )?.key, }, }); } else if (format === FieldFormatEnum.multiSelect) { for (const value of query[fieldKey] as string[]) { osQuery.bool.must.push({ match_phrase: { - [key]: options.find((option) => option.key === value).key, + [key]: (options ?? []).find( + (option) => option.key === value, + )?.key, }, }); } @@ -231,12 +245,12 @@ export class FeedbackOSService { ): Promise> { const { channelId, limit, page, query, sort, fields } = dto; - if (query && query.issueIds) { + if (query?.issueIds) { const feedbackIds = await this.issueIdsToFeedbackIds( query.issueIds as number[], ); - delete query['issueIds']; + delete query.issueIds; if (query.ids) { query.ids = [...query.ids, ...feedbackIds]; } else { @@ -244,15 +258,16 @@ export class FeedbackOSService { } } - const osQuery = this.osQueryBulider(query, sort, fields); + const osQuery = this.osQueryBulider(query, sort, fields ?? []); this.logger.log(osQuery); - const { items, total } = await this.osRepository.getData({ - index: channelId.toString(), - limit, - page, - ...osQuery, - }); + const { items, total }: { items: Record[]; total: number } = + await this.osRepository.getData({ + index: channelId.toString(), + limit, + page, + ...osQuery, + }); const totalItems = await this.osRepository.getTotal( channelId.toString(), @@ -281,12 +296,12 @@ export class FeedbackOSService { scrollId: currentScrollId, } = dto; - if (query && query.issueIds) { + if (query?.issueIds) { const feedbackIds = await this.issueIdsToFeedbackIds( query.issueIds as number[], ); - delete query['issueIds']; + delete query.issueIds; if (query.ids) query.ids = [...query.ids, ...feedbackIds]; else query.ids = feedbackIds; } @@ -326,7 +341,7 @@ export class FeedbackOSService { must: [ { ids: { - values: [feedbackId.toString()], + values: [(feedbackId as number).toString()], }, }, ], diff --git a/apps/api/src/domains/admin/feedback/feedback.service.spec.ts b/apps/api/src/domains/admin/feedback/feedback.service.spec.ts index 22e815cec..bb96266c8 100644 --- a/apps/api/src/domains/admin/feedback/feedback.service.spec.ts +++ b/apps/api/src/domains/admin/feedback/feedback.service.spec.ts @@ -17,8 +17,8 @@ import { faker } from '@faker-js/faker'; import { BadRequestException } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { ClsService } from 'nestjs-cls'; -import type { Repository } from 'typeorm'; +import { ClsModule, ClsService } from 'nestjs-cls'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { FieldFormatEnum, @@ -50,7 +50,7 @@ describe('FeedbackService Test Suite', () => { let feedbackIssueStatsRepo: Repository; beforeEach(async () => { const module = await Test.createTestingModule({ - imports: [TestConfig], + imports: [TestConfig, ClsModule.forFeature()], providers: FeedbackServiceProviders, }).compile(); @@ -77,7 +77,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback succeeds with valid inputs', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; jest .spyOn(feedbackStatsRepo, 'findOne') .mockResolvedValue({ count: 1 } as FeedbackStatisticsEntity); @@ -89,7 +89,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback fails with an invalid channel', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; jest.spyOn(fieldRepo, 'find').mockResolvedValue([]); await expect(feedbackService.create(dto)).rejects.toThrow( @@ -99,7 +99,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback fails with a reserved field key', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; const reservedFieldKey = faker.helpers.arrayElement( RESERVED_FIELD_KEYS.filter((key) => key !== 'createdAt'), ); @@ -114,7 +114,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback fails with an invalid field key', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; const invalidFieldKey = 'invalidFieldKey'; dto.data[invalidFieldKey] = faker.string.sample(); @@ -184,7 +184,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback succeeds with valid inputs and issue names', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; const issueNames = Array.from({ length: faker.number.int({ min: 1, max: 1 }), }).map(() => faker.string.sample()); @@ -195,10 +195,16 @@ describe('FeedbackService Test Suite', () => { .mockResolvedValue({ count: 1 } as FeedbackStatisticsEntity); jest .spyOn(issueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); jest .spyOn(feedbackIssueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); clsService.set = jest.fn(); const feedback = await feedbackService.create(dto); @@ -208,7 +214,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback succeeds with valid inputs and an existent issue name', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; const issueNames = Array.from({ length: faker.number.int({ min: 1, max: 1 }), }).map(() => faker.string.sample()); @@ -219,10 +225,16 @@ describe('FeedbackService Test Suite', () => { .mockResolvedValue({ count: 1 } as FeedbackStatisticsEntity); jest .spyOn(feedbackIssueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); jest .spyOn(issueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); clsService.set = jest.fn(); const feedback = await feedbackService.create(dto); @@ -232,7 +244,7 @@ describe('FeedbackService Test Suite', () => { it('creating a feedback succeeds with valid inputs and a nonexistent issue name', async () => { const dto = new CreateFeedbackDto(); dto.channelId = faker.number.int(); - dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)); + dto.data = JSON.parse(JSON.stringify(feedbackDataFixture)) as object; dto.data.issueNames = [faker.string.sample()]; jest.spyOn(issueRepo, 'findOneBy').mockResolvedValue(null); jest @@ -240,10 +252,16 @@ describe('FeedbackService Test Suite', () => { .mockResolvedValue({ count: 1 } as FeedbackStatisticsEntity); jest .spyOn(issueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); jest .spyOn(feedbackIssueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); clsService.set = jest.fn(); const feedback = await feedbackService.create(dto); diff --git a/apps/api/src/domains/admin/feedback/feedback.service.ts b/apps/api/src/domains/admin/feedback/feedback.service.ts index cac0ecabc..ee74d4632 100644 --- a/apps/api/src/domains/admin/feedback/feedback.service.ts +++ b/apps/api/src/domains/admin/feedback/feedback.service.ts @@ -61,6 +61,19 @@ import { validateValue } from './feedback.common'; import { FeedbackMySQLService } from './feedback.mysql.service'; import { FeedbackOSService } from './feedback.os.service'; +interface File { + fieldname: string; + buffer: Buffer; + mimetype: string; + originalname: string; +} + +interface ImageUrl extends File { + url: string; +} + +type ImageUrlsByKeys = Record; + @Injectable() export class FeedbackService { constructor( @@ -86,6 +99,10 @@ export class FeedbackService { {}, ); + if (query === undefined) { + throw new BadRequestException('query is required'); + } + for (const fieldKey of Object.keys(query)) { if (['ids', 'issueIds'].includes(fieldKey)) { if (!Array.isArray(query[fieldKey])) { @@ -96,7 +113,7 @@ export class FeedbackService { if ('searchText' === fieldKey) { continue; } - if (!fieldsByKey[fieldKey]) { + if (!(fieldKey in fieldsByKey)) { throw new BadRequestException(`invalid key in query: ${fieldKey}`); } @@ -144,7 +161,7 @@ export class FeedbackService { } private convertFeedback( - feedback: any, + feedback: Feedback, fieldsByKey: Record, fieldsToExport: FieldEntity[], ) { @@ -155,13 +172,13 @@ export class FeedbackService { key === 'issues' ? feedback[key].map((issue) => issue.name).join(', ') : feedback[key].join(', ') - : feedback[key]; + : (feedback[key] as string); } return Object.keys(convertedFeedback) .filter((key) => fieldsToExport.find((field) => field.name === key)) .reduce((obj, key) => { - obj[key] = convertedFeedback[key]; + obj[key] = convertedFeedback[key] as object; return obj; }, {}); } @@ -173,11 +190,21 @@ export class FeedbackService { fields, fieldsByKey, fieldsToExport, + }: { + channelId: number; + query: FindFeedbacksByChannelIdDto['query']; + sort: FindFeedbacksByChannelIdDto['sort']; + fields: FieldEntity[]; + fieldsByKey: Record; + fieldsToExport: FieldEntity[]; }) { if (!existsSync('/tmp')) { await fs.mkdir('/tmp'); } - const tempFilePath = path.join('/tmp', `temp_${new Date()}.xlsx`); + const tempFilePath = path.join( + '/tmp', + `temp_${new Date().toString()}.xlsx`, + ); const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ filename: tempFilePath, }); @@ -186,14 +213,14 @@ export class FeedbackService { const headers = fieldsToExport.map((field) => ({ header: field.name, key: field.name, - })); + })) as Partial[]; worksheet.columns = headers; const pageSize = 1000; - let feedbacks = []; - let currentScrollId = null; + let feedbacks: Feedback[] = []; + let currentScrollId: string | null = null; let page = 1; - const feedbackIds = []; + const feedbackIds: number[] = []; do { if (this.configService.get('opensearch.use')) { @@ -206,7 +233,7 @@ export class FeedbackService { scrollId: currentScrollId, }); feedbacks = data; - currentScrollId = scrollId; + currentScrollId = scrollId as unknown as string; } else { const { items } = await this.feedbackMySQLService.findByChannelId({ channelId, @@ -221,18 +248,18 @@ export class FeedbackService { } const issuesByFeedbackIds = await this.issueService.findIssuesByFeedbackIds( - feedbacks.map((feedback) => feedback.id), + feedbacks.map((feedback) => feedback.id as number), ); for (const feedback of feedbacks) { - feedback.issues = issuesByFeedbackIds[feedback.id]; + feedback.issues = issuesByFeedbackIds[feedback.id as number]; const convertedFeedback = this.convertFeedback( feedback, fieldsByKey, fieldsToExport, ); worksheet.addRow(convertedFeedback).commit(); - feedbackIds.push(feedback.id); + feedbackIds.push(feedback.id as number); } } while (feedbacks.length === pageSize); worksheet.commit(); @@ -257,35 +284,35 @@ export class FeedbackService { }) { const stream = new PassThrough(); const csvStream = fastcsv.format({ - headers: fieldsToExport.map((field) => field.name), + headers: (fieldsToExport as FieldEntity[]).map((field) => field.name), }); csvStream.pipe(stream); const pageSize = 1000; - let feedbacks = []; - let currentScrollId = null; + let feedbacks: Record[] = []; + let currentScrollId: number | null = null; let page = 1; - const feedbackIds = []; + const feedbackIds: number[] = []; do { if (this.configService.get('opensearch.use')) { const { data, scrollId } = await this.feedbackOSService.scroll({ - channelId, - query, - sort, - fields, + channelId: channelId as number, + query: query as FindFeedbacksByChannelIdDto['query'], + sort: sort as FindFeedbacksByChannelIdDto['sort'], + fields: fields as FieldEntity[], size: pageSize, - scrollId: currentScrollId, + scrollId: currentScrollId as unknown as string, }); feedbacks = data; currentScrollId = scrollId; } else { const { items } = await this.feedbackMySQLService.findByChannelId({ - channelId, - query, - sort, - fields, + channelId: channelId as number, + query: query as FindFeedbacksByChannelIdDto['query'], + sort: sort as FindFeedbacksByChannelIdDto['sort'], + fields: fields as FieldEntity[], limit: pageSize, page, }); @@ -294,18 +321,18 @@ export class FeedbackService { } const issuesByFeedbackIds = await this.issueService.findIssuesByFeedbackIds( - feedbacks.map((feedback) => feedback.id), + feedbacks.map((feedback: Feedback) => feedback.id as number), ); for (const feedback of feedbacks) { - feedback.issues = issuesByFeedbackIds[feedback.id]; + feedback.issues = issuesByFeedbackIds[feedback.id as number]; const convertedFeedback = this.convertFeedback( feedback, - fieldsByKey, - fieldsToExport, + fieldsByKey as Record, + fieldsToExport as FieldEntity[], ); csvStream.write(convertedFeedback); - feedbackIds.push(feedback.id); + feedbackIds.push(feedback.id as number); } } while (feedbacks.length === pageSize); @@ -341,7 +368,10 @@ export class FeedbackService { ); } - const value = data[fieldKey]; + const value: number | string | string[] = data[fieldKey] as + | number + | string + | string[]; const field = fields.find((v) => v.key === fieldKey); if (!field) { @@ -358,9 +388,9 @@ export class FeedbackService { if (field.format === FieldFormatEnum.images) { const channel = await this.channelService.findById({ channelId }); - const domainWhiteList = channel.imageConfig.domainWhiteList; + const domainWhiteList = channel.imageConfig?.domainWhiteList ?? []; - if (domainWhiteList) { + if (domainWhiteList.length !== 0) { const images = value as string[]; for (const image of images) { const url = new URL(image); @@ -421,7 +451,7 @@ export class FeedbackService { } dto.fields = fields; - this.validateQuery(dto.query || {}, fields); + this.validateQuery(dto.query ?? {}, fields); const feedbacksByPagination = this.configService.get('opensearch.use') ? @@ -429,11 +459,13 @@ export class FeedbackService { : await this.feedbackMySQLService.findByChannelId(dto); const issuesByFeedbackIds = await this.issueService.findIssuesByFeedbackIds( - feedbacksByPagination.items.map((feedback) => feedback.id), + feedbacksByPagination.items.map( + (feedback: Feedback) => feedback.id as number, + ), ); - feedbacksByPagination.items.forEach((feedback) => { - feedback.issues = issuesByFeedbackIds[feedback.id]; + feedbacksByPagination.items.forEach((feedback: Feedback) => { + feedback.issues = issuesByFeedbackIds[feedback.id as number]; }); return feedbacksByPagination; @@ -453,12 +485,12 @@ export class FeedbackService { ); for (const fieldKey of Object.keys(data)) { - const field = fieldsByKey[fieldKey]; - - if (!field) { + if (!(fieldKey in fieldsByKey)) { throw new BadRequestException('invalid field name'); } + const field = fieldsByKey[fieldKey]; + if (field.property === FieldPropertyEnum.READ_ONLY) { throw new BadRequestException('this field is read-only'); } @@ -470,27 +502,27 @@ export class FeedbackService { if (field.format === FieldFormatEnum.multiSelect) { const values = data[fieldKey] as string[]; const newValues = values.filter( - (v) => !field.options.find(({ name }) => name === v), + (v) => !(field.options ?? []).find(({ name }) => name === v), ); const newOptions = await this.optionService.createMany({ fieldId: field.id, options: newValues.map((v) => ({ name: v, key: v })), }); - field.options = field.options.concat(newOptions); + field.options = (field.options ?? []).concat(newOptions); } const value = data[fieldKey] as string; if ( field.format === FieldFormatEnum.select && value && - !field.options.find((v) => v.name === value) + !(field.options ?? []).find((v) => v.name === value) ) { const newOption = await this.optionService.create({ fieldId: field.id, key: value, name: value, }); - field.options = field.options.concat(newOption); + field.options = (field.options ?? []).concat(newOption); } if (!validateValue(field, data[fieldKey])) { @@ -569,7 +601,7 @@ export class FeedbackService { }); if (fields.length === 0) throw new BadRequestException('invalid channel'); - let fieldsToExport = fields; + let fieldsToExport: FieldEntity[] = fields; if (fieldIds) { fieldsToExport = await this.fieldService.findByIds(fieldIds); if (fields.length === 0) { @@ -578,7 +610,7 @@ export class FeedbackService { } this.validateQuery(query, fields); - const fieldsByKey = fields.reduce( + const fieldsByKey: Record = fields.reduce( (prev: Record, field) => { prev[field.key] = field; return prev; @@ -586,24 +618,25 @@ export class FeedbackService { {}, ); - if (type === 'xlsx') { - return this.generateXLSXFile({ - channelId, - query, - sort, - fields, - fieldsByKey, - fieldsToExport, - }); - } else if (type === 'csv') { - return this.generateCSVFile({ - channelId, - query, - sort, - fields, - fieldsByKey, - fieldsToExport, - }); + switch (type) { + case 'xlsx': + return this.generateXLSXFile({ + channelId, + query, + sort, + fields, + fieldsByKey, + fieldsToExport, + }); + case 'csv': + return this.generateCSVFile({ + channelId, + query, + sort, + fields, + fieldsByKey, + fieldsToExport, + }); } } @@ -621,8 +654,10 @@ export class FeedbackService { }); const feedback = items[0]; const issuesByFeedbackIds = - await this.issueService.findIssuesByFeedbackIds([feedback.id]); - feedback.issues = issuesByFeedbackIds[feedback.id]; + await this.issueService.findIssuesByFeedbackIds([ + feedback.id as number, + ]); + feedback.issues = issuesByFeedbackIds[feedback.id as number]; return feedback; } else { @@ -635,27 +670,24 @@ export class FeedbackService { files, }: { channelId: number; - files: Array; + files: File[]; }) { const channel = await this.channelService.findById({ channelId }); - if (!channel) { - throw new BadRequestException('invalid channel id'); - } const s3 = new S3Client({ credentials: { - accessKeyId: channel.imageConfig.accessKeyId, - secretAccessKey: channel.imageConfig.secretAccessKey, + accessKeyId: channel.imageConfig?.accessKeyId ?? '', + secretAccessKey: channel.imageConfig?.secretAccessKey ?? '', }, - endpoint: channel.imageConfig.endpoint, - region: channel.imageConfig.region, + endpoint: channel.imageConfig?.endpoint, + region: channel.imageConfig?.region, }); try { const imageUrls = await Promise.all( files.map(async (file) => { const key = `${channelId}_${Date.now()}_${file.originalname}`; const command = new PutObjectCommand({ - Bucket: channel.imageConfig.bucket, + Bucket: channel.imageConfig?.bucket, Key: key, Body: file.buffer, ContentType: file.mimetype, @@ -665,23 +697,26 @@ export class FeedbackService { return { ...file, - url: `${channel.imageConfig.endpoint}/${channel.imageConfig.bucket}/${key}`, - }; + url: `${channel.imageConfig?.endpoint}/${channel.imageConfig?.bucket}/${key}`, + } as ImageUrl; }), ); - const imageUrlsByKeys = imageUrls.reduce((prev, curr) => { - if (curr.fieldname in prev) { - return { - ...prev, - [curr.fieldname]: prev[curr.fieldname].concat(curr.url), - }; - } else { - return { - ...prev, - [curr.fieldname]: [curr.url], - }; - } - }, {}); + const imageUrlsByKeys: ImageUrlsByKeys = imageUrls.reduce( + (prev: ImageUrlsByKeys, curr: ImageUrl) => { + if (curr.fieldname in prev) { + return { + ...prev, + [curr.fieldname]: prev[curr.fieldname].concat(curr.url), + }; + } else { + return { + ...prev, + [curr.fieldname]: [curr.url], + }; + } + }, + {} as ImageUrlsByKeys, + ); return imageUrlsByKeys; } catch (e) { diff --git a/apps/api/src/domains/admin/history/history.entity.ts b/apps/api/src/domains/admin/history/history.entity.ts index 1f02e3c53..5305add8b 100644 --- a/apps/api/src/domains/admin/history/history.entity.ts +++ b/apps/api/src/domains/admin/history/history.entity.ts @@ -22,8 +22,11 @@ import { EntityNameEnum } from './history-entity.enum'; @Entity('histories') export class HistoryEntity extends CommonEntity { - @ManyToOne(() => UserEntity, { createForeignKeyConstraints: false }) - user: Relation; + @ManyToOne(() => UserEntity, { + createForeignKeyConstraints: false, + nullable: true, + }) + user: Relation | null; @Column('enum', { enum: EntityNameEnum }) entityName: EntityNameEnum; @@ -44,15 +47,19 @@ export class HistoryEntity extends CommonEntity { action, entity, }: { - userId: number; + userId: number | null | undefined; entityName: EntityNameEnum; entityId: number; action: HistoryActionEnum; entity: object; }) { const history = new HistoryEntity(); - history.user = new UserEntity(); - history.user.id = userId; + if (userId) { + history.user = new UserEntity(); + history.user.id = userId; + } else { + history.user = null; + } history.entityName = entityName; history.entityId = entityId; history.action = action; diff --git a/apps/api/src/domains/admin/history/subscribers/abstract-history.subscriber.ts b/apps/api/src/domains/admin/history/subscribers/abstract-history.subscriber.ts index c2c25e827..44cfddbbd 100644 --- a/apps/api/src/domains/admin/history/subscribers/abstract-history.subscriber.ts +++ b/apps/api/src/domains/admin/history/subscribers/abstract-history.subscriber.ts @@ -58,13 +58,16 @@ export abstract class AbstractHistorySubscriber afterRecover({ entity }: RecoverEvent): void | Promise { this.saveHistory(HistoryActionEnum.Recover, entity); } - private saveHistory(action: HistoryActionEnum, entity: T | ObjectLiteral) { - const userId = this.cls.get('userId'); + private saveHistory( + action: HistoryActionEnum, + entity: T | ObjectLiteral | null | undefined, + ) { + const userId: number = this.cls.get('userId'); if (!entity) return; - this.historyService.createHistory({ + void this.historyService.createHistory({ userId, - entityId: entity.id, + entityId: (entity as CommonEntity).id, entityName: this.entityName, action, entity, diff --git a/apps/api/src/domains/admin/history/subscribers/feedback-issue-history.subscriber.ts b/apps/api/src/domains/admin/history/subscribers/feedback-issue-history.subscriber.ts index 2cc7a0e37..ca9f9f3bc 100644 --- a/apps/api/src/domains/admin/history/subscribers/feedback-issue-history.subscriber.ts +++ b/apps/api/src/domains/admin/history/subscribers/feedback-issue-history.subscriber.ts @@ -46,13 +46,13 @@ export class FeedbackIssueHistorySubscriber private saveHistory(action: HistoryActionEnum) { const userId = this.cls.get('userId'); if (!userId) return; - const data = + const data: { feedbackId: number } | undefined = action === HistoryActionEnum.Create ? this.cls.get('addIssueInFeedback') : this.cls.get('removeIssueInFeedback'); if (!data) return; - this.historyService.createHistory({ + void this.historyService.createHistory({ userId, entityId: data.feedbackId, entityName: EntityNameEnum.FeedbackIssue, diff --git a/apps/api/src/domains/admin/project/api-key/api-key.service.spec.ts b/apps/api/src/domains/admin/project/api-key/api-key.service.spec.ts index 9d0f99e8f..3324feac5 100644 --- a/apps/api/src/domains/admin/project/api-key/api-key.service.spec.ts +++ b/apps/api/src/domains/admin/project/api-key/api-key.service.spec.ts @@ -25,7 +25,7 @@ import { ProjectNotFoundException } from '../project/exceptions'; import { ProjectEntity } from '../project/project.entity'; import { ApiKeyEntity } from './api-key.entity'; import { ApiKeyService } from './api-key.service'; -import type { CreateApiKeyDto } from './dtos'; +import { CreateApiKeyDto } from './dtos'; describe('ApiKeyService', () => { let apiKeyService: ApiKeyService; @@ -48,7 +48,9 @@ describe('ApiKeyService', () => { const projectId = faker.number.int(); jest.spyOn(apiKeyRepo, 'findOneBy').mockResolvedValueOnce(null); - const apiKey = await apiKeyService.create({ projectId }); + const apiKey = await apiKeyService.create( + CreateApiKeyDto.from({ projectId }), + ); expect(apiKey.value).toHaveLength(20); }); @@ -63,12 +65,12 @@ describe('ApiKeyService', () => { }); it('creating an api key fails with an invalid project id', async () => { const invalidProjectId = faker.number.int(); - jest - .spyOn(projectRepo, 'findOneBy') - .mockResolvedValueOnce(null as ProjectEntity); + jest.spyOn(projectRepo, 'findOneBy').mockResolvedValueOnce(null); await expect( - apiKeyService.create({ projectId: invalidProjectId }), + apiKeyService.create( + CreateApiKeyDto.from({ projectId: invalidProjectId }), + ), ).rejects.toThrow(ProjectNotFoundException); }); it('creating an api key fails with an invalid api key', async () => { @@ -128,9 +130,7 @@ describe('ApiKeyService', () => { it('creating api keys fails with an invalid project id', async () => { const invalidProjectId = faker.number.int(); dtos[0].projectId = invalidProjectId; - jest - .spyOn(projectRepo, 'findOneBy') - .mockResolvedValue(null as ProjectEntity); + jest.spyOn(projectRepo, 'findOneBy').mockResolvedValue(null); await expect(apiKeyService.createMany(dtos)).rejects.toThrow( ProjectNotFoundException, diff --git a/apps/api/src/domains/admin/project/api-key/api-key.service.ts b/apps/api/src/domains/admin/project/api-key/api-key.service.ts index e40f8ca97..81468e14c 100644 --- a/apps/api/src/domains/admin/project/api-key/api-key.service.ts +++ b/apps/api/src/domains/admin/project/api-key/api-key.service.ts @@ -98,11 +98,12 @@ export class ApiKeyService { @Transactional() async softDeleteById(id: number) { - const apiKey = await this.repository.findOne({ - where: { - id, - }, - }); + const apiKey = + (await this.repository.findOne({ + where: { + id, + }, + })) ?? new ApiKeyEntity(); await this.repository.save( Object.assign(apiKey, { deletedAt: DateTime.utc().toJSDate() }), @@ -111,12 +112,13 @@ export class ApiKeyService { @Transactional() async recoverById(id: number) { - const apiKey = await this.repository.findOne({ - where: { - id, - }, - withDeleted: true, - }); + const apiKey = + (await this.repository.findOne({ + where: { + id, + }, + withDeleted: true, + })) ?? new ApiKeyEntity(); await this.repository.save(Object.assign(apiKey, { deletedAt: null })); } diff --git a/apps/api/src/domains/admin/project/api-key/dtos/create-api-key.dto.ts b/apps/api/src/domains/admin/project/api-key/dtos/create-api-key.dto.ts index 522b71fb8..3cf056232 100644 --- a/apps/api/src/domains/admin/project/api-key/dtos/create-api-key.dto.ts +++ b/apps/api/src/domains/admin/project/api-key/dtos/create-api-key.dto.ts @@ -22,7 +22,7 @@ export class CreateApiKeyDto { projectId: number; @Expose() - value?: string; + value: string; public static from(params: any): CreateApiKeyDto { return plainToInstance(CreateApiKeyDto, params, { diff --git a/apps/api/src/domains/admin/project/issue-tracker/issue-tracker.controller.spec.ts b/apps/api/src/domains/admin/project/issue-tracker/issue-tracker.controller.spec.ts index 04f6b8747..17ad4dc88 100644 --- a/apps/api/src/domains/admin/project/issue-tracker/issue-tracker.controller.spec.ts +++ b/apps/api/src/domains/admin/project/issue-tracker/issue-tracker.controller.spec.ts @@ -18,7 +18,7 @@ import { Test } from '@nestjs/testing'; import { DataSource } from 'typeorm'; import { getMockProvider, MockDataSource } from '@/test-utils/util-functions'; -import { IssueTrackerDataDto } from './dtos/issue-tracker-data.dto'; +import type { IssueTrackerDataDto } from './dtos/issue-tracker-data.dto'; import { IssueTrackerController } from './issue-tracker.controller'; import { IssueTrackerService } from './issue-tracker.service'; diff --git a/apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id.dto.ts b/apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id.dto.ts index d498b929b..cd7ec3762 100644 --- a/apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id.dto.ts +++ b/apps/api/src/domains/admin/project/issue/dtos/find-issues-by-project-id.dto.ts @@ -21,9 +21,13 @@ export class FindIssuesByProjectIdDto extends PaginationDto { projectId: number; query?: { searchText?: string; - [key: string]: string | string[] | TimeRange | number | number[]; - }; - sort?: { - [key: string]: SortMethodEnum; + [key: string]: + | string + | string[] + | TimeRange + | number + | number[] + | undefined; }; + sort?: Record; } diff --git a/apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request.dto.ts b/apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request.dto.ts index 950898c73..28afbadd5 100644 --- a/apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request.dto.ts +++ b/apps/api/src/domains/admin/project/issue/dtos/requests/find-issues-by-project-id-request.dto.ts @@ -30,7 +30,13 @@ export class FindIssuesByProjectIdRequestDto extends PaginationRequestDto { @IsOptional() query?: { searchText?: string; - [key: string]: string | string[] | TimeRange | number | number[]; + [key: string]: + | string + | string[] + | TimeRange + | number + | number[] + | undefined; }; @ApiProperty({ @@ -40,9 +46,7 @@ export class FindIssuesByProjectIdRequestDto extends PaginationRequestDto { example: { createdAt: 'ASC' }, }) @IsOptional() - sort?: { - [key: string]: SortMethodEnum; - }; + sort?: Record; constructor(limit = 10, page = 1) { super(limit, page); diff --git a/apps/api/src/domains/admin/project/issue/dtos/update-issue.dto.ts b/apps/api/src/domains/admin/project/issue/dtos/update-issue.dto.ts index 724087764..dfadafb4d 100644 --- a/apps/api/src/domains/admin/project/issue/dtos/update-issue.dto.ts +++ b/apps/api/src/domains/admin/project/issue/dtos/update-issue.dto.ts @@ -23,7 +23,7 @@ export class UpdateIssueDto extends CreateIssueDto { issueId: number; @Expose() - description: string; + description: string | null; @Expose() status?: IssueStatusEnum; diff --git a/apps/api/src/domains/admin/project/issue/issue.service.spec.ts b/apps/api/src/domains/admin/project/issue/issue.service.spec.ts index 7cc64c1e2..f3550b0de 100644 --- a/apps/api/src/domains/admin/project/issue/issue.service.spec.ts +++ b/apps/api/src/domains/admin/project/issue/issue.service.spec.ts @@ -16,7 +16,7 @@ import { faker } from '@faker-js/faker'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import type { Repository } from 'typeorm'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { Like } from 'typeorm'; import type { TimeRange } from '@/common/dtos'; @@ -63,10 +63,13 @@ describe('IssueService test suite', () => { it('creating an issue succeeds with valid inputs', async () => { dto.name = faker.string.sample(); - jest.spyOn(issueRepo, 'findOneBy').mockResolvedValue(null as IssueEntity); + jest.spyOn(issueRepo, 'findOneBy').mockResolvedValue(null); jest .spyOn(issueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); const issue = await issueService.create(dto); @@ -105,8 +108,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -122,7 +128,7 @@ describe('IssueService test suite', () => { _objectLiteralParameters: { ...(dto.query.createdAt as TimeRange), }, - }), + }) as TimeRange | string, }, ], }); @@ -137,8 +143,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -151,8 +160,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -176,8 +188,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -189,7 +204,7 @@ describe('IssueService test suite', () => { project: { id: dto.projectId, }, - column: Like(`%${dto.query.column}%`), + column: Like(`%${dto.query.column as string}%`), }, ], }); @@ -201,8 +216,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -238,8 +256,11 @@ describe('IssueService test suite', () => { }; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta } = await issueService.findIssuesByProjectId(dto); @@ -269,7 +290,7 @@ describe('IssueService test suite', () => { project: { id: dto.projectId, }, - id: parseInt(dto.query.searchText), + id: parseInt(dto.query.searchText ?? ''), }, ], }); @@ -288,7 +309,7 @@ describe('IssueService test suite', () => { it('updating an issue succeeds with valid inputs', async () => { dto.name = faker.string.sample(); - jest.spyOn(issueRepo, 'findOne').mockResolvedValue(null as IssueEntity); + jest.spyOn(issueRepo, 'findOne').mockResolvedValue(null); const issue = await issueService.update(dto); diff --git a/apps/api/src/domains/admin/project/issue/issue.service.ts b/apps/api/src/domains/admin/project/issue/issue.service.ts index af24e782c..4becf8f95 100644 --- a/apps/api/src/domains/admin/project/issue/issue.service.ts +++ b/apps/api/src/domains/admin/project/issue/issue.service.ts @@ -122,7 +122,7 @@ export class IssueService { continue; } - andWhere[column] = Like(`%${query[column]}%`); + andWhere[column] = Like(`%${query[column] as string}%`); } if (query.searchText) { @@ -220,10 +220,11 @@ export class IssueService { @Transactional() async deleteById(id: number) { - const issue = await this.repository.findOne({ - where: { id }, - relations: { project: true }, - }); + const issue = + (await this.repository.findOne({ + where: { id }, + relations: { project: true }, + })) ?? new IssueEntity(); await this.issueStatisticsService.updateCount({ projectId: issue.project.id, diff --git a/apps/api/src/domains/admin/project/member/member.service.spec.ts b/apps/api/src/domains/admin/project/member/member.service.spec.ts index 3ef9874ac..50d8a3a58 100644 --- a/apps/api/src/domains/admin/project/member/member.service.spec.ts +++ b/apps/api/src/domains/admin/project/member/member.service.spec.ts @@ -61,7 +61,7 @@ describe('MemberService test suite', () => { jest .spyOn(roleRepo, 'findOne') .mockResolvedValue({ project: { id: projectId } } as RoleEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); await memberService.create(dto); @@ -107,7 +107,7 @@ describe('MemberService test suite', () => { jest .spyOn(roleRepo, 'findOne') .mockResolvedValue({ project: { id: projectId } } as RoleEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); await memberService.createMany(dtos); @@ -175,7 +175,7 @@ describe('MemberService test suite', () => { jest .spyOn(roleRepo, 'findOne') .mockResolvedValue({ project: { id: projectId } } as RoleEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); await expect(memberService.update(dto)).rejects.toThrowError( diff --git a/apps/api/src/domains/admin/project/project/dtos/create-project.dto.ts b/apps/api/src/domains/admin/project/project/dtos/create-project.dto.ts index 250557f65..e8dc2c6b0 100644 --- a/apps/api/src/domains/admin/project/project/dtos/create-project.dto.ts +++ b/apps/api/src/domains/admin/project/project/dtos/create-project.dto.ts @@ -20,7 +20,7 @@ import type { Timezone } from '../project.entity'; export class CreateProjectDto { name: string; - description: string; + description: string | null; timezone: Timezone; roles?: Omit[]; members?: { diff --git a/apps/api/src/domains/admin/project/project/project.entity.ts b/apps/api/src/domains/admin/project/project/project.entity.ts index b4c582289..4f0b9a51f 100644 --- a/apps/api/src/domains/admin/project/project/project.entity.ts +++ b/apps/api/src/domains/admin/project/project/project.entity.ts @@ -46,7 +46,7 @@ export class ProjectEntity extends CommonEntity { name: string; @Column('varchar', { nullable: true }) - description: string; + description: string | null; @Column({ type: 'varchar', @@ -56,8 +56,8 @@ export class ProjectEntity extends CommonEntity { offset: '+09:00', }), transformer: { - from: (value: string) => - typeof value === 'object' ? value : JSON.parse(value), + from: (value: string): object => + typeof value === 'object' ? value : (JSON.parse(value) as object), to: (value: Timezone) => JSON.stringify(value), }, }) @@ -111,7 +111,7 @@ export class ProjectEntity extends CommonEntity { }: { tenantId: number; name: string; - description: string; + description: string | null; timezone: Timezone; }) { const project = new ProjectEntity(); diff --git a/apps/api/src/domains/admin/project/project/project.service.spec.ts b/apps/api/src/domains/admin/project/project/project.service.spec.ts index c8cfad90f..bb1e8548a 100644 --- a/apps/api/src/domains/admin/project/project/project.service.spec.ts +++ b/apps/api/src/domains/admin/project/project/project.service.spec.ts @@ -273,9 +273,7 @@ describe('ProjectService Test suite', () => { it('updating a project succeeds with valid inputs', async () => { const name = faker.string.sample(); dto.name = name; - jest - .spyOn(projectRepo, 'findOne') - .mockResolvedValue(null as ProjectEntity); + jest.spyOn(projectRepo, 'findOne').mockResolvedValue(null); jest.spyOn(projectRepo, 'save'); await projectService.update(dto); diff --git a/apps/api/src/domains/admin/project/project/project.service.ts b/apps/api/src/domains/admin/project/project/project.service.ts index 0f9581f5c..92fa7b91c 100644 --- a/apps/api/src/domains/admin/project/project/project.service.ts +++ b/apps/api/src/domains/admin/project/project/project.service.ts @@ -89,7 +89,11 @@ export class ProjectService { } const members = dto.members.map((member) => ({ userId: member.userId, - roleId: savedRoles.find((role) => role.name === member.roleName).id, + roleId: ( + savedRoles.find((role) => role.name === member.roleName) ?? { + id: 0, + } + ).id, })); const savedMembers = await this.memberService.createMany(members); diff --git a/apps/api/src/domains/admin/project/role/dtos/responses/get-all-roles-response.dto.ts b/apps/api/src/domains/admin/project/role/dtos/responses/get-all-roles-response.dto.ts index b079aed1c..1f4165d2a 100644 --- a/apps/api/src/domains/admin/project/role/dtos/responses/get-all-roles-response.dto.ts +++ b/apps/api/src/domains/admin/project/role/dtos/responses/get-all-roles-response.dto.ts @@ -18,7 +18,7 @@ import { Expose, plainToInstance, Type } from 'class-transformer'; import { PermissionEnum } from '../../permission.enum'; -class GetAllRolesResponseRoleDto { +export class GetAllRolesResponseRoleDto { @Expose() @ApiProperty() id: number; diff --git a/apps/api/src/domains/admin/project/role/permission.guard.ts b/apps/api/src/domains/admin/project/role/permission.guard.ts index 03931f593..137ce1119 100644 --- a/apps/api/src/domains/admin/project/role/permission.guard.ts +++ b/apps/api/src/domains/admin/project/role/permission.guard.ts @@ -20,6 +20,7 @@ import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; import { UserTypeEnum } from '@/domains/admin/user/entities/enums'; +import { UserEntity } from '../../user/entities/user.entity'; import type { PermissionEnum } from './permission.enum'; import { PERMISSIONS_KEY } from './require-permission.decorator'; import { RoleEntity } from './role.entity'; @@ -38,9 +39,12 @@ export class PermissionGuard implements CanActivate { [context.getHandler(), context.getClass()], ); - if (!requiredPermission) return true; - - const { user, params } = context.switchToHttp().getRequest(); + const { + user, + params, + }: { user: UserEntity; params: { projectId: number } } = context + .switchToHttp() + .getRequest(); if (user.type === UserTypeEnum.SUPER) return true; diff --git a/apps/api/src/domains/admin/project/role/role.service.ts b/apps/api/src/domains/admin/project/role/role.service.ts index 79d50c4f0..00c9abbca 100644 --- a/apps/api/src/domains/admin/project/role/role.service.ts +++ b/apps/api/src/domains/admin/project/role/role.service.ts @@ -64,7 +64,7 @@ export class RoleService { async update(id: number, projectId: number, dto: UpdateRoleDto) { const { name, permissions } = dto; - const role = await this.roleRepo.findOneBy({ id }); + const role = (await this.roleRepo.findOneBy({ id })) ?? new RoleEntity(); if ( await this.roleRepo.findOne({ diff --git a/apps/api/src/domains/admin/project/webhook/dtos/create-webhook.dto.ts b/apps/api/src/domains/admin/project/webhook/dtos/create-webhook.dto.ts index a92af7422..aea889f72 100644 --- a/apps/api/src/domains/admin/project/webhook/dtos/create-webhook.dto.ts +++ b/apps/api/src/domains/admin/project/webhook/dtos/create-webhook.dto.ts @@ -34,6 +34,9 @@ export class CreateWebhookDto { @Expose() events: EventDto[]; + @Expose() + token: string | null; + public static from(params: any): CreateWebhookDto { return plainToInstance(CreateWebhookDto, params, { excludeExtraneousValues: true, diff --git a/apps/api/src/domains/admin/project/webhook/dtos/requests/create-webhook-request.dto.ts b/apps/api/src/domains/admin/project/webhook/dtos/requests/create-webhook-request.dto.ts index 7e0038444..6e2496a8f 100644 --- a/apps/api/src/domains/admin/project/webhook/dtos/requests/create-webhook-request.dto.ts +++ b/apps/api/src/domains/admin/project/webhook/dtos/requests/create-webhook-request.dto.ts @@ -17,6 +17,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsArray, IsEnum, IsString } from 'class-validator'; import { WebhookStatusEnum } from '@/common/enums'; +import { TokenValidator } from '@/common/validators/token-validator'; +import { IsNullable } from '@/domains/admin/user/decorators'; import { EventDto } from '..'; export class CreateWebhookRequestDto { @@ -35,4 +37,9 @@ export class CreateWebhookRequestDto { @ApiProperty({ type: [EventDto] }) @IsArray() events: EventDto[]; + + @ApiProperty({ nullable: true }) + @IsNullable() + @TokenValidator() + token: string | null; } diff --git a/apps/api/src/domains/admin/project/webhook/dtos/responses/get-webhook-by-id-response.dto.ts b/apps/api/src/domains/admin/project/webhook/dtos/responses/get-webhook-by-id-response.dto.ts index b4021f8a2..49c37a67f 100644 --- a/apps/api/src/domains/admin/project/webhook/dtos/responses/get-webhook-by-id-response.dto.ts +++ b/apps/api/src/domains/admin/project/webhook/dtos/responses/get-webhook-by-id-response.dto.ts @@ -58,6 +58,10 @@ export class GetWebhookByIdResponseDto { @ApiProperty() url: string; + @Expose() + @ApiProperty() + token: string; + @Expose() @ApiProperty({ type: WebhookStatusEnum, enum: WebhookStatusEnum }) status: WebhookStatusEnum; diff --git a/apps/api/src/domains/admin/project/webhook/event.entity.ts b/apps/api/src/domains/admin/project/webhook/event.entity.ts index 0f1b8fed0..cd4dcf8ab 100644 --- a/apps/api/src/domains/admin/project/webhook/event.entity.ts +++ b/apps/api/src/domains/admin/project/webhook/event.entity.ts @@ -70,7 +70,7 @@ export class EventEntity extends CommonEntity { event.webhook.id = webhookId; } - if (channelIds) { + if (channelIds.length !== 0) { event.channels = channelIds.map((channelId) => { const channel = new ChannelEntity(); channel.id = channelId; diff --git a/apps/api/src/domains/admin/project/webhook/webhook.entity.ts b/apps/api/src/domains/admin/project/webhook/webhook.entity.ts index a8092f96a..4224774ce 100644 --- a/apps/api/src/domains/admin/project/webhook/webhook.entity.ts +++ b/apps/api/src/domains/admin/project/webhook/webhook.entity.ts @@ -28,6 +28,9 @@ export class WebhookEntity extends CommonEntity { @Column('varchar') url: string; + @Column('varchar') + token: string | null; + @Column('enum', { enum: WebhookStatusEnum, default: WebhookStatusEnum.ACTIVE, @@ -45,12 +48,27 @@ export class WebhookEntity extends CommonEntity { }) events: Relation[]; - static from({ projectId, name, url, status, events }) { + static from({ + projectId, + name, + url, + token, + status, + events, + }: { + projectId: number; + name: string; + url: string; + token: string | null; + status: WebhookStatusEnum; + events: EventEntity[]; + }): WebhookEntity { const webhook = new WebhookEntity(); webhook.project = new ProjectEntity(); webhook.project.id = projectId; webhook.name = name; webhook.url = url; + webhook.token = token; webhook.status = status; webhook.events = events; diff --git a/apps/api/src/domains/admin/project/webhook/webhook.listener.spec.ts b/apps/api/src/domains/admin/project/webhook/webhook.listener.spec.ts index 98557744f..610a13c87 100644 --- a/apps/api/src/domains/admin/project/webhook/webhook.listener.spec.ts +++ b/apps/api/src/domains/admin/project/webhook/webhook.listener.spec.ts @@ -59,6 +59,7 @@ describe('webhook listener', () => { { headers: { 'Content-Type': 'application/json', + 'x-webhook-token': 'TEST-TOKEN', }, }, ); @@ -87,6 +88,7 @@ describe('webhook listener', () => { { headers: { 'Content-Type': 'application/json', + 'x-webhook-token': 'TEST-TOKEN', }, }, ); @@ -114,6 +116,7 @@ describe('webhook listener', () => { { headers: { 'Content-Type': 'application/json', + 'x-webhook-token': 'TEST-TOKEN', }, }, ); @@ -142,6 +145,7 @@ describe('webhook listener', () => { { headers: { 'Content-Type': 'application/json', + 'x-webhook-token': 'TEST-TOKEN', }, }, ); diff --git a/apps/api/src/domains/admin/project/webhook/webhook.listener.ts b/apps/api/src/domains/admin/project/webhook/webhook.listener.ts index b11e93bdc..aff6e76cc 100644 --- a/apps/api/src/domains/admin/project/webhook/webhook.listener.ts +++ b/apps/api/src/domains/admin/project/webhook/webhook.listener.ts @@ -14,11 +14,11 @@ * under the License. */ import { HttpService } from '@nestjs/axios'; -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; import { InjectRepository } from '@nestjs/typeorm'; import type { AxiosError } from 'axios'; -import { catchError, lastValueFrom, of } from 'rxjs'; +import { catchError, lastValueFrom, of, retry, tap, timer } from 'rxjs'; import { Repository } from 'typeorm'; import type { IssueStatusEnum } from '@/common/enums'; @@ -51,7 +51,7 @@ export class WebhookListener { }: { webhooks: WebhookEntity[]; event: EventTypeEnum; - data: any; + data: object; }) { await Promise.all( webhooks.map((webhook) => @@ -63,15 +63,30 @@ export class WebhookListener { { headers: { 'Content-Type': 'application/json', + 'x-webhook-token': webhook.token, }, }, ) .pipe( + tap(() => { + this.logger.log( + `Successfully sent webhook to ${webhook.url}(event: ${event}, data: ${JSON.stringify(data)}, token: ${webhook.token})`, + ); + }), + retry({ + count: 3, + delay: (error, retryCount) => { + this.logger.warn( + `Retrying webhook... Attempt #${retryCount + 1}`, + ); + return timer(3000); + }, + }), catchError((error: AxiosError) => { this.logger.error({ message: 'Failed to send webhook', axiosError: - error?.response?.data ? + error.response?.data ? { data: error.response.data, status: error.response.status, @@ -102,6 +117,9 @@ export class WebhookListener { issues: true, }, }); + + if (feedback === null) + throw new NotFoundException(`Feedback ${feedbackId} not found`); const webhooks = await this.webhookRepo.find({ where: { project: { id: feedback.channel.project.id }, @@ -140,7 +158,7 @@ export class WebhookListener { }, }; - this.sendWebhooks({ + void this.sendWebhooks({ webhooks, event: EventTypeEnum.FEEDBACK_CREATION, data, @@ -155,15 +173,16 @@ export class WebhookListener { feedbackId: number; issueId: number; }) { - const feedback = await this.feedbackRepo.findOne({ - where: { id: feedbackId }, - relations: { - channel: { - project: true, + const feedback = + (await this.feedbackRepo.findOne({ + where: { id: feedbackId }, + relations: { + channel: { + project: true, + }, + issues: true, }, - issues: true, - }, - }); + })) ?? new FeedbackEntity(); const webhooks = await this.webhookRepo.find({ where: { project: { id: feedback.channel.project.id }, @@ -204,7 +223,7 @@ export class WebhookListener { addedIssue: issues.find((issue) => issue.id === issueId), }; - this.sendWebhooks({ + void this.sendWebhooks({ webhooks, event: EventTypeEnum.ISSUE_ADDITION, data, @@ -213,12 +232,13 @@ export class WebhookListener { @OnEvent(EventTypeEnum.ISSUE_CREATION) async handleIssueCreation({ issueId }: { issueId: number }) { - const issue = await this.issueRepo.findOne({ - where: { id: issueId }, - relations: { - project: true, - }, - }); + const issue = + (await this.issueRepo.findOne({ + where: { id: issueId }, + relations: { + project: true, + }, + })) ?? new IssueEntity(); const webhooks = await this.webhookRepo.find({ where: { project: { id: issue.project.id }, @@ -246,7 +266,7 @@ export class WebhookListener { }, }; - this.sendWebhooks({ + void this.sendWebhooks({ webhooks, event: EventTypeEnum.ISSUE_CREATION, data, @@ -261,12 +281,13 @@ export class WebhookListener { issueId: number; previousStatus: IssueStatusEnum; }) { - const issue = await this.issueRepo.findOne({ - where: { id: issueId }, - relations: { - project: true, - }, - }); + const issue = + (await this.issueRepo.findOne({ + where: { id: issueId }, + relations: { + project: true, + }, + })) ?? new IssueEntity(); const webhooks = await this.webhookRepo.find({ where: { project: { id: issue.project.id }, @@ -295,7 +316,7 @@ export class WebhookListener { previousStatus, }; - this.sendWebhooks({ + void this.sendWebhooks({ webhooks, event: EventTypeEnum.ISSUE_STATUS_CHANGE, data, diff --git a/apps/api/src/domains/admin/project/webhook/webhook.service.spec.ts b/apps/api/src/domains/admin/project/webhook/webhook.service.spec.ts index a9e0a2177..b1684085e 100644 --- a/apps/api/src/domains/admin/project/webhook/webhook.service.spec.ts +++ b/apps/api/src/domains/admin/project/webhook/webhook.service.spec.ts @@ -39,6 +39,7 @@ function createCreateWebhookDto(overrides = {}): CreateWebhookDto { projectId: webhookFixture.project.id, name: faker.string.sample(), url: faker.internet.url(), + token: faker.string.sample(), status: WebhookStatusEnum.ACTIVE, events: [ { @@ -54,12 +55,12 @@ function createCreateWebhookDto(overrides = {}): CreateWebhookDto { { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.ISSUE_CREATION, - channelIds: null, + channelIds: [], }, { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.ISSUE_STATUS_CHANGE, - channelIds: null, + channelIds: [], }, ], ...overrides, @@ -72,6 +73,7 @@ function createUpdateWebhookDto(overrides = {}): UpdateWebhookDto { projectId: webhookFixture.project.id, name: faker.string.sample(), url: faker.internet.url(), + token: faker.string.sample(), status: getRandomEnumValue(WebhookStatusEnum), events: [ { @@ -87,12 +89,12 @@ function createUpdateWebhookDto(overrides = {}): UpdateWebhookDto { { status: getRandomEnumValue(EventStatusEnum), type: EventTypeEnum.ISSUE_CREATION, - channelIds: null, + channelIds: [], }, { status: getRandomEnumValue(EventStatusEnum), type: EventTypeEnum.ISSUE_STATUS_CHANGE, - channelIds: null, + channelIds: [], }, ], ...overrides, @@ -124,12 +126,13 @@ describe('webhook service', () => { expect(webhook.project.id).toBe(dto.projectId); expect(webhook.name).toBe(dto.name); expect(webhook.url).toBe(dto.url); + expect(webhook.token).toBe(dto.token); expect(webhook.status).toBe(dto.status); expect(webhook.events.length).toBe(dto.events.length); for (let i = 0; i < webhook.events.length; i++) { expect(webhook.events[i].status).toBe(dto.events[i].status); expect(webhook.events[i].type).toBe(dto.events[i].type); - if (dto.events[i].channelIds) { + if (dto.events[i].channelIds.length !== 0) { expect(webhook.events[i].channels[0].id).toBe( dto.events[i].channelIds[0], ); @@ -163,6 +166,7 @@ describe('webhook service', () => { expect(webhook.project.id).toBe(dto.projectId); expect(webhook.name).toBe(dto.name); expect(webhook.url).toBe(dto.url); + expect(webhook.token).toBe(dto.token); expect(webhook.status).toBe(dto.status); expect(webhook.events.length).toBe(dto.events.length); expect(webhook.events[0].channels.length).toBe( @@ -199,7 +203,7 @@ describe('webhook service', () => { { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.FEEDBACK_CREATION, - channelIds: null, + channelIds: [], }, ], }); @@ -215,7 +219,7 @@ describe('webhook service', () => { { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.ISSUE_ADDITION, - channelIds: null, + channelIds: [], }, ], }); @@ -273,12 +277,13 @@ describe('webhook service', () => { expect(webhook.project.id).toBe(dto.projectId); expect(webhook.name).toBe(dto.name); expect(webhook.url).toBe(dto.url); + expect(webhook.token).toBe(dto.token); expect(webhook.status).toBe(dto.status); expect(webhook.events.length).toBe(dto.events.length); for (let i = 0; i < webhook.events.length; i++) { expect(webhook.events[i].status).toBe(dto.events[i].status); expect(webhook.events[i].type).toBe(dto.events[i].type); - if (dto.events[i].channelIds) { + if (dto.events[i].channelIds.length !== 0) { expect(webhook.events[i].channels[0].id).toBe( dto.events[i].channelIds[0], ); @@ -300,7 +305,7 @@ describe('webhook service', () => { { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.FEEDBACK_CREATION, - channelIds: null, + channelIds: [], }, ], }); @@ -320,7 +325,7 @@ describe('webhook service', () => { { status: EventStatusEnum.ACTIVE, type: EventTypeEnum.ISSUE_ADDITION, - channelIds: null, + channelIds: [], }, ], }); diff --git a/apps/api/src/domains/admin/project/webhook/webhook.service.ts b/apps/api/src/domains/admin/project/webhook/webhook.service.ts index 70a61f67a..55f65db3b 100644 --- a/apps/api/src/domains/admin/project/webhook/webhook.service.ts +++ b/apps/api/src/domains/admin/project/webhook/webhook.service.ts @@ -48,10 +48,6 @@ export class WebhookService { ]; if (eventRequiresChannelIds.includes(event.type)) { - if (!event.channelIds) { - return false; - } - const channels = await this.channelRepo.findBy({ id: In(event.channelIds), }); @@ -59,7 +55,7 @@ export class WebhookService { } if (eventExcludesChannelIds.includes(event.type)) { - return !event.channelIds || event.channelIds.length === 0; + return event.channelIds.length === 0; } return false; @@ -92,6 +88,7 @@ export class WebhookService { projectId: dto.projectId, name: dto.name, url: dto.url, + token: dto.token, status: dto.status, events, }); @@ -118,11 +115,12 @@ export class WebhookService { } @Transactional() - async update(dto: UpdateWebhookDto) { - const webhook = await this.repository.findOne({ - where: { id: dto.id }, - relations: ['events'], - }); + async update(dto: UpdateWebhookDto): Promise { + const webhook = + (await this.repository.findOne({ + where: { id: dto.id }, + relations: ['events'], + })) ?? new WebhookEntity(); if ( await this.repository.findOne({ @@ -137,6 +135,7 @@ export class WebhookService { webhook.name = dto.name; webhook.url = dto.url; + webhook.token = dto.token; webhook.status = dto.status; webhook.events = ( await Promise.all( @@ -159,10 +158,11 @@ export class WebhookService { } @Transactional() - async delete(webhookId) { - const webhook = await this.repository.findOne({ - where: { id: webhookId }, - }); + async delete(webhookId: number) { + const webhook = + (await this.repository.findOne({ + where: { id: webhookId }, + })) ?? new WebhookEntity(); await this.repository.remove(webhook); } diff --git a/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.spec.ts b/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.spec.ts index 1b03e73f6..dc23448e5 100644 --- a/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.spec.ts +++ b/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.spec.ts @@ -18,7 +18,7 @@ import { SchedulerRegistry } from '@nestjs/schedule'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { DateTime } from 'luxon'; -import type { Repository } from 'typeorm'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { FeedbackEntity } from '@/domains/admin/feedback/feedback.entity'; import { IssueEntity } from '@/domains/admin/project/issue/issue.entity'; @@ -319,8 +319,11 @@ describe('FeedbackIssueStatisticsService suite', () => { jest.spyOn(feedbackIssueStatsRepo, 'findOne').mockResolvedValue(null); jest .spyOn(feedbackIssueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'values'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'values' as never); await feedbackIssueStatsService.updateFeedbackCount({ issueId, @@ -333,7 +336,7 @@ describe('FeedbackIssueStatisticsService suite', () => { expect(createQueryBuilder.values).toBeCalledTimes(1); expect(createQueryBuilder.values).toBeCalledWith({ date: new Date( - DateTime.fromJSDate(date).plus({ hours: 9 }).toISO().split('T')[0] + + DateTime.fromJSDate(date).plus({ hours: 9 }).toISO()?.split('T')[0] + 'T00:00:00', ), feedbackCount, diff --git a/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.ts b/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.ts index 37f04df2e..15feaa83a 100644 --- a/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.ts +++ b/apps/api/src/domains/admin/statistics/feedback-issue/feedback-issue-statistics.service.ts @@ -27,6 +27,7 @@ import { IssueEntity } from '@/domains/admin/project/issue/issue.entity'; import { ProjectEntity } from '@/domains/admin/project/project/project.entity'; import { LockTypeEnum } from '@/domains/operation/scheduler-lock/lock-type.enum'; import { SchedulerLockService } from '@/domains/operation/scheduler-lock/scheduler-lock.service'; +import { ProjectNotFoundException } from '../../project/project/exceptions'; import { getIntervalDatesInFormat } from '../utils/util-functions'; import { UpdateFeedbackCountDto } from './dtos'; import type { GetCountByDateByIssueDto } from './dtos'; @@ -112,10 +113,11 @@ export class FeedbackIssueStatisticsService { } async addCronJobByProjectId(projectId: number) { - const { timezone } = await this.projectRepository.findOne({ + const project = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + const timezoneOffset = project.timezone.offset; const cronHour = (24 - Number(timezoneOffset.split(':')[0])) % 24; @@ -148,14 +150,12 @@ export class FeedbackIssueStatisticsService { this.logger.log(`feedback-issue-statistics-${projectId} cron job started`); } - async createFeedbackIssueStatistics( - projectId: number, - dayToCreate: number = 1, - ) { - const { timezone } = await this.projectRepository.findOne({ + async createFeedbackIssueStatistics(projectId: number, dayToCreate = 1) { + const project = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; @@ -165,58 +165,60 @@ export class FeedbackIssueStatisticsService { for (let day = 1; day <= dayToCreate; day++) { for (const issue of issues) { - await this.repository.manager - .transaction(async (transactionalEntityManager) => { - const feedbackCount = await this.feedbackRepository.count({ - where: { - issues: { id: issue.id }, - createdAt: Between( - DateTime.utc() - .minus({ days: day }) - .startOf('day') - .minus({ hours: offset }) - .toJSDate(), - DateTime.utc() - .minus({ days: day }) - .endOf('day') - .minus({ hours: offset }) - .toJSDate(), - ), - }, - }); - - if (feedbackCount === 0) return; - - await transactionalEntityManager - .createQueryBuilder() - .insert() - .into(FeedbackIssueStatisticsEntity) - .values({ - date: - offset >= 0 ? + try { + await this.repository.manager.transaction( + async (transactionalEntityManager) => { + const feedbackCount = await this.feedbackRepository.count({ + where: { + issues: { id: issue.id }, + createdAt: Between( DateTime.utc() .minus({ days: day }) - .endOf('day') + .startOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd') - : DateTime.utc() + .toJSDate(), + DateTime.utc() .minus({ days: day }) - .startOf('day') + .endOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd'), - issue: { id: issue.id }, - feedbackCount, - }) - .orUpdate(['feedback_count'], ['date', 'issue']) - .updateEntity(false) - .execute(); - }) - .catch((error) => { - this.logger.error({ - message: 'Failed to create feedback issue statistics', - error, - }); + .toJSDate(), + ), + }, + }); + + if (feedbackCount === 0) return; + + await transactionalEntityManager + .createQueryBuilder() + .insert() + .into(FeedbackIssueStatisticsEntity) + .values({ + date: + offset >= 0 ? + DateTime.utc() + .minus({ days: day }) + .endOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd') + : DateTime.utc() + .minus({ days: day }) + .startOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd'), + issue: { id: issue.id }, + feedbackCount, + }) + .orUpdate(['feedback_count'], ['date', 'issue']) + .updateEntity(false) + .execute(); + }, + ); + } catch (error) { + this.logger.error({ + message: 'Failed to create feedback issue statistics', + error: error as Error, }); + } } } } @@ -226,10 +228,11 @@ export class FeedbackIssueStatisticsService { if (dto.feedbackCount === 0) return; if (!dto.feedbackCount) dto.feedbackCount = 1; - const { timezone } = await this.projectRepository.findOne({ + const project = await this.projectRepository.findOne({ where: { issues: { id: dto.issueId } }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; @@ -237,7 +240,7 @@ export class FeedbackIssueStatisticsService { DateTime.fromJSDate(dto.date) .plus({ hours: offset }) .toISO() - .split('T')[0] + 'T00:00:00', + ?.split('T')[0] + 'T00:00:00', ); const stats = await this.repository.findOne({ diff --git a/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.spec.ts b/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.spec.ts index b930d4305..c337f4dc4 100644 --- a/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.spec.ts +++ b/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.spec.ts @@ -18,7 +18,7 @@ import { SchedulerRegistry } from '@nestjs/schedule'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { DateTime } from 'luxon'; -import type { Repository } from 'typeorm'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { ChannelEntity } from '@/domains/admin/channel/channel/channel.entity'; import { FeedbackEntity } from '@/domains/admin/feedback/feedback.entity'; @@ -261,10 +261,13 @@ describe('FeedbackStatisticsService suite', () => { dto.projectId = projectId; jest .spyOn(issueRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); jest - .spyOn(createQueryBuilder, 'getRawMany') - .mockResolvedValue(feedbackStatsFixture); + .spyOn(createQueryBuilder, 'getRawMany' as never) + .mockResolvedValue(feedbackStatsFixture as never); jest .spyOn(feedbackRepo, 'count') .mockResolvedValue(feedbackStatsFixture.length); @@ -373,8 +376,11 @@ describe('FeedbackStatisticsService suite', () => { jest.spyOn(feedbackStatsRepo, 'findOne').mockResolvedValue(null); jest .spyOn(feedbackStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'values'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'values' as never); await feedbackStatsService.updateCount({ channelId, @@ -387,7 +393,7 @@ describe('FeedbackStatisticsService suite', () => { expect(createQueryBuilder.values).toBeCalledTimes(1); expect(createQueryBuilder.values).toBeCalledWith({ date: new Date( - DateTime.fromJSDate(date).plus({ hours: 9 }).toISO().split('T')[0] + + DateTime.fromJSDate(date).plus({ hours: 9 }).toISO()?.split('T')[0] + 'T00:00:00', ), count, diff --git a/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.ts b/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.ts index 8d2cf20d5..549b1000a 100644 --- a/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.ts +++ b/apps/api/src/domains/admin/statistics/feedback/feedback-statistics.service.ts @@ -28,6 +28,7 @@ import { IssueEntity } from '@/domains/admin/project/issue/issue.entity'; import { ProjectEntity } from '@/domains/admin/project/project/project.entity'; import { LockTypeEnum } from '@/domains/operation/scheduler-lock/lock-type.enum'; import { SchedulerLockService } from '@/domains/operation/scheduler-lock/scheduler-lock.service'; +import { ProjectNotFoundException } from '../../project/project/exceptions'; import { getIntervalDatesInFormat } from '../utils/util-functions'; import { UpdateCountDto } from './dtos'; import type { @@ -155,10 +156,12 @@ export class FeedbackStatisticsService { } async addCronJobByProjectId(projectId: number) { - const { timezone } = await this.projectRepository.findOne({ + const project = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + + const timezoneOffset = project.timezone.offset; const cronHour = (24 - Number(timezoneOffset.split(':')[0])) % 24; @@ -189,10 +192,11 @@ export class FeedbackStatisticsService { } async createFeedbackStatistics(projectId: number, dayToCreate = 1) { - const { timezone } = await this.projectRepository.findOne({ + const project = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; @@ -202,58 +206,60 @@ export class FeedbackStatisticsService { for (let day = 1; day <= dayToCreate; day++) { for (const channel of channels) { - await this.repository.manager - .transaction(async (transactionalEntityManager) => { - const feedbackCount = await this.feedbackRepository.count({ - where: { - channel: { id: channel.id }, - createdAt: Between( - DateTime.utc() - .minus({ days: day }) - .startOf('day') - .minus({ hours: offset }) - .toJSDate(), - DateTime.utc() - .minus({ days: day }) - .endOf('day') - .minus({ hours: offset }) - .toJSDate(), - ), - }, - }); - - if (feedbackCount === 0) return; - - await transactionalEntityManager - .createQueryBuilder() - .insert() - .into(FeedbackStatisticsEntity) - .values({ - date: - offset >= 0 ? + try { + await this.repository.manager.transaction( + async (transactionalEntityManager) => { + const feedbackCount = await this.feedbackRepository.count({ + where: { + channel: { id: channel.id }, + createdAt: Between( DateTime.utc() .minus({ days: day }) - .endOf('day') + .startOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd') - : DateTime.utc() + .toJSDate(), + DateTime.utc() .minus({ days: day }) - .startOf('day') + .endOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd'), - count: feedbackCount, - channel: { id: channel.id }, - }) - .orUpdate(['count'], ['date', 'channel']) - .updateEntity(false) - .execute(); - }) - .catch((error) => { - this.logger.error({ - message: 'Failed to create feedback statistics', - error, - }); + .toJSDate(), + ), + }, + }); + + if (feedbackCount === 0) return; + + await transactionalEntityManager + .createQueryBuilder() + .insert() + .into(FeedbackStatisticsEntity) + .values({ + date: + offset >= 0 ? + DateTime.utc() + .minus({ days: day }) + .endOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd') + : DateTime.utc() + .minus({ days: day }) + .startOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd'), + count: feedbackCount, + channel: { id: channel.id }, + }) + .orUpdate(['count'], ['date', 'channel']) + .updateEntity(false) + .execute(); + }, + ); + } catch (error) { + this.logger.error({ + message: 'Failed to create feedback statistics', + error: error as Error, }); + } } } } @@ -263,10 +269,11 @@ export class FeedbackStatisticsService { if (dto.count === 0) return; if (!dto.count) dto.count = 1; - const { timezone } = await this.projectRepository.findOne({ + const project = await this.projectRepository.findOne({ where: { channels: { id: dto.channelId } }, }); - const timezoneOffset = timezone.offset; + if (project === null) throw new ProjectNotFoundException(); + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; @@ -274,7 +281,7 @@ export class FeedbackStatisticsService { DateTime.fromJSDate(dto.date) .plus({ hours: offset }) .toISO() - .split('T')[0] + 'T00:00:00', + ?.split('T')[0] + 'T00:00:00', ); const stats = await this.repository.findOne({ diff --git a/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.spec.ts b/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.spec.ts index d18f1eb41..603d60b2d 100644 --- a/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.spec.ts +++ b/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.spec.ts @@ -18,7 +18,7 @@ import { SchedulerRegistry } from '@nestjs/schedule'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; import { DateTime } from 'luxon'; -import type { Repository } from 'typeorm'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { IssueEntity } from '@/domains/admin/project/issue/issue.entity'; import { ProjectEntity } from '@/domains/admin/project/project/project.entity'; @@ -302,8 +302,11 @@ describe('IssueStatisticsService suite', () => { jest.spyOn(issueStatsRepo, 'findOne').mockResolvedValue(null); jest .spyOn(issueStatsRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'values'); + .mockImplementation( + () => + createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'values' as never); await issueStatsService.updateCount({ projectId, @@ -316,7 +319,7 @@ describe('IssueStatisticsService suite', () => { expect(createQueryBuilder.values).toBeCalledTimes(1); expect(createQueryBuilder.values).toBeCalledWith({ date: new Date( - DateTime.fromJSDate(date).plus({ hours: 9 }).toISO().split('T')[0] + + DateTime.fromJSDate(date).plus({ hours: 9 }).toISO()?.split('T')[0] + 'T00:00:00', ), count, diff --git a/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.ts b/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.ts index e5391dbd2..b1e990bdd 100644 --- a/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.ts +++ b/apps/api/src/domains/admin/statistics/issue/issue-statistics.service.ts @@ -13,7 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ -import { Injectable, Logger } from '@nestjs/common'; +import { Injectable, Logger, NotFoundException } from '@nestjs/common'; import { SchedulerRegistry } from '@nestjs/schedule'; import { InjectRepository } from '@nestjs/typeorm'; import { CronJob } from 'cron'; @@ -37,6 +37,10 @@ import { IssueStatisticsEntity } from './issue-statistics.entity'; dotenv.config(); +interface IssueEntityWithCount extends IssueEntity { + count: string; +} + @Injectable() export class IssueStatisticsService { private logger = new Logger(IssueStatisticsService.name); @@ -114,16 +118,24 @@ export class IssueStatisticsService { .groupBy('issue.status') .getRawMany() .then((res) => - res.map((stat) => ({ status: stat.status, count: +stat.count })), + res.map((stat: IssueEntityWithCount) => ({ + status: stat.status, + count: +stat.count, + })), ), }; } async addCronJobByProjectId(projectId: number) { - const { timezone } = await this.projectRepository.findOne({ + const project: ProjectEntity | null = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + + if (project === null) { + throw new NotFoundException(`Project(id: ${projectId}) not found`); + } + + const timezoneOffset = project.timezone.offset; const cronHour = (24 - Number(timezoneOffset.split(':')[0])) % 24; @@ -153,67 +165,74 @@ export class IssueStatisticsService { this.logger.log(`issue-statistics-${projectId} cron job started`); } - async createIssueStatistics(projectId: number, dayToCreate: number = 1) { - const { timezone, id } = await this.projectRepository.findOne({ + async createIssueStatistics(projectId: number, dayToCreate = 1) { + const project: ProjectEntity | null = await this.projectRepository.findOne({ where: { id: projectId }, }); - const timezoneOffset = timezone.offset; + + if (project === null) { + throw new NotFoundException(`Project(id: ${projectId}) not found`); + } + + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; for (let day = 1; day <= dayToCreate; day++) { - await this.repository.manager - .transaction(async (transactionalEntityManager) => { - const issueCount = await this.issueRepository.count({ - where: { - project: { id }, - createdAt: Between( - DateTime.utc() - .minus({ days: day }) - .startOf('day') - .minus({ hours: offset }) - .toJSDate(), - DateTime.utc() - .minus({ days: day }) - .endOf('day') - .minus({ hours: offset }) - .toJSDate(), - ), - }, - }); - - if (issueCount === 0) return; - - await transactionalEntityManager - .createQueryBuilder() - .insert() - .into(IssueStatisticsEntity) - .values({ - date: - offset >= 0 ? + try { + await this.repository.manager.transaction( + async (transactionalEntityManager) => { + const issueCount = await this.issueRepository.count({ + where: { + project: { id: project.id }, + createdAt: Between( DateTime.utc() .minus({ days: day }) - .endOf('day') + .startOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd') - : DateTime.utc() + .toJSDate(), + DateTime.utc() .minus({ days: day }) - .startOf('day') + .endOf('day') .minus({ hours: offset }) - .toFormat('yyyy-MM-dd'), - count: issueCount, - project: { id }, - }) - .orUpdate(['count'], ['date', 'project']) - .updateEntity(false) - .execute(); - }) - .catch((error) => { - this.logger.error({ - message: 'Failed to create issue statistics', - error, - }); + .toJSDate(), + ), + }, + }); + + if (issueCount === 0) return; + + await transactionalEntityManager + .createQueryBuilder() + .insert() + .into(IssueStatisticsEntity) + .values({ + date: + offset >= 0 ? + DateTime.utc() + .minus({ days: day }) + .endOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd') + : DateTime.utc() + .minus({ days: day }) + .startOf('day') + .minus({ hours: offset }) + .toFormat('yyyy-MM-dd'), + count: issueCount, + project: { id: project.id }, + }) + .orUpdate(['count'], ['date', 'project']) + .updateEntity(false) + .execute(); + }, + ); + } catch (error) { + this.logger.error({ + message: 'Failed to create issue statistics', + error: error as Error, }); + } } } @@ -222,10 +241,14 @@ export class IssueStatisticsService { if (dto.count === 0) return; if (!dto.count) dto.count = 1; - const { timezone } = await this.projectRepository.findOne({ + const project: ProjectEntity | null = await this.projectRepository.findOne({ where: { id: dto.projectId }, }); - const timezoneOffset = timezone.offset; + + if (project === null) { + throw new NotFoundException(`Project(id: ${dto.projectId}) not found`); + } + const timezoneOffset = project.timezone.offset; const [hours, minutes] = timezoneOffset.split(':'); const offset = Number(hours) + Number(minutes) / 60; @@ -233,7 +256,7 @@ export class IssueStatisticsService { DateTime.fromJSDate(dto.date) .plus({ hours: offset }) .toISO() - .split('T')[0] + 'T00:00:00', + ?.split('T')[0] + 'T00:00:00', ); const stats = await this.repository.findOne({ diff --git a/apps/api/src/domains/admin/tenant/tenant.entity.ts b/apps/api/src/domains/admin/tenant/tenant.entity.ts index b8391b8c0..707becb7c 100644 --- a/apps/api/src/domains/admin/tenant/tenant.entity.ts +++ b/apps/api/src/domains/admin/tenant/tenant.entity.ts @@ -48,7 +48,7 @@ export class TenantEntity extends CommonEntity { isRestrictDomain: boolean; @Column('simple-array', { nullable: true }) - allowDomains: Array | null; + allowDomains: string[] | null; @Column('boolean', { default: false }) useOAuth: boolean; diff --git a/apps/api/src/domains/admin/tenant/tenant.service.ts b/apps/api/src/domains/admin/tenant/tenant.service.ts index a36642df8..c5213bd1f 100644 --- a/apps/api/src/domains/admin/tenant/tenant.service.ts +++ b/apps/api/src/domains/admin/tenant/tenant.service.ts @@ -44,8 +44,8 @@ export class TenantService { @Transactional() async create(dto: SetupTenantDto) { - const [tenant] = await this.tenantRepo.find({ take: 1 }); - if (tenant) throw new TenantAlreadyExistsException(); + const tenants = await this.tenantRepo.find({ take: 1 }); + if (tenants.length > 0) throw new TenantAlreadyExistsException(); const newTenant = new TenantEntity(); const savedTenant = await this.tenantRepo.save( Object.assign(newTenant, dto), @@ -68,12 +68,12 @@ export class TenantService { } async findOne() { - const [tenant] = await this.tenantRepo.find(); - if (!tenant) throw new TenantNotFoundException(); + const tenants = await this.tenantRepo.find(); + if (tenants.length === 0) throw new TenantNotFoundException(); return { - ...tenant, - useEmailVerification: this.configService.get('smtp.use'), + ...tenants[0], + useEmailVerification: this.configService.get('smtp.use'), }; } diff --git a/apps/api/src/domains/admin/user/create-user.service.spec.ts b/apps/api/src/domains/admin/user/create-user.service.spec.ts index 8595bf449..dad96e13b 100644 --- a/apps/api/src/domains/admin/user/create-user.service.spec.ts +++ b/apps/api/src/domains/admin/user/create-user.service.spec.ts @@ -59,7 +59,7 @@ describe('CreateUserService', () => { const dto: CreateOAuthUserDto = { email: faker.internet.email(), }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); tenantRepo.setIsRestrictDomain(false); const user = await createUserService.createOAuthUser(dto); @@ -100,7 +100,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.GENERAL, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -115,7 +115,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.SUPER, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -130,7 +130,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.GENERAL, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(createUserService.createInvitationUser(dto)).rejects.toThrow( NotAllowedDomainException, @@ -142,7 +142,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.SUPER, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(createUserService.createInvitationUser(dto)).rejects.toThrow( NotAllowedDomainException, @@ -156,10 +156,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.GENERAL, roleId, }; - jest - .spyOn(userRepo, 'findOneBy') - .mockResolvedValueOnce(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValueOnce(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); @@ -178,8 +176,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.SUPER, roleId, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); @@ -212,7 +210,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.GENERAL, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -227,7 +225,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.SUPER, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -244,8 +242,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.GENERAL, roleId, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); @@ -264,8 +262,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.SUPER, roleId, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); @@ -288,7 +286,7 @@ describe('CreateUserService', () => { email: faker.internet.email().split('@')[0] + '@linecorp.com', password: faker.internet.password(), }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createEmailUser(dto); @@ -302,7 +300,7 @@ describe('CreateUserService', () => { email: faker.internet.email().split('@')[0] + '@invalid.com', password: faker.internet.password(), }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(createUserService.createEmailUser(dto)).rejects.toThrow( NotAllowedDomainException, @@ -314,7 +312,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.GENERAL, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -329,7 +327,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.SUPER, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); const user = await createUserService.createInvitationUser(dto); @@ -344,7 +342,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.GENERAL, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(createUserService.createInvitationUser(dto)).rejects.toThrow( NotAllowedDomainException, @@ -356,7 +354,7 @@ describe('CreateUserService', () => { password: faker.internet.password(), type: UserTypeEnum.SUPER, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(createUserService.createInvitationUser(dto)).rejects.toThrow( NotAllowedDomainException, @@ -370,8 +368,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.GENERAL, roleId, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); @@ -390,8 +388,8 @@ describe('CreateUserService', () => { type: UserTypeEnum.SUPER, roleId, }; - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); - jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null as MemberEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); + jest.spyOn(memberRepo, 'findOne').mockResolvedValue(null); jest.spyOn(memberRepo, 'save'); const user = await createUserService.createInvitationUser(dto); diff --git a/apps/api/src/domains/admin/user/create-user.service.ts b/apps/api/src/domains/admin/user/create-user.service.ts index 5dfc64ee8..08a7c5afd 100644 --- a/apps/api/src/domains/admin/user/create-user.service.ts +++ b/apps/api/src/domains/admin/user/create-user.service.ts @@ -85,7 +85,10 @@ export class CreateUserService { const tenant = await this.tenantService.findOne(); // check restrict domain const domain = email.split('@')[1]; - if (tenant.isRestrictDomain && !tenant.allowDomains.includes(domain)) { + if ( + tenant.isRestrictDomain && + !(tenant.allowDomains ?? []).includes(domain) + ) { throw new NotAllowedDomainException(); } diff --git a/apps/api/src/domains/admin/user/decorators/current-user.decorator.ts b/apps/api/src/domains/admin/user/decorators/current-user.decorator.ts index 011366316..cd08c2be0 100644 --- a/apps/api/src/domains/admin/user/decorators/current-user.decorator.ts +++ b/apps/api/src/domains/admin/user/decorators/current-user.decorator.ts @@ -16,12 +16,17 @@ import type { ExecutionContext } from '@nestjs/common'; import { createParamDecorator } from '@nestjs/common'; +import type { UserDto } from '../dtos/user.dto'; + type DataType = 'id'; +interface Request { + user: UserDto | null; +} export const CurrentUser = createParamDecorator( (data: DataType, ctx: ExecutionContext) => { - const { user } = ctx.switchToHttp().getRequest(); + const { user } = ctx.switchToHttp().getRequest(); if (!user) return null; - return data ? user[data] : user; + return data in user ? user[data] : user; }, ); diff --git a/apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts b/apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts index 6b41796c1..314080caf 100644 --- a/apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts +++ b/apps/api/src/domains/admin/user/dtos/find-all-users.dto.ts @@ -22,8 +22,8 @@ export class FindAllUsersDto { options: IPaginationOptions; query?: { email?: string; - name?: string; - department?: string; + name?: string | null; + department?: string | null; type?: UserTypeEnum; projectId?: number; }; diff --git a/apps/api/src/domains/admin/user/dtos/user.dto.ts b/apps/api/src/domains/admin/user/dtos/user.dto.ts index 7cfda1773..d6568775b 100644 --- a/apps/api/src/domains/admin/user/dtos/user.dto.ts +++ b/apps/api/src/domains/admin/user/dtos/user.dto.ts @@ -25,7 +25,7 @@ export class UserDto { @Expose() @ApiProperty() - email: string; + email: string | null; @Expose() @ApiProperty() diff --git a/apps/api/src/domains/admin/user/super-user.guard.ts b/apps/api/src/domains/admin/user/super-user.guard.ts index 66761be2f..f35ed3710 100644 --- a/apps/api/src/domains/admin/user/super-user.guard.ts +++ b/apps/api/src/domains/admin/user/super-user.guard.ts @@ -17,11 +17,15 @@ import type { CanActivate, ExecutionContext } from '@nestjs/common'; import { Injectable } from '@nestjs/common'; import { UserTypeEnum } from './entities/enums'; +import { UserEntity } from './entities/user.entity'; +interface Request { + user: UserEntity | null; +} @Injectable() export class SuperUserGuard implements CanActivate { canActivate(context: ExecutionContext): boolean { - const { user } = context.switchToHttp().getRequest(); + const { user } = context.switchToHttp().getRequest(); if (!user) return false; diff --git a/apps/api/src/domains/admin/user/user-password.service.spec.ts b/apps/api/src/domains/admin/user/user-password.service.spec.ts index c0dfca71e..370bb1fc8 100644 --- a/apps/api/src/domains/admin/user/user-password.service.spec.ts +++ b/apps/api/src/domains/admin/user/user-password.service.spec.ts @@ -56,7 +56,7 @@ describe('UserPasswordService', () => { }); it('sending a reset password mail fails with invalid email', async () => { const email = faker.internet.email(); - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect( userPasswordService.sendResetPasswordMail(email), @@ -85,7 +85,7 @@ describe('UserPasswordService', () => { dto.email = faker.internet.email(); dto.code = faker.string.sample(); dto.password = faker.internet.password(); - jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOneBy').mockResolvedValue(null); await expect(userPasswordService.resetPassword(dto)).rejects.toThrow( UserNotFoundException, diff --git a/apps/api/src/domains/admin/user/user-password.service.ts b/apps/api/src/domains/admin/user/user-password.service.ts index c5a4e61f9..5a9f6ce92 100644 --- a/apps/api/src/domains/admin/user/user-password.service.ts +++ b/apps/api/src/domains/admin/user/user-password.service.ts @@ -72,9 +72,10 @@ export class UserPasswordService { @Transactional() async changePassword(dto: ChangePasswordDto) { const { newPassword, password, userId } = dto; - const user = await this.userRepo.findOneBy({ - id: userId, - }); + const user = + (await this.userRepo.findOneBy({ + id: userId, + })) ?? new UserEntity(); const originHashPassword = user.hashPassword; if (!bcrypt.compareSync(password, originHashPassword)) { diff --git a/apps/api/src/domains/admin/user/user.controller.spec.ts b/apps/api/src/domains/admin/user/user.controller.spec.ts index f2e0289af..fae725f94 100644 --- a/apps/api/src/domains/admin/user/user.controller.spec.ts +++ b/apps/api/src/domains/admin/user/user.controller.spec.ts @@ -59,56 +59,56 @@ describe('user controller', () => { it('to be defined', () => { expect(userController).toBeDefined(); }); - it('getAllUsers', () => { + it('getAllUsers', async () => { jest.spyOn(MockUserService, 'findAll').mockResolvedValue([]); - userController.getAllUsers({ limit: 10, page: 1 }); + await userController.getAllUsers({ limit: 10, page: 1 }); expect(MockUserService.findAll).toHaveBeenCalledTimes(1); }); - it('deleteUsers', () => { - userController.deleteUsers({ ids: [1] }); + it('deleteUsers', async () => { + await userController.deleteUsers({ ids: [1] }); expect(MockUserService.deleteUsers).toHaveBeenCalledTimes(1); }); - it('inviteUser', () => { + it('inviteUser', async () => { const userDto = new UserDto(); userDto.id = faker.number.int(); - userController.inviteUser(new UserInvitationRequestDto(), userDto); + await userController.inviteUser(new UserInvitationRequestDto(), userDto); expect(MockUserService.sendInvitationCode).toHaveBeenCalledTimes(1); }); - it('requestResetPassword', () => { - userController.requestResetPassword('email'); + it('requestResetPassword', async () => { + await userController.requestResetPassword('email'); expect(MockUserPasswordService.sendResetPasswordMail).toHaveBeenCalledTimes( 1, ); }); - it('resetPassword', () => { - userController.resetPassword(new ResetPasswordRequestDto()); + it('resetPassword', async () => { + await userController.resetPassword(new ResetPasswordRequestDto()); expect(MockUserPasswordService.resetPassword).toHaveBeenCalledTimes(1); }); - it('changePassword', () => { - userController.changePassword( + it('changePassword', async () => { + await userController.changePassword( new UserDto(), new ChangePasswordRequestDto(), ); expect(MockUserPasswordService.changePassword).toHaveBeenCalledTimes(1); }); - it('getUser', () => { + it('getUser', async () => { const userDto = new UserDto(); userDto.id = faker.number.int(); - userController.getUser(userDto.id, userDto); + await userController.getUser(userDto.id, userDto); expect(MockUserService.findById).toHaveBeenCalledTimes(1); expect(MockUserService.findById).toHaveBeenCalledWith(userDto.id); }); describe('deleteUser', () => { - it('positive', () => { + it('positive', async () => { const userDto = new UserDto(); userDto.id = faker.number.int(); - userController.deleteUser(userDto.id, userDto); + await userController.deleteUser(userDto.id, userDto); expect(MockUserService.deleteById).toHaveBeenCalledTimes(1); expect(MockUserService.deleteById).toHaveBeenCalledWith(userDto.id); @@ -117,7 +117,7 @@ describe('user controller', () => { const userDto = new UserDto(); userDto.id = faker.number.int(); - expect( + void expect( userController.deleteUser(faker.number.int(), userDto), ).rejects.toThrow(UnauthorizedException); }); diff --git a/apps/api/src/domains/admin/user/user.controller.ts b/apps/api/src/domains/admin/user/user.controller.ts index 57c36ca1b..8f2acd5a6 100644 --- a/apps/api/src/domains/admin/user/user.controller.ts +++ b/apps/api/src/domains/admin/user/user.controller.ts @@ -102,7 +102,7 @@ export class UserController { @Param('id', ParseIntPipe) id: number, @CurrentUser() user: UserDto, ) { - if (id !== user?.id) throw new UnauthorizedException(''); + if (id !== user.id) throw new UnauthorizedException(''); return UserDto.transform(await this.userService.findById(id)); } diff --git a/apps/api/src/domains/admin/user/user.service.spec.ts b/apps/api/src/domains/admin/user/user.service.spec.ts index 2c1a4b8f5..a06ea0839 100644 --- a/apps/api/src/domains/admin/user/user.service.spec.ts +++ b/apps/api/src/domains/admin/user/user.service.spec.ts @@ -16,7 +16,7 @@ import { faker } from '@faker-js/faker'; import { Test } from '@nestjs/testing'; import { getRepositoryToken } from '@nestjs/typeorm'; -import type { Repository } from 'typeorm'; +import type { Repository, SelectQueryBuilder } from 'typeorm'; import { Like } from 'typeorm'; import { SortMethodEnum } from '@/common/enums'; @@ -71,8 +71,10 @@ describe('UserService', () => { }; jest .spyOn(userRepo, 'createQueryBuilder') - .mockImplementation(() => createQueryBuilder); - jest.spyOn(createQueryBuilder, 'setFindOptions'); + .mockImplementation( + () => createQueryBuilder as unknown as SelectQueryBuilder, + ); + jest.spyOn(createQueryBuilder, 'setFindOptions' as never); const { meta: { currentPage, itemCount }, @@ -120,19 +122,23 @@ describe('UserService', () => { const result = await userService.findById(userId); expect(userRepo.findOne).toBeCalledTimes(1); - expect(userRepo.findOne).toBeCalledWith({ where: { id: userId } }); + expect(userRepo.findOne).toBeCalledWith({ + where: { id: userId }, + }); expect(result).toMatchObject({ id: userId }); }); it('finding by an id fails with a nonexistent id', async () => { const userId = faker.number.int(); - jest.spyOn(userRepo, 'findOne').mockResolvedValue(null as UserEntity); + jest.spyOn(userRepo, 'findOne').mockResolvedValue(null); await expect(userService.findById(userId)).rejects.toThrow( UserNotFoundException, ); expect(userRepo.findOne).toBeCalledTimes(1); - expect(userRepo.findOne).toBeCalledWith({ where: { id: userId } }); + expect(userRepo.findOne).toBeCalledWith({ + where: { id: userId }, + }); }); }); describe('sendInvitationCode', () => { diff --git a/apps/api/src/domains/admin/user/user.service.ts b/apps/api/src/domains/admin/user/user.service.ts index b66ae9d05..03014766e 100644 --- a/apps/api/src/domains/admin/user/user.service.ts +++ b/apps/api/src/domains/admin/user/user.service.ts @@ -35,6 +35,11 @@ import { UserNotFoundException, } from './exceptions'; +interface ValueRange { + lt: string | number; + gte: string | number; +} + @Injectable() export class UserService { constructor( @@ -53,7 +58,7 @@ export class UserService { return { ...prev, members: { role: { project: { id: value } } } }; } if (key === 'createdAt') { - const { lt, gte } = value as any; + const { lt, gte } = value as unknown as ValueRange; return { ...prev, createdAt: Raw((alias) => `${alias} >= :gte AND ${alias} < :lt`, { @@ -121,7 +126,7 @@ export class UserService { const code = await this.codeService.setCode({ type: CodeTypeEnum.USER_INVITATION, key: email, - data: { roleId, userType, invitedBy }, + data: { roleId: roleId ?? 0, userType, invitedBy }, durationSec: 60 * 60 * 24, }); await this.userInvitationMailingService.send({ code, email }); @@ -139,18 +144,22 @@ export class UserService { async validateEmail(email: string) { const tenant = await this.tenantService.findOne(); const domain = email.split('@')[1]; - if (tenant.isRestrictDomain && !tenant.allowDomains.includes(domain)) { + if (tenant.isRestrictDomain && !tenant.allowDomains?.includes(domain)) { throw new NotAllowedDomainException(); } return true; } async findRolesById(id: number) { - const { members } = await this.userRepo.findOne({ + const user = await this.userRepo.findOne({ where: { id }, select: { members: true }, relations: { members: { role: { project: true } } }, }); + if (user === null) { + throw new UserNotFoundException(); + } + const { members } = user; return members.map((v) => v.role); } } diff --git a/apps/api/src/domains/api/api.controller.ts b/apps/api/src/domains/api/api.controller.ts index e5e59cbc6..957a50c3c 100644 --- a/apps/api/src/domains/api/api.controller.ts +++ b/apps/api/src/domains/api/api.controller.ts @@ -13,29 +13,16 @@ * License for the specific language governing permissions and limitations * under the License. */ -import { HttpService } from '@nestjs/axios'; import { Controller, Get, Req, Res } from '@nestjs/common'; import { ApiExcludeController } from '@nestjs/swagger'; import { FastifyReply, FastifyRequest } from 'fastify'; -import { lastValueFrom } from 'rxjs'; @Controller() @ApiExcludeController() export class APIController { - constructor(private readonly httpService: HttpService) {} - @Get('docs/redoc') - async getAPIDocs( - @Req() request: FastifyRequest, - @Res() reply: FastifyReply, - ): Promise { + getAPIDocs(@Req() request: FastifyRequest, @Res() reply: FastifyReply) { const { hostname } = request; - let specUrl = `https://${hostname}/docs-json`; - try { - await lastValueFrom(this.httpService.head(specUrl)); - } catch (e) { - specUrl = `http://${hostname}/docs-json`; - } const html = ` @@ -57,10 +44,10 @@ export class APIController { - + `; - reply.type('text/html').send(html); + void reply.type('text/html').send(html); } } diff --git a/apps/api/src/domains/api/feedback.controller.ts b/apps/api/src/domains/api/feedback.controller.ts index 6d3de8839..a2a4de471 100644 --- a/apps/api/src/domains/api/feedback.controller.ts +++ b/apps/api/src/domains/api/feedback.controller.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import { Multipart, MultipartFile } from '@fastify/multipart'; import { BadRequestException, Body, @@ -49,6 +50,13 @@ import { } from '../admin/feedback/dtos/responses'; import { FeedbackService } from '../admin/feedback/feedback.service'; +interface File { + fieldname: string; + buffer: Buffer; + mimetype: string; + originalname: string; +} + @ApiTags('feedbacks') @Controller('/projects/:projectId/channels/:channelId') @ApiSecurity('apiKey') @@ -167,16 +175,21 @@ export class FeedbackController { throw new BadRequestException('Invalid channel id'); } - const files = []; + const files: File[] = []; const body = {}; - const parts = await request.parts(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + const parts = (await request.parts()) as AsyncIterableIterator< + Multipart | MultipartFile + >; for await (const part of parts) { if (part.type === 'file') { if (part.mimetype.includes('image') === false) { throw new BadRequestException(`Not Image File (${part.mimetype})`); } const buffer = await part.toBuffer(); + const mimes = filetypemime(buffer).map((mime) => mime.mime); + if (mimes.includes(part.mimetype) === false) { throw new BadRequestException( `Invalid file (sent type: ${ diff --git a/apps/api/src/domains/operation/scheduler-lock/scheduler-lock.service.ts b/apps/api/src/domains/operation/scheduler-lock/scheduler-lock.service.ts index 0293008b7..1e92eb587 100644 --- a/apps/api/src/domains/operation/scheduler-lock/scheduler-lock.service.ts +++ b/apps/api/src/domains/operation/scheduler-lock/scheduler-lock.service.ts @@ -24,22 +24,29 @@ import type { ConfigServiceType } from '@/types/config-service.type'; import { LockTypeEnum } from './lock-type.enum'; import { SchedulerLockEntity } from './scheduler-lock.entity'; +interface AppConfig { + serverId?: string | undefined; +} + @Injectable() export class SchedulerLockService { - private readonly serverId: string; + private readonly serverId: string | undefined; constructor( @InjectRepository(SchedulerLockEntity) private readonly repository: Repository, private readonly configService: ConfigService, ) { - this.serverId = this.configService.get('app', { infer: true }).serverId; + const appConfig: AppConfig | undefined = this.configService.get('app', { + infer: true, + }); + this.serverId = appConfig?.serverId; } @Transactional() async acquireLock( lockType: LockTypeEnum, lockTTLInMilliseconds: number, - ): Promise { + ): Promise { const expiryTime = DateTime.utc() .plus({ milliseconds: lockTTLInMilliseconds }) .toJSDate(); diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index 1d19e4e49..515826303 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -80,7 +80,11 @@ async function bootstrap() { SwaggerModule.setup('docs', app, document); const configService = app.get(ConfigService); - const { port, address } = configService.get('app', { infer: true }); + const { port, address }: { port: number; address: string } = + configService.get('app', { infer: true }) ?? { + port: 4000, + address: 'localhost', + }; await app.listen(port, address); DefaultLogger.log(`🚀 Application is running on: ${await app.getUrl()}`); diff --git a/apps/api/src/shared/code/code.entity.ts b/apps/api/src/shared/code/code.entity.ts index 2e20c675f..1be335936 100644 --- a/apps/api/src/shared/code/code.entity.ts +++ b/apps/api/src/shared/code/code.entity.ts @@ -32,8 +32,8 @@ export class CodeEntity extends CommonEntity { @Column('varchar', { nullable: true, transformer: { - from: (v) => (v ? JSON.parse(v) : v), - to: (v) => (v ? JSON.stringify(v) : v), + from: (v) => (v ? (JSON.parse(v as string) as object) : (v as object)), + to: (v) => (v ? JSON.stringify(v as object) : (v as object)), }, }) data: any; diff --git a/apps/api/src/shared/code/code.service.spec.ts b/apps/api/src/shared/code/code.service.spec.ts index 53ad6c779..a932abd6a 100644 --- a/apps/api/src/shared/code/code.service.spec.ts +++ b/apps/api/src/shared/code/code.service.spec.ts @@ -135,7 +135,7 @@ describe('CodeService', () => { }); describe('verifyCode', () => { const key = faker.string.sample(); - beforeEach(async () => { + beforeEach(() => { codeRepo.setType(CodeTypeEnum.EMAIL_VEIRIFICATION); codeRepo.setIsVerified(false); }); diff --git a/apps/api/src/shared/code/code.service.ts b/apps/api/src/shared/code/code.service.ts index e1b5b66ec..c2c47ebb0 100644 --- a/apps/api/src/shared/code/code.service.ts +++ b/apps/api/src/shared/code/code.service.ts @@ -44,8 +44,9 @@ export class CodeService { const code = this.createCode(); - const codeEntity = - (await this.codeRepo.findOneBy({ key, type })) || new CodeEntity(); + let codeEntity = await this.codeRepo.findOneBy({ key, type }); + + if (codeEntity === null) codeEntity = new CodeEntity(); await this.codeRepo.save( Object.assign(codeEntity, { @@ -97,12 +98,12 @@ export class CodeService { type: CodeTypeEnum.USER_INVITATION, code: string, ): Promise { - const codeEntity = await this.codeRepo.findOneBy({ + const codeEntity: CodeEntity | null = await this.codeRepo.findOneBy({ type, code, }); if (!codeEntity) throw new NotFoundException('code not found'); - return codeEntity.data; + return codeEntity.data as SetCodeUserInvitationDataDto; } async checkVerified(type: CodeTypeEnum, key: string) { diff --git a/apps/api/src/shared/mailing/email-verification-mailing.service.ts b/apps/api/src/shared/mailing/email-verification-mailing.service.ts index 21ecc2305..d52c1b3f3 100644 --- a/apps/api/src/shared/mailing/email-verification-mailing.service.ts +++ b/apps/api/src/shared/mailing/email-verification-mailing.service.ts @@ -27,7 +27,9 @@ export class EmailVerificationMailingService { private readonly mailerService: MailerService, private readonly configService: ConfigService, ) { - this.baseUrl = this.configService.get('smtp', { infer: true }).baseUrl; + this.baseUrl = + (this.configService.get('smtp', { infer: true }) ?? { baseUrl: '' }) + .baseUrl ?? ''; } async send({ code, email }: SendMailDto) { await this.mailerService.sendMail({ diff --git a/apps/api/src/shared/mailing/reset-password-mailing.service.ts b/apps/api/src/shared/mailing/reset-password-mailing.service.ts index 46b44e81e..bcf19a18e 100644 --- a/apps/api/src/shared/mailing/reset-password-mailing.service.ts +++ b/apps/api/src/shared/mailing/reset-password-mailing.service.ts @@ -27,7 +27,9 @@ export class ResetPasswordMailingService { private readonly mailerService: MailerService, private readonly configService: ConfigService, ) { - this.baseUrl = this.configService.get('smtp', { infer: true }).baseUrl; + this.baseUrl = + (this.configService.get('smtp', { infer: true }) ?? { baseUrl: '' }) + .baseUrl ?? ''; } async send({ code, email }: SendMailDto) { await this.mailerService.sendMail({ diff --git a/apps/api/src/shared/mailing/user-invitation-mailing.service.ts b/apps/api/src/shared/mailing/user-invitation-mailing.service.ts index 8097dec72..a5f35e78c 100644 --- a/apps/api/src/shared/mailing/user-invitation-mailing.service.ts +++ b/apps/api/src/shared/mailing/user-invitation-mailing.service.ts @@ -27,7 +27,9 @@ export class UserInvitationMailingService { private readonly mailerService: MailerService, private readonly configService: ConfigService, ) { - this.baseUrl = this.configService.get('smtp', { infer: true }).baseUrl; + this.baseUrl = + (this.configService.get('smtp', { infer: true }) ?? { baseUrl: '' }) + .baseUrl ?? ''; } async send({ code, email }: SendMailDto) { diff --git a/apps/api/src/test-utils/fixtures.ts b/apps/api/src/test-utils/fixtures.ts index 08c1b761c..10dcf2141 100644 --- a/apps/api/src/test-utils/fixtures.ts +++ b/apps/api/src/test-utils/fixtures.ts @@ -57,9 +57,9 @@ import { import type { UserEntity } from '@/domains/admin/user/entities/user.entity'; export const createFieldEntity = (input: Partial) => { - const format = input?.format ?? getRandomEnumValue(FieldFormatEnum); - const property = input?.property ?? getRandomEnumValue(FieldPropertyEnum); - const status = input?.status ?? getRandomEnumValue(FieldStatusEnum); + const format = input.format ?? getRandomEnumValue(FieldFormatEnum); + const property = input.property ?? getRandomEnumValue(FieldPropertyEnum); + const status = input.status ?? getRandomEnumValue(FieldStatusEnum); return { name: faker.string.alphanumeric(20), description: faker.lorem.lines(2), @@ -73,10 +73,10 @@ export const createFieldEntity = (input: Partial) => { ...input, }; }; -export const createFieldDto = (input: Partial) => { - const format = input?.format ?? getRandomEnumValue(FieldFormatEnum); - const property = input?.property ?? getRandomEnumValue(FieldPropertyEnum); - const status = input?.status ?? getRandomEnumValue(FieldStatusEnum); +export const createFieldDto = (input: Partial = {}) => { + const format = input.format ?? getRandomEnumValue(FieldFormatEnum); + const property = input.property ?? getRandomEnumValue(FieldPropertyEnum); + const status = input.status ?? getRandomEnumValue(FieldStatusEnum); return { name: faker.string.alphanumeric(20), key: faker.string.alphanumeric(20), @@ -108,7 +108,7 @@ export const createIssueDto = (input: Partial) => { export const getRandomValue = ( format: FieldFormatEnum, options?: { id: number; name: string; key: string }[], -) => { +): string | number | string[] | number[] => { switch (format) { case FieldFormatEnum.text: return faker.string.sample(); @@ -117,11 +117,11 @@ export const getRandomValue = ( case FieldFormatEnum.number: return faker.number.int(); case FieldFormatEnum.select: - return options.length === 0 ? - undefined + return !options || options.length === 0 ? + [] : options[faker.number.int({ min: 0, max: options.length - 1 })].key; case FieldFormatEnum.multiSelect: - return options.length === 0 ? + return !options || options.length === 0 ? [] : faker.helpers .shuffle(options) @@ -155,18 +155,23 @@ const getRandomOptionDtos = () => { }); }; -export const getRandomEnumValue = (anEnum: T): T[keyof T] => { - const enumValues = Object.keys(anEnum) as Array; +export const getRandomEnumValue = (anEnum: T): T[keyof T] => { + const enumValues = Object.keys(anEnum) as (keyof T)[]; const randomIndex = faker.number.int(enumValues.length - 1); const randomEnumKey = enumValues[randomIndex]; return anEnum[randomEnumKey]; }; -export const getRandomEnumValues = (anEnum: T): T[keyof T][] => { - const enumValues = Object.values(anEnum) as Array; +export const getRandomEnumValues = ( + anEnum: T, +): T[keyof T][] => { + const enumValues = Object.values(anEnum); return faker.helpers.arrayElements(enumValues) as T[keyof T][]; }; -export const optionSort = (a, b) => +export const optionSort = ( + a: { id: number; name: string }, + b: { id: number; name: string }, +) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0; @@ -191,6 +196,10 @@ export const tenantFixture = { oauthConfig: null, createdAt: faker.date.past(), updatedAt: faker.date.past(), + projects: [], + deletedAt: new Date(0), + beforeInsertHook: jest.fn(), + beforeUpdateHook: jest.fn(), } as TenantEntity; export const projectFixture = { @@ -336,6 +345,9 @@ export const feedbackFixture = { updatedAt: faker.date.past(), channel: channelFixture, issues: [], + deletedAt: new Date(0), + beforeInsertHook: jest.fn(), + beforeUpdateHook: jest.fn(), } as FeedbackEntity; export const eventFixture = { @@ -358,6 +370,7 @@ export const webhookFixture = { id: faker.number.int(), name: faker.string.sample(), url: faker.internet.url(), + token: 'TEST-TOKEN', status: WebhookStatusEnum.ACTIVE, project: projectFixture, events: getAllEvents(), diff --git a/apps/api/src/test-utils/providers/auth.service.providers.ts b/apps/api/src/test-utils/providers/auth.service.providers.ts index 4c7269574..2b72e7543 100644 --- a/apps/api/src/test-utils/providers/auth.service.providers.ts +++ b/apps/api/src/test-utils/providers/auth.service.providers.ts @@ -15,7 +15,7 @@ */ import { HttpService } from '@nestjs/axios'; import { JwtService } from '@nestjs/jwt'; -import { ClsService } from 'nestjs-cls'; +import { ClsModule } from 'nestjs-cls'; import { EmailVerificationMailingService } from '@/shared/mailing/email-verification-mailing.service'; @@ -50,7 +50,7 @@ export const AuthServiceProviders = [ ...TenantServiceProviders, ...RoleServiceProviders, ...MemberServiceProviders, - ClsService, + ClsModule, { provide: HttpService, useValue: { diff --git a/apps/api/src/test-utils/providers/feedback.service.providers.ts b/apps/api/src/test-utils/providers/feedback.service.providers.ts index 40f653b52..0059b632a 100644 --- a/apps/api/src/test-utils/providers/feedback.service.providers.ts +++ b/apps/api/src/test-utils/providers/feedback.service.providers.ts @@ -15,7 +15,7 @@ */ import { EventEmitter2 } from '@nestjs/event-emitter'; import { getRepositoryToken } from '@nestjs/typeorm'; -import { ClsService } from 'nestjs-cls'; +import { ClsModule } from 'nestjs-cls'; import { OpensearchRepository } from '@/common/repositories'; import { FeedbackEntity } from '@/domains/admin/feedback/feedback.entity'; @@ -41,7 +41,7 @@ export const FeedbackServiceProviders = [ provide: getRepositoryToken(FeedbackEntity), useClass: FeedbackRepositoryStub, }, - ClsService, + ClsModule, ...FieldServiceProviders, ...IssueServiceProviders, ...OptionServiceProviders, diff --git a/apps/api/src/test-utils/stubs/api-key-repository.stub.ts b/apps/api/src/test-utils/stubs/api-key-repository.stub.ts index d02f5c4d9..171292328 100644 --- a/apps/api/src/test-utils/stubs/api-key-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/api-key-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { ApiKeyEntity } from '@/domains/admin/project/api-key/api-key.entity'; import { apiKeyFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class ApiKeyRepositoryStub { - apiKey = apiKeyFixture; + apiKey: ApiKeyEntity | null = apiKeyFixture; findOne() { return this.apiKey; } diff --git a/apps/api/src/test-utils/stubs/channel-repository.stub.ts b/apps/api/src/test-utils/stubs/channel-repository.stub.ts index 228f12d6d..8d02ead40 100644 --- a/apps/api/src/test-utils/stubs/channel-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/channel-repository.stub.ts @@ -13,11 +13,12 @@ * License for the specific language governing permissions and limitations * under the License. */ +import { ChannelEntity } from '@/domains/admin/channel/channel/channel.entity'; import { channelFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class ChannelRepositoryStub { - channel = channelFixture; + channel: ChannelEntity | null = channelFixture; findOne() { return this.channel; } @@ -59,7 +60,7 @@ export class ChannelRepositoryStub { } setImageConfig(config) { - this.channel.imageConfig = config; + if (this.channel) this.channel.imageConfig = config; } setNull() { diff --git a/apps/api/src/test-utils/stubs/code-repository.stub.ts b/apps/api/src/test-utils/stubs/code-repository.stub.ts index 8ac3a6d6b..1673b5d39 100644 --- a/apps/api/src/test-utils/stubs/code-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/code-repository.stub.ts @@ -16,12 +16,13 @@ import { faker } from '@faker-js/faker'; import type { CodeTypeEnum } from '@/shared/code/code-type.enum'; +import { CodeEntity } from '@/shared/code/code.entity'; import { codeFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class CodeRepositoryStub { - code = codeFixture; + code: CodeEntity | null = codeFixture; findOne() { return this.code; } @@ -75,15 +76,15 @@ export class CodeRepositoryStub { } setIsVerified(bool) { - this.code.isVerified = bool; + if (this.code) this.code.isVerified = bool; } setType(type: CodeTypeEnum) { - this.code.type = type; + if (this.code) this.code.type = type; } setTryCount(tryCount) { - this.code.tryCount = tryCount; + if (this.code) this.code.tryCount = tryCount; } createQueryBuilder() { diff --git a/apps/api/src/test-utils/stubs/event-repository.stub.ts b/apps/api/src/test-utils/stubs/event-repository.stub.ts index decc1961a..3062ca45c 100644 --- a/apps/api/src/test-utils/stubs/event-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/event-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { EventEntity } from '@/domains/admin/project/webhook/event.entity'; import { eventFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class EventRepositoryStub { - event = eventFixture; + event: EventEntity | null = eventFixture; findOne() { return this.event; } diff --git a/apps/api/src/test-utils/stubs/field-repository.stub.ts b/apps/api/src/test-utils/stubs/field-repository.stub.ts index c84561a97..3b7c0ccff 100644 --- a/apps/api/src/test-utils/stubs/field-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/field-repository.stub.ts @@ -15,12 +15,13 @@ */ import { faker } from '@faker-js/faker'; +import { FieldEntity } from '@/domains/admin/channel/field/field.entity'; import { fieldsFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class FieldRepositoryStub { - field = fieldsFixture[0]; - fields = fieldsFixture; + field: FieldEntity | null = fieldsFixture[0]; + fields: FieldEntity[] = fieldsFixture; findOne() { return this.field; } diff --git a/apps/api/src/test-utils/stubs/issue-repository.stub.ts b/apps/api/src/test-utils/stubs/issue-repository.stub.ts index 085effc87..1c4229625 100644 --- a/apps/api/src/test-utils/stubs/issue-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/issue-repository.stub.ts @@ -16,11 +16,12 @@ import { faker } from '@faker-js/faker'; import { IssueStatusEnum } from '@/common/enums'; +import { IssueEntity } from '@/domains/admin/project/issue/issue.entity'; import { issueFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class IssueRepositoryStub { - issue = issueFixture; + issue: IssueEntity | null = issueFixture; findOne() { return this.issue; } @@ -59,8 +60,8 @@ export class IssueRepositoryStub { return { ...this.issue, ...issueToSave, - status: issueToSave.status || IssueStatusEnum.INIT, - feedbackCount: issueToSave.feedbackCount || 0, + status: (issueToSave as IssueEntity).status || IssueStatusEnum.INIT, + feedbackCount: (issueToSave as IssueEntity).feedbackCount || 0, }; } } diff --git a/apps/api/src/test-utils/stubs/issue-tracker-repository.stub.ts b/apps/api/src/test-utils/stubs/issue-tracker-repository.stub.ts index f1b035ae5..e6287aaad 100644 --- a/apps/api/src/test-utils/stubs/issue-tracker-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/issue-tracker-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { IssueTrackerEntity } from '@/domains/admin/project/issue-tracker/issue-tracker.entity'; import { issueTrackerFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class IssueTrackerRepositoryStub { - issueTracker = issueTrackerFixture; + issueTracker: IssueTrackerEntity | null = issueTrackerFixture; findOne() { return this.issueTracker; } diff --git a/apps/api/src/test-utils/stubs/member-repository.stub.ts b/apps/api/src/test-utils/stubs/member-repository.stub.ts index c3a29d72d..caba27751 100644 --- a/apps/api/src/test-utils/stubs/member-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/member-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { MemberEntity } from '@/domains/admin/project/member/member.entity'; import { memberFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class MemberRepositoryStub { - member = memberFixture; + member: MemberEntity | null = memberFixture; findOne() { return this.member; } @@ -51,11 +52,11 @@ export class MemberRepositoryStub { ...this.member, ...e, role: { - ...this.member.role, + ...this.member?.role, ...e.role, }, user: { - ...this.member.user, + ...this.member?.user, ...e.user, }, id: faker.number.int(), @@ -64,12 +65,12 @@ export class MemberRepositoryStub { return { ...this.member, role: { - ...this.member.role, - ...memberToSave.role, + ...this.member?.role, + ...(memberToSave as MemberEntity).role, }, user: { - ...this.member.user, - ...memberToSave.user, + ...this.member?.user, + ...(memberToSave as MemberEntity).user, }, ...memberToSave, }; diff --git a/apps/api/src/test-utils/stubs/option-repository.stub.ts b/apps/api/src/test-utils/stubs/option-repository.stub.ts index 47b440e8a..f7fd2d080 100644 --- a/apps/api/src/test-utils/stubs/option-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/option-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { OptionEntity } from '@/domains/admin/channel/option/option.entity'; import { optionFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class OptionRepositoryStub { - option = optionFixture; + option: OptionEntity | null = optionFixture; findOne() { return this.option; } diff --git a/apps/api/src/test-utils/stubs/project-repository.stub.ts b/apps/api/src/test-utils/stubs/project-repository.stub.ts index 59bef58cb..42536715f 100644 --- a/apps/api/src/test-utils/stubs/project-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/project-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { ProjectEntity } from '@/domains/admin/project/project/project.entity'; import { projectFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class ProjectRepositoryStub { - project = projectFixture; + project: ProjectEntity | null = projectFixture; findOne() { return this.project; } diff --git a/apps/api/src/test-utils/stubs/role-repository.stub.ts b/apps/api/src/test-utils/stubs/role-repository.stub.ts index e3e17c8f1..e9110f449 100644 --- a/apps/api/src/test-utils/stubs/role-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/role-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { RoleEntity } from '@/domains/admin/project/role/role.entity'; import { roleFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class RoleRepositoryStub { - role = roleFixture; + role: RoleEntity | null = roleFixture; findOne() { return this.role; } diff --git a/apps/api/src/test-utils/stubs/tenant-repository.stub.ts b/apps/api/src/test-utils/stubs/tenant-repository.stub.ts index 9866769e2..77479fc4c 100644 --- a/apps/api/src/test-utils/stubs/tenant-repository.stub.ts +++ b/apps/api/src/test-utils/stubs/tenant-repository.stub.ts @@ -15,11 +15,12 @@ */ import { faker } from '@faker-js/faker'; +import { TenantEntity } from '@/domains/admin/tenant/tenant.entity'; import { tenantFixture } from '../fixtures'; import { createQueryBuilder, removeUndefinedValues } from '../util-functions'; export class TenantRepositoryStub { - tenant = tenantFixture; + tenant: TenantEntity | null = tenantFixture; findOne() { return this.tenant; } @@ -64,18 +65,24 @@ export class TenantRepositoryStub { return 1; } - setIsRestrictDomain(bool, domains = []) { - this.tenant.isRestrictDomain = bool; - this.tenant.allowDomains = domains; + setIsRestrictDomain(bool, domains: string[] = []) { + if (this.tenant) { + this.tenant.isRestrictDomain = bool; + this.tenant.allowDomains = domains; + } } setIsPrivate(bool) { - this.tenant.isPrivate = bool; + if (this.tenant) { + this.tenant.isPrivate = bool; + } } setUseOAuth(bool, config) { - this.tenant.useOAuth = bool; - this.tenant.oauthConfig = config; + if (this.tenant) { + this.tenant.useOAuth = bool; + this.tenant.oauthConfig = config; + } } setNull() { diff --git a/apps/api/src/test-utils/util-functions.ts b/apps/api/src/test-utils/util-functions.ts index d728d7caa..8bc5620e8 100644 --- a/apps/api/src/test-utils/util-functions.ts +++ b/apps/api/src/test-utils/util-functions.ts @@ -50,14 +50,16 @@ export const MockDataSource = { initialize: jest.fn(), }; -export const getRandomEnumValue = (anEnum: T): T[keyof T] => { - const enumValues = Object.keys(anEnum) as Array; +export const getRandomEnumValue = (anEnum: T): T[keyof T] => { + const enumValues = Object.keys(anEnum) as (keyof T)[]; const randomIndex = faker.number.int(enumValues.length - 1); const randomEnumKey = enumValues[randomIndex]; return anEnum[randomEnumKey]; }; -export const getRandomEnumValues = (anEnum: T): T[keyof T][] => { - const enumValues = Object.values(anEnum) as Array; +export const getRandomEnumValues = ( + anEnum: T, +): T[keyof T][] => { + const enumValues = Object.values(anEnum); return faker.helpers.arrayElements(enumValues) as T[keyof T][]; }; @@ -84,7 +86,7 @@ export const signInTestUser = async ( export const DEFAULT_FIELD_COUNT = 2; -export const createQueryBuilder: any = { +export const createQueryBuilder: Record = { setFindOptions: () => jest.fn().mockImplementation(() => createQueryBuilder), select: () => createQueryBuilder, innerJoin: () => createQueryBuilder, @@ -121,7 +123,7 @@ export const mockRepository = () => ({ createQueryBuilder: jest.fn(() => createQueryBuilder), query: jest.fn(), manager: { - transaction: async () => jest.fn().mockImplementation(mockRepository), + transaction: () => jest.fn().mockImplementation(mockRepository), }, }); @@ -135,10 +137,10 @@ export const MockOpensearchRepository = { getTotal: jest.fn(), }; -export function removeUndefinedValues(obj) { +export function removeUndefinedValues(obj: object): object { Object.keys(obj).forEach((key) => { if (obj[key] && typeof obj[key] === 'object') { - removeUndefinedValues(obj[key]); + removeUndefinedValues(obj[key] as object); } else if (obj[key] === undefined) { delete obj[key]; } diff --git a/apps/api/src/utils/validate-unique.ts b/apps/api/src/utils/validate-unique.ts index c27c0eb57..9114cb658 100644 --- a/apps/api/src/utils/validate-unique.ts +++ b/apps/api/src/utils/validate-unique.ts @@ -13,6 +13,8 @@ * License for the specific language governing permissions and limitations * under the License. */ -export const validateUnique = (objList: T[], name: keyof T) => { - return new Set(objList.map((v) => v[name])).size === objList.length; +export const validateUnique = (objList: T[] | undefined, name: keyof T) => { + return ( + new Set((objList ?? []).map((v) => v[name])).size === (objList ?? []).length + ); }; diff --git a/apps/api/test/auth.e2e-spec.ts b/apps/api/test/auth.e2e-spec.ts index e5e822dcc..c805d8842 100644 --- a/apps/api/test/auth.e2e-spec.ts +++ b/apps/api/test/auth.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -35,8 +36,10 @@ import { EmailVerificationMailingRequestDto, InvitationUserSignUpRequestDto, } from '@/domains/admin/auth/dtos/requests'; +import type { SignInResponseDto } from '@/domains/admin/auth/dtos/responses/sign-in-response.dto'; import type { RoleEntity } from '@/domains/admin/project/role/role.entity'; import { TenantEntity } from '@/domains/admin/tenant/tenant.entity'; +import { UserDto } from '@/domains/admin/user/dtos/user.dto'; import { UserStateEnum, UserTypeEnum, @@ -45,6 +48,13 @@ import { UserEntity } from '@/domains/admin/user/entities/user.entity'; import { UserPasswordService } from '@/domains/admin/user/user-password.service'; import { clearEntities } from '@/test-utils/util-functions'; +interface JwtPayload { + sub: number; + email: string; + permissions: string[]; + roleName: string; +} + describe('AppController (e2e)', () => { let app: INestApplication; @@ -98,7 +108,7 @@ describe('AppController (e2e)', () => { const dto = new EmailVerificationMailingRequestDto(); dto.email = faker.internet.email(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/email/code') .send(dto) .expect(201) @@ -116,7 +126,7 @@ describe('AppController (e2e)', () => { const dto = new EmailVerificationMailingRequestDto(); dto.email = user.email; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/email/code') .send(dto) .expect(400); @@ -139,15 +149,15 @@ describe('AppController (e2e)', () => { dto.code = code; const originalCode = await codeRepo.findOneBy({ code }); - expect(originalCode.isVerified).toEqual(false); + expect(originalCode?.isVerified).toEqual(false); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .post('/auth/email/code/verify') .send(dto) .expect(200); const updatedCode = await codeRepo.findOneBy({ code }); - expect(updatedCode.isVerified).toEqual(true); + expect(updatedCode?.isVerified).toEqual(true); }); it('invalid code', async () => { const dto = new EmailVerificationCodeRequestDto(); @@ -155,15 +165,15 @@ describe('AppController (e2e)', () => { dto.code = faker.string.sample(); const originalCode = await codeRepo.findOneBy({ code }); - expect(originalCode.isVerified).toEqual(false); + expect(originalCode?.isVerified).toEqual(false); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/email/code/verify') .send(dto) .expect(400) .then(async () => { const updatedCode = await codeRepo.findOneBy({ code }); - expect(updatedCode.isVerified).toEqual(false); + expect(updatedCode?.isVerified).toEqual(false); }); }); it('invalid email', async () => { @@ -171,7 +181,7 @@ describe('AppController (e2e)', () => { dto.email = faker.internet.email(); dto.code = code; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/email/code/verify') .send(dto) .expect(404); @@ -192,7 +202,7 @@ describe('AppController (e2e)', () => { key: email, }); - beforeEach(async () => { + beforeEach(() => { email = faker.internet.email(); }); @@ -204,7 +214,7 @@ describe('AppController (e2e)', () => { dto.email = email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/email') .send(dto) .expect(201) @@ -219,7 +229,7 @@ describe('AppController (e2e)', () => { dto.email = faker.internet.email(); dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/email') .send(dto) .expect(400); @@ -232,7 +242,7 @@ describe('AppController (e2e)', () => { dto.email = faker.internet.email(); dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/email') .send(dto) .expect(400); @@ -251,7 +261,7 @@ describe('AppController (e2e)', () => { dto.email = email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/email') .send(dto) .expect(400); @@ -263,7 +273,11 @@ describe('AppController (e2e)', () => { await codeService.setCode({ type: CodeTypeEnum.USER_INVITATION, key: email, - data: { roleId: 1, userType: UserTypeEnum.GENERAL, invitedBy: null }, + data: { + roleId: 1, + userType: UserTypeEnum.GENERAL, + invitedBy: new UserDto(), + }, }); beforeEach(() => { @@ -276,7 +290,7 @@ describe('AppController (e2e)', () => { dto.code = code; dto.email = email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/invitation') .send(dto) .expect(201); @@ -287,7 +301,7 @@ describe('AppController (e2e)', () => { dto.email = email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/invitation') .send(dto) .expect(400); @@ -300,7 +314,7 @@ describe('AppController (e2e)', () => { dto.email = email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/invitation') .send(dto) .expect(400); @@ -313,7 +327,7 @@ describe('AppController (e2e)', () => { dto.email = faker.internet.email(); dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signUp/invitation') .send(dto) .expect(400); @@ -337,7 +351,7 @@ describe('AppController (e2e)', () => { dto.email = userEntity.email; dto.password = password; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signIn/email') .send(dto) .expect(201) @@ -345,7 +359,10 @@ describe('AppController (e2e)', () => { expect(body).toHaveProperty('accessToken'); expect(body).toHaveProperty('refreshToken'); - const payload = jwtService.verify(body.accessToken); + const payload = jwtService.verify( + (body as SignInResponseDto).accessToken, + ); + expect(payload.sub).toEqual(userEntity.id); expect(payload).toHaveProperty('email'); expect(payload).toHaveProperty('permissions'); @@ -358,7 +375,7 @@ describe('AppController (e2e)', () => { dto.email = faker.internet.email(); dto.password = password; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signIn/email') .send(dto) .expect(404); @@ -369,7 +386,7 @@ describe('AppController (e2e)', () => { dto.email = userEntity.email; dto.password = faker.internet.password(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/auth/signIn/email') .send(dto) .expect(401); diff --git a/apps/api/test/feedback/channel.e2e-spec.ts b/apps/api/test/feedback/channel.e2e-spec.ts index 6ee7c69cd..52dcddd8b 100644 --- a/apps/api/test/feedback/channel.e2e-spec.ts +++ b/apps/api/test/feedback/channel.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -36,6 +37,9 @@ import { CreateChannelRequestDto, UpdateChannelRequestDto, } from '@/domains/admin/channel/channel/dtos/requests'; +import type { CreateChannelResponseDto } from '@/domains/admin/channel/channel/dtos/responses/create-channel-response.dto'; +import type { FindChannelByIdResponseDto } from '@/domains/admin/channel/channel/dtos/responses/find-channel-by-id-response.dto'; +import type { FindChannelsByProjectIdResponseDto } from '@/domains/admin/channel/channel/dtos/responses/find-channels-by-id-response.dto'; import { FieldEntity } from '@/domains/admin/channel/field/field.entity'; import { FIELD_TYPES_TO_MAPPING_TYPES } from '@/domains/admin/channel/field/field.service'; import { OptionEntity } from '@/domains/admin/channel/option/option.entity'; @@ -46,6 +50,12 @@ import { DEFAULT_FIELD_COUNT, } from '@/test-utils/util-functions'; +interface OpenSearchIndex { + mappings: { + properties: ArrayLike>; + }; +} + describe('AppController (e2e)', () => { let app: INestApplication; @@ -108,15 +118,20 @@ describe('AppController (e2e)', () => { createFieldDto({}), ); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post(`/projects/${project.id}/channels`) .send(dto) .expect(201) - .then(async ({ body }) => { + .then(async ({ body }: { body: CreateChannelResponseDto }) => { expect(body.id).toBeDefined(); - const channel = await channelRepo.findOneBy({ id: body.id }); + const channel = await channelRepo.findOneBy({ + id: body.id, + }); expect(channel).toBeDefined(); + if (channel === null) { + throw new Error('Channel not found'); + } expect(channel.name).toEqual(dto.name); expect(channel.description).toEqual(dto.description); @@ -149,13 +164,21 @@ describe('AppController (e2e)', () => { }), ); - const result = await osService.indices.get({ index: body.id }); + const result: { body: OpenSearchIndex[] } = await osService.indices.get( + { + index: body.id.toString(), + }, + ); expect(Object.keys(result.body)[0]).toEqual(body.id); - Object.entries<{ [x: string]: { type: string } }>( - result.body[body.id].mappings.properties, + Object.entries>( + result.body[body.id].mappings.properties as ArrayLike< + Record + >, ).forEach(([fieldId, { type }]) => { - const field = fields.find(({ id }) => id === parseInt(fieldId)); + const field = + fields.find(({ id }) => id === parseInt(fieldId)) ?? + new FieldEntity(); expect(field).toBeDefined(); expect(FIELD_TYPES_TO_MAPPING_TYPES[field.format]).toEqual(type); }); @@ -173,20 +196,25 @@ describe('AppController (e2e)', () => { })), ); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get(`/projects/${project.id}/channels`) .expect(200) .expect(({ body }) => { expect(body).toHaveProperty('items'); expect(body).toHaveProperty('meta'); - expect(Array.isArray(body.items)).toEqual(true); - for (const channel of body.items) { + expect( + Array.isArray((body as FindChannelsByProjectIdResponseDto).items), + ).toEqual(true); + for (const channel of (body as FindChannelsByProjectIdResponseDto) + .items) { expect(channel).toHaveProperty('id'); expect(channel).toHaveProperty('name'); expect(channel).toHaveProperty('description'); } - expect(body.meta.totalItems).toEqual(total); + expect( + (body as FindChannelsByProjectIdResponseDto).meta.totalItems, + ).toEqual(total); }); }); @@ -196,13 +224,15 @@ describe('AppController (e2e)', () => { description: faker.string.sample(), }); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/channels/' + channel.id) .expect(200) .expect(({ body }) => { - expect(body.id).toEqual(channel.id); - expect(body.name).toEqual(channel.name); - expect(body.description).toEqual(channel.description); + expect((body as FindChannelByIdResponseDto).id).toEqual(channel.id); + expect((body as FindChannelByIdResponseDto).name).toEqual(channel.name); + expect((body as FindChannelByIdResponseDto).description).toEqual( + channel.description, + ); }); }); it('/channels/:id (PUT)', async () => { @@ -234,14 +264,14 @@ describe('AppController (e2e)', () => { dto.description = faker.string.sample(); // dto.fields = [...existingFields, ...newfields]; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put(`/channels/${channelId}`) .send(dto) .expect(200) .then(async () => { const updatedchannel = await channelRepo.findOneBy({ id: channelId }); - expect(updatedchannel.name).toEqual(dto.name); - expect(updatedchannel.description).toEqual(dto.description); + expect(updatedchannel?.name).toEqual(dto.name); + expect(updatedchannel?.description).toEqual(dto.description); const updatedFields = await fieldRepo.find({ where: { channel: { id: channelId } }, @@ -295,6 +325,6 @@ const fieldEntityToDto2 = (field: FieldEntity) => ({ description: field.description, options: field.format === FieldFormatEnum.select ? - field.options.map(({ name }) => ({ name })).sort(optionSort) + (field.options ?? []).map(({ name }) => ({ name })).sort(optionSort) : undefined, }); diff --git a/apps/api/test/feedback/feedback.e2e-spec.ts b/apps/api/test/feedback/feedback.e2e-spec.ts index 16fb9cfc5..7a3356ac0 100644 --- a/apps/api/test/feedback/feedback.e2e-spec.ts +++ b/apps/api/test/feedback/feedback.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -35,6 +36,11 @@ import { ProjectService } from '@/domains/admin/project/project/project.service' import { createFieldDto, getRandomValue } from '@/test-utils/fixtures'; import { clearEntities } from '@/test-utils/util-functions'; +interface OpenSearchResponse { + _source: Record; + total: { value: number }; +} + describe('AppController (e2e)', () => { let app: INestApplication; @@ -82,7 +88,11 @@ describe('AppController (e2e)', () => { const { id: projectId } = await projectService.create({ name: faker.random.word(), description: faker.lorem.lines(1), - timezone: null, + timezone: { + countryCode: 'KR', + name: 'Asia/Seoul', + offset: '+09:00', + }, }); const { id: channelId } = await channelService.create({ @@ -104,36 +114,42 @@ describe('AppController (e2e)', () => { }); it('/channels/:channelId/feedbacks (POST)', () => { - const dto = {}; + const dto: Record = {}; fields .filter(({ name }) => name !== 'createdAt' && name !== 'updatedAt') .forEach(({ name, format, options }) => { dto[name] = getRandomValue(format, options); }); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post(`/channels/${channel.id}/feedbacks`) .send(dto) .expect(201) - .then(async ({ body }) => { - expect(body.id).toBeDefined(); - const esResult = await osService.get({ - id: body.id, - index: channel.id.toString(), - }); - - delete esResult.body._source[ - fields.find((v) => v.name === 'createdAt').id - ]; - expect(toApi(dto, fields)).toMatchObject(esResult.body._source); - }); + .then( + async ({ + body, + }: { + body: Record & { issueNames?: string[] }; + }) => { + expect(body.id).toBeDefined(); + const esResult = await osService.get({ + id: body.id as string, + index: channel.id.toString(), + }); + + delete esResult.body._source[ + (fields.find((v) => v.name === 'createdAt') ?? { id: 0 }).id + ]; + expect(toApi(dto, fields)).toMatchObject(esResult.body._source); + }, + ); }); it('/channels/:channelId/feedbacks (GET)', async () => { const feedbackCount = faker.number.int({ min: 1, max: 10 }); - const dataset = []; + const dataset: Record[] = []; for (let i = 0; i < feedbackCount; i++) { - const data = {}; + const data: Record = {}; fields .filter(({ name }) => name !== 'createdAt' && name !== 'updatedAt') .forEach(({ name, format, options }) => { @@ -143,10 +159,10 @@ describe('AppController (e2e)', () => { dataset.push(data); } - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get(`/channels/${channel.id}/feedbacks`) .expect(200) - .then(async ({ body }) => { + .then(({ body }) => { expect(Array.isArray(body)).toEqual(true); expect(body).toHaveLength(feedbackCount); }); @@ -171,21 +187,22 @@ describe('AppController (e2e)', () => { const newValue = getRandomValue(targetField.format, targetField.options); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put( `/channels/${channel.id}/feedbacks/${feedbackId}/field/${targetField.id}`, ) .send({ value: newValue }) .expect(200) .then(async () => { - const { body } = await osService.get({ + const { body } = await osService.get({ id: feedbackId.toString(), index: channel.id.toString(), }); expect(body._source[targetField.id]).toEqual( targetField.format === FieldFormatEnum.select ? - targetField.options.find((v) => v.name === newValue).id + ((targetField.options ?? []).find((v) => v.name === newValue) ?? + { id: 0 }.id) : newValue, ); }); @@ -251,13 +268,20 @@ describe('AppController (e2e)', () => { // }); }); -const toApi = (data: Record, fields: FieldEntity[]) => { +const toApi = ( + data: Record, + fields: FieldEntity[], +) => { return Object.entries(data).reduce((prev, [key, value]) => { - const field = fields.find((v) => v.name === key); + const field: FieldEntity = + fields.find((v) => v.name === key) ?? new FieldEntity(); return Object.assign(prev, { [field.id]: field.format === FieldFormatEnum.select ? - field.options?.find((v) => v.name === value).id + ( + (field.options ?? []).find((v) => v.name === value) ?? + new FieldEntity() + ).id : value, }); }, {}); diff --git a/apps/api/test/feedback/project.e2e-spec.ts b/apps/api/test/feedback/project.e2e-spec.ts index 4b53ac3d7..236a44479 100644 --- a/apps/api/test/feedback/project.e2e-spec.ts +++ b/apps/api/test/feedback/project.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -25,6 +26,8 @@ import type { DataSource, Repository } from 'typeorm'; import { AppModule } from '@/app.module'; import { HttpExceptionFilter } from '@/common/filters'; import { CreateProjectRequestDto } from '@/domains/admin/project/project/dtos/requests'; +import type { FindProjectByIdResponseDto } from '@/domains/admin/project/project/dtos/responses/find-project-by-id-response.dto'; +import type { FindProjectsResponseDto } from '@/domains/admin/project/project/dtos/responses/find-projects-response.dto'; import { ProjectEntity } from '@/domains/admin/project/project/project.entity'; import { clearEntities } from '@/test-utils/util-functions'; @@ -72,20 +75,24 @@ describe('AppController (e2e)', () => { })), ); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/projects') .expect(200) .expect(({ body }) => { expect(body).toHaveProperty('items'); expect(body).toHaveProperty('meta'); - expect(Array.isArray(body.items)).toEqual(true); - for (const project of body.items) { + expect(Array.isArray((body as FindProjectsResponseDto).items)).toEqual( + true, + ); + for (const project of (body as FindProjectsResponseDto).items) { expect(project).toHaveProperty('id'); expect(project).toHaveProperty('name'); expect(project).toHaveProperty('description'); } - expect(body.meta.totalItems).toEqual(total); + expect((body as FindProjectsResponseDto).meta.totalItems).toEqual( + total, + ); }); }); @@ -94,7 +101,10 @@ describe('AppController (e2e)', () => { dto.name = faker.string.sample(); dto.description = faker.string.sample(); - return request(app.getHttpServer()).post('/projects').send(dto).expect(201); + return request(app.getHttpServer() as Server) + .post('/projects') + .send(dto) + .expect(201); }); it('/projects/:id (GET)', async () => { @@ -103,13 +113,15 @@ describe('AppController (e2e)', () => { description: faker.string.sample(), }); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/projects/' + project.id) .expect(200) .expect(({ body }) => { - expect(body.id).toEqual(project.id); - expect(body.name).toEqual(project.name); - expect(body.description).toEqual(project.description); + expect((body as FindProjectByIdResponseDto).id).toEqual(project.id); + expect((body as FindProjectByIdResponseDto).name).toEqual(project.name); + expect((body as FindProjectByIdResponseDto).description).toEqual( + project.description, + ); }); }); it('/projects/:id (PUT)', async () => { @@ -121,14 +133,14 @@ describe('AppController (e2e)', () => { const name = faker.string.sample(); const description = faker.string.sample(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put(`/projects/${project.id}`) .send({ name, description }) .expect(200) .then(async () => { const updatedproject = await projectRepo.findOneBy({ id: project.id }); - expect(updatedproject.name).toEqual(name); - expect(updatedproject.description).toEqual(description); + expect(updatedproject?.name).toEqual(name); + expect(updatedproject?.description).toEqual(description); }); }); // it('/projects/:id (DELETE)', async () => { diff --git a/apps/api/test/role.e2e-spec.ts b/apps/api/test/role.e2e-spec.ts index 6119cce78..af1455ee6 100644 --- a/apps/api/test/role.e2e-spec.ts +++ b/apps/api/test/role.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -25,6 +26,10 @@ import type { DataSource, Repository } from 'typeorm'; import { AppModule } from '@/app.module'; import { AuthService } from '@/domains/admin/auth/auth.service'; import { UpdateRoleRequestDto } from '@/domains/admin/project/role/dtos/requests'; +import type { + GetAllRolesResponseDto, + GetAllRolesResponseRoleDto, +} from '@/domains/admin/project/role/dtos/responses/get-all-roles-response.dto'; import { PermissionEnum } from '@/domains/admin/project/role/permission.enum'; import { RoleEntity } from '@/domains/admin/project/role/role.entity'; import { @@ -79,26 +84,28 @@ describe('AppController (e2e)', () => { permissions: getRandomEnumValues(PermissionEnum), }); } - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/roles') .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.OK) .expect(({ body }) => { expect(body).toHaveProperty('roles'); - expect(Array.isArray(body.roles)).toEqual(true); + expect(Array.isArray((body as GetAllRolesResponseDto).roles)).toEqual( + true, + ); - for (const role of body.roles) { + for (const role of (body as GetAllRolesResponseDto).roles) { expect(role).toHaveProperty('id'); expect(role).toHaveProperty('name'); expect(role).toHaveProperty('permissions'); } expect(body).toHaveProperty('total'); - expect(body.total).toEqual(total + 1); + expect((body as GetAllRolesResponseDto).total).toEqual(total + 1); }); }); it('Unauthroized', async () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/roles') .expect(HttpStatusCode.UNAUTHORIZED); }); @@ -106,7 +113,7 @@ describe('AppController (e2e)', () => { describe('/roles (POST)', () => { it('positive case', () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/roles') .set('Authorization', `Bearer ${accessToken}`) .send({ @@ -116,7 +123,7 @@ describe('AppController (e2e)', () => { .expect(201); }); it('Unauthroized', () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/roles') .send({ name: faker.string.sample(), @@ -132,13 +139,15 @@ describe('AppController (e2e)', () => { permissions: getRandomEnumValues(PermissionEnum), }); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/roles/' + role.id) .expect(HttpStatusCode.OK) .expect(({ body }) => { - expect(body.id).toEqual(role.id); - expect(body.name).toEqual(role.name); - expect(body.permissions).toEqual(role.permissions); + expect((body as GetAllRolesResponseRoleDto).id).toEqual(role.id); + expect((body as GetAllRolesResponseRoleDto).name).toEqual(role.name); + expect((body as GetAllRolesResponseRoleDto).permissions).toEqual( + role.permissions, + ); }); }); describe('/roles/:id (PUT)', () => { @@ -152,19 +161,19 @@ describe('AppController (e2e)', () => { dto.name = 'updatedRole'; dto.permissions = getRandomEnumValues(PermissionEnum); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .put(`/roles/${role.id}`) .set('Authorization', `Bearer ${accessToken}`) .send(dto) .expect(204) .then(async () => { const updatedRole = await roleRepo.findOneBy({ id: role.id }); - expect(updatedRole.name).toEqual(dto.name); - expect(updatedRole.permissions).toEqual(dto.permissions); + expect(updatedRole?.name).toEqual(dto.name); + expect(updatedRole?.permissions).toEqual(dto.permissions); }); }); it('Unauthrized', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .put(`/roles/${faker.number.int()}`) .expect(HttpStatusCode.UNAUTHORIZED); }); @@ -176,7 +185,7 @@ describe('AppController (e2e)', () => { permissions: getRandomEnumValues(PermissionEnum), }); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .delete(`/roles/${role.id}`) .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.OK) @@ -185,7 +194,7 @@ describe('AppController (e2e)', () => { }); }); it('Unauthrized', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .delete(`/roles/${faker.number.int()}`) .expect(HttpStatusCode.UNAUTHORIZED); }); diff --git a/apps/api/test/tenant.e2e-spec.ts b/apps/api/test/tenant.e2e-spec.ts index f34e72c29..80b724a14 100644 --- a/apps/api/test/tenant.e2e-spec.ts +++ b/apps/api/test/tenant.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -28,6 +29,7 @@ import { SetupTenantRequestDto, UpdateTenantRequestDto, } from '@/domains/admin/tenant/dtos/requests'; +import type { GetTenantResponseDto } from '@/domains/admin/tenant/dtos/responses/get-tenant-response.dto'; import { TenantEntity } from '@/domains/admin/tenant/tenant.entity'; import { clearEntities, signInTestUser } from '@/test-utils/util-functions'; import { HttpStatusCode } from '@/types/http-status'; @@ -69,7 +71,7 @@ describe('AppController (e2e)', () => { const dto = new SetupTenantRequestDto(); dto.siteName = faker.string.sample(); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .post('/tenant') .send(dto) .expect(201) @@ -78,7 +80,7 @@ describe('AppController (e2e)', () => { expect(tenants).toHaveLength(1); const [tenant] = tenants; for (const key in dto) { - const value = dto[key]; + const value = dto[key] as string; expect(tenant[key]).toEqual(value); } }); @@ -93,7 +95,10 @@ describe('AppController (e2e)', () => { const dto = new SetupTenantRequestDto(); dto.siteName = faker.string.sample(); - return request(app.getHttpServer()).post('/tenant').send(dto).expect(400); + return request(app.getHttpServer() as Server) + .post('/tenant') + .send(dto) + .expect(400); }); }); describe('/tenant (PUT)', () => { @@ -117,7 +122,7 @@ describe('AppController (e2e)', () => { dto.isRestrictDomain = faker.datatype.boolean(); dto.allowDomains = []; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put('/tenant') .set('Authorization', `Bearer ${accessToken}`) .send(dto) @@ -126,10 +131,10 @@ describe('AppController (e2e)', () => { const updatedTenant = await tenantRepo.findOne({ where: { id: tenant.id }, }); - expect(updatedTenant.siteName).toEqual(dto.siteName); - expect(updatedTenant.isPrivate).toEqual(dto.isPrivate); - expect(updatedTenant.isRestrictDomain).toEqual(dto.isRestrictDomain); - expect(updatedTenant.allowDomains).toEqual(dto.allowDomains); + expect(updatedTenant?.siteName).toEqual(dto.siteName); + expect(updatedTenant?.isPrivate).toEqual(dto.isPrivate); + expect(updatedTenant?.isRestrictDomain).toEqual(dto.isRestrictDomain); + expect(updatedTenant?.allowDomains).toEqual(dto.allowDomains); }); }); it('not found tenant', async () => { @@ -142,7 +147,7 @@ describe('AppController (e2e)', () => { dto.isRestrictDomain = faker.datatype.boolean(); dto.allowDomains = []; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put('/tenant') .set('Authorization', `Bearer ${accessToken}`) @@ -157,7 +162,7 @@ describe('AppController (e2e)', () => { dto.isRestrictDomain = faker.datatype.boolean(); dto.allowDomains = []; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put('/tenant') .set('Authorization', `Bearer ${accessToken}`) .send(dto) @@ -171,7 +176,7 @@ describe('AppController (e2e)', () => { dto.isRestrictDomain = faker.datatype.boolean(); dto.allowDomains = []; - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .put('/tenant') .send(dto) .expect(HttpStatusCode.UNAUTHORIZED); @@ -182,15 +187,17 @@ describe('AppController (e2e)', () => { beforeEach(async () => { dto.siteName = faker.string.sample(); - await request(app.getHttpServer()).post('/tenant').send(dto); + await request(app.getHttpServer() as Server) + .post('/tenant') + .send(dto); }); it('find', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .get('/tenant') .expect(200) .expect(({ body }) => { - expect(dto.siteName).toEqual(body.siteName); + expect(dto.siteName).toEqual((body as GetTenantResponseDto).siteName); }); }); }); diff --git a/apps/api/test/user.e2e-spec.ts b/apps/api/test/user.e2e-spec.ts index f63570de2..13b6b9d83 100644 --- a/apps/api/test/user.e2e-spec.ts +++ b/apps/api/test/user.e2e-spec.ts @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. */ +import type { Server } from 'net'; import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import { ValidationPipe } from '@nestjs/common'; @@ -26,6 +27,8 @@ import type { DataSource, Repository } from 'typeorm'; import { AppModule } from '@/app.module'; import { AuthService } from '@/domains/admin/auth/auth.service'; import { RoleEntity } from '@/domains/admin/project/role/role.entity'; +import type { UserDto } from '@/domains/admin/user/dtos'; +import type { GetAllUserResponseDto } from '@/domains/admin/user/dtos/responses/get-all-user-response.dto'; import { UserStateEnum } from '@/domains/admin/user/entities/enums'; import { UserEntity } from '@/domains/admin/user/entities/user.entity'; import { @@ -111,7 +114,7 @@ describe('AppController (e2e)', () => { })) .slice(0, 10); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/users') .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.OK) @@ -119,7 +122,7 @@ describe('AppController (e2e)', () => { expect(body).toHaveProperty('items'); expect(body).toHaveProperty('meta'); - const { items, meta } = body; + const { items, meta } = body as GetAllUserResponseDto; expect(items).toEqual(expectUsers); expect(meta.totalItems).toEqual(total); expect(meta.itemCount).toEqual(10); @@ -127,7 +130,7 @@ describe('AppController (e2e)', () => { }); it('UnAuthorized', async () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get('/users') .expect(HttpStatusCode.UNAUTHORIZED); }); @@ -152,7 +155,7 @@ describe('AppController (e2e)', () => { })) .slice((page - 1) * limit, page * limit); - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .get(`/users?page=${page}&limit=${limit}`) .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.OK) @@ -160,7 +163,7 @@ describe('AppController (e2e)', () => { expect(body).toHaveProperty('items'); expect(body).toHaveProperty('meta'); - const { items, meta } = body; + const { items, meta } = body as GetAllUserResponseDto; expect(items).toEqual(expectUsers); expect(meta.totalItems).toEqual(total); expect(meta.itemCount).toBeLessThanOrEqual(10); @@ -172,7 +175,7 @@ describe('AppController (e2e)', () => { it('positive case', async () => { const ids = faker.helpers.arrayElements(userEntities).map((v) => v.id); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .delete(`/users`) .set('Authorization', `Bearer ${accessToken}`) .send({ ids }) @@ -186,7 +189,7 @@ describe('AppController (e2e)', () => { }); it('Unauthorized', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .delete(`/users`) .expect(HttpStatusCode.UNAUTHORIZED); }); @@ -194,24 +197,24 @@ describe('AppController (e2e)', () => { describe('/users/:id (GET)', () => { it('', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .get(`/users/${ownerUser.id}`) .set('Authorization', `Bearer ${accessToken}`) .expect(200) .expect(({ body }) => { - expect(body.id).toEqual(ownerUser.id); - expect(body.email).toEqual(ownerUser.email); + expect((body as UserDto).id).toEqual(ownerUser.id); + expect((body as UserDto).email).toEqual(ownerUser.email); }); }); it('', async () => { - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .get(`/users/${ownerUser.id}`) .expect(HttpStatusCode.UNAUTHORIZED); }); }); describe('/users/:id (DELETE)', () => { it('positive', async () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .delete(`/users/${ownerUser.id}`) .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.OK) @@ -221,13 +224,13 @@ describe('AppController (e2e)', () => { }); }); it('Unauthorization', async () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .delete(`/users/${faker.number.int()}`) .set('Authorization', `Bearer ${accessToken}`) .expect(HttpStatusCode.UNAUTHORIZED); }); it('Unauthorization', async () => { - return request(app.getHttpServer()) + return request(app.getHttpServer() as Server) .delete(`/users/${ownerUser.id}`) .expect(HttpStatusCode.UNAUTHORIZED); }); @@ -240,7 +243,7 @@ describe('AppController (e2e)', () => { permissions: [], }); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .put(`/users/${ownerUser.id}/role`) .set('Authorization', `Bearer ${accessToken}`) .send({ roleId: role.id }) @@ -252,7 +255,7 @@ describe('AppController (e2e)', () => { permissions: [], }); - await request(app.getHttpServer()) + await request(app.getHttpServer() as Server) .put(`/users/${ownerUser.id}/role`) .send({ roleId: role.id }) .expect(HttpStatusCode.UNAUTHORIZED); diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js index 9024f4d9f..b2f7c18c9 100644 --- a/apps/web/eslint.config.js +++ b/apps/web/eslint.config.js @@ -12,6 +12,7 @@ module.exports = [ 'jest.setup.ts', 'next-env.d.ts', 'jest.polyfills.js', + '**/api.type.ts', ], }, ...baseConfig, diff --git a/apps/web/package.json b/apps/web/package.json index 9dd8bf507..6aea0dda3 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -87,7 +87,7 @@ "@testing-library/react": "^16.0.0", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.12", - "@types/node": "20.14.11", + "@types/node": "20.14.14", "@types/react": "^18.2.79", "@types/react-beautiful-dnd": "^13.1.8", "@types/react-datepicker": "^6.0.0", diff --git a/apps/web/public/locales/de/common.json b/apps/web/public/locales/de/common.json index e7506b475..8fcb972cf 100644 --- a/apps/web/public/locales/de/common.json +++ b/apps/web/public/locales/de/common.json @@ -252,7 +252,8 @@ "next": "Nächste", "complete": "Abschließen", "next-time": "Später", - "start": "Starten" + "start": "Starten", + "generate": "Generieren" }, "input": { "label": { diff --git a/apps/web/public/locales/en/common.json b/apps/web/public/locales/en/common.json index 16e636303..1dff08d54 100644 --- a/apps/web/public/locales/en/common.json +++ b/apps/web/public/locales/en/common.json @@ -252,7 +252,8 @@ "next": "Next", "complete": "Complete", "next-time": "Later", - "start": "Start" + "start": "Start", + "generate": "Generate" }, "input": { "label": { diff --git a/apps/web/public/locales/ja/common.json b/apps/web/public/locales/ja/common.json index dd1b494dd..a7fac8c8e 100644 --- a/apps/web/public/locales/ja/common.json +++ b/apps/web/public/locales/ja/common.json @@ -240,7 +240,8 @@ "next": "次へ", "complete": "完了", "next-time": "次回", - "start": "はじまり" + "start": "はじまり", + "generate": "生成" }, "input": { "label": { diff --git a/apps/web/public/locales/ko/common.json b/apps/web/public/locales/ko/common.json index 61c9531c8..6311ed2c4 100644 --- a/apps/web/public/locales/ko/common.json +++ b/apps/web/public/locales/ko/common.json @@ -240,7 +240,8 @@ "next": "다음", "complete": "완료", "next-time": "다음에", - "start": "시작하기" + "start": "시작하기", + "generate": "생성" }, "input": { "label": { diff --git a/apps/web/public/locales/zh/common.json b/apps/web/public/locales/zh/common.json index 48f1a27d9..8fa04e5d6 100644 --- a/apps/web/public/locales/zh/common.json +++ b/apps/web/public/locales/zh/common.json @@ -252,7 +252,8 @@ "next": "下一个", "complete": "完成", "next-time": "下次", - "start": "开始" + "start": "开始", + "generate": "產生" }, "input": { "label": { diff --git a/apps/web/src/entities/webhook/ui/create-webhook-popover.tsx b/apps/web/src/entities/webhook/ui/create-webhook-popover.tsx index 857e78b8b..f08b791ba 100644 --- a/apps/web/src/entities/webhook/ui/create-webhook-popover.tsx +++ b/apps/web/src/entities/webhook/ui/create-webhook-popover.tsx @@ -30,6 +30,7 @@ const defaultValues: WebhookInfo = { name: '', status: 'ACTIVE', url: '', + token: null, events: [ { type: 'FEEDBACK_CREATION', channelIds: [], status: 'INACTIVE' }, { type: 'ISSUE_ADDITION', channelIds: [], status: 'INACTIVE' }, diff --git a/apps/web/src/entities/webhook/ui/update-webhook-popover.tsx b/apps/web/src/entities/webhook/ui/update-webhook-popover.tsx index 4a1459bab..19ac67e2e 100644 --- a/apps/web/src/entities/webhook/ui/update-webhook-popover.tsx +++ b/apps/web/src/entities/webhook/ui/update-webhook-popover.tsx @@ -98,6 +98,7 @@ const convertDefatulValuesToFormValues = (defaultValues: Webhook) => { name: defaultValues.name, url: defaultValues.url, status: defaultValues.status, + token: defaultValues.token, events: defaultValues.events.map((event) => ({ status: event.status, type: event.type, diff --git a/apps/web/src/entities/webhook/ui/webhook-form.ui.tsx b/apps/web/src/entities/webhook/ui/webhook-form.ui.tsx index 2e4a5a5dc..14fc6f0e1 100644 --- a/apps/web/src/entities/webhook/ui/webhook-form.ui.tsx +++ b/apps/web/src/entities/webhook/ui/webhook-form.ui.tsx @@ -33,7 +33,9 @@ interface IProps { const WebhookForm: React.FC = (props) => { const { channels } = props; + const { t } = useTranslation(); + const { register, setValue, getValues, watch, formState } = useFormContext(); @@ -107,10 +109,28 @@ const WebhookForm: React.FC = (props) => { {...register('url')} isSubmitted={formState.isSubmitted} isSubmitting={formState.isSubmitting} - isValid={!formState.errors.name} + isValid={!formState.errors.url} hint={formState.errors.url?.message} required /> + setValue('token', window.crypto.randomUUID())} + > + {t('button.generate')} + + } + />

Event

diff --git a/apps/web/src/entities/webhook/webhook.schema.ts b/apps/web/src/entities/webhook/webhook.schema.ts index 328810675..f46c4ef39 100644 --- a/apps/web/src/entities/webhook/webhook.schema.ts +++ b/apps/web/src/entities/webhook/webhook.schema.ts @@ -36,6 +36,17 @@ export const webhookSchema = z.object({ url: z.string(), status: z.enum(['ACTIVE', 'INACTIVE']), events: z.array(webhookEventSchema), + token: z + .string() + .min(16) + .regex(/^[a-zA-Z0-9._-]+$/) + .or( + z + .string() + .length(0) + .transform(() => null), + ) + .or(z.null()), createdAt: z.string(), }); diff --git a/apps/web/src/shared/constants/path.ts b/apps/web/src/shared/constants/path.ts index 8d09ed616..9b4a1048b 100644 --- a/apps/web/src/shared/constants/path.ts +++ b/apps/web/src/shared/constants/path.ts @@ -14,10 +14,9 @@ * under the License. */ class PathV3 { - private static instance: PathV3; + private static instance: PathV3 | null; public static get Instance(): PathV3 { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return this.instance || (this.instance = new this()); + return this.instance ?? (this.instance = new this()); } readonly CREATE_TENANT = '/tenant/create'; diff --git a/apps/web/src/shared/lib/client.ts b/apps/web/src/shared/lib/client.ts index cf096fb55..fea436d98 100644 --- a/apps/web/src/shared/lib/client.ts +++ b/apps/web/src/shared/lib/client.ts @@ -35,10 +35,9 @@ class client { baseURL: env.NEXT_PUBLIC_API_BASE_URL, }); - private static instance: client; + private static instance: client | null; public static get Instance(): client { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return this.instance || (this.instance = new this()); + return this.instance ?? (this.instance = new this()); } constructor() { diff --git a/apps/web/src/shared/lib/session-storage.ts b/apps/web/src/shared/lib/session-storage.ts index d37a68c31..346829996 100644 --- a/apps/web/src/shared/lib/session-storage.ts +++ b/apps/web/src/shared/lib/session-storage.ts @@ -31,10 +31,9 @@ export type SessionStorageValueType = class sessionStorage { private storage: Storage; - private static instance: sessionStorage; + private static instance: sessionStorage | null; public static get Instance(): sessionStorage { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return this.instance || (this.instance = new this()); + return this.instance ?? (this.instance = new this()); } constructor() { diff --git a/apps/web/src/shared/types/api.type.ts b/apps/web/src/shared/types/api.type.ts index 896e5c780..8f45c6ff4 100644 --- a/apps/web/src/shared/types/api.type.ts +++ b/apps/web/src/shared/types/api.type.ts @@ -1882,6 +1882,7 @@ export interface components { /** @enum {string} */ status: 'ACTIVE' | 'INACTIVE'; events: components['schemas']['EventDto'][]; + token: string | null; }; CreateWebhookResponseDto: { id: number; @@ -1904,6 +1905,7 @@ export interface components { id: number; name: string; url: string; + token: string; /** @enum {string} */ status: 'ACTIVE' | 'INACTIVE'; events: components['schemas']['GetWebhookResponseEventDto'][]; @@ -1919,6 +1921,7 @@ export interface components { /** @enum {string} */ status: 'ACTIVE' | 'INACTIVE'; events: components['schemas']['EventDto'][]; + token: string | null; }; UpdateWebhookResponseDto: { id: number; @@ -1946,7 +1949,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['SendEmailCodeResponseDto']; }; @@ -1967,7 +1972,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -1986,7 +1993,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2005,7 +2014,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2024,7 +2035,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2043,7 +2056,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['SignInResponseDto']; }; @@ -2062,7 +2077,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['OAuthLoginUrlResponseDto']; }; @@ -2079,7 +2096,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2094,7 +2113,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['SignInResponseDto']; }; @@ -2116,7 +2137,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetAllUserResponseDto']; }; @@ -2137,7 +2160,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2156,7 +2181,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetAllUserResponseDto']; }; @@ -2175,7 +2202,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['UserDto']; }; @@ -2198,7 +2227,9 @@ export interface operations { }; responses: { 204: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2215,7 +2246,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2232,7 +2265,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetRolesByIdResponseDto']; }; @@ -2253,7 +2288,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2272,7 +2309,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2291,7 +2330,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2310,7 +2351,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2325,7 +2368,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetTenantResponseDto']; }; @@ -2346,7 +2391,9 @@ export interface operations { }; responses: { 204: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2365,7 +2412,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2382,7 +2431,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CountFeedbacksByTenantIdResponseDto']; }; @@ -2401,7 +2452,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetAllRolesResponseDto']; }; @@ -2424,7 +2477,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2446,7 +2501,9 @@ export interface operations { }; responses: { 204: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2464,7 +2521,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2483,7 +2542,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetAllMemberResponseDto']; }; @@ -2506,7 +2567,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2528,7 +2591,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2546,7 +2611,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2563,7 +2630,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindApiKeysResponseDto']; }; @@ -2586,7 +2655,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateApiKeyResponseDto']; }; @@ -2605,7 +2676,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2622,7 +2695,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2639,7 +2714,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2662,7 +2739,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindChannelsByProjectIdResponseDto']; }; @@ -2685,7 +2764,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateChannelResponseDto']; }; @@ -2706,7 +2787,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': boolean; }; @@ -2726,7 +2809,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindChannelByIdResponseDto']; }; @@ -2750,7 +2835,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2768,7 +2855,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2790,7 +2879,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2811,7 +2902,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['ImageUploadUrlTestResponseDto']; }; @@ -2830,7 +2923,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindOptionByFieldIdResponseDto'][]; }; @@ -2853,7 +2948,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateOptionResponseDto']; }; @@ -2876,7 +2973,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindProjectsResponseDto']; }; @@ -2897,7 +2996,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateProjectResponseDto']; }; @@ -2916,7 +3017,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2933,7 +3036,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindProjectByIdResponseDto']; }; @@ -2956,7 +3061,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['UpdateProjectResponseDto']; }; @@ -2975,7 +3082,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -2992,7 +3101,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CountFeedbacksByIdResponseDto']; }; @@ -3011,7 +3122,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CountIssuesByIdResponseDto']; }; @@ -3031,7 +3144,9 @@ export interface operations { requestBody?: never; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3053,7 +3168,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3075,7 +3192,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindFeedbacksByChannelIdResponseDto']; }; @@ -3097,7 +3216,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['AddIssueResponseDto']; }; @@ -3119,7 +3240,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['AddIssueResponseDto']; }; @@ -3143,7 +3266,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3162,7 +3287,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3183,7 +3310,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateIssueResponseDto']; }; @@ -3206,7 +3335,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3224,7 +3355,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindIssueByIdResponseDto'][]; }; @@ -3248,7 +3381,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3266,7 +3401,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content?: never; }; }; @@ -3287,7 +3424,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindIssuesByProjectIdResponseDto']; }; @@ -3308,7 +3447,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountResponseDto']; }; @@ -3330,7 +3471,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountByDateResponseDto']; }; @@ -3349,7 +3492,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountByStatusResponseDto']; }; @@ -3371,7 +3516,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountByDateByChannelResponseDto']; }; @@ -3392,7 +3539,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountResponseDto']; }; @@ -3413,7 +3562,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindIssuedRateResponseDto']; }; @@ -3435,7 +3586,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindCountByDateByIssueResponseDto']; }; @@ -3454,7 +3607,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['FindIssueTrackerResponseDto']; }; @@ -3477,7 +3632,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['UpdateIssueTrackerResponseDto']; }; @@ -3500,7 +3657,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateIssueTrackerResponseDto']; }; @@ -3519,7 +3678,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetWebhooksByProjectIdResponseDto']; }; @@ -3542,7 +3703,9 @@ export interface operations { }; responses: { 201: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['CreateWebhookResponseDto']; }; @@ -3561,7 +3724,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetWebhookByIdResponseDto']; }; @@ -3585,7 +3750,9 @@ export interface operations { }; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['UpdateWebhookResponseDto']; }; @@ -3604,7 +3771,9 @@ export interface operations { requestBody?: never; responses: { 200: { - headers: Record; + headers: { + [name: string]: unknown; + }; content: { 'application/json': components['schemas']['GetWebhookByIdResponseDto']; }; diff --git a/apps/web/src/widgets/setting-menu/ui/project/project-info-setting.ui.tsx b/apps/web/src/widgets/setting-menu/ui/project/project-info-setting.ui.tsx index 82a9c304f..f9c71cfe7 100644 --- a/apps/web/src/widgets/setting-menu/ui/project/project-info-setting.ui.tsx +++ b/apps/web/src/widgets/setting-menu/ui/project/project-info-setting.ui.tsx @@ -74,7 +74,7 @@ const ProjectInfoSetting: React.FC = ({ projectId }) => { return ( =16.0.0'} - '@aws-sdk/client-sso-oidc@3.616.0': - resolution: {integrity: sha512-YY1hpYS/G1uRGjQf88dL8VLHkP/IjGxKeXdhy+JnzMdCkAWl3V9j0fEALw40NZe0x79gr6R2KUOUH/IKYQfUmg==} + '@aws-sdk/client-sso-oidc@3.621.0': + resolution: {integrity: sha512-mMjk3mFUwV2Y68POf1BQMTF+F6qxt5tPu6daEUCNGC9Cenk3h2YXQQoS4/eSyYzuBiYk3vx49VgleRvdvkg8rg==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.616.0 + '@aws-sdk/client-sts': ^3.621.0 - '@aws-sdk/client-sso@3.616.0': - resolution: {integrity: sha512-hwW0u1f8U4dSloAe61/eupUiGd5Q13B72BuzGxvRk0cIpYX/2m0KBG8DDl7jW1b2QQ+CflTLpG2XUf2+vRJxGA==} + '@aws-sdk/client-sso@3.621.0': + resolution: {integrity: sha512-xpKfikN4u0BaUYZA9FGUMkkDmfoIP0Q03+A86WjqDWhcOoqNA1DkHsE4kZ+r064ifkPUfcNuUvlkVTEoBZoFjA==} engines: {node: '>=16.0.0'} - '@aws-sdk/client-sts@3.616.0': - resolution: {integrity: sha512-FP7i7hS5FpReqnysQP1ukQF1OUWy8lkomaOnbu15H415YUrfCp947SIx6+BItjmx+esKxPkEjh/fbCVzw2D6hQ==} + '@aws-sdk/client-sts@3.621.0': + resolution: {integrity: sha512-707uiuReSt+nAx6d0c21xLjLm2lxeKc7padxjv92CIrIocnQSlJPxSCM7r5zBhwiahJA6MNQwmTl2xznU67KgA==} engines: {node: '>=16.0.0'} - '@aws-sdk/core@3.616.0': - resolution: {integrity: sha512-O/urkh2kECs/IqZIVZxyeyHZ7OR2ZWhLNK7btsVQBQvJKrEspLrk/Fp20Qfg5JDerQfBN83ZbyRXLJOOucdZpw==} + '@aws-sdk/core@3.621.0': + resolution: {integrity: sha512-CtOwWmDdEiINkGXD93iGfXjN0WmCp9l45cDWHHGa8lRgEDyhuL7bwd/pH5aSzj0j8SiQBG2k0S7DHbd5RaqvbQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-env@3.609.0': - resolution: {integrity: sha512-v69ZCWcec2iuV9vLVJMa6fAb5xwkzN4jYIT8yjo2c4Ia/j976Q+TPf35Pnz5My48Xr94EFcaBazrWedF+kwfuQ==} + '@aws-sdk/credential-provider-env@3.620.1': + resolution: {integrity: sha512-ExuILJ2qLW5ZO+rgkNRj0xiAipKT16Rk77buvPP8csR7kkCflT/gXTyzRe/uzIiETTxM7tr8xuO9MP/DQXqkfg==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-http@3.616.0': - resolution: {integrity: sha512-1rgCkr7XvEMBl7qWCo5BKu3yAxJs71dRaZ55Xnjte/0ZHH6Oc93ZrHzyYy6UH6t0nZrH+FAuw7Yko2YtDDwDeg==} + '@aws-sdk/credential-provider-http@3.621.0': + resolution: {integrity: sha512-/jc2tEsdkT1QQAI5Dvoci50DbSxtJrevemwFsm0B73pwCcOQZ5ZwwSdVqGsPutzYzUVx3bcXg3LRL7jLACqRIg==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-ini@3.616.0': - resolution: {integrity: sha512-5gQdMr9cca3xV7FF2SxpxWGH2t6+t4o+XBGiwsHm8muEjf4nUmw7Ij863x25Tjt2viPYV0UStczSb5Sihp7bkA==} + '@aws-sdk/credential-provider-ini@3.621.0': + resolution: {integrity: sha512-0EWVnSc+JQn5HLnF5Xv405M8n4zfdx9gyGdpnCmAmFqEDHA8LmBdxJdpUk1Ovp/I5oPANhjojxabIW5f1uU0RA==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.616.0 + '@aws-sdk/client-sts': ^3.621.0 - '@aws-sdk/credential-provider-node@3.616.0': - resolution: {integrity: sha512-Se+u6DAxjDPjKE3vX1X2uxjkWgGq69BTo0uTB0vDUiWwBVgh16s9BsBhSAlKEH1CCbbJHvOg4YdTrzjwzqyClg==} + '@aws-sdk/credential-provider-node@3.621.0': + resolution: {integrity: sha512-4JqpccUgz5Snanpt2+53hbOBbJQrSFq7E1sAAbgY6BKVQUsW5qyXqnjvSF32kDeKa5JpBl3bBWLZl04IadcPHw==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-process@3.614.0': - resolution: {integrity: sha512-Q0SI0sTRwi8iNODLs5+bbv8vgz8Qy2QdxbCHnPk/6Cx6LMf7i3dqmWquFbspqFRd8QiqxStrblwxrUYZi09tkA==} + '@aws-sdk/credential-provider-process@3.620.1': + resolution: {integrity: sha512-hWqFMidqLAkaV9G460+1at6qa9vySbjQKKc04p59OT7lZ5cO5VH5S4aI05e+m4j364MBROjjk2ugNvfNf/8ILg==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-sso@3.616.0': - resolution: {integrity: sha512-3rsWs9GBi8Z8Gps5ROwqguxtw+J6OIg1vawZMLRNMqqZoBvbOToe9wEnpid8ylU+27+oG8uibJNlNuRyXApUjw==} + '@aws-sdk/credential-provider-sso@3.621.0': + resolution: {integrity: sha512-Kza0jcFeA/GEL6xJlzR2KFf1PfZKMFnxfGzJzl5yN7EjoGdMijl34KaRyVnfRjnCWcsUpBWKNIDk9WZVMY9yiw==} engines: {node: '>=16.0.0'} - '@aws-sdk/credential-provider-web-identity@3.609.0': - resolution: {integrity: sha512-U+PG8NhlYYF45zbr1km3ROtBMYqyyj/oK8NRp++UHHeuavgrP+4wJ4wQnlEaKvJBjevfo3+dlIBcaeQ7NYejWg==} + '@aws-sdk/credential-provider-web-identity@3.621.0': + resolution: {integrity: sha512-w7ASSyfNvcx7+bYGep3VBgC3K6vEdLmlpjT7nSIHxxQf+WSdvy+HynwJosrpZax0sK5q0D1Jpn/5q+r5lwwW6w==} engines: {node: '>=16.0.0'} peerDependencies: - '@aws-sdk/client-sts': ^3.609.0 + '@aws-sdk/client-sts': ^3.621.0 - '@aws-sdk/middleware-bucket-endpoint@3.616.0': - resolution: {integrity: sha512-KZv78s8UE7+s3qZCfG3pE9U9XV5WTP478aNWis5gDXmsb5LF7QWzEeR8kve5dnjNlK6qVQ33v+mUZa6lR5PwMw==} + '@aws-sdk/middleware-bucket-endpoint@3.620.0': + resolution: {integrity: sha512-eGLL0W6L3HDb3OACyetZYOWpHJ+gLo0TehQKeQyy2G8vTYXqNTeqYhuI6up9HVjBzU9eQiULVQETmgQs7TFaRg==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-expect-continue@3.616.0': - resolution: {integrity: sha512-IM1pfJPm7pDUXa55js9bnGjS8o3ldzDwf95mL9ZAYdEsm10q6i0ZxZbbro2gTq25Ap5ykdeeS34lOSzIqPiW1A==} + '@aws-sdk/middleware-expect-continue@3.620.0': + resolution: {integrity: sha512-QXeRFMLfyQ31nAHLbiTLtk0oHzG9QLMaof5jIfqcUwnOkO8YnQdeqzakrg1Alpy/VQ7aqzIi8qypkBe2KXZz0A==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.616.0': - resolution: {integrity: sha512-Mrco/dURoTXVqwcnYRcyrFaPTIg36ifg2PK0kUYfSVTGEOClZOQXlVG5zYCZoo3yEMgy/gLT907FjUQxwoifIw==} + '@aws-sdk/middleware-flexible-checksums@3.620.0': + resolution: {integrity: sha512-ftz+NW7qka2sVuwnnO1IzBku5ccP+s5qZGeRTPgrKB7OzRW85gthvIo1vQR2w+OwHFk7WJbbhhWwbCbktnP4UA==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-host-header@3.616.0': - resolution: {integrity: sha512-mhNfHuGhCDZwYCABebaOvTgOM44UCZZRq2cBpgPZLVKP0ydAv5aFHXv01goexxXHqgHoEGx0uXWxlw0s2EpFDg==} + '@aws-sdk/middleware-host-header@3.620.0': + resolution: {integrity: sha512-VMtPEZwqYrII/oUkffYsNWY9PZ9xpNJpMgmyU0rlDQ25O1c0Hk3fJmZRe6pEkAJ0omD7kLrqGl1DUjQVxpd/Rg==} engines: {node: '>=16.0.0'} '@aws-sdk/middleware-location-constraint@3.609.0': @@ -839,36 +851,36 @@ packages: resolution: {integrity: sha512-S62U2dy4jMDhDFDK5gZ4VxFdWzCtLzwbYyFZx2uvPYTECkepLUfzLic2BHg2Qvtu4QjX+oGE3P/7fwaGIsGNuQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-recursion-detection@3.616.0': - resolution: {integrity: sha512-LQKAcrZRrR9EGez4fdCIVjdn0Ot2HMN12ChnoMGEU6oIxnQ2aSC7iASFFCV39IYfeMh7iSCPj7Wopqw8rAouzg==} + '@aws-sdk/middleware-recursion-detection@3.620.0': + resolution: {integrity: sha512-nh91S7aGK3e/o1ck64sA/CyoFw+gAYj2BDOnoNa6ouyCrVJED96ZXWbhye/fz9SgmNUZR2g7GdVpiLpMKZoI5w==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-sdk-s3@3.616.0': - resolution: {integrity: sha512-heq9pzn0NRX6VL/oMlmwZdgcCh5eJUDscvwMl/oGev0tNdTpB2oGU+wPaNMka7IrW3eBPn7APmY9fdS1kBaBoQ==} + '@aws-sdk/middleware-sdk-s3@3.621.0': + resolution: {integrity: sha512-CJrQrtKylcqvyPkRR16JmPZkHroCkWwLErQrg30ZcBPNNok8xbfX6cYqG16XDTnu4lSYzv2Yqc4w4oOBv8xerQ==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-signing@3.616.0': - resolution: {integrity: sha512-wwzZFlXyURwo40oz1NmufreQa5DqwnCF8hR8tIP5+oKCyhbkmlmv8xG4Wn51bzY2WEbQhvFebgZSFTEvelCoCg==} + '@aws-sdk/middleware-signing@3.620.0': + resolution: {integrity: sha512-gxI7rubiaanUXaLfJ4NybERa9MGPNg2Ycl/OqANsozrBnR3Pw8vqy3EuVImQOyn2pJ2IFvl8ZPoSMHf4pX56FQ==} engines: {node: '>=16.0.0'} '@aws-sdk/middleware-ssec@3.609.0': resolution: {integrity: sha512-GZSD1s7+JswWOTamVap79QiDaIV7byJFssBW68GYjyRS5EBjNfwA/8s+6uE6g39R3ojyTbYOmvcANoZEhSULXg==} engines: {node: '>=16.0.0'} - '@aws-sdk/middleware-user-agent@3.616.0': - resolution: {integrity: sha512-iMcAb4E+Z3vuEcrDsG6T2OBNiqWAquwahP9qepHqfmnmJqHr1mSHtXDYTGBNid31+621sUQmneUQ+fagpGAe4w==} + '@aws-sdk/middleware-user-agent@3.620.0': + resolution: {integrity: sha512-bvS6etn+KsuL32ubY5D3xNof1qkenpbJXf/ugGXbg0n98DvDFQ/F+SMLxHgbnER5dsKYchNnhmtI6/FC3HFu/A==} engines: {node: '>=16.0.0'} '@aws-sdk/region-config-resolver@3.614.0': resolution: {integrity: sha512-vDCeMXvic/LU0KFIUjpC3RiSTIkkvESsEfbVHiHH0YINfl8HnEqR5rj+L8+phsCeVg2+LmYwYxd5NRz4PHxt5g==} engines: {node: '>=16.0.0'} - '@aws-sdk/s3-request-presigner@3.616.0': - resolution: {integrity: sha512-C5ADFHTBCPGw+W3XNvS7vZdCY2LtRbcw05hu34xxhNlDXatOAPE4O22uRfiaZq12Lu0Qq8ylNYnD8I28r7I4Qg==} + '@aws-sdk/s3-request-presigner@3.621.0': + resolution: {integrity: sha512-7XCH5wy1guywSa4PHKrSiAqm/mYpuKURQWD9nGN9tl2DWec6OK7z+TTTCOml8lBX8Mg5Hx2GUdO3V8uRVYnEmw==} engines: {node: '>=16.0.0'} - '@aws-sdk/signature-v4-multi-region@3.616.0': - resolution: {integrity: sha512-WQn43cfnwbG6jnPjh/SyujDQVqbRjGFY9tGI/tqtUvvGwoDhI343TSDCA7fvs0FEC6Za6vgOBq1CwPv3CFyfhA==} + '@aws-sdk/signature-v4-multi-region@3.621.0': + resolution: {integrity: sha512-u+ulCaHFveqHaTxgiYrEAyfBVP6GRKjnmDut67CtjhjslshPWYpo/ndtlCW1zc0RDne3uUeK13Pqp7dp7p1d6g==} engines: {node: '>=16.0.0'} '@aws-sdk/token-providers@3.614.0': @@ -921,14 +933,22 @@ packages: resolution: {integrity: sha512-e701mcfApCJqMMueQI0Fb68Amflj83+dvAvHawoBpAz+GDjCIyGHzNwnefjsWJ3xiYAqqiQFoWbspGYBdb2/ng==} engines: {node: '>=6.9.0'} - '@babel/core@7.24.9': - resolution: {integrity: sha512-5e3FI4Q3M3Pbr21+5xJwCv6ZT6KmGkI0vw3Tozy5ODAQFTIWe37iT8Cr7Ice2Ntb+M3iSKCEWMB1MBgKrW3whg==} + '@babel/compat-data@7.25.2': + resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} engines: {node: '>=6.9.0'} '@babel/generator@7.24.9': resolution: {integrity: sha512-G8v3jRg+z8IwY1jHFxvCNhOPYPterE4XljNgdGTYfSTtzzwjIswIzIaSPSLs3R7yFuqnqNeay5rjICfqVr+/6A==} engines: {node: '>=6.9.0'} + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@7.24.7': resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} engines: {node: '>=6.9.0'} @@ -937,8 +957,8 @@ packages: resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.24.8': - resolution: {integrity: sha512-oU+UoqCHdp+nWVDkpldqIQL/i/bvAv53tRqLG/s+cOXxe66zOYLU7ar/Xs3LdmBihrUMEUhwu6dMZwbNOYDwvw==} + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} engines: {node: '>=6.9.0'} '@babel/helper-create-class-features-plugin@7.24.8': @@ -978,8 +998,8 @@ packages: resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.24.9': - resolution: {integrity: sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==} + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -1032,8 +1052,8 @@ packages: resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.24.8': - resolution: {integrity: sha512-gV2265Nkcz7weJJfvDoAEVzC1e2OTDpkGbEsebse8koXUJUXPsCMi7sRo/+SPMuMZ9MtUPnGwITTnQnU5YjyaQ==} + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} engines: {node: '>=6.9.0'} '@babel/highlight@7.24.7': @@ -1045,6 +1065,11 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.25.0': + resolution: {integrity: sha512-CzdIU9jdP0dg7HdyB+bHvDJGagUv+qtzZt5rYCWwW6tITNqV9odjp6Qu41gkG0ca5UfdDUWrKkiAnHHdGRnOrA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7': resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} engines: {node: '>=6.9.0'} @@ -1542,18 +1567,30 @@ packages: resolution: {integrity: sha512-5F7SDGs1T72ZczbRwbGO9lQi0NLjQxzl6i4lJxLxfW9U5UluCSyEJeniWvnhl3/euNiqQVbo8zruhsDfid0esA==} engines: {node: '>=6.9.0'} - '@babel/template@7.24.7': - resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + '@babel/runtime@7.25.0': + resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} engines: {node: '>=6.9.0'} '@babel/traverse@7.24.8': resolution: {integrity: sha512-t0P1xxAPzEDcEPmjprAQq19NWum4K0EQPjMwZQZbHt+GiZqvjCHjj755Weq1YRPVzBI+3zSfvScfpnuIecVFJQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.2': + resolution: {integrity: sha512-s4/r+a7xTnny2O6FcZzqgT6nE4/GHEdcqj4qAeglbUOh0TeglEfmNJFAd/OLoVtGd6ZhAO8GCVvCNUO5t/VJVQ==} + engines: {node: '>=6.9.0'} + '@babel/types@7.24.9': resolution: {integrity: sha512-xm8XrMKz0IlUdocVbYJe0Z9xEgidU7msskG8BbhnTPK/HZ2z/7FP7ykqPgrUH+C+r414mNfNWam1f2vqOjqjYQ==} engines: {node: '>=6.9.0'} + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1563,6 +1600,9 @@ packages: '@bundled-es-modules/statuses@1.0.1': resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -1851,16 +1891,16 @@ packages: resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.17.0': - resolution: {integrity: sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==} + '@eslint/config-array@0.17.1': + resolution: {integrity: sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.1.0': resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.7.0': - resolution: {integrity: sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==} + '@eslint/js@9.8.0': + resolution: {integrity: sha512-MfluB7EUfxXtv3i/++oh89uzAr4PDI4nn201hsp+qaXqsjAWzinlZEHEfPgAX4doIlKvPG/i0A9dpKxOLII8yA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.4': @@ -1927,14 +1967,14 @@ packages: '@floating-ui/core@1.6.4': resolution: {integrity: sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==} - '@floating-ui/core@1.6.5': - resolution: {integrity: sha512-8GrTWmoFhm5BsMZOTHeGD2/0FLKLQQHvO/ZmQga4tKempYRLz8aqJGqXVuQgisnMObq2YZ2SgkwctN1LOOxcqA==} + '@floating-ui/core@1.6.6': + resolution: {integrity: sha512-Vkvsw6EcpMHjvZZdMkSY+djMGFbt7CRssW99Ne8tar2WLnZ/l3dbxeTShbLQj+/s35h+Qb4cmnob+EzwtjrXGQ==} '@floating-ui/dom@1.6.7': resolution: {integrity: sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==} - '@floating-ui/dom@1.6.8': - resolution: {integrity: sha512-kx62rP19VZ767Q653wsP1XZCGIirkE09E0QUGNYTM/ttbbQHqcGPdSfWFxUyyNLc/W6aoJRBajOSXhP6GXjC0Q==} + '@floating-ui/dom@1.6.9': + resolution: {integrity: sha512-zB1PcI350t4tkm3rvUhSRKa9sT7vH5CrAbQxW+VaPYJXKAO0gsg4CTueL+6Ajp7XzAQC8CW4Jj1Wgqc0sB6oUQ==} '@floating-ui/react-dom@2.1.1': resolution: {integrity: sha512-4h84MJt3CHrtG18mGsXuLCHMrug49d7DFkU0RMIyshRveBeyV2hmV/pDaF2Uxtu8kgq5r46llp5E5FQiR0K2Yg==} @@ -1942,14 +1982,14 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/react@0.26.20': - resolution: {integrity: sha512-RixKJJG92fcIsVoqrFr4Onpzh7hlOx4U7NV4aLhMLmtvjZ5oTB/WzXaANYUZATKqXvvW7t9sCxtzejip26N5Ag==} + '@floating-ui/react@0.26.21': + resolution: {integrity: sha512-7P5ncDIiYd6RrwpCDbKyFzvabM014QlzlumtDbK3Bck0UueC+Rp8BLS34qcGBcN1pZCTodl4QNnCVmKv4tSxfQ==} peerDependencies: react: '>=16.8.0' react-dom: '>=16.8.0' - '@floating-ui/utils@0.2.5': - resolution: {integrity: sha512-sTcG+QZ6fdEUObICavU+aB3Mp8HY4n14wYHdxK4fXjPmv3PXZZeY5RaguJmGyeH/CJQhX3fqKUtS4qc1LoHwhQ==} + '@floating-ui/utils@0.2.6': + resolution: {integrity: sha512-0KI3zGxIUs1KDR/pjQPdJH4Z8nGBm0yJ5WRoRfdw1Kzeh45jkIfA0rmD0kBF6fKHH+xaH7g8y4jIXyAV5MGK3g==} '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -2105,20 +2145,20 @@ packages: cpu: [x64] os: [win32] - '@inquirer/confirm@3.1.15': - resolution: {integrity: sha512-CiLGi3JmKGEsia5kYJN62yG/njHydbYIkzSBril7tCaKbsnIqxa2h/QiON9NjfwiKck/2siosz4h7lVhLFocMQ==} + '@inquirer/confirm@3.1.20': + resolution: {integrity: sha512-UvG5Plh0MfCqUvZB8RKzBBEWB/EeMzO59Awy/Jg4NgeSjIPqhPaQFnnmxiyWUTwZh4uENB7wCklEFUwckioXWg==} engines: {node: '>=18'} - '@inquirer/core@9.0.3': - resolution: {integrity: sha512-p2BRZv/vMmpwlU4ZR966vKQzGVCi4VhLjVofwnFLziTQia541T7i1Ar8/LPh+LzjkXzocme+g5Io6MRtzlCcNA==} + '@inquirer/core@9.0.8': + resolution: {integrity: sha512-ttnI/BGlP9SxjbQnv1nssv7dPAwiR82KmjJZx2SxSZyi2mGbaEvh4jg0I4yU/4mVQf7QvCVGGr/hGuJFEYhwnw==} engines: {node: '>=18'} - '@inquirer/figures@1.0.4': - resolution: {integrity: sha512-R7Gsg6elpuqdn55fBH2y9oYzrU/yKrSmIsDX4ROT51vohrECFzTf2zw9BfUbOW8xjfmM2QbVoVYdTwhrtEKWSQ==} + '@inquirer/figures@1.0.5': + resolution: {integrity: sha512-79hP/VWdZ2UVc9bFGJnoQ/lQMpL74mGgzSYX1xUqCVk7/v73vJCMw1VuyWN1jGkZ9B3z7THAbySqGbCNefcjfA==} engines: {node: '>=18'} - '@inquirer/type@1.5.0': - resolution: {integrity: sha512-L/UdayX9Z1lLN+itoTKqJ/X4DX5DaWu2Sruwt4XgZzMNv32x4qllbzMX4MbJlz0yxAQtU19UvABGOjmdq1u3qA==} + '@inquirer/type@1.5.1': + resolution: {integrity: sha512-m3YgGQlKNS0BM+8AFiJkCsTqHEFCWn6s/Rqye3mYwvqY6LdfUv12eSwbsgNzrYyrLXiy7IrrjDLPysaSBwEfhw==} engines: {node: '>=18'} '@isaacs/cliui@8.0.2': @@ -2246,9 +2286,9 @@ packages: '@microsoft/tsdoc@0.15.0': resolution: {integrity: sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA==} - '@mswjs/cookies@1.1.1': - resolution: {integrity: sha512-W68qOHEjx1iD+4VjQudlx26CPIoxmIAtK4ZCexU0/UJBG6jYhcuyzKJx+Iw8uhBIGd9eba64XgWVgo20it1qwA==} - engines: {node: '>=18'} + '@mole-inc/bin-wrapper@8.0.1': + resolution: {integrity: sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} '@mswjs/interceptors@0.29.1': resolution: {integrity: sha512-3rDakgJZ77+RiQUuSK69t1F0m8BQKA8Vh5DCS5V0DWvNY67zob2JhhQrhCO0AKLGINTRSFd1tBaHcJTkhefoSw==} @@ -2404,8 +2444,8 @@ packages: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 - '@nestjs/schematics@10.1.2': - resolution: {integrity: sha512-S0bMtZM5U4mAiqkhRyZkXgjmOHBS5P/lp/vEydgMR4F7csOShc3jFeKVs1Eghd9xCFezGKy3SHy7hFT6dpPhWQ==} + '@nestjs/schematics@10.1.3': + resolution: {integrity: sha512-aLJ4Nl/K/u6ZlgLa0NjKw5CuBOIgc6vudF42QvmGueu5FaMGM6IJrAuEvB5T2kr0PAfVwYmDFBBHCWdYhTw4Tg==} peerDependencies: typescript: '>=4.8.2' @@ -2672,8 +2712,8 @@ packages: '@open-draft/until@2.1.0': resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@opensearch-project/opensearch@2.10.0': - resolution: {integrity: sha512-I3Ko09HvA50zyDi92fgEZfFFaNHhpvXcYLImdKTSL6eEwKqQmszqkLF2g5NTgEyb4Jh9uD2RGX8EYr9PO9zenQ==} + '@opensearch-project/opensearch@2.11.0': + resolution: {integrity: sha512-G+SZwtWRDv90IrtTSNnCt0MQjHVyqrcIXcpwN68vjHnfbun2+RHn+ux4K7dnG+s/KwWzVKIpPFoRjg2gfFX0Mw==} engines: {node: '>=10', yarn: ^1.22.10} '@opentelemetry/api@1.9.0': @@ -2743,8 +2783,8 @@ packages: resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.45.3': - resolution: {integrity: sha512-UKF4XsBfy+u3MFWEH44hva1Q8Da28G6RFtR2+5saw+jgAFQV5yYnB1fu68Mz7fO+5GJF3wgwAIs0UelU8TxFrA==} + '@playwright/test@1.46.0': + resolution: {integrity: sha512-/QYft5VArOrGRP5pgkrfKksqsKA6CEFyGQ/gjNe6q0y4tZ1aaPfq4gIjudr1s3D+pXyrPRdsy4opKDrjBabE5w==} engines: {node: '>=18'} hasBin: true @@ -2785,11 +2825,11 @@ packages: '@redocly/ajv@8.11.0': resolution: {integrity: sha512-9GWx27t7xWhDIR02PA18nzBdLcKQRgc46xNQvjFkrYk4UOmvKhJ/dawwiX0cCOeetN5LcaaiqQbVOWYK62SGHw==} - '@redocly/config@0.6.3': - resolution: {integrity: sha512-hGWJgCsXRw0Ow4rplqRlUQifZvoSwZipkYnt11e3SeH1Eb23VUIDBcRuaQOUqy1wn0eevXkU2GzzQ8fbKdQ7Mg==} + '@redocly/config@0.7.0': + resolution: {integrity: sha512-6GKxTo/9df0654Mtivvr4lQnMOp+pRj9neVywmI5+BwfZLTtkJnj2qB3D6d8FHTr4apsNOf6zTa5FojX0Evh4g==} - '@redocly/openapi-core@1.18.0': - resolution: {integrity: sha512-kcbt7w23pcVYGLnJkh2LZpXF1OX5RDM4DLOtwPug2HvRE8ow/YfY8ZEM1YCFlA41D8rBPBVP918cYeIx4BVUbw==} + '@redocly/openapi-core@1.19.0': + resolution: {integrity: sha512-ezK6qr80sXvjDgHNrk/zmRs9vwpIAeHa0T/qmo96S+ib4ThQ5a8f3qjwEqxMeVxkxCTbkaY9sYSJKOxv4ejg5w==} engines: {node: '>=14.19.0', npm: '>=7.0.0'} '@rollup/plugin-commonjs@26.0.1': @@ -2810,83 +2850,83 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.19.0': - resolution: {integrity: sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==} + '@rollup/rollup-android-arm-eabi@4.20.0': + resolution: {integrity: sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.19.0': - resolution: {integrity: sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==} + '@rollup/rollup-android-arm64@4.20.0': + resolution: {integrity: sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.19.0': - resolution: {integrity: sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==} + '@rollup/rollup-darwin-arm64@4.20.0': + resolution: {integrity: sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.19.0': - resolution: {integrity: sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==} + '@rollup/rollup-darwin-x64@4.20.0': + resolution: {integrity: sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-linux-arm-gnueabihf@4.19.0': - resolution: {integrity: sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==} + '@rollup/rollup-linux-arm-gnueabihf@4.20.0': + resolution: {integrity: sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.19.0': - resolution: {integrity: sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==} + '@rollup/rollup-linux-arm-musleabihf@4.20.0': + resolution: {integrity: sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.19.0': - resolution: {integrity: sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==} + '@rollup/rollup-linux-arm64-gnu@4.20.0': + resolution: {integrity: sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.19.0': - resolution: {integrity: sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==} + '@rollup/rollup-linux-arm64-musl@4.20.0': + resolution: {integrity: sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.19.0': - resolution: {integrity: sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==} + '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': + resolution: {integrity: sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.19.0': - resolution: {integrity: sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==} + '@rollup/rollup-linux-riscv64-gnu@4.20.0': + resolution: {integrity: sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.19.0': - resolution: {integrity: sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==} + '@rollup/rollup-linux-s390x-gnu@4.20.0': + resolution: {integrity: sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.19.0': - resolution: {integrity: sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==} + '@rollup/rollup-linux-x64-gnu@4.20.0': + resolution: {integrity: sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.19.0': - resolution: {integrity: sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==} + '@rollup/rollup-linux-x64-musl@4.20.0': + resolution: {integrity: sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.19.0': - resolution: {integrity: sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==} + '@rollup/rollup-win32-arm64-msvc@4.20.0': + resolution: {integrity: sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.19.0': - resolution: {integrity: sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==} + '@rollup/rollup-win32-ia32-msvc@4.20.0': + resolution: {integrity: sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.19.0': - resolution: {integrity: sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==} + '@rollup/rollup-win32-x64-msvc@4.20.0': + resolution: {integrity: sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==} cpu: [x64] os: [win32] @@ -2905,6 +2945,10 @@ packages: '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + '@sindresorhus/merge-streams@2.3.0': resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} @@ -2929,12 +2973,12 @@ packages: resolution: {integrity: sha512-SkW5LxfkSI1bUC74OtfBbdz+grQXYiPYolyu8VfpLIjEoN/sHVBlLeGXMQ1vX4ejkgfv6sxVbQJ32yF2cl1veA==} engines: {node: '>=16.0.0'} - '@smithy/core@2.2.8': - resolution: {integrity: sha512-1Y0XX0Ucyg0LWTfTVLWpmvSRtFRniykUl3dQ0os1sTd03mKDudR6mVyX+2ak1phwPXx2aEWMAAdW52JNi0mc3A==} + '@smithy/core@2.3.1': + resolution: {integrity: sha512-BC7VMXx/1BCmRPCVzzn4HGWAtsrb7/0758EtwOGFJQrlSwJBEjCcDLNZLFoL/68JexYa2s+KmgL/UfmXdG6v1w==} engines: {node: '>=16.0.0'} - '@smithy/credential-provider-imds@3.1.4': - resolution: {integrity: sha512-NKyH01m97Xa5xf3pB2QOF3lnuE8RIK0hTVNU5zvZAwZU8uspYO4DHQVlK+Y5gwSrujTfHvbfd1D9UFJAc0iYKQ==} + '@smithy/credential-provider-imds@3.2.0': + resolution: {integrity: sha512-0SCIzgd8LYZ9EJxUjLXBmEKSZR/P/w6l7Rz/pab9culE/RWuqelAKGJvn5qUOl8BgX8Yj5HWM50A5hiB/RzsgA==} engines: {node: '>=16.0.0'} '@smithy/eventstream-codec@3.1.2': @@ -2956,8 +3000,8 @@ packages: resolution: {integrity: sha512-Od9dv8zh3PgOD7Vj4T3HSuox16n0VG8jJIM2gvKASL6aCtcS8CfHZDWe1Ik3ZXW6xBouU+45Q5wgoliWDZiJ0A==} engines: {node: '>=16.0.0'} - '@smithy/fetch-http-handler@3.2.2': - resolution: {integrity: sha512-3LaWlBZObyGrOOd7e5MlacnAKEwFBmAeiW/TOj2eR9475Vnq30uS2510+tnKbxrGjROfNdOhQqGo5j3sqLT6bA==} + '@smithy/fetch-http-handler@3.2.4': + resolution: {integrity: sha512-kBprh5Gs5h7ug4nBWZi1FZthdqSM+T7zMmsZxx0IBvWUn7dK3diz2SHn7Bs4dQGFDk8plDv375gzenDoNwrXjg==} '@smithy/hash-blob-browser@3.1.2': resolution: {integrity: sha512-hAbfqN2UbISltakCC2TP0kx4LqXBttEv2MqSPE98gVuDFMf05lU+TpC41QtqGP3Ff5A3GwZMPfKnEy0VmEUpmg==} @@ -2984,16 +3028,16 @@ packages: '@smithy/md5-js@3.0.3': resolution: {integrity: sha512-O/SAkGVwpWmelpj/8yDtsaVe6sINHLB1q8YE/+ZQbDxIw3SRLbTZuRaI10K12sVoENdnHqzPp5i3/H+BcZ3m3Q==} - '@smithy/middleware-content-length@3.0.4': - resolution: {integrity: sha512-wySGje/KfhsnF8YSh9hP16pZcl3C+X6zRsvSfItQGvCyte92LliilU3SD0nR7kTlxnAJwxY8vE/k4Eoezj847Q==} + '@smithy/middleware-content-length@3.0.5': + resolution: {integrity: sha512-ILEzC2eyxx6ncej3zZSwMpB5RJ0zuqH7eMptxC4KN3f+v9bqT8ohssKbhNR78k/2tWW+KS5Spw+tbPF4Ejyqvw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-endpoint@3.0.5': - resolution: {integrity: sha512-V4acqqrh5tDxUEGVTOgf2lYMZqPQsoGntCrjrJZEeBzEzDry2d2vcI1QCXhGltXPPY+BMc6eksZMguA9fIY8vA==} + '@smithy/middleware-endpoint@3.1.0': + resolution: {integrity: sha512-5y5aiKCEwg9TDPB4yFE7H6tYvGFf1OJHNczeY10/EFF8Ir8jZbNntQJxMWNfeQjC1mxPsaQ6mR9cvQbf+0YeMw==} engines: {node: '>=16.0.0'} - '@smithy/middleware-retry@3.0.11': - resolution: {integrity: sha512-/TIRWmhwMpv99JCGuMhJPnH7ggk/Lah7s/uNDyr7faF02BxNsyD/fz9Tw7pgCf9tYOKgjimm2Qml1Aq1pbkt6g==} + '@smithy/middleware-retry@3.0.13': + resolution: {integrity: sha512-zvCLfaRYCaUmjbF2yxShGZdolSHft7NNCTA28HVN9hKcEbOH+g5irr1X9s+in8EpambclGnevZY4A3lYpvDCFw==} engines: {node: '>=16.0.0'} '@smithy/middleware-serde@3.0.3': @@ -3008,16 +3052,16 @@ packages: resolution: {integrity: sha512-YvnElQy8HR4vDcAjoy7Xkx9YT8xZP4cBXcbJSgm/kxmiQu08DwUwj8rkGnyoJTpfl/3xYHH+d8zE+eHqoDCSdQ==} engines: {node: '>=16.0.0'} - '@smithy/node-http-handler@3.1.3': - resolution: {integrity: sha512-UiKZm8KHb/JeOPzHZtRUfyaRDO1KPKPpsd7iplhiwVGOeVdkiVJ5bVe7+NhWREMOKomrDIDdSZyglvMothLg0Q==} + '@smithy/node-http-handler@3.1.4': + resolution: {integrity: sha512-+UmxgixgOr/yLsUxcEKGH0fMNVteJFGkmRltYFHnBMlogyFdpzn2CwqWmxOrfJELhV34v0WSlaqG1UtE1uXlJg==} engines: {node: '>=16.0.0'} '@smithy/property-provider@3.1.3': resolution: {integrity: sha512-zahyOVR9Q4PEoguJ/NrFP4O7SMAfYO1HLhB18M+q+Z4KFd4V2obiMnlVoUFzFLSPeVt1POyNWneHHrZaTMoc/g==} engines: {node: '>=16.0.0'} - '@smithy/protocol-http@4.0.4': - resolution: {integrity: sha512-fAA2O4EFyNRyYdFLVIv5xMMeRb+3fRKc/Rt2flh5k831vLvUmNFXcydeg7V3UeEhGURJI4c1asmGJBjvmF6j8Q==} + '@smithy/protocol-http@4.1.0': + resolution: {integrity: sha512-dPVoHYQ2wcHooGXg3LQisa1hH0e4y0pAddPMeeUPipI1tEOqL6A4N0/G7abeq+K8wrwSgjk4C0wnD1XZpJm5aA==} engines: {node: '>=16.0.0'} '@smithy/querystring-builder@3.0.3': @@ -3036,12 +3080,12 @@ packages: resolution: {integrity: sha512-qMxS4hBGB8FY2GQqshcRUy1K6k8aBWP5vwm8qKkCT3A9K2dawUwOIJfqh9Yste/Bl0J2lzosVyrXDj68kLcHXQ==} engines: {node: '>=16.0.0'} - '@smithy/signature-v4@4.0.0': - resolution: {integrity: sha512-ervYjQ+ZvmNG51Ui77IOTPri7nOyo8Kembzt9uwwlmtXJPmFXvslOahbA1blvAVs7G0KlYMiOBog1rAt7RVXxg==} + '@smithy/signature-v4@4.1.0': + resolution: {integrity: sha512-aRryp2XNZeRcOtuJoxjydO6QTaVhxx/vjaR+gx7ZjaFgrgPRyZ3HCTbfwqYj6ZWEBHkCSUfcaymKPURaByukag==} engines: {node: '>=16.0.0'} - '@smithy/smithy-client@3.1.9': - resolution: {integrity: sha512-My2RaInZ4gSwJUPMaiLR/Nk82+c4LlvqpXA+n7lonGYgCZq23Tg+/xFhgmiejJ6XPElYJysTPyV90vKyp17+1g==} + '@smithy/smithy-client@3.1.11': + resolution: {integrity: sha512-l0BpyYkciNyMaS+PnFFz4aO5sBcXvGLoJd7mX9xrMBIm2nIQBVvYgp2ZpPDMzwjKCavsXu06iuCm0F6ZJZc6yQ==} engines: {node: '>=16.0.0'} '@smithy/types@3.3.0': @@ -3074,12 +3118,12 @@ packages: resolution: {integrity: sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==} engines: {node: '>=16.0.0'} - '@smithy/util-defaults-mode-browser@3.0.11': - resolution: {integrity: sha512-O3s9DGb3bmRvEKmT8RwvSWK4A9r6svfd+MnJB+UMi9ZcCkAnoRtliulOnGF0qCMkKF9mwk2tkopBBstalPY/vg==} + '@smithy/util-defaults-mode-browser@3.0.13': + resolution: {integrity: sha512-ZIRSUsnnMRStOP6OKtW+gCSiVFkwnfQF2xtf32QKAbHR6ACjhbAybDvry+3L5qQYdh3H6+7yD/AiUE45n8mTTw==} engines: {node: '>= 10.0.0'} - '@smithy/util-defaults-mode-node@3.0.11': - resolution: {integrity: sha512-qd4a9qtyOa/WY14aHHOkMafhh9z8D2QTwlcBoXMTPnEwtcY+xpe1JyFm9vya7VsB8hHsfn3XodEtwqREiu4ygQ==} + '@smithy/util-defaults-mode-node@3.0.13': + resolution: {integrity: sha512-voUa8TFJGfD+U12tlNNLCDlXibt9vRdNzRX45Onk/WxZe7TS+hTOZouEZRa7oARGicdgeXvt1A0W45qLGYdy+g==} engines: {node: '>= 10.0.0'} '@smithy/util-endpoints@2.0.5': @@ -3098,8 +3142,8 @@ packages: resolution: {integrity: sha512-AFw+hjpbtVApzpNDhbjNG5NA3kyoMs7vx0gsgmlJF4s+yz1Zlepde7J58zpIRIsdjc+emhpAITxA88qLkPF26w==} engines: {node: '>=16.0.0'} - '@smithy/util-stream@3.1.1': - resolution: {integrity: sha512-EhRnVvl3AhoHAT2rGQ5o+oSDRM/BUSMPLZZdRJZLcNVUsFAjOs4vHaPdNQivTSzRcFxf5DA4gtO46WWU2zimaw==} + '@smithy/util-stream@3.1.3': + resolution: {integrity: sha512-FIv/bRhIlAxC0U7xM1BCnF2aDRPq0UaelqBHkM2lsCp26mcBbgI0tCVTv+jGdsQLUmAMybua/bjDsSu8RQHbmw==} engines: {node: '>=16.0.0'} '@smithy/util-uri-escape@3.0.0': @@ -3222,68 +3266,79 @@ packages: '@swc-node/sourcemap-support@0.5.1': resolution: {integrity: sha512-JxIvIo/Hrpv0JCHSyRpetAdQ6lB27oFYhv0PKCNf1g2gUXOjpeR1exrXccRxLMuAV5WAmGFBwRnNOJqN38+qtg==} - '@swc/core-darwin-arm64@1.7.0': - resolution: {integrity: sha512-2ylhM7f0HwUwLrFYZAe/dse8PCbPsYcJS3Dt7Q8NT3PUn7vy6QOMxNcOPPuDrnmaXqQQO3oxdmRapguTxaat9g==} + '@swc/cli@0.4.0': + resolution: {integrity: sha512-4JdVrPtF/4rCMXp6Q1h5I6YkYZrCCcqod7Wk97ZQq7K8vNGzJUryBv4eHCvqx5sJOJBrbYm9fcswe1B0TygNoA==} + engines: {node: '>= 16.14.0'} + hasBin: true + peerDependencies: + '@swc/core': ^1.2.66 + chokidar: ^3.5.1 + peerDependenciesMeta: + chokidar: + optional: true + + '@swc/core-darwin-arm64@1.7.6': + resolution: {integrity: sha512-6lYHey84ZzsdtC7UuPheM4Rm0Inzxm6Sb8U6dmKc4eCx8JL0LfWG4LC5RsdsrTxnjTsbriWlnhZBffh8ijUHIQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.7.0': - resolution: {integrity: sha512-SgVnN4gT1Rb9YfTkp4FCUITqSs7Yj0uB2SUciu5CV3HuGvS5YXCUzh+KrwpLFtx8NIgivISKcNnb41mJi98X8Q==} + '@swc/core-darwin-x64@1.7.6': + resolution: {integrity: sha512-Fyl+8aH9O5rpx4O7r2KnsPpoi32iWoKOYKiipeTbGjQ/E95tNPxbmsz4yqE8Ovldcga60IPJ5OKQA3HWRiuzdw==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.7.0': - resolution: {integrity: sha512-+Z9Dayart1iKJQEJJ9N/KS4z5EdXJE3WPFikY0jonKTo4Dd8RuyVz5yLvqcIMeVdz/SwximATaL6iJXw7hZS9A==} + '@swc/core-linux-arm-gnueabihf@1.7.6': + resolution: {integrity: sha512-2WxYTqFaOx48GKC2cbO1/IntA+w+kfCFy436Ij7qRqqtV/WAvTM9TC1OmiFbqq436rSot52qYmX8fkwdB5UcLQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.7.0': - resolution: {integrity: sha512-UnLrCiZ1EI4shznJn0xP6DLgsXUSwtfsdgHhGYCrvbgVBBve3S9iFgVFEB3SPl7Q/TdowNbrN4zHU0oChfiNfw==} + '@swc/core-linux-arm64-gnu@1.7.6': + resolution: {integrity: sha512-TBEGMSe0LhvPe4S7E68c7VzgT3OMu4VTmBLS7B2aHv4v8uZO92Khpp7L0WqgYU1y5eMjk+XLDLi4kokiNHv/Hg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.7.0': - resolution: {integrity: sha512-H724UANA+ptsfwKRr9mnaDa9cb5fw0oFysiGKTgb3DMYcgk3Od0jMTnXVPFSVpo7FlmyxeC9K8ueUPBOoOK6XA==} + '@swc/core-linux-arm64-musl@1.7.6': + resolution: {integrity: sha512-QI8QGL0HGT42tj7F1A+YAzhGkJjUcvvTfI1e2m704W0Enl2/UIK9v5D1zvQzYwusRyKuaQfbeBRYDh0NcLOGLg==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.7.0': - resolution: {integrity: sha512-SY3HA0K0Dpqt1HIfMLGpwL4hd4UaL2xHP5oZXPlRQPhUDZrbb4PbI3ZJnh66c63eL4ZR8EJ+HRFI0Alx5p69Zw==} + '@swc/core-linux-x64-gnu@1.7.6': + resolution: {integrity: sha512-61AYVzhjuNQAVIKKWOJu3H0/pFD28RYJGxnGg3YMhvRLRyuWNyY5Nyyj2WkKcz/ON+g38Arlz00NT1LDIViRLg==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.7.0': - resolution: {integrity: sha512-cEJ2ebtV1v/5Ilb55E05J6F5SrHKQWzUttIhR5Mkayyo+yvPslcpByuFC3D+J7X1ebziTOBpWuMpUdjLfh3SMQ==} + '@swc/core-linux-x64-musl@1.7.6': + resolution: {integrity: sha512-hQFznpfLK8XajfAAN9Cjs0w/aVmO7iu9VZvInyrTCRcPqxV5O+rvrhRxKvC1LRMZXr5M6JRSRtepp5w+TK4kAw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.7.0': - resolution: {integrity: sha512-ecQOOmzEssz+m0pR4xDYCGuvn3E/l0nQ3tk5jp1NA1lsAy4bMV0YbYCHjptYvWL/UjhIerIp3IlCJ8x5DodSog==} + '@swc/core-win32-arm64-msvc@1.7.6': + resolution: {integrity: sha512-Aqsd9afykVMuekzjm4X4TDqwxmG4CrzoOSFe0hZrn9SMio72l5eAPnMtYoe5LsIqtjV8MNprLfXaNbjHjTegmA==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.7.0': - resolution: {integrity: sha512-gz81seZkRn3zMnVOc7L5k6F4vQC82gIxmHiL+GedK+A37XI/X26AASU3zxvORnqQbwQYXQ+AEVckxBmFlz3v2g==} + '@swc/core-win32-ia32-msvc@1.7.6': + resolution: {integrity: sha512-9h0hYnOeRVNeQgHQTvD1Im67faNSSzBZ7Adtxyu9urNLfBTJilMllFd2QuGHlKW5+uaT6ZH7ZWDb+c/enx7Lcg==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.7.0': - resolution: {integrity: sha512-b5Fd1xEOw9uqBpj2lqsaR4Iq9UhiL84hNDcEsi6DQA7Y1l85waQAslTbS0E4/pJ1PISAs0jW0zIGLco1eaWBOg==} + '@swc/core-win32-x64-msvc@1.7.6': + resolution: {integrity: sha512-izeoB8glCSe6IIDQmrVm6bvR9muk9TeKgmtY7b6l1BwL4BFnTUk4dMmpbntT90bEVQn3JPCaPtUG4HfL8VuyuA==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.7.0': - resolution: {integrity: sha512-d4vMzH6ICllDwlPuhset2h8gu/USHdbyfJim+2hQEdxC0UONtfpmu38XBgNqRjStrji1Q5M10jfeUZL3cu1i8g==} + '@swc/core@1.7.6': + resolution: {integrity: sha512-FZxyao9eQks1MRmUshgsZTmlg/HB2oXK5fghkoWJm/1CU2q2kaJlVDll2as5j+rmWiwkp0Gidlq8wlXcEEAO+g==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '*' @@ -3306,8 +3361,12 @@ packages: peerDependencies: '@swc/core': '*' - '@swc/types@0.1.9': - resolution: {integrity: sha512-qKnCno++jzcJ4lM4NTfYifm1EFSCeIfKiAHAfkENZAV5Kl9PjJIyd2yeeVv6c/2CckuLyv2NmRC5pv6pm2WQBg==} + '@swc/types@0.1.12': + resolution: {integrity: sha512-wBJA+SdtkbFhHjTMYH+dEH1y4VpfGdAc2Kw/LK09i9bXd/K6j6PkDcFCEzb6iVfZMkPRrl/q0e3toqTAJdkIVA==} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} '@t3-oss/env-core@0.11.0': resolution: {integrity: sha512-PSalC5bG0a7XbyoLydiQdAnx3gICX6IQNctvh+TyLrdFxsxgocdj9Ui7sd061UlBzi+z4aIGjnem1kZx9QtUgQ==} @@ -3327,20 +3386,20 @@ packages: typescript: optional: true - '@tanstack/query-core@5.51.9': - resolution: {integrity: sha512-HsAwaY5J19MD18ykZDS3aVVh+bAt0i7m6uQlFC2b77DLV9djo+xEN7MWQAQQTR8IM+7r/zbozTQ7P0xr0bHuew==} + '@tanstack/query-core@5.51.21': + resolution: {integrity: sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==} - '@tanstack/query-devtools@5.51.9': - resolution: {integrity: sha512-FQqJynaEDuwQxoFLP3/i10HQwNYh4wxgs0NeSoL24BLWvpUdstgHqUm2zgwRov8Tmh5kjndPIWaXenwl0D47EA==} + '@tanstack/query-devtools@5.51.16': + resolution: {integrity: sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw==} - '@tanstack/react-query-devtools@5.51.11': - resolution: {integrity: sha512-8nQRbhdtvl/J9bO+bk/kPQesCOtDgk+oI4AmZJDnkf5OfKTJL3J4tTe+fhuXph7KP4DUOS+ge9o9TGt0OgWFHw==} + '@tanstack/react-query-devtools@5.51.21': + resolution: {integrity: sha512-mi5ef8dvsS48GsG6/8M60O2EgrzPK1kNPngOcHBTlIUrB5dGkxP9fuHf05GQRxtSp5W5GlyeUpzOmtkKNpf9dQ==} peerDependencies: - '@tanstack/react-query': ^5.51.11 + '@tanstack/react-query': ^5.51.21 react: ^18 || ^19 - '@tanstack/react-query@5.51.11': - resolution: {integrity: sha512-4Kq2x0XpDlpvSnaLG+8pHNH60zEc3mBvb3B2tOMDjcPCi/o+Du3p/9qpPLwJOTliVxxPJAP27fuIhLrsRdCr7A==} + '@tanstack/react-query@5.51.21': + resolution: {integrity: sha512-Q/V81x3sAYgCsxjwOkfLXfrmoG+FmDhLeHH5okC/Bp8Aaw2c33lbEo/mMcMnkxUPVtB2FLpzHT0tq3c+OlZEbw==} peerDependencies: react: ^18.0.0 @@ -3368,26 +3427,9 @@ packages: resolution: {integrity: sha512-0bxIdP9mmPiOJ6wHLj8bdJRq+51oddObeCGdEf6PNEhYd93ZYAN+lPRnEOVFtheVwDM7+p+tza3LAQgp0PTudg==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.4.7': - resolution: {integrity: sha512-GaKJ0nijoNf30dWSOOzQEBkWBRk4rG3C/efw8zKrimNuZpnS/6/AEwo0WvZHgJxG84cNCgxt+mtbe1fsvfLp2A==} + '@testing-library/jest-dom@6.4.8': + resolution: {integrity: sha512-JD0G+Zc38f5MBHA4NgxQMR5XtO5Jx9g86jqturNTt2WUfRmLDIY7iKkWHDCCTiDuFMre6nxAD5wHw9W5kI4rGw==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} - peerDependencies: - '@jest/globals': '>= 28' - '@types/bun': latest - '@types/jest': '>= 28' - jest: '>= 28' - vitest: '>= 0.32' - peerDependenciesMeta: - '@jest/globals': - optional: true - '@types/bun': - optional: true - '@types/jest': - optional: true - jest: - optional: true - vitest: - optional: true '@testing-library/react@16.0.0': resolution: {integrity: sha512-guuxUKRWQ+FgNX0h0NS0FIq3Q3uLtWVpBzcLOggmfMoUpgBnzBzvLLd4fbm6yS8ydJd94cIfY4yP9qUQjM2KwQ==} @@ -3410,6 +3452,9 @@ packages: peerDependencies: '@testing-library/dom': '>=7.21.4' + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} @@ -3459,6 +3504,9 @@ packages: '@types/body-parser@1.19.5': resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/cls-hooked@4.3.8': resolution: {integrity: sha512-tf/7H883gFA6MPlWI15EQtfNZ+oPL0gLKkOlx9UHFrun1fC/FkuyNBpTKq1B5E3T4fbvjId6WifHUdSGsMMuPg==} @@ -3522,6 +3570,9 @@ packages: '@types/hoist-non-react-statics@3.3.5': resolution: {integrity: sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==} + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/http-errors@2.0.4': resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} @@ -3552,6 +3603,9 @@ packages: '@types/jsonwebtoken@9.0.5': resolution: {integrity: sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==} + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + '@types/luxon@3.4.2': resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} @@ -3573,8 +3627,11 @@ packages: '@types/node@14.18.63': resolution: {integrity: sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==} - '@types/node@20.14.11': - resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} + '@types/node@20.14.14': + resolution: {integrity: sha512-d64f00982fS9YoOgJkAMolK7MN8Iq3TDdVjchbYHdEmjth/DHowx82GnoA+tVUAN+7vxfYUgAzi+JXbKNd2SDQ==} + + '@types/node@22.1.0': + resolution: {integrity: sha512-AOmuRF0R2/5j1knA3c6G3HOk523Ga+l+ZXltX8SF1+5oqcXijjfTd8fY3XRZqSihEu9XhtQnKYLmkFaoxgsJHw==} '@types/nodemailer@6.4.15': resolution: {integrity: sha512-0EBJxawVNjPkng1zm2vopRctuWVCxk34JcIlRuXSf54habUWdz1FB7wHDqOqvDa8Mtpt0Q3LTXQkAs2LNyK5jQ==} @@ -3582,6 +3639,18 @@ packages: '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + '@types/passport-jwt@4.0.1': + resolution: {integrity: sha512-Y0Ykz6nWP4jpxgEUYq8NoVZeCQPo1ZndJLfapI249g1jHChvRfZRO/LS3tqu26YgAS/laI1qx98sYGz0IalRXQ==} + + '@types/passport-local@1.0.38': + resolution: {integrity: sha512-nsrW4A963lYE7lNTv9cr5WmiUD1ibYJvWrpE13oxApFsRt77b0RdtZvKbCdNIY4v/QZ6TRQWaDDEwV1kCTmcXg==} + + '@types/passport-strategy@0.2.38': + resolution: {integrity: sha512-GC6eMqqojOooq993Tmnmp7AUTbbQSgilyvpCYQjT+H6JfG/g6RGc7nXEniZlp0zyKJ0WUdOiZWLBZft9Yug1uA==} + + '@types/passport@1.0.16': + resolution: {integrity: sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A==} + '@types/prop-types@15.7.12': resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} @@ -3612,6 +3681,9 @@ packages: '@types/react@18.3.3': resolution: {integrity: sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==} + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + '@types/send@0.17.4': resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} @@ -3645,8 +3717,8 @@ packages: '@types/yargs@17.0.32': resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} - '@typescript-eslint/eslint-plugin@7.16.1': - resolution: {integrity: sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==} + '@typescript-eslint/eslint-plugin@7.17.0': + resolution: {integrity: sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -3656,8 +3728,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@7.16.1': - resolution: {integrity: sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==} + '@typescript-eslint/parser@7.17.0': + resolution: {integrity: sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -3666,12 +3738,12 @@ packages: typescript: optional: true - '@typescript-eslint/scope-manager@7.16.1': - resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==} + '@typescript-eslint/scope-manager@7.17.0': + resolution: {integrity: sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/type-utils@7.16.1': - resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==} + '@typescript-eslint/type-utils@7.17.0': + resolution: {integrity: sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -3680,12 +3752,12 @@ packages: typescript: optional: true - '@typescript-eslint/types@7.16.1': - resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==} + '@typescript-eslint/types@7.17.0': + resolution: {integrity: sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A==} engines: {node: ^18.18.0 || >=20.0.0} - '@typescript-eslint/typescript-estree@7.16.1': - resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==} + '@typescript-eslint/typescript-estree@7.17.0': + resolution: {integrity: sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -3693,14 +3765,14 @@ packages: typescript: optional: true - '@typescript-eslint/utils@7.16.1': - resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==} + '@typescript-eslint/utils@7.17.0': + resolution: {integrity: sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 - '@typescript-eslint/visitor-keys@7.16.1': - resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==} + '@typescript-eslint/visitor-keys@7.17.0': + resolution: {integrity: sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A==} engines: {node: ^18.18.0 || >=20.0.0} '@webassemblyjs/ast@1.12.1': @@ -3914,6 +3986,9 @@ packages: aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + arch@2.2.0: + resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} + archiver-utils@2.1.0: resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} engines: {node: '>= 6'} @@ -4008,8 +4083,8 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - autoprefixer@10.4.19: - resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==} + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} hasBin: true peerDependencies: @@ -4022,8 +4097,8 @@ packages: avvio@8.3.2: resolution: {integrity: sha512-st8e519GWHa/azv8S87mcJvZs4WsgTBjOw/Ih1CP6u+8SZvcOeAYNG6JbsIrAUUJJ7JfmrnOkR8ipDS+u9SIRQ==} - aws-sdk@2.1659.0: - resolution: {integrity: sha512-WOoy5DdWW4kpQuxjWiQdoSDR+dT/HeAUwjb6b+8taEMZzvUzp3fmdDwdryUTlLWGxrnb7ru2yu5pryjhPOzANg==} + aws-sdk@2.1665.0: + resolution: {integrity: sha512-IhEcdGmiplF3l/pCROxEYIdi0s+LZ2VkbMAq3RgoXTHxY5cgqVRNaqsEsgIHev2Clxa9V08HttnIERTIUqb1+Q==} engines: {node: '>= 10.0.0'} aws-ssl-profiles@1.1.1: @@ -4038,8 +4113,8 @@ packages: peerDependencies: axios: '>= 0.18 < 0.19.0 || >= 0.19.1' - axios@1.7.2: - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + axios@1.7.3: + resolution: {integrity: sha512-Ar7ND9pU99eJ9GpoGQKhKf58GpUOgnzuaB7ueNQ5BMi0p+LZ5oaEnfF999fAArcTIBwXTCHAmGcHOZJaWPq9Nw==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -4106,6 +4181,18 @@ packages: resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} engines: {node: '>=0.6'} + bin-check@4.1.0: + resolution: {integrity: sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==} + engines: {node: '>=4'} + + bin-version-check@5.1.0: + resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} + engines: {node: '>=12'} + + bin-version@6.0.0: + resolution: {integrity: sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==} + engines: {node: '>=12'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -4154,6 +4241,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + bs-logger@0.2.6: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} @@ -4205,6 +4297,14 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -4235,6 +4335,9 @@ packages: caniuse-lite@1.0.30001642: resolution: {integrity: sha512-3XQ0DoRgLijXJErLSl+bLnJ+Et4KqV1PY6JJBGAFlsNsz31zeAIncyeZfLCabHK/jtSh+671RM9YMldxjUPZtA==} + caniuse-lite@1.0.30001649: + resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==} + chainsaw@0.1.0: resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} @@ -4350,6 +4453,9 @@ packages: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone@1.0.4: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} @@ -4422,6 +4528,10 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + comment-json@4.2.3: resolution: {integrity: sha512-SsxdiOf064DWoZLH799Ata6u7iV658A11PlWtZATDlXPpKGJnbJZ5Z24ybixAi+LUUqJ/GKowAejtC5GFUG7Tw==} engines: {node: '>= 6'} @@ -4551,6 +4661,9 @@ packages: cron@3.1.7: resolution: {integrity: sha512-tlBg7ARsAMQLzgwqVxy8AZl/qlTc5nibqYwtNGoCrd+cV+ugI+tvZC1oT/8dFH8W455YrywGykx/KMmAqOr7Jw==} + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + cross-spawn@6.0.5: resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} engines: {node: '>=4.8'} @@ -4707,12 +4820,25 @@ packages: supports-color: optional: true + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dedent@1.5.3: resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} peerDependencies: @@ -4735,6 +4861,10 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -4902,6 +5032,9 @@ packages: electron-to-chromium@1.4.828: resolution: {integrity: sha512-QOIJiWpQJDHAVO4P58pwb133Cwee0nbvy/MV1CwzZVGpkH1RX33N3vsaWRCpR6bF63AAq366neZrRTu7Qlsbbw==} + electron-to-chromium@1.5.4: + resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==} + emitter-listener@1.1.2: resolution: {integrity: sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==} @@ -5013,6 +5146,10 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} @@ -5024,8 +5161,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-config-turbo@2.0.9: - resolution: {integrity: sha512-FoIMElI8md/dR5DxjB5Om52KJfi7Qf7RInXeE+PGU6lN388rumppwyqEJsZ7vnR5GhGa9cLPt0vNZwEK9iXtKg==} + eslint-config-turbo@2.0.12: + resolution: {integrity: sha512-3PUzoyeJi2SjsTSjfWgTUIHK7kOqsapDEaOT7sCjFnZXvuhYLKxW37lysjq7+55abGGm0yQTXxNFLjrQKUORag==} peerDependencies: eslint: '>6.6.0' @@ -5089,8 +5226,8 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - eslint-plugin-turbo@2.0.9: - resolution: {integrity: sha512-q4s4mg6JcXzz5zK4LC3c6FcWehGAWjGj7kIM76ZvG0KiR9Ks0znzjnAKW0NoiDP4s/gt3r4YPOpI357qWt167Q==} + eslint-plugin-turbo@2.0.12: + resolution: {integrity: sha512-vXWKer7F0RPTcVy1B+hFTEK4mlEOpouB8MCAFD3WW4C6t98wvuDCsIPjxIldpxg7CnwmRxALpNWgNVkU2LVVEQ==} peerDependencies: eslint: '>6.6.0' @@ -5110,8 +5247,8 @@ packages: resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.7.0: - resolution: {integrity: sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==} + eslint@9.8.0: + resolution: {integrity: sha512-K8qnZ/QJzT2dLKdZJVX6W4XOwBzutMYmt0lqUS+JdXgd+HTYFlonFgkJ8s44d/zMPPCnOOk0kMWCApCPhiOy9A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true @@ -5186,10 +5323,18 @@ packages: resolution: {integrity: sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==} engines: {node: '>=4'} + execa@0.7.0: + resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} + engines: {node: '>=4'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} + executable@4.1.1: + resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} + engines: {node: '>=4'} + exit@0.1.2: resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} engines: {node: '>= 0.8.0'} @@ -5202,6 +5347,14 @@ packages: resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} engines: {node: '>= 0.10.0'} + ext-list@2.2.2: + resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} + engines: {node: '>=0.10.0'} + + ext-name@5.0.0: + resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} + engines: {node: '>=4'} + extend-object@1.0.0: resolution: {integrity: sha512-0dHDIXC7y7LDmCh/lp1oYkmv73K25AMugQI07r8eFopkW6f7Ufn1q+ETMsJjnV9Am14SlElkqy3O92r6xEaxPw==} @@ -5268,8 +5421,8 @@ packages: fast-uri@3.0.1: resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} - fast-xml-parser@4.2.5: - resolution: {integrity: sha512-B9/wizE4WngqQftFPmdaMYlXoJlJOYxGQOanC77fq9k8+Z0v5dDSVh+3glErdIROP//s/jgb7ZuxKfB8nVyo0g==} + fast-xml-parser@4.4.1: + resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} hasBin: true fastest-stable-stringify@2.0.2: @@ -5298,12 +5451,24 @@ packages: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} + file-type@17.1.6: + resolution: {integrity: sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filename-reserved-regex@3.0.0: + resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + filenamify@5.1.1: + resolution: {integrity: sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA==} + engines: {node: '>=12.20'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -5327,6 +5492,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-versions@5.1.0: + resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} + engines: {node: '>=12'} + fixpack@4.0.0: resolution: {integrity: sha512-5SM1+H2CcuJ3gGEwTiVo/+nd/hYpNj9Ch3iMDOQ58ndY+VGQ2QdvaUTkd3otjZvYnd/8LF/HkJ5cx7PBq0orCQ==} hasBin: true @@ -5375,8 +5544,8 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} - framer-motion@11.3.7: - resolution: {integrity: sha512-wolMesg8ruYgZX8nMELY2a/ZgMMpYhggLNIexx1blaYN0yb2+SdQ78sEkGDKde+3LTCeFy/wCi97i5Br4yT0GQ==} + framer-motion@11.3.20: + resolution: {integrity: sha512-xRPHtcrSjCdQ7gIttxcnSXOPq+P0AiU7tU82fWE3Tco7EmQQmu5AIgwkdcI6ebZolm+rz9ehSzECVSdZONSj+Q==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 @@ -5478,6 +5647,10 @@ packages: resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} engines: {node: '>=4'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -5553,6 +5726,10 @@ packages: gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -5665,6 +5842,9 @@ packages: htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -5673,6 +5853,10 @@ packages: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + https-proxy-agent@5.0.1: resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} engines: {node: '>= 6'} @@ -5688,8 +5872,8 @@ packages: hyphenate-style-name@1.1.0: resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} - i18next-fs-backend@2.3.1: - resolution: {integrity: sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==} + i18next-fs-backend@2.3.2: + resolution: {integrity: sha512-LIwUlkqDZnUI8lnUxBnEj8K/FrHQTT/Sc+1rvDm9E8YvvY5YxzoEAASNx+W5M9DfD5s77lI5vSAFWeTp26B/3Q==} i18next@23.12.2: resolution: {integrity: sha512-XIeh5V+bi8SJSWGL3jqbTEBW5oD6rbP5L+E7dVQh1MNTxxYef0x15rhJVcRb7oiuq4jLtgy2SD8eFlf6P2cmqg==} @@ -5811,10 +5995,6 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.14.0: - resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} - engines: {node: '>= 0.4'} - is-core-module@2.15.0: resolution: {integrity: sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==} engines: {node: '>= 0.4'} @@ -5889,6 +6069,10 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} @@ -6003,8 +6187,8 @@ packages: resolution: {integrity: sha512-cub8rahkh0Q/bw1+GxP7aeSe29hHHn2V4m29nnDlvCdlgU+3UGxkZp7Z53jLUdpX3jdTO0nJZUDl3xvbWc2Xog==} engines: {node: 20 || >=22} - jake@10.9.1: - resolution: {integrity: sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==} + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} engines: {node: '>=10'} hasBin: true @@ -6458,6 +6642,10 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} @@ -6465,6 +6653,9 @@ packages: resolution: {integrity: sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==} engines: {node: 20 || >=22} + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} @@ -6588,6 +6779,14 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -6761,8 +6960,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.3.2: - resolution: {integrity: sha512-vDn6d6a50vxPE+HnaKQfpmZ4SVXlOjF97yD5FJcUT3v2/uZ65qvTYNL25yOmnrfCNWZ4wtAS7EbtXxygMug2Tw==} + msw@2.3.5: + resolution: {integrity: sha512-+GUI4gX5YC5Bv33epBrD+BGdmDvBg2XGruiWnI3GbIbRmMMBeZ5gs3mJ51OWSGHgJKztZ8AtZeYMMNMVrje2/Q==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -6782,8 +6981,8 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - mysql2@3.10.3: - resolution: {integrity: sha512-k43gmH9i79rZD4hGPdj7pDuT0UBiFjs4UzXEy1cJrV0QqcSABomoLwvejqdbcXN+Vd7gi999CVM6o9vCPKq29g==} + mysql2@3.11.0: + resolution: {integrity: sha512-J9phbsXGvTOcRVPR95YedzVSxJecpW5A5+cQ57rhHIFXteTP10HCs+VBjS7DHIKfEaI1zQ5tlVrquCd64A6YvA==} engines: {node: '>= 8.0'} mz@2.7.0: @@ -6814,9 +7013,9 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - nestjs-cls@3.6.0: - resolution: {integrity: sha512-hAu8Pyhl0okB7LgQFoxP8kq26izBh0UCnDLfE2Ze9eJAz2A8XdFkBNIVca868T1Yf8bsLzvfsKPTxCQZ0hTMDQ==} - engines: {node: '>=12.17.0'} + nestjs-cls@4.4.1: + resolution: {integrity: sha512-4yhldwm/cJ02lQ8ZAdM8KQ7gMfjAc1z3fo5QAQgXNyN4N6X5So9BCwv+BTLRugDCkELUo3qtzQHnKhGYL/ftPg==} + engines: {node: '>=16'} peerDependencies: '@nestjs/common': '> 7.0.0 < 11' '@nestjs/core': '> 7.0.0 < 11' @@ -6836,8 +7035,8 @@ packages: '@nestjs/common': ^6.1.1 || ^5.6.2 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 typeorm: ^0.3.0 - next-i18next@15.3.0: - resolution: {integrity: sha512-bq7Cc9XJFcmGOCLnyEtHaeJ3+JJNsI/8Pkj9BaHAnhm4sZ9vNNC4ZsaqYnlRZ7VH5ypSo73fEqLK935jLsmCvQ==} + next-i18next@15.3.1: + resolution: {integrity: sha512-+pa2pZJb7B6k5PKW3TLVMmAodqkNaOBWVYlpWX56mgcEJz0UMW+MKSdKM9Z72CHp6Bp48g7OWwDnLqxXNp/84w==} engines: {node: '>=14'} peerDependencies: i18next: '>= 23.7.13' @@ -6869,6 +7068,10 @@ packages: sass: optional: true + nice-napi@1.0.2: + resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} + os: ['!win32'] + nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -6884,6 +7087,9 @@ packages: node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} @@ -6899,16 +7105,23 @@ packages: encoding: optional: true + node-gyp-build@4.8.1: + resolution: {integrity: sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==} + hasBin: true + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-mocks-http@1.15.0: - resolution: {integrity: sha512-3orGBAxXrnwz3ixU8AZpa0x8srAvVSHvbWanAqd5F0zVCVA2QstxaVcTSarFcjz4+pFSnR1zm28MsV83s/BtmA==} + node-mocks-http@1.15.1: + resolution: {integrity: sha512-X/GpUpNNiPDYUeUD183W8V4OW6OHYWI29w/QDyb+c/GzOfVEAlo6HjbW9++eXT2aV2lGg+uS+XqTD2q0pNREQA==} engines: {node: '>=14'} node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + nodemailer@6.9.13: resolution: {integrity: sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA==} engines: {node: '>=6.0.0'} @@ -6935,6 +7148,10 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + npm-run-path@2.0.2: resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} engines: {node: '>=4'} @@ -6950,8 +7167,8 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nuqs@1.17.5: - resolution: {integrity: sha512-F9bsK/Eyp6kqIvATDVsak7qqexmiuUY79l+jBiDCDitwPAvbRkqPbiCeUmx8pZIpK0mY1evp01RLR2i0W7edBA==} + nuqs@1.17.7: + resolution: {integrity: sha512-LiiC5XGqVPCGNA3Hg4tPmI5Ur0egmp+mB9FLWPltQfC6VbQyHqkJf4aZV6f9o8wX86Le9KAIHdnNCtx0f1ZTnw==} peerDependencies: next: '>=13.4 <14.0.2 || ^14.0.3' @@ -7016,8 +7233,8 @@ packages: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} - openapi-typescript@7.1.0: - resolution: {integrity: sha512-qxjGhIO6ODCGximE2HiozkPUNbO4y7F2OQyGa+gcn6TdZMMtmuiyDPqoKmf+Y4VlvQRfhJUTU635w8KfZVeuVA==} + openapi-typescript@7.3.0: + resolution: {integrity: sha512-EkljRjYWOPwGXiK++uI9MkGv2Y7uhbkZbi9V1z3r3EpmWVO6aFTHXSLNvxIWo6UT6LCTYgEYkUB3BWQjwwXthg==} hasBin: true peerDependencies: typescript: ^5.x @@ -7030,6 +7247,10 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + os-filter-obj@2.0.0: + resolution: {integrity: sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==} + engines: {node: '>=4'} + os-homedir@1.0.2: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} @@ -7047,6 +7268,10 @@ packages: oxc-resolver@1.10.2: resolution: {integrity: sha512-NIbwVqoU8Bhl7PVtItHCg+VFFokIDwBgIgFUwFG2Y8ePhxftFh5xG+KLar5PLWXlCP4WunPIuXD3jr3v6/MfRw==} + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + p-event@4.2.0: resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==} engines: {node: '>=8'} @@ -7199,6 +7424,10 @@ packages: peberminta@0.9.0: resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} + peek-readable@5.1.3: + resolution: {integrity: sha512-kCsc9HwH5RgVA3H3VqkWFyGQwsxUxLdiSX1d5nqAm7hnMFjNFX1VhBLmJoUY0hZNc8gmDNgBkLjfhiWPsziXWA==} + engines: {node: '>=14.16'} + picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} @@ -7220,8 +7449,8 @@ packages: pino-http@10.2.0: resolution: {integrity: sha512-am03BxnV3Ckx68OkbH0iZs3indsrH78wncQ6w1w51KroIbvJZNImBKX2X1wjdY8lSyaJ0UrX/dnO2DY3cTeCRw==} - pino-pretty@11.2.1: - resolution: {integrity: sha512-O05NuD9tkRasFRWVaF/uHLOvoRDFD7tb5VMertr78rbsYFjYp48Vg3477EshVAF5eZaEw+OpDl/tu+B0R5o+7g==} + pino-pretty@11.2.2: + resolution: {integrity: sha512-2FnyGir8nAJAqD3srROdrF1J5BIcMT4nwj7hHSc60El6Uxlym00UbCCd8pYIterstVBFlMyF1yFV8XdGIPbj4A==} hasBin: true pino-std-serializers@7.0.0: @@ -7231,21 +7460,28 @@ packages: resolution: {integrity: sha512-afSfrq/hUiW/MFmQcLEwV9Zh8Ry6MrMTOyBU53o/fc0gEl+1OZ/Fks/xQCM2nOC0C/OfDtQMnT2d8c3kpcfSzA==} hasBin: true + pino@9.3.2: + resolution: {integrity: sha512-WtARBjgZ7LNEkrGWxMBN/jvlFiE17LTbBoH0konmBU684Kd0uIiDwBXlcTCW7iJnA6HfIKwUssS/2AC6cDEanw==} + hasBin: true + pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} + piscina@4.6.1: + resolution: {integrity: sha512-z30AwWGtQE+Apr+2WBZensP2lIvwoaMcOPkQlIEmSGMJNUvaYACylPYrQM6wSdUNJlnDVMSpLv7xTMJqlVshOA==} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - playwright-core@1.45.3: - resolution: {integrity: sha512-+ym0jNbcjikaOwwSZycFbwkWgfruWvYlJfThKYAlImbxUgdWFO2oW70ojPm4OpE4t6TAo2FY/smM+hpVTtkhDA==} + playwright-core@1.46.0: + resolution: {integrity: sha512-9Y/d5UIwuJk8t3+lhmMSAJyNP1BUC/DqP3cQJDQQL/oWqAiuPTLgy7Q5dzglmTLwcBRdetzgNM/gni7ckfTr6A==} engines: {node: '>=18'} hasBin: true - playwright@1.45.3: - resolution: {integrity: sha512-QhVaS+lpluxCaioejDZ95l4Y4jSFCsBvl2UZkpeXlzxmqS+aABr5c82YmfMHrL6x27nvrvykJAFpkzT2eWdJww==} + playwright@1.46.0: + resolution: {integrity: sha512-XYJ5WvfefWONh1uPAUAi0H2xXV5S3vrtcnXe6uAOgdGi3aSpqOSXX08IAjXW34xitfuOJsvXU5anXZxPSEQiJw==} engines: {node: '>=18'} hasBin: true @@ -7342,8 +7578,8 @@ packages: resolution: {integrity: sha512-/WGUMYhKiryWjYO6c7kAcqMuD7DVkaQ8HcbQenDme/d3OBOmrYMFObOKgUWyUy1uih5U2Dakq8H6VcJi5C9wHQ==} engines: {node: '>=0.12'} - postcss-nested@6.0.1: - resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 @@ -7384,8 +7620,8 @@ packages: resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} engines: {node: ^10 || ^12 || >=14} - postcss@8.4.39: - resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==} + postcss@8.4.41: + resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} engines: {node: ^10 || ^12 || >=14} prejss-cli@0.3.3: @@ -7482,6 +7718,9 @@ packages: process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -7510,6 +7749,9 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} @@ -7588,6 +7830,10 @@ packages: quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + raf-schd@4.0.3: resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} @@ -7623,9 +7869,9 @@ packages: peerDependencies: react: ^18.3.1 - react-hook-form@7.52.1: - resolution: {integrity: sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==} - engines: {node: '>=12.22.0'} + react-hook-form@7.52.2: + resolution: {integrity: sha512-pqfPEbERnxxiNMPd0bzmt1tuaPcVccywFDpyk2uV5xCIBphHV5T8SVnX9/o3kplPE1zzKt77+YIoq+EMwJp56A==} + engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -7724,6 +7970,10 @@ packages: resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + readable-web-to-node-stream@3.0.2: + resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} + engines: {node: '>=8'} + readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} @@ -7813,6 +8063,9 @@ packages: resize-observer-polyfill@1.5.1: resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -7837,6 +8090,9 @@ packages: resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} hasBin: true + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -7867,8 +8123,8 @@ packages: engines: {node: 20 || >=22} hasBin: true - rollup@4.19.0: - resolution: {integrity: sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==} + rollup@4.20.0: + resolution: {integrity: sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7945,6 +8201,14 @@ packages: selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semver-regex@4.0.5: + resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} + engines: {node: '>=12'} + + semver-truncate@3.0.0: + resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==} + engines: {node: '>=12'} + semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -8062,6 +8326,14 @@ packages: sonic-boom@4.0.1: resolution: {integrity: sha512-hTSD/6JMLyT4r9zeof6UtuBDpjJ9sO08/nmS5djaA9eozT9oOlNdpXSnzcgj4FTqpk3nkLrs61l4gip9r1HCrQ==} + sort-keys-length@1.0.1: + resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} + engines: {node: '>=0.10.0'} + + sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + source-map-js@1.2.0: resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} engines: {node: '>=0.10.0'} @@ -8213,9 +8485,17 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-outer@2.0.0: + resolution: {integrity: sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} + strtok3@7.1.1: + resolution: {integrity: sha512-mKX8HA/cdBqMKUr0MMZAFssCkIGoZeSCMXgnt79yKxNFguMLVFgRe6wB+fsL0NmoHDbeyZXczy7vEPSoo3rkzg==} + engines: {node: '>=16'} + styled-jsx@5.1.1: resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -8307,8 +8587,8 @@ packages: tailwind-scrollbar-hide@1.1.7: resolution: {integrity: sha512-X324n9OtpTmOMqEgDUEA/RgLrNfBF/jwJdctaPZDzB3mppxJk7TLIDmOreEDm1Bq4R9LSPu4Epf8VSdovNU+iA==} - tailwindcss@3.4.6: - resolution: {integrity: sha512-1uRHzPB+Vzu57ocybfZ4jh5Q3SdlH7XW23J5sQoM9LhE9eIOlzxer/3XPSsycvih3rboRsvt0QCmzSrqyOYUIA==} + tailwindcss@3.4.7: + resolution: {integrity: sha512-rxWZbe87YJb4OcSopb7up2Ba4U82BoiSGUdoDr3Ydrg9ckxFS/YWsvhN323GMcddgU65QRy7JndC7ahhInhvlQ==} engines: {node: '>=14.0.0'} hasBin: true @@ -8415,6 +8695,10 @@ packages: token-stream@1.0.0: resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + token-types@5.0.1: + resolution: {integrity: sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==} + engines: {node: '>=14.16'} + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -8436,6 +8720,10 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true + trim-repeated@2.0.0: + resolution: {integrity: sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg==} + engines: {node: '>=12'} + ts-api-utils@1.3.0: resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} engines: {node: '>=16'} @@ -8448,8 +8736,8 @@ packages: ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} - ts-jest@29.2.3: - resolution: {integrity: sha512-yCcfVdiBFngVz9/keHin9EnsrQtQtEu3nRykNy9RVp+FiPFFbPJ3Sg6Qg4+TkmH0vMP5qsTKgXSsk80HRwvdgQ==} + ts-jest@29.2.4: + resolution: {integrity: sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==} engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: @@ -8510,8 +8798,8 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - tsup@8.2.2: - resolution: {integrity: sha512-MufIuzdSt6HYPOeOtjUXLR4rqRJySi6XsRNZdwvjC2XR+xghsu2L3vSmYmX+k4S1mO6j0OlUEyVQ3Fc0H66XcA==} + tsup@8.2.4: + resolution: {integrity: sha512-akpCPePnBnC/CXgRrcy72ZSntgIEUa1jN0oJbbvpALWKNOz1B7aM+UVDWGRGIO/T/PZugAESWDJUAb5FD48o8Q==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -8529,38 +8817,38 @@ packages: typescript: optional: true - turbo-darwin-64@2.0.9: - resolution: {integrity: sha512-owlGsOaExuVGBUfrnJwjkL1BWlvefjSKczEAcpLx4BI7Oh6ttakOi+JyomkPkFlYElRpjbvlR2gP8WIn6M/+xQ==} + turbo-darwin-64@2.0.12: + resolution: {integrity: sha512-NAgfgbXxX/JScWQmmQnGbPuFZq7LIswHfcMk5JwyBXQM/xmklNOxxac7MnGGIOf19Z2f6S3qHy17VIj0SeGfnA==} cpu: [x64] os: [darwin] - turbo-darwin-arm64@2.0.9: - resolution: {integrity: sha512-XAXkKkePth5ZPPE/9G9tTnPQx0C8UTkGWmNGYkpmGgRr8NedW+HrPsi9N0HcjzzIH9A4TpNYvtiV+WcwdaEjKA==} + turbo-darwin-arm64@2.0.12: + resolution: {integrity: sha512-cP02uer5KSJ+fXL+OfRRk5hnVjV0c60hxDgNcJxrZpfhun7HHoKDDR7w2xhQntiA45aC6ZZEXRqMKpj6GAmKbg==} cpu: [arm64] os: [darwin] - turbo-linux-64@2.0.9: - resolution: {integrity: sha512-l9wSgEjrCFM1aG16zItBsZ206ZlhSSx1owB8Cgskfv0XyIXRGHRkluihiaxkp+UeU5WoEfz4EN5toc+ICA0q0w==} + turbo-linux-64@2.0.12: + resolution: {integrity: sha512-+mQgGfg1eq5qF+wenK/FKJaNMNAo5DQLC4htQy+8osW+fx6U+8+6UlPQPaycAWDEqwOI7NwuqkeHfkEQLQUTyQ==} cpu: [x64] os: [linux] - turbo-linux-arm64@2.0.9: - resolution: {integrity: sha512-gRnjxXRne18B27SwxXMqL3fJu7jw/8kBrOBTBNRSmZZiG1Uu3nbnP7b4lgrA/bCku6C0Wligwqurvtpq6+nFHA==} + turbo-linux-arm64@2.0.12: + resolution: {integrity: sha512-KFyEZDXfPU1DK4zimxdCcqAcK7IIttX4mfsgB7NsSEOmH0dhHOih/YFYiyEDC1lTRx0C2RlzQ0Kjjdz48AN5Eg==} cpu: [arm64] os: [linux] - turbo-windows-64@2.0.9: - resolution: {integrity: sha512-ZVo0apxUvaRq4Vm1qhsfqKKhtRgReYlBVf9MQvVU1O9AoyydEQvLDO1ryqpXDZWpcHoFxHAQc9msjAMtE5K2lA==} + turbo-windows-64@2.0.12: + resolution: {integrity: sha512-kJj4KCkZTkDTDCqsSw1m1dbO4WeoQq1mYUm/thXOH0OkeqYbSMt0EyoTcJOgKUDsrMnzZD2gPfYrlYHtV69lVA==} cpu: [x64] os: [win32] - turbo-windows-arm64@2.0.9: - resolution: {integrity: sha512-sGRz7c5Pey6y7y9OKi8ypbWNuIRPF9y8xcMqL56OZifSUSo+X2EOsOleR9MKxQXVaqHPGOUKWsE6y8hxBi9pag==} + turbo-windows-arm64@2.0.12: + resolution: {integrity: sha512-TY3ROxguDilN2olCwcZMaePdW01Xhma0pZU7bNhsQEqca9RGAmsZBuzfGnTMcWPmv4tpnb/PlX1hrt1Hod/44Q==} cpu: [arm64] os: [win32] - turbo@2.0.9: - resolution: {integrity: sha512-QaLaUL1CqblSKKPgLrFW3lZWkWG4pGBQNW+q1ScJB5v1D/nFWtsrD/yZljW/bdawg90ihi4/ftQJ3h6fz1FamA==} + turbo@2.0.12: + resolution: {integrity: sha512-8s2KwqjwQj7z8Z53SUZSKVkQOZ2/Sl4D2F440oaBY/k2lGju60dW6srEpnn8/RIDeICZmQn3pQHF79Jfnc5Skw==} hasBin: true type-check@0.4.0: @@ -8579,8 +8867,8 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - type-fest@4.22.1: - resolution: {integrity: sha512-9tHNEa0Ov81YOopiVkcCJVz5TM6AEQ+CHHjFIktqPnE3NV0AHIkx+gh9tiCl58m/66wWxkOC9eltpa75J4lQPA==} + type-fest@4.23.0: + resolution: {integrity: sha512-ZiBujro2ohr5+Z/hZWHESLz3g08BBdrdLMieYFULJO+tWc437sn8kQsWLJoZErY8alNhxre9K4p3GURAG11n+w==} engines: {node: '>=16'} type-is@1.6.18: @@ -8676,8 +8964,8 @@ packages: typeorm-aurora-data-api-driver: optional: true - typescript-eslint@7.16.1: - resolution: {integrity: sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==} + typescript-eslint@7.17.0: + resolution: {integrity: sha512-spQxsQvPguduCUfyUvLItvKqK3l8KJ/kqs5Pb/URtzQ5AC53Z6us32St37rpmlt2uESG23lOFpV4UErrmy4dZQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -8691,8 +8979,8 @@ packages: engines: {node: '>=14.17'} hasBin: true - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} engines: {node: '>=14.17'} hasBin: true @@ -8717,6 +9005,9 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.13.0: + resolution: {integrity: sha512-xtFJHudx8S2DSoujjMd1WeWvn7KKWFRESZTMeL1RptAYERu29D6jphMjjY+vn96jvN3kVPDNxU/E13VTaXj6jg==} + undici@5.28.4: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} @@ -9005,6 +9296,9 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -9023,6 +9317,11 @@ packages: engines: {node: '>= 14'} hasBin: true + yaml@2.5.0: + resolution: {integrity: sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==} + engines: {node: '>= 14'} + hasBin: true + yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -9163,106 +9462,106 @@ snapshots: '@smithy/util-utf8': 2.3.0 tslib: 2.6.3 - '@aws-sdk/client-s3@3.616.0': + '@aws-sdk/client-s3@3.621.0': dependencies: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/client-sts': 3.616.0 - '@aws-sdk/core': 3.616.0 - '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/middleware-bucket-endpoint': 3.616.0 - '@aws-sdk/middleware-expect-continue': 3.616.0 - '@aws-sdk/middleware-flexible-checksums': 3.616.0 - '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/client-sso-oidc': 3.621.0(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/client-sts': 3.621.0 + '@aws-sdk/core': 3.621.0 + '@aws-sdk/credential-provider-node': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/middleware-bucket-endpoint': 3.620.0 + '@aws-sdk/middleware-expect-continue': 3.620.0 + '@aws-sdk/middleware-flexible-checksums': 3.620.0 + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-location-constraint': 3.609.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.616.0 - '@aws-sdk/middleware-sdk-s3': 3.616.0 - '@aws-sdk/middleware-signing': 3.616.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-sdk-s3': 3.621.0 + '@aws-sdk/middleware-signing': 3.620.0 '@aws-sdk/middleware-ssec': 3.609.0 - '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/middleware-user-agent': 3.620.0 '@aws-sdk/region-config-resolver': 3.614.0 - '@aws-sdk/signature-v4-multi-region': 3.616.0 + '@aws-sdk/signature-v4-multi-region': 3.621.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-endpoints': 3.614.0 '@aws-sdk/util-user-agent-browser': 3.609.0 '@aws-sdk/util-user-agent-node': 3.614.0 '@aws-sdk/xml-builder': 3.609.0 '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.8 + '@smithy/core': 2.3.1 '@smithy/eventstream-serde-browser': 3.0.5 '@smithy/eventstream-serde-config-resolver': 3.0.3 '@smithy/eventstream-serde-node': 3.0.4 - '@smithy/fetch-http-handler': 3.2.2 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-blob-browser': 3.1.2 '@smithy/hash-node': 3.0.3 '@smithy/hash-stream-node': 3.1.2 '@smithy/invalid-dependency': 3.0.3 '@smithy/md5-js': 3.0.3 - '@smithy/middleware-content-length': 3.0.4 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.13 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.11 - '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-defaults-mode-browser': 3.0.13 + '@smithy/util-defaults-mode-node': 3.0.13 '@smithy/util-endpoints': 2.0.5 '@smithy/util-retry': 3.0.3 - '@smithy/util-stream': 3.1.1 + '@smithy/util-stream': 3.1.3 '@smithy/util-utf8': 3.0.0 '@smithy/util-waiter': 3.1.2 tslib: 2.6.3 transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0)': + '@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0)': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sts': 3.616.0 - '@aws-sdk/core': 3.616.0 - '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/client-sts': 3.621.0 + '@aws-sdk/core': 3.621.0 + '@aws-sdk/credential-provider-node': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.616.0 - '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.620.0 '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-endpoints': 3.614.0 '@aws-sdk/util-user-agent-browser': 3.609.0 '@aws-sdk/util-user-agent-node': 3.614.0 '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.8 - '@smithy/fetch-http-handler': 3.2.2 + '@smithy/core': 2.3.1 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.4 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.13 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.11 - '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-defaults-mode-browser': 3.0.13 + '@smithy/util-defaults-mode-node': 3.0.13 '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 @@ -9271,41 +9570,41 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sso@3.616.0': + '@aws-sdk/client-sso@3.621.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.616.0 - '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/core': 3.621.0 + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.616.0 - '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.620.0 '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-endpoints': 3.614.0 '@aws-sdk/util-user-agent-browser': 3.609.0 '@aws-sdk/util-user-agent-node': 3.614.0 '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.8 - '@smithy/fetch-http-handler': 3.2.2 + '@smithy/core': 2.3.1 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.4 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.13 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.11 - '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-defaults-mode-browser': 3.0.13 + '@smithy/util-defaults-mode-node': 3.0.13 '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 @@ -9314,43 +9613,43 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/client-sts@3.616.0': + '@aws-sdk/client-sts@3.621.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/core': 3.616.0 - '@aws-sdk/credential-provider-node': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/middleware-host-header': 3.616.0 + '@aws-sdk/client-sso-oidc': 3.621.0(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/core': 3.621.0 + '@aws-sdk/credential-provider-node': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/middleware-host-header': 3.620.0 '@aws-sdk/middleware-logger': 3.609.0 - '@aws-sdk/middleware-recursion-detection': 3.616.0 - '@aws-sdk/middleware-user-agent': 3.616.0 + '@aws-sdk/middleware-recursion-detection': 3.620.0 + '@aws-sdk/middleware-user-agent': 3.620.0 '@aws-sdk/region-config-resolver': 3.614.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-endpoints': 3.614.0 '@aws-sdk/util-user-agent-browser': 3.609.0 '@aws-sdk/util-user-agent-node': 3.614.0 '@smithy/config-resolver': 3.0.5 - '@smithy/core': 2.2.8 - '@smithy/fetch-http-handler': 3.2.2 + '@smithy/core': 2.3.1 + '@smithy/fetch-http-handler': 3.2.4 '@smithy/hash-node': 3.0.3 '@smithy/invalid-dependency': 3.0.3 - '@smithy/middleware-content-length': 3.0.4 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-content-length': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.13 '@smithy/middleware-serde': 3.0.3 '@smithy/middleware-stack': 3.0.3 '@smithy/node-config-provider': 3.1.4 - '@smithy/node-http-handler': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/node-http-handler': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/url-parser': 3.0.3 '@smithy/util-base64': 3.0.0 '@smithy/util-body-length-browser': 3.0.0 '@smithy/util-body-length-node': 3.0.0 - '@smithy/util-defaults-mode-browser': 3.0.11 - '@smithy/util-defaults-mode-node': 3.0.11 + '@smithy/util-defaults-mode-browser': 3.0.13 + '@smithy/util-defaults-mode-node': 3.0.13 '@smithy/util-endpoints': 2.0.5 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 @@ -9359,45 +9658,47 @@ snapshots: transitivePeerDependencies: - aws-crt - '@aws-sdk/core@3.616.0': + '@aws-sdk/core@3.621.0': dependencies: - '@smithy/core': 2.2.8 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 - '@smithy/smithy-client': 3.1.9 + '@smithy/core': 2.3.1 + '@smithy/node-config-provider': 3.1.4 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 - fast-xml-parser: 4.2.5 + '@smithy/util-middleware': 3.0.3 + fast-xml-parser: 4.4.1 tslib: 2.6.3 - '@aws-sdk/credential-provider-env@3.609.0': + '@aws-sdk/credential-provider-env@3.620.1': dependencies: '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/credential-provider-http@3.616.0': + '@aws-sdk/credential-provider-http@3.621.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/fetch-http-handler': 3.2.2 - '@smithy/node-http-handler': 3.1.3 + '@smithy/fetch-http-handler': 3.2.4 + '@smithy/node-http-handler': 3.1.4 '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.1.1 + '@smithy/util-stream': 3.1.3 tslib: 2.6.3 - '@aws-sdk/credential-provider-ini@3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0)': + '@aws-sdk/credential-provider-ini@3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0)': dependencies: - '@aws-sdk/client-sts': 3.616.0 - '@aws-sdk/credential-provider-env': 3.609.0 - '@aws-sdk/credential-provider-http': 3.616.0 - '@aws-sdk/credential-provider-process': 3.614.0 - '@aws-sdk/credential-provider-sso': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/client-sts': 3.621.0 + '@aws-sdk/credential-provider-env': 3.620.1 + '@aws-sdk/credential-provider-http': 3.621.0 + '@aws-sdk/credential-provider-process': 3.620.1 + '@aws-sdk/credential-provider-sso': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0)) + '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.621.0) '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.1.4 + '@smithy/credential-provider-imds': 3.2.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 @@ -9406,16 +9707,16 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-node@3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0)': + '@aws-sdk/credential-provider-node@3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0)': dependencies: - '@aws-sdk/credential-provider-env': 3.609.0 - '@aws-sdk/credential-provider-http': 3.616.0 - '@aws-sdk/credential-provider-ini': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))(@aws-sdk/client-sts@3.616.0) - '@aws-sdk/credential-provider-process': 3.614.0 - '@aws-sdk/credential-provider-sso': 3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0)) - '@aws-sdk/credential-provider-web-identity': 3.609.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/credential-provider-env': 3.620.1 + '@aws-sdk/credential-provider-http': 3.621.0 + '@aws-sdk/credential-provider-ini': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))(@aws-sdk/client-sts@3.621.0) + '@aws-sdk/credential-provider-process': 3.620.1 + '@aws-sdk/credential-provider-sso': 3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0)) + '@aws-sdk/credential-provider-web-identity': 3.621.0(@aws-sdk/client-sts@3.621.0) '@aws-sdk/types': 3.609.0 - '@smithy/credential-provider-imds': 3.1.4 + '@smithy/credential-provider-imds': 3.2.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 '@smithy/types': 3.3.0 @@ -9425,7 +9726,7 @@ snapshots: - '@aws-sdk/client-sts' - aws-crt - '@aws-sdk/credential-provider-process@3.614.0': + '@aws-sdk/credential-provider-process@3.620.1': dependencies: '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 @@ -9433,10 +9734,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/credential-provider-sso@3.616.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))': + '@aws-sdk/credential-provider-sso@3.621.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))': dependencies: - '@aws-sdk/client-sso': 3.616.0 - '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0)) + '@aws-sdk/client-sso': 3.621.0 + '@aws-sdk/token-providers': 3.614.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0)) '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 @@ -9446,46 +9747,46 @@ snapshots: - '@aws-sdk/client-sso-oidc' - aws-crt - '@aws-sdk/credential-provider-web-identity@3.609.0(@aws-sdk/client-sts@3.616.0)': + '@aws-sdk/credential-provider-web-identity@3.621.0(@aws-sdk/client-sts@3.621.0)': dependencies: - '@aws-sdk/client-sts': 3.616.0 + '@aws-sdk/client-sts': 3.621.0 '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-bucket-endpoint@3.616.0': + '@aws-sdk/middleware-bucket-endpoint@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 '@aws-sdk/util-arn-parser': 3.568.0 '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-expect-continue@3.616.0': + '@aws-sdk/middleware-expect-continue@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-flexible-checksums@3.616.0': + '@aws-sdk/middleware-flexible-checksums@3.620.0': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-sdk/types': 3.609.0 '@smithy/is-array-buffer': 3.0.0 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-host-header@3.616.0': + '@aws-sdk/middleware-host-header@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -9501,33 +9802,33 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-recursion-detection@3.616.0': + '@aws-sdk/middleware-recursion-detection@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-sdk-s3@3.616.0': + '@aws-sdk/middleware-sdk-s3@3.621.0': dependencies: '@aws-sdk/types': 3.609.0 '@aws-sdk/util-arn-parser': 3.568.0 '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 - '@smithy/smithy-client': 3.1.9 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/util-config-provider': 3.0.0 - '@smithy/util-stream': 3.1.1 + '@smithy/util-stream': 3.1.3 '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@aws-sdk/middleware-signing@3.616.0': + '@aws-sdk/middleware-signing@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 @@ -9538,11 +9839,11 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/middleware-user-agent@3.616.0': + '@aws-sdk/middleware-user-agent@3.620.0': dependencies: '@aws-sdk/types': 3.609.0 '@aws-sdk/util-endpoints': 3.614.0 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -9555,29 +9856,29 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@aws-sdk/s3-request-presigner@3.616.0': + '@aws-sdk/s3-request-presigner@3.621.0': dependencies: - '@aws-sdk/signature-v4-multi-region': 3.616.0 + '@aws-sdk/signature-v4-multi-region': 3.621.0 '@aws-sdk/types': 3.609.0 '@aws-sdk/util-format-url': 3.609.0 - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/signature-v4-multi-region@3.616.0': + '@aws-sdk/signature-v4-multi-region@3.621.0': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.616.0 + '@aws-sdk/middleware-sdk-s3': 3.621.0 '@aws-sdk/types': 3.609.0 - '@smithy/protocol-http': 4.0.4 - '@smithy/signature-v4': 4.0.0 + '@smithy/protocol-http': 4.1.0 + '@smithy/signature-v4': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.616.0(@aws-sdk/client-sts@3.616.0))': + '@aws-sdk/token-providers@3.614.0(@aws-sdk/client-sso-oidc@3.621.0(@aws-sdk/client-sts@3.621.0))': dependencies: - '@aws-sdk/client-sso-oidc': 3.616.0(@aws-sdk/client-sts@3.616.0) + '@aws-sdk/client-sso-oidc': 3.621.0(@aws-sdk/client-sts@3.621.0) '@aws-sdk/types': 3.609.0 '@smithy/property-provider': 3.1.3 '@smithy/shared-ini-file-loader': 3.1.4 @@ -9637,20 +9938,22 @@ snapshots: '@babel/compat-data@7.24.9': {} - '@babel/core@7.24.9': + '@babel/compat-data@7.25.2': {} + + '@babel/core@7.25.2': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.7 - '@babel/generator': 7.24.9 - '@babel/helper-compilation-targets': 7.24.8 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) - '@babel/helpers': 7.24.8 - '@babel/parser': 7.24.8 - '@babel/template': 7.24.7 - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.0 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 convert-source-map: 2.0.0 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -9664,53 +9967,60 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 + '@babel/generator@7.25.0': + dependencies: + '@babel/types': 7.25.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + '@babel/helper-annotate-as-pure@7.24.7': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': dependencies: - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - '@babel/helper-compilation-targets@7.24.8': + '@babel/helper-compilation-targets@7.25.2': dependencies: - '@babel/compat-data': 7.24.9 + '@babel/compat-data': 7.25.2 '@babel/helper-validator-option': 7.24.8 browserslist: 4.23.2 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.24.8(@babel/core@7.24.9)': + '@babel/helper-create-class-features-plugin@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 '@babel/helper-member-expression-to-functions': 7.24.8 '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.9) + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.25.2) '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.9)': + '@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 regexpu-core: 5.3.2 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.9)': + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-compilation-targets': 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) lodash.debounce: 4.0.8 resolve: 1.22.8 transitivePeerDependencies: @@ -9722,7 +10032,7 @@ snapshots: '@babel/helper-function-name@7.24.7': dependencies: - '@babel/template': 7.24.7 + '@babel/template': 7.25.0 '@babel/types': 7.24.9 '@babel/helper-hoist-variables@7.24.7': @@ -9731,47 +10041,46 @@ snapshots: '@babel/helper-member-expression-to-functions@7.24.8': dependencies: - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.24.7': dependencies: - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.24.9(@babel/core@7.24.9)': + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-environment-visitor': 7.24.7 + '@babel/core': 7.25.2 '@babel/helper-module-imports': 7.24.7 '@babel/helper-simple-access': 7.24.7 - '@babel/helper-split-export-declaration': 7.24.7 '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.2 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.24.7': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 '@babel/helper-plugin-utils@7.24.8': {} - '@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.9)': + '@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-wrap-function': 7.24.7 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.24.7(@babel/core@7.24.9)': + '@babel/helper-replace-supers@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-member-expression-to-functions': 7.24.8 '@babel/helper-optimise-call-expression': 7.24.7 @@ -9780,15 +10089,15 @@ snapshots: '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.24.7': dependencies: - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color @@ -9805,16 +10114,16 @@ snapshots: '@babel/helper-wrap-function@7.24.7': dependencies: '@babel/helper-function-name': 7.24.7 - '@babel/template': 7.24.7 - '@babel/traverse': 7.24.8 - '@babel/types': 7.24.9 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.2 + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - '@babel/helpers@7.24.8': + '@babel/helpers@7.25.0': dependencies: - '@babel/template': 7.24.7 - '@babel/types': 7.24.9 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 '@babel/highlight@7.24.7': dependencies: @@ -9827,623 +10136,627 @@ snapshots: dependencies: '@babel/types': 7.24.9 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.9)': + '@babel/parser@7.25.0': + dependencies: + '@babel/types': 7.25.2 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.24.9) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.9)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.9)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.9)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.9)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.9)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.9)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.9)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.9)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.9)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.9)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.9)': + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.9) + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-module-imports': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.9) + '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.9) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-classes@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-classes@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.24.8 + '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.9) + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.25.2) '@babel/helper-split-export-declaration': 7.24.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/template': 7.24.7 + '@babel/template': 7.25.0 - '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-function-name@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-compilation-targets': 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-function-name': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-literals@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-simple-access': 7.24.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-module-transforms': 7.24.9(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) - '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-compilation-targets': 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) - '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.9) + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) - '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.9) + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.9) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-react-constant-elements@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-react-constant-elements@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-react-display-name@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-react-display-name@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-react-jsx-development@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-react-jsx-development@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-jsx@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-react-jsx@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-module-imports': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) - '@babel/types': 7.24.9 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/types': 7.25.2 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-react-pure-annotations@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-react-pure-annotations@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 regenerator-transform: 0.15.2 - '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 transitivePeerDependencies: - supports-color - '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-typescript@7.24.8(@babel/core@7.24.9)': + '@babel/plugin-transform-typescript@7.24.8(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.24.9) + '@babel/helper-create-class-features-plugin': 7.24.8(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.9)': + '@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.25.2) '@babel/helper-plugin-utils': 7.24.8 - '@babel/preset-env@7.24.8(@babel/core@7.24.9)': + '@babel/preset-env@7.24.8(@babel/core@7.25.2)': dependencies: '@babel/compat-data': 7.24.9 - '@babel/core': 7.24.9 - '@babel/helper-compilation-targets': 7.24.8 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.9) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.9) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.9) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.9) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.9) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.9) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-classes': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.9) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.9) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.9) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.9) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.9) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-classes': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.25.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.25.2) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) core-js-compat: 3.37.1 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.9)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 esutils: 2.0.3 - '@babel/preset-react@7.24.7(@babel/core@7.24.9)': + '@babel/preset-react@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-react-jsx-development': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-react-pure-annotations': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-transform-react-display-name': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-development': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-pure-annotations': 7.24.7(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.24.7(@babel/core@7.24.9)': + '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/helper-plugin-utils': 7.24.8 '@babel/helper-validator-option': 7.24.8 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.24.9) - '@babel/plugin-transform-typescript': 7.24.8(@babel/core@7.24.9) + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-typescript': 7.24.8(@babel/core@7.25.2) transitivePeerDependencies: - supports-color @@ -10453,11 +10766,15 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.24.7': + '@babel/runtime@7.25.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.0 + '@babel/types': 7.25.2 '@babel/traverse@7.24.8': dependencies: @@ -10469,7 +10786,19 @@ snapshots: '@babel/helper-split-export-declaration': 7.24.7 '@babel/parser': 7.24.8 '@babel/types': 7.24.9 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.25.2': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.0 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + debug: 4.3.6(supports-color@9.4.0) globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -10480,6 +10809,12 @@ snapshots: '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 + '@babel/types@7.25.2': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + '@bcoe/v8-coverage@0.2.3': {} '@bundled-es-modules/cookie@2.0.0': @@ -10490,6 +10825,11 @@ snapshots: dependencies: statuses: 2.0.1 + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + '@colors/colors@1.5.0': optional: true @@ -10700,17 +11040,17 @@ snapshots: '@esbuild/win32-x64@0.23.0': optional: true - '@eslint-community/eslint-utils@4.4.0(eslint@9.7.0)': + '@eslint-community/eslint-utils@4.4.0(eslint@9.8.0)': dependencies: - eslint: 9.7.0 + eslint: 9.8.0 eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.11.0': {} - '@eslint/config-array@0.17.0': + '@eslint/config-array@0.17.1': dependencies: '@eslint/object-schema': 2.1.4 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.5 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -10718,7 +11058,7 @@ snapshots: '@eslint/eslintrc@3.1.0': dependencies: ajv: 6.12.6 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.5 espree: 10.1.0 globals: 14.0.0 ignore: 5.3.1 @@ -10729,7 +11069,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.7.0': {} + '@eslint/js@9.8.0': {} '@eslint/object-schema@2.1.4': {} @@ -10838,37 +11178,37 @@ snapshots: '@floating-ui/core@1.6.4': dependencies: - '@floating-ui/utils': 0.2.5 + '@floating-ui/utils': 0.2.6 - '@floating-ui/core@1.6.5': + '@floating-ui/core@1.6.6': dependencies: - '@floating-ui/utils': 0.2.5 + '@floating-ui/utils': 0.2.6 '@floating-ui/dom@1.6.7': dependencies: '@floating-ui/core': 1.6.4 - '@floating-ui/utils': 0.2.5 + '@floating-ui/utils': 0.2.6 - '@floating-ui/dom@1.6.8': + '@floating-ui/dom@1.6.9': dependencies: - '@floating-ui/core': 1.6.5 - '@floating-ui/utils': 0.2.5 + '@floating-ui/core': 1.6.6 + '@floating-ui/utils': 0.2.6 '@floating-ui/react-dom@2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/dom': 1.6.8 + '@floating-ui/dom': 1.6.9 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@floating-ui/react@0.26.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@floating-ui/react@0.26.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@floating-ui/react-dom': 2.1.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@floating-ui/utils': 0.2.5 + '@floating-ui/utils': 0.2.6 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) tabbable: 6.2.0 - '@floating-ui/utils@0.2.5': {} + '@floating-ui/utils@0.2.6': {} '@hapi/hoek@9.3.0': {} @@ -10878,20 +11218,20 @@ snapshots: '@headlessui/react@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react': 0.26.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react': 0.26.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@react-aria/focus': 3.17.1(react@18.3.1) '@react-aria/interactions': 3.21.3(react@18.3.1) '@tanstack/react-virtual': 3.8.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.6(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)))': + '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.7(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)))': dependencies: - tailwindcss: 3.4.6(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(typescript@5.5.3)) + tailwindcss: 3.4.7(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(typescript@5.5.4)) - '@hookform/resolvers@3.9.0(react-hook-form@7.52.1(react@18.3.1))': + '@hookform/resolvers@3.9.0(react-hook-form@7.52.2(react@18.3.1))': dependencies: - react-hook-form: 7.52.1(react@18.3.1) + react-hook-form: 7.52.2(react@18.3.1) '@humanwhocodes/module-importer@1.0.1': {} @@ -10899,7 +11239,7 @@ snapshots: '@ianvs/prettier-plugin-sort-imports@4.3.1(prettier@3.3.3)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@babel/generator': 7.24.9 '@babel/parser': 7.24.8 '@babel/traverse': 7.24.8 @@ -10984,17 +11324,17 @@ snapshots: '@img/sharp-win32-x64@0.33.4': optional: true - '@inquirer/confirm@3.1.15': + '@inquirer/confirm@3.1.20': dependencies: - '@inquirer/core': 9.0.3 - '@inquirer/type': 1.5.0 + '@inquirer/core': 9.0.8 + '@inquirer/type': 1.5.1 - '@inquirer/core@9.0.3': + '@inquirer/core@9.0.8': dependencies: - '@inquirer/figures': 1.0.4 - '@inquirer/type': 1.5.0 + '@inquirer/figures': 1.0.5 + '@inquirer/type': 1.5.1 '@types/mute-stream': 0.0.4 - '@types/node': 20.14.11 + '@types/node': 22.1.0 '@types/wrap-ansi': 3.0.0 ansi-escapes: 4.3.2 cli-spinners: 2.9.2 @@ -11005,9 +11345,9 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 - '@inquirer/figures@1.0.4': {} + '@inquirer/figures@1.0.5': {} - '@inquirer/type@1.5.0': + '@inquirer/type@1.5.1': dependencies: mute-stream: 1.0.0 @@ -11033,27 +11373,27 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + jest-config: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -11082,7 +11422,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -11100,7 +11440,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -11122,7 +11462,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -11169,7 +11509,7 @@ snapshots: '@jest/transform@29.7.0': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -11192,7 +11532,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/yargs': 17.0.32 chalk: 4.1.2 @@ -11248,7 +11588,16 @@ snapshots: '@microsoft/tsdoc@0.15.0': {} - '@mswjs/cookies@1.1.1': {} + '@mole-inc/bin-wrapper@8.0.1': + dependencies: + bin-check: 4.1.0 + bin-version-check: 5.1.0 + content-disposition: 0.5.4 + ext-name: 5.0.0 + file-type: 17.1.6 + filenamify: 5.1.1 + got: 11.8.6 + os-filter-obj: 2.0.0 '@mswjs/interceptors@0.29.1': dependencies: @@ -11314,23 +11663,23 @@ snapshots: transitivePeerDependencies: - encoding - '@nestjs/axios@3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.2)(rxjs@7.8.1)': + '@nestjs/axios@3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.3)(rxjs@7.8.1)': dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) - axios: 1.7.2 + axios: 1.7.3 rxjs: 7.8.1 - '@nestjs/cli@10.4.2(@swc/core@1.7.0(@swc/helpers@0.5.12))': + '@nestjs/cli@10.4.2(@swc/cli@0.4.0(@swc/core@1.7.6(@swc/helpers@0.5.12))(chokidar@3.6.0))(@swc/core@1.7.6(@swc/helpers@0.5.12))': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics-cli': 17.3.8(chokidar@3.6.0) - '@nestjs/schematics': 10.1.2(chokidar@3.6.0)(typescript@5.3.3) + '@nestjs/schematics': 10.1.3(chokidar@3.6.0)(typescript@5.3.3) chalk: 4.1.2 chokidar: 3.6.0 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12))) + fork-ts-checker-webpack-plugin: 9.0.2(typescript@5.3.3)(webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12))) glob: 10.4.2 inquirer: 8.2.6 node-emoji: 1.11.0 @@ -11339,10 +11688,11 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.1.0 typescript: 5.3.3 - webpack: 5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12)) + webpack: 5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12)) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/core': 1.7.0(@swc/helpers@0.5.12) + '@swc/cli': 0.4.0(@swc/core@1.7.6(@swc/helpers@0.5.12))(chokidar@3.6.0) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) transitivePeerDependencies: - esbuild - uglify-js @@ -11441,7 +11791,7 @@ snapshots: cron: 3.1.7 uuid: 10.0.0 - '@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@5.3.3)': + '@nestjs/schematics@10.1.3(chokidar@3.6.0)(typescript@5.3.3)': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) @@ -11452,14 +11802,14 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/schematics@10.1.2(chokidar@3.6.0)(typescript@5.5.3)': + '@nestjs/schematics@10.1.3(chokidar@3.6.0)(typescript@5.5.4)': dependencies: '@angular-devkit/core': 17.3.8(chokidar@3.6.0) '@angular-devkit/schematics': 17.3.8(chokidar@3.6.0) comment-json: 4.2.3 jsonc-parser: 3.3.1 pluralize: 8.0.0 - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - chokidar @@ -11479,7 +11829,7 @@ snapshots: class-transformer: 0.5.1 class-validator: 0.14.1 - '@nestjs/terminus@10.2.3(lo6srhfctxk5ogvbefiaqkk7t4)': + '@nestjs/terminus@10.2.3(xr5osr4zr4qjvwrofxwh6v5cru)': dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -11488,9 +11838,9 @@ snapshots: reflect-metadata: 0.2.2 rxjs: 7.8.1 optionalDependencies: - '@nestjs/axios': 3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.2)(rxjs@7.8.1) - '@nestjs/typeorm': 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3))) - typeorm: 0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + '@nestjs/axios': 3.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(axios@1.7.3)(rxjs@7.8.1) + '@nestjs/typeorm': 10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4))) + typeorm: 0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) '@nestjs/testing@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10))': dependencies: @@ -11500,13 +11850,13 @@ snapshots: optionalDependencies: '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10) - '@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)))': + '@nestjs/typeorm@10.0.2(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1)(typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)))': dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1) reflect-metadata: 0.2.2 rxjs: 7.8.1 - typeorm: 0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + typeorm: 0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) uuid: 9.0.1 '@next/env@14.2.5': {} @@ -11635,10 +11985,10 @@ snapshots: '@open-draft/until@2.1.0': {} - '@opensearch-project/opensearch@2.10.0': + '@opensearch-project/opensearch@2.11.0': dependencies: aws4: 1.13.0 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) hpagent: 1.2.0 json11: 1.1.2 ms: 2.1.3 @@ -11688,9 +12038,9 @@ snapshots: '@pkgr/core@0.1.1': {} - '@playwright/test@1.45.3': + '@playwright/test@1.46.0': dependencies: - playwright: 1.45.3 + playwright: 1.46.0 '@popperjs/core@2.11.8': {} @@ -11741,12 +12091,12 @@ snapshots: require-from-string: 2.0.2 uri-js: 4.4.1 - '@redocly/config@0.6.3': {} + '@redocly/config@0.7.0': {} - '@redocly/openapi-core@1.18.0(supports-color@9.4.0)': + '@redocly/openapi-core@1.19.0(supports-color@9.4.0)': dependencies: '@redocly/ajv': 8.11.0 - '@redocly/config': 0.6.3 + '@redocly/config': 0.7.0 colorette: 1.4.0 https-proxy-agent: 7.0.5(supports-color@9.4.0) js-levenshtein: 1.1.6 @@ -11760,71 +12110,71 @@ snapshots: - encoding - supports-color - '@rollup/plugin-commonjs@26.0.1(rollup@4.19.0)': + '@rollup/plugin-commonjs@26.0.1(rollup@4.20.0)': dependencies: - '@rollup/pluginutils': 5.1.0(rollup@4.19.0) + '@rollup/pluginutils': 5.1.0(rollup@4.20.0) commondir: 1.0.1 estree-walker: 2.0.2 glob: 10.4.5 is-reference: 1.2.1 magic-string: 0.30.10 optionalDependencies: - rollup: 4.19.0 + rollup: 4.20.0 - '@rollup/pluginutils@5.1.0(rollup@4.19.0)': + '@rollup/pluginutils@5.1.0(rollup@4.20.0)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 optionalDependencies: - rollup: 4.19.0 + rollup: 4.20.0 - '@rollup/rollup-android-arm-eabi@4.19.0': + '@rollup/rollup-android-arm-eabi@4.20.0': optional: true - '@rollup/rollup-android-arm64@4.19.0': + '@rollup/rollup-android-arm64@4.20.0': optional: true - '@rollup/rollup-darwin-arm64@4.19.0': + '@rollup/rollup-darwin-arm64@4.20.0': optional: true - '@rollup/rollup-darwin-x64@4.19.0': + '@rollup/rollup-darwin-x64@4.20.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.19.0': + '@rollup/rollup-linux-arm-gnueabihf@4.20.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.19.0': + '@rollup/rollup-linux-arm-musleabihf@4.20.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.19.0': + '@rollup/rollup-linux-arm64-gnu@4.20.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.19.0': + '@rollup/rollup-linux-arm64-musl@4.20.0': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.19.0': + '@rollup/rollup-linux-powerpc64le-gnu@4.20.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.19.0': + '@rollup/rollup-linux-riscv64-gnu@4.20.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.19.0': + '@rollup/rollup-linux-s390x-gnu@4.20.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.19.0': + '@rollup/rollup-linux-x64-gnu@4.20.0': optional: true - '@rollup/rollup-linux-x64-musl@4.19.0': + '@rollup/rollup-linux-x64-musl@4.20.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.19.0': + '@rollup/rollup-win32-arm64-msvc@4.20.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.19.0': + '@rollup/rollup-win32-ia32-msvc@4.20.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.19.0': + '@rollup/rollup-win32-x64-msvc@4.20.0': optional: true '@selderee/plugin-htmlparser2@0.11.0': @@ -11843,6 +12193,8 @@ snapshots: '@sinclair/typebox@0.27.8': {} + '@sindresorhus/is@4.6.0': {} + '@sindresorhus/merge-streams@2.3.0': {} '@sinonjs/commons@3.0.1': @@ -11875,18 +12227,18 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@smithy/core@2.2.8': + '@smithy/core@2.3.1': dependencies: - '@smithy/middleware-endpoint': 3.0.5 - '@smithy/middleware-retry': 3.0.11 + '@smithy/middleware-endpoint': 3.1.0 + '@smithy/middleware-retry': 3.0.13 '@smithy/middleware-serde': 3.0.3 - '@smithy/protocol-http': 4.0.4 - '@smithy/smithy-client': 3.1.9 + '@smithy/protocol-http': 4.1.0 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@smithy/credential-provider-imds@3.1.4': + '@smithy/credential-provider-imds@3.2.0': dependencies: '@smithy/node-config-provider': 3.1.4 '@smithy/property-provider': 3.1.3 @@ -11924,9 +12276,9 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/fetch-http-handler@3.2.2': + '@smithy/fetch-http-handler@3.2.4': dependencies: - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/querystring-builder': 3.0.3 '@smithy/types': 3.3.0 '@smithy/util-base64': 3.0.0 @@ -11971,13 +12323,13 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/middleware-content-length@3.0.4': + '@smithy/middleware-content-length@3.0.5': dependencies: - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/middleware-endpoint@3.0.5': + '@smithy/middleware-endpoint@3.1.0': dependencies: '@smithy/middleware-serde': 3.0.3 '@smithy/node-config-provider': 3.1.4 @@ -11987,12 +12339,12 @@ snapshots: '@smithy/util-middleware': 3.0.3 tslib: 2.6.3 - '@smithy/middleware-retry@3.0.11': + '@smithy/middleware-retry@3.0.13': dependencies: '@smithy/node-config-provider': 3.1.4 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/service-error-classification': 3.0.3 - '@smithy/smithy-client': 3.1.9 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 '@smithy/util-middleware': 3.0.3 '@smithy/util-retry': 3.0.3 @@ -12016,10 +12368,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/node-http-handler@3.1.3': + '@smithy/node-http-handler@3.1.4': dependencies: '@smithy/abort-controller': 3.1.1 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/querystring-builder': 3.0.3 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -12029,7 +12381,7 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/protocol-http@4.0.4': + '@smithy/protocol-http@4.1.0': dependencies: '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -12054,9 +12406,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/signature-v4@4.0.0': + '@smithy/signature-v4@4.1.0': dependencies: '@smithy/is-array-buffer': 3.0.0 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 '@smithy/util-hex-encoding': 3.0.0 '@smithy/util-middleware': 3.0.3 @@ -12064,13 +12417,13 @@ snapshots: '@smithy/util-utf8': 3.0.0 tslib: 2.6.3 - '@smithy/smithy-client@3.1.9': + '@smithy/smithy-client@3.1.11': dependencies: - '@smithy/middleware-endpoint': 3.0.5 + '@smithy/middleware-endpoint': 3.1.0 '@smithy/middleware-stack': 3.0.3 - '@smithy/protocol-http': 4.0.4 + '@smithy/protocol-http': 4.1.0 '@smithy/types': 3.3.0 - '@smithy/util-stream': 3.1.1 + '@smithy/util-stream': 3.1.3 tslib: 2.6.3 '@smithy/types@3.3.0': @@ -12111,21 +12464,21 @@ snapshots: dependencies: tslib: 2.6.3 - '@smithy/util-defaults-mode-browser@3.0.11': + '@smithy/util-defaults-mode-browser@3.0.13': dependencies: '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.9 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 bowser: 2.11.0 tslib: 2.6.3 - '@smithy/util-defaults-mode-node@3.0.11': + '@smithy/util-defaults-mode-node@3.0.13': dependencies: '@smithy/config-resolver': 3.0.5 - '@smithy/credential-provider-imds': 3.1.4 + '@smithy/credential-provider-imds': 3.2.0 '@smithy/node-config-provider': 3.1.4 '@smithy/property-provider': 3.1.3 - '@smithy/smithy-client': 3.1.9 + '@smithy/smithy-client': 3.1.11 '@smithy/types': 3.3.0 tslib: 2.6.3 @@ -12150,10 +12503,10 @@ snapshots: '@smithy/types': 3.3.0 tslib: 2.6.3 - '@smithy/util-stream@3.1.1': + '@smithy/util-stream@3.1.3': dependencies: - '@smithy/fetch-http-handler': 3.2.2 - '@smithy/node-http-handler': 3.1.3 + '@smithy/fetch-http-handler': 3.2.4 + '@smithy/node-http-handler': 3.1.4 '@smithy/types': 3.3.0 '@smithy/util-base64': 3.0.0 '@smithy/util-buffer-from': 3.0.0 @@ -12183,56 +12536,56 @@ snapshots: '@sqltools/formatter@1.2.5': {} - '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-svg-dynamic-title@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-svg-em-dimensions@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-transform-react-native-svg@8.1.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.24.9)': + '@svgr/babel-plugin-transform-svg-component@8.0.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 - '@svgr/babel-preset@8.1.0(@babel/core@7.24.9)': + '@svgr/babel-preset@8.1.0(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.9 - '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.24.9) - '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.24.9) - '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@svgr/babel-plugin-add-jsx-attribute': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-replace-jsx-attribute-value': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-svg-dynamic-title': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-svg-em-dimensions': 8.0.0(@babel/core@7.25.2) + '@svgr/babel-plugin-transform-react-native-svg': 8.1.0(@babel/core@7.25.2) + '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.25.2) - '@svgr/core@8.1.0(typescript@5.5.3)': + '@svgr/core@8.1.0(typescript@5.5.4)': dependencies: - '@babel/core': 7.24.9 - '@svgr/babel-preset': 8.1.0(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.5.3) + cosmiconfig: 8.3.6(typescript@5.5.4) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -12240,69 +12593,69 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 entities: 4.5.0 - '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.5.3))': + '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.5.4))': dependencies: - '@babel/core': 7.24.9 - '@svgr/babel-preset': 8.1.0(@babel/core@7.24.9) - '@svgr/core': 8.1.0(typescript@5.5.3) + '@babel/core': 7.25.2 + '@svgr/babel-preset': 8.1.0(@babel/core@7.25.2) + '@svgr/core': 8.1.0(typescript@5.5.4) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: - supports-color - '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.5.3))(typescript@5.5.3)': + '@svgr/plugin-svgo@8.1.0(@svgr/core@8.1.0(typescript@5.5.4))(typescript@5.5.4)': dependencies: - '@svgr/core': 8.1.0(typescript@5.5.3) - cosmiconfig: 8.3.6(typescript@5.5.3) + '@svgr/core': 8.1.0(typescript@5.5.4) + cosmiconfig: 8.3.6(typescript@5.5.4) deepmerge: 4.3.1 svgo: 3.3.2 transitivePeerDependencies: - typescript - '@svgr/webpack@8.1.0(typescript@5.5.3)': + '@svgr/webpack@8.1.0(typescript@5.5.4)': dependencies: - '@babel/core': 7.24.9 - '@babel/plugin-transform-react-constant-elements': 7.24.7(@babel/core@7.24.9) - '@babel/preset-env': 7.24.8(@babel/core@7.24.9) - '@babel/preset-react': 7.24.7(@babel/core@7.24.9) - '@babel/preset-typescript': 7.24.7(@babel/core@7.24.9) - '@svgr/core': 8.1.0(typescript@5.5.3) - '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.5.3)) - '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.5.3))(typescript@5.5.3) + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-constant-elements': 7.24.7(@babel/core@7.25.2) + '@babel/preset-env': 7.24.8(@babel/core@7.25.2) + '@babel/preset-react': 7.24.7(@babel/core@7.25.2) + '@babel/preset-typescript': 7.24.7(@babel/core@7.25.2) + '@svgr/core': 8.1.0(typescript@5.5.4) + '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.5.4)) + '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.5.4))(typescript@5.5.4) transitivePeerDependencies: - supports-color - typescript - '@swc-node/core@1.13.3(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9)': + '@swc-node/core@1.13.3(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12)': dependencies: - '@swc/core': 1.7.0(@swc/helpers@0.5.12) - '@swc/types': 0.1.9 + '@swc/core': 1.7.6(@swc/helpers@0.5.12) + '@swc/types': 0.1.12 - '@swc-node/jest@1.8.12(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9)(typescript@5.5.3)': + '@swc-node/jest@1.8.12(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4)': dependencies: '@node-rs/xxhash': 1.7.3 - '@swc-node/core': 1.13.3(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9) - '@swc-node/register': 1.10.9(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9)(typescript@5.5.3) - '@swc/core': 1.7.0(@swc/helpers@0.5.12) - '@swc/types': 0.1.9 - typescript: 5.5.3 + '@swc-node/core': 1.13.3(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12) + '@swc-node/register': 1.10.9(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) + '@swc/types': 0.1.12 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@swc-node/register@1.10.9(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9)(typescript@5.5.3)': + '@swc-node/register@1.10.9(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12)(typescript@5.5.4)': dependencies: - '@swc-node/core': 1.13.3(@swc/core@1.7.0(@swc/helpers@0.5.12))(@swc/types@0.1.9) + '@swc-node/core': 1.13.3(@swc/core@1.7.6(@swc/helpers@0.5.12))(@swc/types@0.1.12) '@swc-node/sourcemap-support': 0.5.1 - '@swc/core': 1.7.0(@swc/helpers@0.5.12) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) colorette: 2.0.20 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.5 oxc-resolver: 1.10.2 pirates: 4.0.6 tslib: 2.6.3 - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - '@swc/types' - supports-color @@ -12312,51 +12665,66 @@ snapshots: source-map-support: 0.5.21 tslib: 2.6.3 - '@swc/core-darwin-arm64@1.7.0': + '@swc/cli@0.4.0(@swc/core@1.7.6(@swc/helpers@0.5.12))(chokidar@3.6.0)': + dependencies: + '@mole-inc/bin-wrapper': 8.0.1 + '@swc/core': 1.7.6(@swc/helpers@0.5.12) + '@swc/counter': 0.1.3 + commander: 8.3.0 + fast-glob: 3.3.2 + minimatch: 9.0.5 + piscina: 4.6.1 + semver: 7.6.3 + slash: 3.0.0 + source-map: 0.7.4 + optionalDependencies: + chokidar: 3.6.0 + + '@swc/core-darwin-arm64@1.7.6': optional: true - '@swc/core-darwin-x64@1.7.0': + '@swc/core-darwin-x64@1.7.6': optional: true - '@swc/core-linux-arm-gnueabihf@1.7.0': + '@swc/core-linux-arm-gnueabihf@1.7.6': optional: true - '@swc/core-linux-arm64-gnu@1.7.0': + '@swc/core-linux-arm64-gnu@1.7.6': optional: true - '@swc/core-linux-arm64-musl@1.7.0': + '@swc/core-linux-arm64-musl@1.7.6': optional: true - '@swc/core-linux-x64-gnu@1.7.0': + '@swc/core-linux-x64-gnu@1.7.6': optional: true - '@swc/core-linux-x64-musl@1.7.0': + '@swc/core-linux-x64-musl@1.7.6': optional: true - '@swc/core-win32-arm64-msvc@1.7.0': + '@swc/core-win32-arm64-msvc@1.7.6': optional: true - '@swc/core-win32-ia32-msvc@1.7.0': + '@swc/core-win32-ia32-msvc@1.7.6': optional: true - '@swc/core-win32-x64-msvc@1.7.0': + '@swc/core-win32-x64-msvc@1.7.6': optional: true - '@swc/core@1.7.0(@swc/helpers@0.5.12)': + '@swc/core@1.7.6(@swc/helpers@0.5.12)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.9 + '@swc/types': 0.1.12 optionalDependencies: - '@swc/core-darwin-arm64': 1.7.0 - '@swc/core-darwin-x64': 1.7.0 - '@swc/core-linux-arm-gnueabihf': 1.7.0 - '@swc/core-linux-arm64-gnu': 1.7.0 - '@swc/core-linux-arm64-musl': 1.7.0 - '@swc/core-linux-x64-gnu': 1.7.0 - '@swc/core-linux-x64-musl': 1.7.0 - '@swc/core-win32-arm64-msvc': 1.7.0 - '@swc/core-win32-ia32-msvc': 1.7.0 - '@swc/core-win32-x64-msvc': 1.7.0 + '@swc/core-darwin-arm64': 1.7.6 + '@swc/core-darwin-x64': 1.7.6 + '@swc/core-linux-arm-gnueabihf': 1.7.6 + '@swc/core-linux-arm64-gnu': 1.7.6 + '@swc/core-linux-arm64-musl': 1.7.6 + '@swc/core-linux-x64-gnu': 1.7.6 + '@swc/core-linux-x64-musl': 1.7.6 + '@swc/core-win32-arm64-msvc': 1.7.6 + '@swc/core-win32-ia32-msvc': 1.7.6 + '@swc/core-win32-x64-msvc': 1.7.6 '@swc/helpers': 0.5.12 '@swc/counter@0.1.3': {} @@ -12370,43 +12738,47 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.6.3 - '@swc/jest@0.2.36(@swc/core@1.7.0(@swc/helpers@0.5.12))': + '@swc/jest@0.2.36(@swc/core@1.7.6(@swc/helpers@0.5.12))': dependencies: '@jest/create-cache-key-function': 29.7.0 - '@swc/core': 1.7.0(@swc/helpers@0.5.12) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) '@swc/counter': 0.1.3 jsonc-parser: 3.3.1 - '@swc/types@0.1.9': + '@swc/types@0.1.12': dependencies: '@swc/counter': 0.1.3 - '@t3-oss/env-core@0.11.0(typescript@5.5.3)(zod@3.23.8)': + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@t3-oss/env-core@0.11.0(typescript@5.5.4)(zod@3.23.8)': dependencies: zod: 3.23.8 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 - '@t3-oss/env-nextjs@0.11.0(typescript@5.5.3)(zod@3.23.8)': + '@t3-oss/env-nextjs@0.11.0(typescript@5.5.4)(zod@3.23.8)': dependencies: - '@t3-oss/env-core': 0.11.0(typescript@5.5.3)(zod@3.23.8) + '@t3-oss/env-core': 0.11.0(typescript@5.5.4)(zod@3.23.8) zod: 3.23.8 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 - '@tanstack/query-core@5.51.9': {} + '@tanstack/query-core@5.51.21': {} - '@tanstack/query-devtools@5.51.9': {} + '@tanstack/query-devtools@5.51.16': {} - '@tanstack/react-query-devtools@5.51.11(@tanstack/react-query@5.51.11(react@18.3.1))(react@18.3.1)': + '@tanstack/react-query-devtools@5.51.21(@tanstack/react-query@5.51.21(react@18.3.1))(react@18.3.1)': dependencies: - '@tanstack/query-devtools': 5.51.9 - '@tanstack/react-query': 5.51.11(react@18.3.1) + '@tanstack/query-devtools': 5.51.16 + '@tanstack/react-query': 5.51.21(react@18.3.1) react: 18.3.1 - '@tanstack/react-query@5.51.11(react@18.3.1)': + '@tanstack/react-query@5.51.21(react@18.3.1)': dependencies: - '@tanstack/query-core': 5.51.9 + '@tanstack/query-core': 5.51.21 react: 18.3.1 '@tanstack/react-table@8.19.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -12428,7 +12800,7 @@ snapshots: '@testing-library/dom@10.3.2': dependencies: '@babel/code-frame': 7.24.7 - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.0 '@types/aria-query': 5.0.4 aria-query: 5.3.0 chalk: 4.1.2 @@ -12436,7 +12808,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.7(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)))': + '@testing-library/jest-dom@6.4.8': dependencies: '@adobe/css-tools': 4.4.0 '@babel/runtime': 7.24.8 @@ -12446,10 +12818,6 @@ snapshots: dom-accessibility-api: 0.6.3 lodash: 4.17.21 redent: 3.0.0 - optionalDependencies: - '@jest/globals': 29.7.0 - '@types/jest': 29.5.12 - jest: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) '@testing-library/react@16.0.0(@testing-library/dom@10.3.2)(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: @@ -12465,6 +12833,8 @@ snapshots: dependencies: '@testing-library/dom': 10.3.2 + '@tokenizer/token@0.3.0': {} + '@tootallnate/once@2.0.0': {} '@toss/use-overlay@1.4.0(react@18.3.1)': @@ -12490,41 +12860,48 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.0 + '@babel/types': 7.25.2 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.0 + '@babel/types': 7.25.2 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 '@types/bcrypt@5.0.2': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/body-parser@1.19.5': dependencies: '@types/connect': 3.4.38 - '@types/node': 20.14.11 + '@types/node': 20.14.14 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 20.14.14 + '@types/responselike': 1.0.3 '@types/cls-hooked@4.3.8': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/connect@3.4.38': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/cookie@0.6.0': {} @@ -12571,7 +12948,7 @@ snapshots: '@types/express-serve-static-core@4.19.5': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/qs': 6.9.15 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -12585,13 +12962,15 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/hoist-non-react-statics@3.3.5': dependencies: '@types/react': 18.3.3 hoist-non-react-statics: 3.3.2 + '@types/http-cache-semantics@4.0.4': {} + '@types/http-errors@2.0.4': {} '@types/istanbul-lib-coverage@2.0.6': {} @@ -12613,7 +12992,7 @@ snapshots: '@types/jsdom@20.0.1': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/tough-cookie': 4.0.5 parse5: 7.1.2 @@ -12623,7 +13002,11 @@ snapshots: '@types/jsonwebtoken@9.0.5': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 20.14.14 '@types/luxon@3.4.2': {} @@ -12641,20 +13024,44 @@ snapshots: '@types/mute-stream@0.0.4': dependencies: - '@types/node': 20.14.11 + '@types/node': 22.1.0 '@types/node@14.18.63': {} - '@types/node@20.14.11': + '@types/node@20.14.14': dependencies: undici-types: 5.26.5 + '@types/node@22.1.0': + dependencies: + undici-types: 6.13.0 + '@types/nodemailer@6.4.15': dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/parse-json@4.0.2': {} + '@types/passport-jwt@4.0.1': + dependencies: + '@types/jsonwebtoken': 9.0.5 + '@types/passport-strategy': 0.2.38 + + '@types/passport-local@1.0.38': + dependencies: + '@types/express': 4.17.21 + '@types/passport': 1.0.16 + '@types/passport-strategy': 0.2.38 + + '@types/passport-strategy@0.2.38': + dependencies: + '@types/express': 4.17.21 + '@types/passport': 1.0.16 + + '@types/passport@1.0.16': + dependencies: + '@types/express': 4.17.21 + '@types/prop-types@15.7.12': {} '@types/pug@2.0.10': @@ -12670,7 +13077,7 @@ snapshots: '@types/react-datepicker@6.2.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: - '@floating-ui/react': 0.26.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react': 0.26.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/react': 18.3.3 date-fns: 3.6.0 transitivePeerDependencies: @@ -12697,15 +13104,19 @@ snapshots: '@types/prop-types': 15.7.12 csstype: 3.1.3 + '@types/responselike@1.0.3': + dependencies: + '@types/node': 20.14.14 + '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/send': 0.17.4 '@types/stack-utils@2.0.3': {} @@ -12716,7 +13127,7 @@ snapshots: dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 20.14.11 + '@types/node': 20.14.14 '@types/supertest@6.0.2': dependencies: @@ -12735,85 +13146,85 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/eslint-plugin@7.17.0(@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4))(eslint@9.8.0)(typescript@5.5.4)': dependencies: '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/type-utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 - eslint: 9.7.0 + '@typescript-eslint/parser': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/type-utils': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.17.0 + eslint: 9.8.0 graphemer: 1.4.0 ignore: 5.3.1 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.3) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 - debug: 4.3.5(supports-color@9.4.0) - eslint: 9.7.0 + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.17.0 + debug: 4.3.5 + eslint: 9.8.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@7.16.1': + '@typescript-eslint/scope-manager@7.17.0': dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/visitor-keys': 7.17.0 - '@typescript-eslint/type-utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/type-utils@7.17.0(eslint@9.8.0)(typescript@5.5.4)': dependencies: - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - debug: 4.3.5(supports-color@9.4.0) - eslint: 9.7.0 - ts-api-utils: 1.3.0(typescript@5.5.3) + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4) + '@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + debug: 4.3.5 + eslint: 9.8.0 + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@7.16.1': {} + '@typescript-eslint/types@7.17.0': {} - '@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)': + '@typescript-eslint/typescript-estree@7.17.0(typescript@5.5.4)': dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 - debug: 4.3.5(supports-color@9.4.0) + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/visitor-keys': 7.17.0 + debug: 4.3.5 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.5.3) + ts-api-utils: 1.3.0(typescript@5.5.4) optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': + '@typescript-eslint/utils@7.17.0(eslint@9.8.0)(typescript@5.5.4)': dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.7.0) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - eslint: 9.7.0 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) + '@typescript-eslint/scope-manager': 7.17.0 + '@typescript-eslint/types': 7.17.0 + '@typescript-eslint/typescript-estree': 7.17.0(typescript@5.5.4) + eslint: 9.8.0 transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/visitor-keys@7.16.1': + '@typescript-eslint/visitor-keys@7.17.0': dependencies: - '@typescript-eslint/types': 7.16.1 + '@typescript-eslint/types': 7.17.0 eslint-visitor-keys: 3.4.3 '@webassemblyjs/ast@1.12.1': @@ -12945,13 +13356,13 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color agent-base@7.1.1(supports-color@9.4.0): dependencies: - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -13041,6 +13452,8 @@ snapshots: aproba@2.0.0: {} + arch@2.2.0: {} + archiver-utils@2.1.0: dependencies: glob: 7.2.3 @@ -13182,14 +13595,14 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.4.19(postcss@8.4.39): + autoprefixer@10.4.20(postcss@8.4.41): dependencies: - browserslist: 4.23.2 - caniuse-lite: 1.0.30001642 + browserslist: 4.23.3 + caniuse-lite: 1.0.30001649 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.1 - postcss: 8.4.39 + postcss: 8.4.41 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -13201,7 +13614,7 @@ snapshots: '@fastify/error': 3.4.1 fastq: 1.17.1 - aws-sdk@2.1659.0: + aws-sdk@2.1665.0: dependencies: buffer: 4.9.2 events: 1.1.1 @@ -13218,11 +13631,11 @@ snapshots: aws4@1.13.0: {} - axios-auth-refresh@3.3.6(axios@1.7.2): + axios-auth-refresh@3.3.6(axios@1.7.3): dependencies: - axios: 1.7.2 + axios: 1.7.3 - axios@1.7.2: + axios@1.7.3: dependencies: follow-redirects: 1.15.6 form-data: 4.0.0 @@ -13230,13 +13643,13 @@ snapshots: transitivePeerDependencies: - debug - babel-jest@29.7.0(@babel/core@7.24.9): + babel-jest@29.7.0(@babel/core@7.25.2): dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.24.9) + babel-preset-jest: 29.6.3(@babel/core@7.25.2) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -13255,8 +13668,8 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: - '@babel/template': 7.24.7 - '@babel/types': 7.24.9 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 @@ -13266,51 +13679,51 @@ snapshots: cosmiconfig: 7.1.0 resolve: 1.22.8 - babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.9): + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): dependencies: '@babel/compat-data': 7.24.9 - '@babel/core': 7.24.9 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) semver: 6.3.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.9): + babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.25.2): dependencies: - '@babel/core': 7.24.9 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) core-js-compat: 3.37.1 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.9): + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): dependencies: - '@babel/core': 7.24.9 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.9) + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) transitivePeerDependencies: - supports-color - babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.9): - dependencies: - '@babel/core': 7.24.9 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.9) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.9) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.9) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.9) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.9) - - babel-preset-jest@29.6.3(@babel/core@7.24.9): - dependencies: - '@babel/core': 7.24.9 + babel-preset-current-node-syntax@1.0.1(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + + babel-preset-jest@29.6.3(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.9) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.25.2) babel-runtime@6.26.0: dependencies: @@ -13319,7 +13732,7 @@ snapshots: babel-walk@3.0.0-canary-5: dependencies: - '@babel/types': 7.24.9 + '@babel/types': 7.25.2 optional: true balanced-match@1.0.2: {} @@ -13336,6 +13749,22 @@ snapshots: big-integer@1.6.52: {} + bin-check@4.1.0: + dependencies: + execa: 0.7.0 + executable: 4.1.1 + + bin-version-check@5.1.0: + dependencies: + bin-version: 6.0.0 + semver: 7.6.3 + semver-truncate: 3.0.0 + + bin-version@6.0.0: + dependencies: + execa: 5.1.1 + find-versions: 5.1.0 + binary-extensions@2.3.0: {} binary@0.3.0: @@ -13404,11 +13833,18 @@ snapshots: browserslist@4.23.2: dependencies: - caniuse-lite: 1.0.30001642 + caniuse-lite: 1.0.30001649 electron-to-chromium: 1.4.828 node-releases: 2.0.14 update-browserslist-db: 1.1.0(browserslist@4.23.2) + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001649 + electron-to-chromium: 1.5.4 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + bs-logger@0.2.6: dependencies: fast-json-stable-stringify: 2.1.0 @@ -13456,6 +13892,18 @@ snapshots: cac@6.7.14: {} + cacheable-lookup@5.0.4: {} + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 @@ -13482,6 +13930,8 @@ snapshots: caniuse-lite@1.0.30001642: {} + caniuse-lite@1.0.30001649: {} + chainsaw@0.1.0: dependencies: traverse: 0.3.9 @@ -13620,6 +14070,10 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + clone@1.0.4: {} cls-hooked@4.2.2: @@ -13678,6 +14132,8 @@ snapshots: commander@7.2.0: {} + commander@8.3.0: {} + comment-json@4.2.3: dependencies: array-timsort: 1.0.3 @@ -13720,8 +14176,8 @@ snapshots: constantinople@4.0.1: dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.0 + '@babel/types': 7.25.2 optional: true content-disposition@0.5.4: @@ -13753,7 +14209,7 @@ snapshots: core-js-compat@3.37.1: dependencies: - browserslist: 4.23.2 + browserslist: 4.23.3 core-js@2.6.12: {} @@ -13793,14 +14249,14 @@ snapshots: optionalDependencies: typescript: 5.3.3 - cosmiconfig@8.3.6(typescript@5.5.3): + cosmiconfig@8.3.6(typescript@5.5.4): dependencies: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 countries-and-timezones@3.6.0: {} @@ -13811,13 +14267,13 @@ snapshots: crc-32: 1.2.2 readable-stream: 3.6.2 - create-jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)): + create-jest@29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + jest-config: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -13833,6 +14289,12 @@ snapshots: '@types/luxon': 3.4.2 luxon: 3.4.4 + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@6.0.5: dependencies: nice-try: 1.0.5 @@ -13980,7 +14442,11 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.3.5(supports-color@9.4.0): + debug@4.3.5: + dependencies: + ms: 2.1.2 + + debug@4.3.6(supports-color@9.4.0): dependencies: ms: 2.1.2 optionalDependencies: @@ -13990,6 +14456,10 @@ snapshots: decimal.js@10.4.3: {} + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + dedent@1.5.3(babel-plugin-macros@3.1.0): optionalDependencies: babel-plugin-macros: 3.1.0 @@ -14005,6 +14475,8 @@ snapshots: dependencies: clone: 1.0.4 + defer-to-connect@2.0.1: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.0 @@ -14161,10 +14633,12 @@ snapshots: ejs@3.1.10: dependencies: - jake: 10.9.1 + jake: 10.9.2 electron-to-chromium@1.4.828: {} + electron-to-chromium@1.5.4: {} + emitter-listener@1.1.2: dependencies: shimmer: 1.2.1 @@ -14342,6 +14816,8 @@ snapshots: escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -14350,34 +14826,34 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-config-prettier@9.1.0(eslint@9.7.0): + eslint-config-prettier@9.1.0(eslint@9.8.0): dependencies: - eslint: 9.7.0 + eslint: 9.8.0 - eslint-config-turbo@2.0.9(eslint@9.7.0): + eslint-config-turbo@2.0.12(eslint@9.8.0): dependencies: - eslint: 9.7.0 - eslint-plugin-turbo: 2.0.9(eslint@9.7.0) + eslint: 9.8.0 + eslint-plugin-turbo: 2.0.12(eslint@9.8.0) eslint-import-resolver-node@0.3.9: dependencies: debug: 3.2.7 - is-core-module: 2.14.0 + is-core-module: 2.15.0 resolve: 1.22.8 transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@9.7.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@9.8.0): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - eslint: 9.7.0 + '@typescript-eslint/parser': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + eslint: 9.8.0 eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4))(eslint@9.8.0): dependencies: array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 @@ -14385,11 +14861,11 @@ snapshots: array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 9.7.0 + eslint: 9.8.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@9.7.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint@9.8.0) hasown: 2.0.2 - is-core-module: 2.14.0 + is-core-module: 2.15.0 is-glob: 4.0.3 minimatch: 3.1.2 object.fromentries: 2.0.8 @@ -14398,27 +14874,27 @@ snapshots: semver: 6.3.1 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) + '@typescript-eslint/parser': 7.17.0(eslint@9.8.0)(typescript@5.5.4) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color - eslint-plugin-prettier@5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.7.0))(eslint@9.7.0)(prettier@3.3.3): + eslint-plugin-prettier@5.2.1(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.8.0))(eslint@9.8.0)(prettier@3.3.3): dependencies: - eslint: 9.7.0 + eslint: 9.8.0 prettier: 3.3.3 prettier-linter-helpers: 1.0.0 synckit: 0.9.1 optionalDependencies: '@types/eslint': 8.56.10 - eslint-config-prettier: 9.1.0(eslint@9.7.0) + eslint-config-prettier: 9.1.0(eslint@9.8.0) - eslint-plugin-react-hooks@4.6.2(eslint@9.7.0): + eslint-plugin-react-hooks@4.6.2(eslint@9.8.0): dependencies: - eslint: 9.7.0 + eslint: 9.8.0 - eslint-plugin-react@7.35.0(eslint@9.7.0): + eslint-plugin-react@7.35.0(eslint@9.8.0): dependencies: array-includes: 3.1.8 array.prototype.findlast: 1.2.5 @@ -14426,7 +14902,7 @@ snapshots: array.prototype.tosorted: 1.1.4 doctrine: 2.1.0 es-iterator-helpers: 1.0.19 - eslint: 9.7.0 + eslint: 9.8.0 estraverse: 5.3.0 hasown: 2.0.2 jsx-ast-utils: 3.3.5 @@ -14440,10 +14916,10 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 - eslint-plugin-turbo@2.0.9(eslint@9.7.0): + eslint-plugin-turbo@2.0.12(eslint@9.8.0): dependencies: dotenv: 16.0.3 - eslint: 9.7.0 + eslint: 9.8.0 eslint-scope@5.1.1: dependencies: @@ -14459,20 +14935,20 @@ snapshots: eslint-visitor-keys@4.0.0: {} - eslint@9.7.0: + eslint@9.8.0: dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.7.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@9.8.0) '@eslint-community/regexpp': 4.11.0 - '@eslint/config-array': 0.17.0 + '@eslint/config-array': 0.17.1 '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.7.0 + '@eslint/js': 9.8.0 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.3.0 '@nodelib/fs.walk': 1.2.8 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.5 escape-string-regexp: 4.0.0 eslint-scope: 8.0.2 eslint-visitor-keys: 4.0.0 @@ -14563,6 +15039,16 @@ snapshots: strip-eof: 1.0.0 optional: true + execa@0.7.0: + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + execa@5.1.1: dependencies: cross-spawn: 7.0.3 @@ -14575,6 +15061,10 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + executable@4.1.1: + dependencies: + pify: 2.3.0 + exit@0.1.2: {} expect@29.7.0: @@ -14621,6 +15111,15 @@ snapshots: transitivePeerDependencies: - supports-color + ext-list@2.2.2: + dependencies: + mime-db: 1.52.0 + + ext-name@5.0.0: + dependencies: + ext-list: 2.2.2 + sort-keys-length: 1.0.1 + extend-object@1.0.0: optional: true @@ -14688,7 +15187,7 @@ snapshots: fast-uri@3.0.1: {} - fast-xml-parser@4.2.5: + fast-xml-parser@4.4.1: dependencies: strnum: 1.0.5 @@ -14707,7 +15206,7 @@ snapshots: fast-json-stringify: 5.16.1 find-my-way: 8.2.0 light-my-request: 5.13.0 - pino: 9.3.1 + pino: 9.3.2 process-warning: 3.0.0 proxy-addr: 2.0.7 rfdc: 1.4.1 @@ -14750,12 +15249,26 @@ snapshots: dependencies: flat-cache: 4.0.1 + file-type@17.1.6: + dependencies: + readable-web-to-node-stream: 3.0.2 + strtok3: 7.1.1 + token-types: 5.0.1 + file-uri-to-path@1.0.0: {} filelist@1.0.4: dependencies: minimatch: 5.1.6 + filename-reserved-regex@3.0.0: {} + + filenamify@5.1.1: + dependencies: + filename-reserved-regex: 3.0.0 + strip-outer: 2.0.0 + trim-repeated: 2.0.0 + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -14790,6 +15303,10 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-versions@5.1.0: + dependencies: + semver-regex: 4.0.5 + fixpack@4.0.0: dependencies: alce: 1.2.0 @@ -14818,7 +15335,7 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12))): + fork-ts-checker-webpack-plugin@9.0.2(typescript@5.3.3)(webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12))): dependencies: '@babel/code-frame': 7.24.7 chalk: 4.1.2 @@ -14833,7 +15350,7 @@ snapshots: semver: 7.6.3 tapable: 2.2.1 typescript: 5.3.3 - webpack: 5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12)) + webpack: 5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12)) form-data@4.0.0: dependencies: @@ -14851,7 +15368,7 @@ snapshots: fraction.js@4.3.7: {} - framer-motion@11.3.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + framer-motion@11.3.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: tslib: 2.6.3 optionalDependencies: @@ -14943,8 +15460,11 @@ snapshots: get-stdin@9.0.0: {} - get-stream@3.0.0: - optional: true + get-stream@3.0.0: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.0 get-stream@6.0.1: {} @@ -15051,6 +15571,20 @@ snapshots: dependencies: get-intrinsic: 1.2.4 + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} @@ -15170,6 +15704,8 @@ snapshots: entities: 4.5.0 optional: true + http-cache-semantics@4.1.1: {} + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -15182,21 +15718,26 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.5(supports-color@9.4.0): dependencies: agent-base: 7.1.1(supports-color@9.4.0) - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) transitivePeerDependencies: - supports-color @@ -15204,7 +15745,7 @@ snapshots: hyphenate-style-name@1.1.0: {} - i18next-fs-backend@2.3.1: {} + i18next-fs-backend@2.3.2: {} i18next@23.12.2: dependencies: @@ -15345,10 +15886,6 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.14.0: - dependencies: - hasown: 2.0.2 - is-core-module@2.15.0: dependencies: hasown: 2.0.2 @@ -15406,6 +15943,8 @@ snapshots: is-path-inside@3.0.3: {} + is-plain-obj@1.1.0: {} + is-potential-custom-element-name@1.0.1: {} is-promise@2.2.2: @@ -15428,8 +15967,7 @@ snapshots: dependencies: call-bind: 1.0.7 - is-stream@1.1.0: - optional: true + is-stream@1.1.0: {} is-stream@2.0.1: {} @@ -15473,8 +16011,8 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.24.9 - '@babel/parser': 7.24.8 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -15483,8 +16021,8 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.24.9 - '@babel/parser': 7.24.8 + '@babel/core': 7.25.2 + '@babel/parser': 7.25.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -15499,7 +16037,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -15538,7 +16076,7 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jake@10.9.1: + jake@10.9.2: dependencies: async: 3.2.5 chalk: 4.1.2 @@ -15557,7 +16095,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3(babel-plugin-macros@3.1.0) @@ -15577,16 +16115,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)): + jest-cli@29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + create-jest: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + jest-config: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -15596,12 +16134,12 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)): + jest-config@29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)): dependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.24.9) + babel-jest: 29.7.0(@babel/core@7.25.2) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -15621,8 +16159,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 20.14.11 - ts-node: 10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3) + '@types/node': 20.14.14 + ts-node: 10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -15652,7 +16190,7 @@ snapshots: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -15666,7 +16204,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -15676,7 +16214,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.14.11 + '@types/node': 20.14.14 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -15715,7 +16253,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -15750,7 +16288,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -15778,7 +16316,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 cjs-module-lexer: 1.3.1 collect-v8-coverage: 1.0.2 @@ -15798,15 +16336,15 @@ snapshots: jest-snapshot@29.7.0: dependencies: - '@babel/core': 7.24.9 - '@babel/generator': 7.24.9 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.9) - '@babel/types': 7.24.9 + '@babel/core': 7.25.2 + '@babel/generator': 7.25.0 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + '@babel/types': 7.25.2 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.9) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.25.2) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -15824,7 +16362,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -15843,7 +16381,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.14.11 + '@types/node': 20.14.14 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -15852,23 +16390,23 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 20.14.11 + '@types/node': 20.14.14 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)): + jest@29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + jest-cli: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -16201,10 +16739,17 @@ snapshots: dependencies: tslib: 2.6.3 + lowercase-keys@2.0.0: {} + lru-cache@10.4.3: {} lru-cache@11.0.0: {} + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + lru-cache@5.1.1: dependencies: yallist: 3.1.1 @@ -16310,6 +16855,10 @@ snapshots: mimic-fn@2.1.0: {} + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + min-indent@1.0.1: {} minimatch@10.0.1: @@ -16699,12 +17248,12 @@ snapshots: ms@2.1.3: {} - msw@2.3.2(typescript@5.5.3): + msw@2.3.5(typescript@5.5.4): dependencies: '@bundled-es-modules/cookie': 2.0.0 '@bundled-es-modules/statuses': 1.0.1 - '@inquirer/confirm': 3.1.15 - '@mswjs/cookies': 1.1.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 3.1.20 '@mswjs/interceptors': 0.29.1 '@open-draft/until': 2.1.0 '@types/cookie': 0.6.0 @@ -16716,10 +17265,10 @@ snapshots: outvariant: 1.4.3 path-to-regexp: 6.2.2 strict-event-emitter: 0.5.1 - type-fest: 4.22.1 + type-fest: 4.23.0 yargs: 17.7.2 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 multer@1.4.4-lts.1: dependencies: @@ -16735,7 +17284,7 @@ snapshots: mute-stream@1.0.0: {} - mysql2@3.10.3: + mysql2@3.11.0: dependencies: aws-ssl-profiles: 1.1.1 denque: 2.1.0 @@ -16778,7 +17327,7 @@ snapshots: neo-async@2.6.2: {} - nestjs-cls@3.6.0(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1): + nestjs-cls@4.4.1(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/core@10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1))(reflect-metadata@0.2.2)(rxjs@7.8.1): dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) '@nestjs/core': 10.3.10(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(@nestjs/platform-express@10.3.10)(reflect-metadata@0.2.2)(rxjs@7.8.1) @@ -16790,29 +17339,29 @@ snapshots: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) pino-http: 10.2.0 - nestjs-typeorm-paginate@4.0.4(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3))): + nestjs-typeorm-paginate@4.0.4(@nestjs/common@10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1))(typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4))): dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.1) - typeorm: 0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + typeorm: 0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) - next-i18next@15.3.0(i18next@23.12.2)(next@14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-i18next@15.0.0(i18next@23.12.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + next-i18next@15.3.1(i18next@23.12.2)(next@14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-i18next@15.0.0(i18next@23.12.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.0 '@types/hoist-non-react-statics': 3.3.5 core-js: 3.37.1 hoist-non-react-statics: 3.3.2 i18next: 23.12.2 - i18next-fs-backend: 2.3.1 - next: 14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + i18next-fs-backend: 2.3.2 + next: 14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-i18next: 15.0.0(i18next@23.12.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - next-router-mock@0.9.13(next@14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + next-router-mock@0.9.13(next@14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): dependencies: - next: 14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 - next@14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + next@14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@next/env': 14.2.5 '@swc/helpers': 0.5.5 @@ -16822,7 +17371,7 @@ snapshots: postcss: 8.4.31 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - styled-jsx: 5.1.1(@babel/core@7.24.9)(babel-plugin-macros@3.1.0)(react@18.3.1) + styled-jsx: 5.1.1(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@18.3.1) optionalDependencies: '@next/swc-darwin-arm64': 14.2.5 '@next/swc-darwin-x64': 14.2.5 @@ -16834,11 +17383,17 @@ snapshots: '@next/swc-win32-ia32-msvc': 14.2.5 '@next/swc-win32-x64-msvc': 14.2.5 '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.45.3 + '@playwright/test': 1.46.0 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + nice-napi@1.0.2: + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.8.1 + optional: true + nice-try@1.0.5: optional: true @@ -16856,6 +17411,9 @@ snapshots: node-addon-api@1.7.2: {} + node-addon-api@3.2.1: + optional: true + node-addon-api@5.1.0: {} node-emoji@1.11.0: @@ -16866,12 +17424,15 @@ snapshots: dependencies: whatwg-url: 5.0.0 + node-gyp-build@4.8.1: + optional: true + node-int64@0.4.0: {} - node-mocks-http@1.15.0: + node-mocks-http@1.15.1: dependencies: '@types/express': 4.17.21 - '@types/node': 20.14.11 + '@types/node': 20.14.14 accepts: 1.3.8 content-disposition: 0.5.4 depd: 1.1.2 @@ -16885,6 +17446,8 @@ snapshots: node-releases@2.0.14: {} + node-releases@2.0.18: {} + nodemailer@6.9.13: optional: true @@ -16903,10 +17466,11 @@ snapshots: normalize-range@0.1.2: {} + normalize-url@6.1.0: {} + npm-run-path@2.0.2: dependencies: path-key: 2.0.1 - optional: true npm-run-path@4.0.1: dependencies: @@ -16923,10 +17487,10 @@ snapshots: dependencies: boolbase: 1.0.0 - nuqs@1.17.5(next@14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): + nuqs@1.17.7(next@14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)): dependencies: mitt: 3.0.1 - next: 14.2.5(@babel/core@7.24.9)(@opentelemetry/api@1.9.0)(@playwright/test@1.45.3)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + next: 14.2.5(@babel/core@7.25.2)(@opentelemetry/api@1.9.0)(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nwsapi@2.2.12: {} @@ -16992,13 +17556,13 @@ snapshots: is-wsl: 2.2.0 optional: true - openapi-typescript@7.1.0(typescript@5.5.3): + openapi-typescript@7.3.0(typescript@5.5.4): dependencies: - '@redocly/openapi-core': 1.18.0(supports-color@9.4.0) + '@redocly/openapi-core': 1.19.0(supports-color@9.4.0) ansi-colors: 4.1.3 parse-json: 8.1.0 supports-color: 9.4.0 - typescript: 5.5.3 + typescript: 5.5.4 yargs-parser: 21.1.1 transitivePeerDependencies: - encoding @@ -17024,6 +17588,10 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + os-filter-obj@2.0.0: + dependencies: + arch: 2.2.0 + os-homedir@1.0.2: {} os-tmpdir@1.0.2: {} @@ -17050,13 +17618,14 @@ snapshots: '@oxc-resolver/binding-win32-arm64-msvc': 1.10.2 '@oxc-resolver/binding-win32-x64-msvc': 1.10.2 + p-cancelable@2.1.1: {} + p-event@4.2.0: dependencies: p-timeout: 3.2.0 optional: true - p-finally@1.0.0: - optional: true + p-finally@1.0.0: {} p-limit@2.3.0: dependencies: @@ -17114,7 +17683,7 @@ snapshots: dependencies: '@babel/code-frame': 7.24.7 index-to-position: 0.1.2 - type-fest: 4.22.1 + type-fest: 4.23.0 parse5-htmlparser2-tree-adapter@6.0.1: dependencies: @@ -17167,8 +17736,7 @@ snapshots: path-is-absolute@1.0.1: {} - path-key@2.0.1: - optional: true + path-key@2.0.1: {} path-key@3.1.1: {} @@ -17199,6 +17767,8 @@ snapshots: peberminta@0.9.0: optional: true + peek-readable@5.1.3: {} + picocolors@1.0.1: {} picomatch@2.3.1: {} @@ -17219,7 +17789,7 @@ snapshots: pino-std-serializers: 7.0.0 process-warning: 3.0.0 - pino-pretty@11.2.1: + pino-pretty@11.2.2: dependencies: colorette: 2.0.20 dateformat: 4.6.3 @@ -17252,17 +17822,35 @@ snapshots: sonic-boom: 4.0.1 thread-stream: 3.1.0 + pino@9.3.2: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 4.0.1 + thread-stream: 3.1.0 + pirates@4.0.6: {} + piscina@4.6.1: + optionalDependencies: + nice-napi: 1.0.2 + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 - playwright-core@1.45.3: {} + playwright-core@1.46.0: {} - playwright@1.45.3: + playwright@1.46.0: dependencies: - playwright-core: 1.45.3 + playwright-core: 1.46.0 optionalDependencies: fsevents: 2.3.2 @@ -17270,7 +17858,7 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-cli@11.0.0(jiti@1.21.6)(postcss@8.4.39): + postcss-cli@11.0.0(jiti@1.21.6)(postcss@8.4.41): dependencies: chokidar: 3.6.0 dependency-graph: 0.11.0 @@ -17278,9 +17866,9 @@ snapshots: get-stdin: 9.0.0 globby: 14.0.2 picocolors: 1.0.1 - postcss: 8.4.39 - postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.39) - postcss-reporter: 7.1.0(postcss@8.4.39) + postcss: 8.4.41 + postcss-load-config: 5.1.0(jiti@1.21.6)(postcss@8.4.41) + postcss-reporter: 7.1.0(postcss@8.4.41) pretty-hrtime: 1.0.3 read-cache: 1.0.0 slash: 5.1.0 @@ -17289,16 +17877,16 @@ snapshots: - jiti - tsx - postcss-import@15.1.0(postcss@8.4.39): + postcss-import@15.1.0(postcss@8.4.41): dependencies: - postcss: 8.4.39 + postcss: 8.4.41 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 - postcss-import@16.1.0(postcss@8.4.39): + postcss-import@16.1.0(postcss@8.4.41): dependencies: - postcss: 8.4.39 + postcss: 8.4.41 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.8 @@ -17308,10 +17896,10 @@ snapshots: camelcase-css: 1.0.1 postcss: 5.2.18 - postcss-js@4.0.1(postcss@8.4.39): + postcss-js@4.0.1(postcss@8.4.41): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.39 + postcss: 8.4.41 postcss-load-config@1.2.0: dependencies: @@ -17320,29 +17908,29 @@ snapshots: postcss-load-options: 1.2.0 postcss-load-plugins: 2.3.0 - postcss-load-config@4.0.2(postcss@8.4.39)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(typescript@5.5.3)): + postcss-load-config@4.0.2(postcss@8.4.41)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(typescript@5.5.4)): dependencies: lilconfig: 3.1.2 - yaml: 2.4.5 + yaml: 2.5.0 optionalDependencies: - postcss: 8.4.39 - ts-node: 10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3) + postcss: 8.4.41 + ts-node: 10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4) - postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.39): + postcss-load-config@5.1.0(jiti@1.21.6)(postcss@8.4.41): dependencies: lilconfig: 3.1.2 yaml: 2.4.5 optionalDependencies: jiti: 1.21.6 - postcss: 8.4.39 + postcss: 8.4.41 - postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.39)(yaml@2.4.5): + postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.41)(yaml@2.5.0): dependencies: lilconfig: 3.1.2 optionalDependencies: jiti: 1.21.6 - postcss: 8.4.39 - yaml: 2.4.5 + postcss: 8.4.41 + yaml: 2.5.0 postcss-load-options@1.2.0: dependencies: @@ -17354,22 +17942,22 @@ snapshots: cosmiconfig: 2.2.2 object-assign: 4.1.1 - postcss-nested@6.0.1(postcss@8.4.39): + postcss-nested@6.2.0(postcss@8.4.41): dependencies: - postcss: 8.4.39 + postcss: 8.4.41 postcss-selector-parser: 6.1.1 - postcss-nesting@12.1.5(postcss@8.4.39): + postcss-nesting@12.1.5(postcss@8.4.41): dependencies: '@csstools/selector-resolve-nested': 1.1.0(postcss-selector-parser@6.1.1) '@csstools/selector-specificity': 3.1.1(postcss-selector-parser@6.1.1) - postcss: 8.4.39 + postcss: 8.4.41 postcss-selector-parser: 6.1.1 - postcss-reporter@7.1.0(postcss@8.4.39): + postcss-reporter@7.1.0(postcss@8.4.41): dependencies: picocolors: 1.0.1 - postcss: 8.4.39 + postcss: 8.4.41 thenby: 1.3.4 postcss-safe-parser@2.0.1: @@ -17404,7 +17992,7 @@ snapshots: picocolors: 1.0.1 source-map-js: 1.2.0 - postcss@8.4.39: + postcss@8.4.41: dependencies: nanoid: 3.3.7 picocolors: 1.0.1 @@ -17477,6 +18065,8 @@ snapshots: process-warning@3.0.0: {} + process-warning@4.0.0: {} + process@0.11.10: {} prom-client@15.1.3: @@ -17510,6 +18100,8 @@ snapshots: proxy-from-env@1.1.0: {} + pseudomap@1.0.2: {} + psl@1.9.0: {} pug-attrs@3.0.0: @@ -17621,6 +18213,8 @@ snapshots: quick-format-unescaped@4.0.4: {} + quick-lru@5.1.1: {} + raf-schd@4.0.3: {} randombytes@2.1.0: @@ -17660,7 +18254,7 @@ snapshots: react-datepicker@6.9.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@floating-ui/react': 0.26.20(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@floating-ui/react': 0.26.21(react-dom@18.3.1(react@18.3.1))(react@18.3.1) clsx: 2.1.1 date-fns: 3.6.0 prop-types: 15.8.1 @@ -17674,7 +18268,7 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-hook-form@7.52.1(react@18.3.1): + react-hook-form@7.52.2(react@18.3.1): dependencies: react: 18.3.1 @@ -17808,6 +18402,10 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 + readable-web-to-node-stream@3.0.2: + dependencies: + readable-stream: 3.6.2 + readdir-glob@1.1.3: dependencies: minimatch: 5.1.6 @@ -17868,7 +18466,7 @@ snapshots: regenerator-transform@0.15.2: dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.0 regexp.prototype.flags@1.5.2: dependencies: @@ -17905,6 +18503,8 @@ snapshots: resize-observer-polyfill@1.5.1: {} + resolve-alpn@1.2.1: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 @@ -17927,6 +18527,10 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -17951,31 +18555,31 @@ snapshots: glob: 11.0.0 package-json-from-dist: 1.0.0 - rollup@4.19.0: + rollup@4.20.0: dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.19.0 - '@rollup/rollup-android-arm64': 4.19.0 - '@rollup/rollup-darwin-arm64': 4.19.0 - '@rollup/rollup-darwin-x64': 4.19.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.19.0 - '@rollup/rollup-linux-arm-musleabihf': 4.19.0 - '@rollup/rollup-linux-arm64-gnu': 4.19.0 - '@rollup/rollup-linux-arm64-musl': 4.19.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.19.0 - '@rollup/rollup-linux-riscv64-gnu': 4.19.0 - '@rollup/rollup-linux-s390x-gnu': 4.19.0 - '@rollup/rollup-linux-x64-gnu': 4.19.0 - '@rollup/rollup-linux-x64-musl': 4.19.0 - '@rollup/rollup-win32-arm64-msvc': 4.19.0 - '@rollup/rollup-win32-ia32-msvc': 4.19.0 - '@rollup/rollup-win32-x64-msvc': 4.19.0 + '@rollup/rollup-android-arm-eabi': 4.20.0 + '@rollup/rollup-android-arm64': 4.20.0 + '@rollup/rollup-darwin-arm64': 4.20.0 + '@rollup/rollup-darwin-x64': 4.20.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.20.0 + '@rollup/rollup-linux-arm-musleabihf': 4.20.0 + '@rollup/rollup-linux-arm64-gnu': 4.20.0 + '@rollup/rollup-linux-arm64-musl': 4.20.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.20.0 + '@rollup/rollup-linux-riscv64-gnu': 4.20.0 + '@rollup/rollup-linux-s390x-gnu': 4.20.0 + '@rollup/rollup-linux-x64-gnu': 4.20.0 + '@rollup/rollup-linux-x64-musl': 4.20.0 + '@rollup/rollup-win32-arm64-msvc': 4.20.0 + '@rollup/rollup-win32-ia32-msvc': 4.20.0 + '@rollup/rollup-win32-x64-msvc': 4.20.0 fsevents: 2.3.3 rtl-css-js@1.16.1: dependencies: - '@babel/runtime': 7.24.8 + '@babel/runtime': 7.25.0 run-applescript@3.2.0: dependencies: @@ -18048,6 +18652,12 @@ snapshots: parseley: 0.12.1 optional: true + semver-regex@4.0.5: {} + + semver-truncate@3.0.0: + dependencies: + semver: 7.6.3 + semver@5.7.2: {} semver@6.3.1: {} @@ -18149,14 +18759,12 @@ snapshots: shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 - optional: true shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - shebang-regex@1.0.0: - optional: true + shebang-regex@1.0.0: {} shebang-regex@3.0.0: {} @@ -18195,6 +18803,14 @@ snapshots: dependencies: atomic-sleep: 1.0.0 + sort-keys-length@1.0.1: + dependencies: + sort-keys: 1.1.2 + + sort-keys@1.1.2: + dependencies: + is-plain-obj: 1.1.0 + source-map-js@1.2.0: {} source-map-support@0.5.13: @@ -18336,8 +18952,7 @@ snapshots: strip-bom@4.0.0: {} - strip-eof@1.0.0: - optional: true + strip-eof@1.0.0: {} strip-final-newline@2.0.0: {} @@ -18350,14 +18965,21 @@ snapshots: strip-json-comments@3.1.1: {} + strip-outer@2.0.0: {} + strnum@1.0.5: {} - styled-jsx@5.1.1(@babel/core@7.24.9)(babel-plugin-macros@3.1.0)(react@18.3.1): + strtok3@7.1.1: + dependencies: + '@tokenizer/token': 0.3.0 + peek-readable: 5.1.3 + + styled-jsx@5.1.1(@babel/core@7.25.2)(babel-plugin-macros@3.1.0)(react@18.3.1): dependencies: client-only: 0.0.1 react: 18.3.1 optionalDependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 babel-plugin-macros: 3.1.0 stylis@4.2.0: {} @@ -18378,7 +19000,7 @@ snapshots: dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) fast-safe-stringify: 2.1.1 form-data: 4.0.0 formidable: 3.5.1 @@ -18446,7 +19068,7 @@ snapshots: tailwind-scrollbar-hide@1.1.7: {} - tailwindcss@3.4.6(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(typescript@5.5.3)): + tailwindcss@3.4.7(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(typescript@5.5.4)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -18462,11 +19084,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.1 - postcss: 8.4.39 - postcss-import: 15.1.0(postcss@8.4.39) - postcss-js: 4.0.1(postcss@8.4.39) - postcss-load-config: 4.0.2(postcss@8.4.39)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(typescript@5.5.3)) - postcss-nested: 6.0.1(postcss@8.4.39) + postcss: 8.4.41 + postcss-import: 15.1.0(postcss@8.4.41) + postcss-js: 4.0.1(postcss@8.4.41) + postcss-load-config: 4.0.2(postcss@8.4.41)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(typescript@5.5.4)) + postcss-nested: 6.2.0(postcss@8.4.41) postcss-selector-parser: 6.1.1 resolve: 1.22.8 sucrase: 3.35.0 @@ -18496,16 +19118,16 @@ snapshots: dependencies: bintrees: 1.0.2 - terser-webpack-plugin@5.3.10(@swc/core@1.7.0(@swc/helpers@0.5.12))(webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12))): + terser-webpack-plugin@5.3.10(@swc/core@1.7.6(@swc/helpers@0.5.12))(webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12))): dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 schema-utils: 3.3.0 serialize-javascript: 6.0.2 terser: 5.31.2 - webpack: 5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12)) + webpack: 5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12)) optionalDependencies: - '@swc/core': 1.7.0(@swc/helpers@0.5.12) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) terser@5.31.2: dependencies: @@ -18568,6 +19190,11 @@ snapshots: token-stream@1.0.0: optional: true + token-types@5.0.1: + dependencies: + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + tough-cookie@4.1.4: dependencies: psl: 1.9.0 @@ -18589,62 +19216,66 @@ snapshots: tree-kill@1.2.2: {} - ts-api-utils@1.3.0(typescript@5.5.3): + trim-repeated@2.0.0: + dependencies: + escape-string-regexp: 5.0.0 + + ts-api-utils@1.3.0(typescript@5.5.4): dependencies: - typescript: 5.5.3 + typescript: 5.5.4 ts-easing@0.2.0: {} ts-interface-checker@0.1.13: {} - ts-jest@29.2.3(@babel/core@7.24.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.24.9))(jest@29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)))(typescript@5.5.3): + ts-jest@29.2.4(@babel/core@7.25.2)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.25.2))(jest@29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)))(typescript@5.5.4): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.14.11)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + jest: 29.7.0(@types/node@20.14.14)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 semver: 7.6.3 - typescript: 5.5.3 + typescript: 5.5.4 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.24.9 + '@babel/core': 7.25.2 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.24.9) + babel-jest: 29.7.0(@babel/core@7.25.2) - ts-loader@9.5.1(typescript@5.5.3)(webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12))): + ts-loader@9.5.1(typescript@5.5.4)(webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12))): dependencies: chalk: 4.1.2 enhanced-resolve: 5.17.0 micromatch: 4.0.7 semver: 7.6.2 source-map: 0.7.4 - typescript: 5.5.3 - webpack: 5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12)) + typescript: 5.5.4 + webpack: 5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12)) - ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3): + ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.14.11 + '@types/node': 20.14.14 acorn: 8.12.1 acorn-walk: 8.3.3 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 make-error: 1.3.6 - typescript: 5.5.3 + typescript: 5.5.4 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.7.0(@swc/helpers@0.5.12) + '@swc/core': 1.7.6(@swc/helpers@0.5.12) ts-toolbelt@9.6.0: {} @@ -18669,60 +19300,60 @@ snapshots: tslib@2.6.3: {} - tsup@8.2.2(@swc/core@1.7.0)(jiti@1.21.6)(postcss@8.4.39)(typescript@5.5.3)(yaml@2.4.5): + tsup@8.2.4(@swc/core@1.7.6)(jiti@1.21.6)(postcss@8.4.41)(typescript@5.5.4)(yaml@2.5.0): dependencies: bundle-require: 5.0.0(esbuild@0.23.0) cac: 6.7.14 chokidar: 3.6.0 consola: 3.2.3 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.6(supports-color@9.4.0) esbuild: 0.23.0 execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 picocolors: 1.0.1 - postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.39)(yaml@2.4.5) + postcss-load-config: 6.0.1(jiti@1.21.6)(postcss@8.4.41)(yaml@2.5.0) resolve-from: 5.0.0 - rollup: 4.19.0 + rollup: 4.20.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.7.0(@swc/helpers@0.5.12) - postcss: 8.4.39 - typescript: 5.5.3 + '@swc/core': 1.7.6(@swc/helpers@0.5.12) + postcss: 8.4.41 + typescript: 5.5.4 transitivePeerDependencies: - jiti - supports-color - tsx - yaml - turbo-darwin-64@2.0.9: + turbo-darwin-64@2.0.12: optional: true - turbo-darwin-arm64@2.0.9: + turbo-darwin-arm64@2.0.12: optional: true - turbo-linux-64@2.0.9: + turbo-linux-64@2.0.12: optional: true - turbo-linux-arm64@2.0.9: + turbo-linux-arm64@2.0.12: optional: true - turbo-windows-64@2.0.9: + turbo-windows-64@2.0.12: optional: true - turbo-windows-arm64@2.0.9: + turbo-windows-arm64@2.0.12: optional: true - turbo@2.0.9: + turbo@2.0.12: optionalDependencies: - turbo-darwin-64: 2.0.9 - turbo-darwin-arm64: 2.0.9 - turbo-linux-64: 2.0.9 - turbo-linux-arm64: 2.0.9 - turbo-windows-64: 2.0.9 - turbo-windows-arm64: 2.0.9 + turbo-darwin-64: 2.0.12 + turbo-darwin-arm64: 2.0.12 + turbo-linux-64: 2.0.12 + turbo-linux-arm64: 2.0.12 + turbo-windows-64: 2.0.12 + turbo-windows-arm64: 2.0.12 type-check@0.4.0: dependencies: @@ -18734,7 +19365,7 @@ snapshots: type-fest@0.21.3: {} - type-fest@4.22.1: {} + type-fest@4.23.0: {} type-is@1.6.18: dependencies: @@ -18775,19 +19406,19 @@ snapshots: typedarray@0.0.6: {} - typeorm-naming-strategies@4.1.0(typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3))): + typeorm-naming-strategies@4.1.0(typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4))): dependencies: - typeorm: 0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + typeorm: 0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) - typeorm-transactional@0.5.0(reflect-metadata@0.2.2)(typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3))): + typeorm-transactional@0.5.0(reflect-metadata@0.2.2)(typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4))): dependencies: '@types/cls-hooked': 4.3.8 cls-hooked: 4.2.2 reflect-metadata: 0.2.2 semver: 7.6.2 - typeorm: 0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)) + typeorm: 0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)) - typeorm@0.3.20(mysql2@3.10.3)(ts-node@10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3)): + typeorm@0.3.20(mysql2@3.11.0)(ts-node@10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4)): dependencies: '@sqltools/formatter': 1.2.5 app-root-path: 3.1.0 @@ -18795,7 +19426,7 @@ snapshots: chalk: 4.1.2 cli-highlight: 2.1.11 dayjs: 1.11.11 - debug: 4.3.5(supports-color@9.4.0) + debug: 4.3.5 dotenv: 16.4.5 glob: 10.4.5 mkdirp: 2.1.6 @@ -18805,25 +19436,25 @@ snapshots: uuid: 9.0.1 yargs: 17.7.2 optionalDependencies: - mysql2: 3.10.3 - ts-node: 10.9.2(@swc/core@1.7.0(@swc/helpers@0.5.12))(@types/node@20.14.11)(typescript@5.5.3) + mysql2: 3.11.0 + ts-node: 10.9.2(@swc/core@1.7.6(@swc/helpers@0.5.12))(@types/node@20.14.14)(typescript@5.5.4) transitivePeerDependencies: - supports-color - typescript-eslint@7.16.1(eslint@9.7.0)(typescript@5.5.3): + typescript-eslint@7.17.0(eslint@9.8.0)(typescript@5.5.4): dependencies: - '@typescript-eslint/eslint-plugin': 7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - eslint: 9.7.0 + '@typescript-eslint/eslint-plugin': 7.17.0(@typescript-eslint/parser@7.17.0(eslint@9.8.0)(typescript@5.5.4))(eslint@9.8.0)(typescript@5.5.4) + '@typescript-eslint/parser': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.17.0(eslint@9.8.0)(typescript@5.5.4) + eslint: 9.8.0 optionalDependencies: - typescript: 5.5.3 + typescript: 5.5.4 transitivePeerDependencies: - supports-color typescript@5.3.3: {} - typescript@5.5.3: {} + typescript@5.5.4: {} uc.micro@2.1.0: optional: true @@ -18846,6 +19477,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@6.13.0: {} + undici@5.28.4: dependencies: '@fastify/busboy': 2.1.1 @@ -18888,6 +19521,12 @@ snapshots: escalade: 3.1.2 picocolors: 1.0.1 + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + upper-case@1.1.3: optional: true @@ -19012,7 +19651,7 @@ snapshots: webpack-sources@3.2.3: {} - webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12)): + webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.5 @@ -19035,7 +19674,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 3.3.0 tapable: 2.2.1 - terser-webpack-plugin: 5.3.10(@swc/core@1.7.0(@swc/helpers@0.5.12))(webpack@5.92.1(@swc/core@1.7.0(@swc/helpers@0.5.12))) + terser-webpack-plugin: 5.3.10(@swc/core@1.7.6(@swc/helpers@0.5.12))(webpack@5.92.1(@swc/core@1.7.6(@swc/helpers@0.5.12))) watchpack: 2.4.1 webpack-sources: 3.2.3 transitivePeerDependencies: @@ -19106,7 +19745,6 @@ snapshots: which@1.3.1: dependencies: isexe: 2.0.0 - optional: true which@2.0.2: dependencies: @@ -19122,8 +19760,8 @@ snapshots: with@7.0.2: dependencies: - '@babel/parser': 7.24.8 - '@babel/types': 7.24.9 + '@babel/parser': 7.25.0 + '@babel/types': 7.25.2 assert-never: 1.3.0 babel-walk: 3.0.0-canary-5 optional: true @@ -19175,6 +19813,8 @@ snapshots: y18n@5.0.8: {} + yallist@2.1.2: {} + yallist@3.1.1: {} yallist@4.0.0: {} @@ -19185,6 +19825,8 @@ snapshots: yaml@2.4.5: {} + yaml@2.5.0: {} + yargs-parser@20.2.9: {} yargs-parser@21.1.1: {} diff --git a/tooling/eslint/base.js b/tooling/eslint/base.js index 33366a134..a73986b92 100644 --- a/tooling/eslint/base.js +++ b/tooling/eslint/base.js @@ -21,7 +21,7 @@ const headerPlugin = require('@ufb/eslint-plugin-header'); module.exports = tseslint.config( { - ignores: ['**/*.config.*', 'dist/**'], + ignores: ['**/*.config.*', 'dist/**', '**/*.stub.ts'], }, { files: ['**/*.js', '**/*.ts', '**/*.tsx'], diff --git a/tooling/eslint/nestjs.js b/tooling/eslint/nestjs.js index 33a7d6674..2ea2273ea 100644 --- a/tooling/eslint/nestjs.js +++ b/tooling/eslint/nestjs.js @@ -23,6 +23,7 @@ module.exports = [ '@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/unbound-method': 'off', }, }, ]; diff --git a/tooling/prettier/package.json b/tooling/prettier/package.json index 354f0847b..b35953861 100644 --- a/tooling/prettier/package.json +++ b/tooling/prettier/package.json @@ -18,7 +18,7 @@ "prettier-plugin-tailwindcss": "^0.6.0" }, "devDependencies": { - "@types/node": "20.14.11", + "@types/node": "20.14.14", "@ufb/tsconfig": "workspace:*", "typescript": "^5.4.5" }, diff --git a/tooling/typescript/nestjs.json b/tooling/typescript/nestjs.json index 910f43c95..e48656a90 100644 --- a/tooling/typescript/nestjs.json +++ b/tooling/typescript/nestjs.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/tsconfig", "compilerOptions": { "module": "CommonJS", - "moduleResolution": "Node10", + "moduleResolution": "Node10", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, @@ -13,6 +13,7 @@ "incremental": true, "esModuleInterop": true, "skipLibCheck": true, - "outDir": "./dist" + "outDir": "./dist", + "strictNullChecks": true } }