From f5c4da6358bb69cb7c3b05d0927390d0f03028c3 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Wed, 22 Oct 2025 23:38:52 -0500 Subject: [PATCH 01/52] =?UTF-8?q?=F0=9F=8E=89=20First=20Commit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 56 + backend/manager/.prettierrc | 4 + backend/manager/README.md | 98 + .../manager-api-gateway/src/config/envs.ts | 19 + .../apps/manager-api-gateway/src/main.ts | 10 + .../manager-api-gateway.controller.spec.ts | 22 + .../src/manager-api-gateway.controller.ts | 12 + .../src/manager-api-gateway.module.ts | 11 + .../src/manager-api-gateway.service.ts | 9 + .../src/patients/patients.controller.spec.ts | 18 + .../src/patients/patients.controller.ts | 13 + .../src/patients/patients.module.ts | 15 + .../src/patients/patients.service.spec.ts | 18 + .../src/patients/patients.service.ts | 17 + .../src/shared-client/shared-client.module.ts | 26 + .../manager-api-gateway/test/app.e2e-spec.ts | 24 + .../manager-api-gateway/test/jest-e2e.json | 9 + .../manager-api-gateway/tsconfig.app.json | 9 + .../manager/apps/patients/src/config/envs.ts | 19 + backend/manager/apps/patients/src/main.ts | 19 + .../patients/src/patients.controller.spec.ts | 22 + .../apps/patients/src/patients.controller.ts | 15 + .../apps/patients/src/patients.module.ts | 10 + .../apps/patients/src/patients.service.ts | 8 + .../apps/patients/test/app.e2e-spec.ts | 24 + .../manager/apps/patients/test/jest-e2e.json | 9 + .../manager/apps/patients/tsconfig.app.json | 9 + backend/manager/apps/providers/src/main.ts | 8 + .../src/providers.controller.spec.ts | 22 + .../providers/src/providers.controller.ts | 12 + .../apps/providers/src/providers.module.ts | 10 + .../apps/providers/src/providers.service.ts | 8 + .../apps/providers/test/app.e2e-spec.ts | 24 + .../manager/apps/providers/test/jest-e2e.json | 9 + .../manager/apps/providers/tsconfig.app.json | 9 + .../manager/apps/status-history/src/main.ts | 8 + .../src/status-history.controller.spec.ts | 22 + .../src/status-history.controller.ts | 12 + .../src/status-history.module.ts | 10 + .../src/status-history.service.ts | 8 + .../apps/status-history/test/app.e2e-spec.ts | 24 + .../apps/status-history/test/jest-e2e.json | 9 + .../apps/status-history/tsconfig.app.json | 9 + backend/manager/apps/statuses/src/main.ts | 8 + .../statuses/src/statuses.controller.spec.ts | 22 + .../apps/statuses/src/statuses.controller.ts | 12 + .../apps/statuses/src/statuses.module.ts | 10 + .../apps/statuses/src/statuses.service.ts | 8 + .../apps/statuses/test/app.e2e-spec.ts | 24 + .../manager/apps/statuses/test/jest-e2e.json | 9 + .../manager/apps/statuses/tsconfig.app.json | 9 + backend/manager/eslint.config.mjs | 35 + .../libs/contracts/src/contracts.module.ts | 8 + .../contracts/src/contracts.service.spec.ts | 18 + .../libs/contracts/src/contracts.service.ts | 4 + backend/manager/libs/contracts/src/index.ts | 2 + .../manager-api-gateway/manager.namespace.ts | 1 + .../src/patients/patients.constants.ts | 2 + .../src/patients/patients.namespace.ts | 1 + .../manager/libs/contracts/tsconfig.lib.json | 9 + backend/manager/nest-cli.json | 77 + backend/manager/package-lock.json | 10607 ++++++++++++++++ backend/manager/package.json | 85 + backend/manager/tsconfig.build.json | 4 + backend/manager/tsconfig.json | 39 + 65 files changed, 11723 insertions(+) create mode 100644 .gitignore create mode 100644 backend/manager/.prettierrc create mode 100644 backend/manager/README.md create mode 100644 backend/manager/apps/manager-api-gateway/src/config/envs.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/main.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/patients/patients.controller.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/patients/patients.service.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/test/app.e2e-spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/test/jest-e2e.json create mode 100644 backend/manager/apps/manager-api-gateway/tsconfig.app.json create mode 100644 backend/manager/apps/patients/src/config/envs.ts create mode 100644 backend/manager/apps/patients/src/main.ts create mode 100644 backend/manager/apps/patients/src/patients.controller.spec.ts create mode 100644 backend/manager/apps/patients/src/patients.controller.ts create mode 100644 backend/manager/apps/patients/src/patients.module.ts create mode 100644 backend/manager/apps/patients/src/patients.service.ts create mode 100644 backend/manager/apps/patients/test/app.e2e-spec.ts create mode 100644 backend/manager/apps/patients/test/jest-e2e.json create mode 100644 backend/manager/apps/patients/tsconfig.app.json create mode 100644 backend/manager/apps/providers/src/main.ts create mode 100644 backend/manager/apps/providers/src/providers.controller.spec.ts create mode 100644 backend/manager/apps/providers/src/providers.controller.ts create mode 100644 backend/manager/apps/providers/src/providers.module.ts create mode 100644 backend/manager/apps/providers/src/providers.service.ts create mode 100644 backend/manager/apps/providers/test/app.e2e-spec.ts create mode 100644 backend/manager/apps/providers/test/jest-e2e.json create mode 100644 backend/manager/apps/providers/tsconfig.app.json create mode 100644 backend/manager/apps/status-history/src/main.ts create mode 100644 backend/manager/apps/status-history/src/status-history.controller.spec.ts create mode 100644 backend/manager/apps/status-history/src/status-history.controller.ts create mode 100644 backend/manager/apps/status-history/src/status-history.module.ts create mode 100644 backend/manager/apps/status-history/src/status-history.service.ts create mode 100644 backend/manager/apps/status-history/test/app.e2e-spec.ts create mode 100644 backend/manager/apps/status-history/test/jest-e2e.json create mode 100644 backend/manager/apps/status-history/tsconfig.app.json create mode 100644 backend/manager/apps/statuses/src/main.ts create mode 100644 backend/manager/apps/statuses/src/statuses.controller.spec.ts create mode 100644 backend/manager/apps/statuses/src/statuses.controller.ts create mode 100644 backend/manager/apps/statuses/src/statuses.module.ts create mode 100644 backend/manager/apps/statuses/src/statuses.service.ts create mode 100644 backend/manager/apps/statuses/test/app.e2e-spec.ts create mode 100644 backend/manager/apps/statuses/test/jest-e2e.json create mode 100644 backend/manager/apps/statuses/tsconfig.app.json create mode 100644 backend/manager/eslint.config.mjs create mode 100644 backend/manager/libs/contracts/src/contracts.module.ts create mode 100644 backend/manager/libs/contracts/src/contracts.service.spec.ts create mode 100644 backend/manager/libs/contracts/src/contracts.service.ts create mode 100644 backend/manager/libs/contracts/src/index.ts create mode 100644 backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts create mode 100644 backend/manager/libs/contracts/src/patients/patients.constants.ts create mode 100644 backend/manager/libs/contracts/src/patients/patients.namespace.ts create mode 100644 backend/manager/libs/contracts/tsconfig.lib.json create mode 100644 backend/manager/nest-cli.json create mode 100644 backend/manager/package-lock.json create mode 100644 backend/manager/package.json create mode 100644 backend/manager/tsconfig.build.json create mode 100644 backend/manager/tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1823299 --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +# compiled output +**/dist +**/node_modules +/build + +# Logs +logs +*.log +npm-debug.log* +pnpm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# OS +.DS_Store + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# temp directory +.temp +.tmp + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json diff --git a/backend/manager/.prettierrc b/backend/manager/.prettierrc new file mode 100644 index 0000000..a20502b --- /dev/null +++ b/backend/manager/.prettierrc @@ -0,0 +1,4 @@ +{ + "singleQuote": true, + "trailingComma": "all" +} diff --git a/backend/manager/README.md b/backend/manager/README.md new file mode 100644 index 0000000..8f0f65f --- /dev/null +++ b/backend/manager/README.md @@ -0,0 +1,98 @@ +

+ Nest Logo +

+ +[circleci-image]: https://img.shields.io/circleci/build/github/nestjs/nest/master?token=abc123def456 +[circleci-url]: https://circleci.com/gh/nestjs/nest + +

A progressive Node.js framework for building efficient and scalable server-side applications.

+

+NPM Version +Package License +NPM Downloads +CircleCI +Discord +Backers on Open Collective +Sponsors on Open Collective + Donate us + Support us + Follow us on Twitter +

+ + +## Description + +[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. + +## Project setup + +```bash +$ npm install +``` + +## Compile and run the project + +```bash +# development +$ npm run start + +# watch mode +$ npm run start:dev + +# production mode +$ npm run start:prod +``` + +## Run tests + +```bash +# unit tests +$ npm run test + +# e2e tests +$ npm run test:e2e + +# test coverage +$ npm run test:cov +``` + +## Deployment + +When you're ready to deploy your NestJS application to production, there are some key steps you can take to ensure it runs as efficiently as possible. Check out the [deployment documentation](https://docs.nestjs.com/deployment) for more information. + +If you are looking for a cloud-based platform to deploy your NestJS application, check out [Mau](https://mau.nestjs.com), our official platform for deploying NestJS applications on AWS. Mau makes deployment straightforward and fast, requiring just a few simple steps: + +```bash +$ npm install -g @nestjs/mau +$ mau deploy +``` + +With Mau, you can deploy your application in just a few clicks, allowing you to focus on building features rather than managing infrastructure. + +## Resources + +Check out a few resources that may come in handy when working with NestJS: + +- Visit the [NestJS Documentation](https://docs.nestjs.com) to learn more about the framework. +- For questions and support, please visit our [Discord channel](https://discord.gg/G7Qnnhy). +- To dive deeper and get more hands-on experience, check out our official video [courses](https://courses.nestjs.com/). +- Deploy your application to AWS with the help of [NestJS Mau](https://mau.nestjs.com) in just a few clicks. +- Visualize your application graph and interact with the NestJS application in real-time using [NestJS Devtools](https://devtools.nestjs.com). +- Need help with your project (part-time to full-time)? Check out our official [enterprise support](https://enterprise.nestjs.com). +- To stay in the loop and get updates, follow us on [X](https://x.com/nestframework) and [LinkedIn](https://linkedin.com/company/nestjs). +- Looking for a job, or have a job to offer? Check out our official [Jobs board](https://jobs.nestjs.com). + +## Support + +Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). + +## Stay in touch + +- Author - [Kamil Myśliwiec](https://twitter.com/kammysliwiec) +- Website - [https://nestjs.com](https://nestjs.com/) +- Twitter - [@nestframework](https://twitter.com/nestframework) + +## License + +Nest is [MIT licensed](https://github.com/nestjs/nest/blob/master/LICENSE). diff --git a/backend/manager/apps/manager-api-gateway/src/config/envs.ts b/backend/manager/apps/manager-api-gateway/src/config/envs.ts new file mode 100644 index 0000000..b3392df --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/config/envs.ts @@ -0,0 +1,19 @@ +import { MANAGER_NAMESPACE } from '@app/contracts/manager-api-gateway/manager.namespace'; +import { config } from 'dotenv'; +import { resolve } from 'path'; +import { number, object, string } from 'yup'; + +config({ + path: resolve(process.cwd(), `apps/${MANAGER_NAMESPACE}/.env`), +}); + +const envVarsSchema = object({ + NODE_ENV: string().oneOf(['dev', 'prod', 'test']).default('dev'), + HOST: string().default('0.0.0.0'), + PORT: number().default(3000), + RMQ_USER: string().default('guest'), + RMQ_PASSWORD: string().default('guest'), + RABBITMQ_URL: string().default('localhost:5672'), +}).noUnknown(); + +export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/manager-api-gateway/src/main.ts b/backend/manager/apps/manager-api-gateway/src/main.ts new file mode 100644 index 0000000..cd447f0 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/main.ts @@ -0,0 +1,10 @@ +import { NestFactory } from '@nestjs/core'; +import { ManagerApiGatewayModule } from './manager-api-gateway.module'; +import { envs } from './config/envs'; + +async function bootstrap() { + const app = await NestFactory.create(ManagerApiGatewayModule); + + await app.listen(envs.PORT); +} +bootstrap(); diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts new file mode 100644 index 0000000..d0fd7c7 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ManagerApiGatewayController } from './manager-api-gateway.controller'; +import { ManagerApiGatewayService } from './manager-api-gateway.service'; + +describe('ManagerApiGatewayController', () => { + let managerApiGatewayController: ManagerApiGatewayController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [ManagerApiGatewayController], + providers: [ManagerApiGatewayService], + }).compile(); + + managerApiGatewayController = app.get(ManagerApiGatewayController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(managerApiGatewayController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts new file mode 100644 index 0000000..9b0bf37 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { PatientsService } from './patients/patients.service'; + +@Controller('api') +export class ManagerApiGatewayController { + constructor(private readonly patientService: PatientsService) {} + + @Get('hello') + getHello(): string { + return this.patientService.getHello(); + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts new file mode 100644 index 0000000..8d014c9 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common'; +import { ManagerApiGatewayController } from './manager-api-gateway.controller'; +import { ManagerApiGatewayService } from './manager-api-gateway.service'; +import { PatientsModule } from './patients/patients.module'; + +@Module({ + imports: [PatientsModule], + controllers: [ManagerApiGatewayController], + providers: [ManagerApiGatewayService], +}) +export class ManagerApiGatewayModule {} diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts new file mode 100644 index 0000000..b710192 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts @@ -0,0 +1,9 @@ +import { Get, Injectable } from '@nestjs/common'; + +@Injectable() +export class ManagerApiGatewayService { + + getHello(): string { + return 'Hello World!'; + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.spec.ts new file mode 100644 index 0000000..a7c6a20 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PatientsController } from './patients.controller'; + +describe('PatientsController', () => { + let controller: PatientsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [PatientsController], + }).compile(); + + controller = module.get(PatientsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts new file mode 100644 index 0000000..edee84d --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common'; +import { PatientsService } from './patients.service'; + +@Controller('patients') +export class PatientsController { + + constructor(private readonly patientService: PatientsService) {} + + @Get('hello') + getHello(): string { + return this.patientService.getHello(); + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts new file mode 100644 index 0000000..4d0d126 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { PatientsService } from './patients.service'; +import { SharedClientModule } from '../shared-client/shared-client.module'; +import { PatientsController } from './patients.controller'; +import { QUEUE_NAME, SERVICE_NAME } from '@app/contracts/patients/patients.constants'; + +@Module({ + imports: [ + SharedClientModule.register(SERVICE_NAME, QUEUE_NAME) + ], + providers: [PatientsService], + exports: [PatientsService], + controllers: [PatientsController], +}) +export class PatientsModule {} diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.service.spec.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.spec.ts new file mode 100644 index 0000000..b1a661a --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PatientsService } from './patients.service'; + +describe('PatientsService', () => { + let service: PatientsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PatientsService], + }).compile(); + + service = module.get(PatientsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts new file mode 100644 index 0000000..8fed8e6 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts @@ -0,0 +1,17 @@ +import { SERVICE_NAME } from '@app/contracts/patients/patients.constants'; +import { Inject, Injectable } from '@nestjs/common'; +import { ClientProxy } from '@nestjs/microservices'; + +@Injectable() +export class PatientsService { + + constructor( + @Inject(SERVICE_NAME) private readonly client: ClientProxy + ) {} + + + getHello(): string { + this.client.emit('get_hello', { message: 'ping' }); + return 'Hello from Patients Service!'; + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts b/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts new file mode 100644 index 0000000..979e25f --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts @@ -0,0 +1,26 @@ +import { DynamicModule, Module } from '@nestjs/common'; +import { ClientsModule, Transport } from '@nestjs/microservices'; +import { envs } from '../config/envs'; + +@Module({}) +export class SharedClientModule { + static register(serviceName: symbol, queue: string): DynamicModule { + return { + module: SharedClientModule, + imports: [ + ClientsModule.register([ + { + name: serviceName, + transport: Transport.RMQ, + options: { + urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], + queue, + queueOptions: { durable: false }, + }, + }, + ]), + ], + exports: [ClientsModule], + }; + } +} \ No newline at end of file diff --git a/backend/manager/apps/manager-api-gateway/test/app.e2e-spec.ts b/backend/manager/apps/manager-api-gateway/test/app.e2e-spec.ts new file mode 100644 index 0000000..f8118d0 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { ManagerApiGatewayModule } from './../src/manager-api-gateway.module'; + +describe('ManagerApiGatewayController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [ManagerApiGatewayModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/test/jest-e2e.json b/backend/manager/apps/manager-api-gateway/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/backend/manager/apps/manager-api-gateway/tsconfig.app.json b/backend/manager/apps/manager-api-gateway/tsconfig.app.json new file mode 100644 index 0000000..f98b851 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "../../dist/apps/manager-api-gateway" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/apps/patients/src/config/envs.ts b/backend/manager/apps/patients/src/config/envs.ts new file mode 100644 index 0000000..f69162e --- /dev/null +++ b/backend/manager/apps/patients/src/config/envs.ts @@ -0,0 +1,19 @@ +import { PATIENTS_NAMESPACE } from '@app/contracts/patients/patients.namespace'; +import { config } from 'dotenv'; +import { resolve } from 'path'; +import { number, object, string } from 'yup'; + +config({ + path: resolve(process.cwd(), `apps/${PATIENTS_NAMESPACE}/.env`), +}); + +const envVarsSchema = object({ + NODE_ENV: string().oneOf(['dev', 'prod', 'test']).default('dev'), + HOST: string().default('0.0.0.0'), + PORT: number().default(3000), + RMQ_USER: string().default('guest'), + RMQ_PASSWORD: string().default('guest'), + RABBITMQ_URL: string().default('localhost:5672'), +}).noUnknown(); + +export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/patients/src/main.ts b/backend/manager/apps/patients/src/main.ts new file mode 100644 index 0000000..5d8451b --- /dev/null +++ b/backend/manager/apps/patients/src/main.ts @@ -0,0 +1,19 @@ +import { NestFactory } from '@nestjs/core'; +import { PatientsModule } from './patients.module'; +import { MicroserviceOptions, Transport } from '@nestjs/microservices'; +import { envs } from './config/envs'; + +async function bootstrap() { + const app = await NestFactory.createMicroservice(PatientsModule, { + transport: Transport.RMQ, + options: { + urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], + queue: 'patients_queue', + queueOptions: { + durable: false, + } + }, + }); + await app.listen(); +} +bootstrap(); diff --git a/backend/manager/apps/patients/src/patients.controller.spec.ts b/backend/manager/apps/patients/src/patients.controller.spec.ts new file mode 100644 index 0000000..a9d5357 --- /dev/null +++ b/backend/manager/apps/patients/src/patients.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PatientsController } from './patients.controller'; +import { PatientsService } from './patients.service'; + +describe('PatientsController', () => { + let patientsController: PatientsController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [PatientsController], + providers: [PatientsService], + }).compile(); + + patientsController = app.get(PatientsController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(patientsController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/backend/manager/apps/patients/src/patients.controller.ts b/backend/manager/apps/patients/src/patients.controller.ts new file mode 100644 index 0000000..d4f3a1f --- /dev/null +++ b/backend/manager/apps/patients/src/patients.controller.ts @@ -0,0 +1,15 @@ +import { Controller, Get } from '@nestjs/common'; +import { PatientsService } from './patients.service'; +import { MessagePattern } from '@nestjs/microservices'; + +@Controller() +export class PatientsController { + constructor(private readonly patientsService: PatientsService) {} + + @MessagePattern('get_hello') + handleHello(data: any) { + console.log('📩 Received from gateway:', data); + return 'Hello from Patients Microservice!'; + } +} + diff --git a/backend/manager/apps/patients/src/patients.module.ts b/backend/manager/apps/patients/src/patients.module.ts new file mode 100644 index 0000000..a9f53eb --- /dev/null +++ b/backend/manager/apps/patients/src/patients.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { PatientsController } from './patients.controller'; +import { PatientsService } from './patients.service'; + +@Module({ + imports: [], + controllers: [PatientsController], + providers: [PatientsService], +}) +export class PatientsModule {} diff --git a/backend/manager/apps/patients/src/patients.service.ts b/backend/manager/apps/patients/src/patients.service.ts new file mode 100644 index 0000000..a8aa3d6 --- /dev/null +++ b/backend/manager/apps/patients/src/patients.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class PatientsService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/backend/manager/apps/patients/test/app.e2e-spec.ts b/backend/manager/apps/patients/test/app.e2e-spec.ts new file mode 100644 index 0000000..63c576f --- /dev/null +++ b/backend/manager/apps/patients/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { PatientsModule } from './../src/patients.module'; + +describe('PatientsController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [PatientsModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/backend/manager/apps/patients/test/jest-e2e.json b/backend/manager/apps/patients/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/backend/manager/apps/patients/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/backend/manager/apps/patients/tsconfig.app.json b/backend/manager/apps/patients/tsconfig.app.json new file mode 100644 index 0000000..a2daf3a --- /dev/null +++ b/backend/manager/apps/patients/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "../../dist/apps/patients" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/apps/providers/src/main.ts b/backend/manager/apps/providers/src/main.ts new file mode 100644 index 0000000..7866130 --- /dev/null +++ b/backend/manager/apps/providers/src/main.ts @@ -0,0 +1,8 @@ +import { NestFactory } from '@nestjs/core'; +import { ProvidersModule } from './providers.module'; + +async function bootstrap() { + const app = await NestFactory.create(ProvidersModule); + await app.listen(process.env.port ?? 3000); +} +bootstrap(); diff --git a/backend/manager/apps/providers/src/providers.controller.spec.ts b/backend/manager/apps/providers/src/providers.controller.spec.ts new file mode 100644 index 0000000..1087832 --- /dev/null +++ b/backend/manager/apps/providers/src/providers.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ProvidersController } from './providers.controller'; +import { ProvidersService } from './providers.service'; + +describe('ProvidersController', () => { + let providersController: ProvidersController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [ProvidersController], + providers: [ProvidersService], + }).compile(); + + providersController = app.get(ProvidersController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(providersController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/backend/manager/apps/providers/src/providers.controller.ts b/backend/manager/apps/providers/src/providers.controller.ts new file mode 100644 index 0000000..78f9537 --- /dev/null +++ b/backend/manager/apps/providers/src/providers.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { ProvidersService } from './providers.service'; + +@Controller() +export class ProvidersController { + constructor(private readonly providersService: ProvidersService) {} + + @Get() + getHello(): string { + return this.providersService.getHello(); + } +} diff --git a/backend/manager/apps/providers/src/providers.module.ts b/backend/manager/apps/providers/src/providers.module.ts new file mode 100644 index 0000000..32d7bf2 --- /dev/null +++ b/backend/manager/apps/providers/src/providers.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { ProvidersController } from './providers.controller'; +import { ProvidersService } from './providers.service'; + +@Module({ + imports: [], + controllers: [ProvidersController], + providers: [ProvidersService], +}) +export class ProvidersModule {} diff --git a/backend/manager/apps/providers/src/providers.service.ts b/backend/manager/apps/providers/src/providers.service.ts new file mode 100644 index 0000000..5a2da0a --- /dev/null +++ b/backend/manager/apps/providers/src/providers.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class ProvidersService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/backend/manager/apps/providers/test/app.e2e-spec.ts b/backend/manager/apps/providers/test/app.e2e-spec.ts new file mode 100644 index 0000000..803d2b7 --- /dev/null +++ b/backend/manager/apps/providers/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { ProvidersModule } from './../src/providers.module'; + +describe('ProvidersController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [ProvidersModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/backend/manager/apps/providers/test/jest-e2e.json b/backend/manager/apps/providers/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/backend/manager/apps/providers/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/backend/manager/apps/providers/tsconfig.app.json b/backend/manager/apps/providers/tsconfig.app.json new file mode 100644 index 0000000..cc597e1 --- /dev/null +++ b/backend/manager/apps/providers/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "../../dist/apps/providers" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/apps/status-history/src/main.ts b/backend/manager/apps/status-history/src/main.ts new file mode 100644 index 0000000..3454734 --- /dev/null +++ b/backend/manager/apps/status-history/src/main.ts @@ -0,0 +1,8 @@ +import { NestFactory } from '@nestjs/core'; +import { StatusHistoryModule } from './status-history.module'; + +async function bootstrap() { + const app = await NestFactory.create(StatusHistoryModule); + await app.listen(process.env.port ?? 3000); +} +bootstrap(); diff --git a/backend/manager/apps/status-history/src/status-history.controller.spec.ts b/backend/manager/apps/status-history/src/status-history.controller.spec.ts new file mode 100644 index 0000000..a62856a --- /dev/null +++ b/backend/manager/apps/status-history/src/status-history.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusHistoryController } from './status-history.controller'; +import { StatusHistoryService } from './status-history.service'; + +describe('StatusHistoryController', () => { + let statusHistoryController: StatusHistoryController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [StatusHistoryController], + providers: [StatusHistoryService], + }).compile(); + + statusHistoryController = app.get(StatusHistoryController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(statusHistoryController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/backend/manager/apps/status-history/src/status-history.controller.ts b/backend/manager/apps/status-history/src/status-history.controller.ts new file mode 100644 index 0000000..e2834e6 --- /dev/null +++ b/backend/manager/apps/status-history/src/status-history.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { StatusHistoryService } from './status-history.service'; + +@Controller() +export class StatusHistoryController { + constructor(private readonly statusHistoryService: StatusHistoryService) {} + + @Get() + getHello(): string { + return this.statusHistoryService.getHello(); + } +} diff --git a/backend/manager/apps/status-history/src/status-history.module.ts b/backend/manager/apps/status-history/src/status-history.module.ts new file mode 100644 index 0000000..eb5310f --- /dev/null +++ b/backend/manager/apps/status-history/src/status-history.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { StatusHistoryController } from './status-history.controller'; +import { StatusHistoryService } from './status-history.service'; + +@Module({ + imports: [], + controllers: [StatusHistoryController], + providers: [StatusHistoryService], +}) +export class StatusHistoryModule {} diff --git a/backend/manager/apps/status-history/src/status-history.service.ts b/backend/manager/apps/status-history/src/status-history.service.ts new file mode 100644 index 0000000..33bf1c4 --- /dev/null +++ b/backend/manager/apps/status-history/src/status-history.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class StatusHistoryService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/backend/manager/apps/status-history/test/app.e2e-spec.ts b/backend/manager/apps/status-history/test/app.e2e-spec.ts new file mode 100644 index 0000000..1802558 --- /dev/null +++ b/backend/manager/apps/status-history/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { StatusHistoryModule } from './../src/status-history.module'; + +describe('StatusHistoryController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [StatusHistoryModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/backend/manager/apps/status-history/test/jest-e2e.json b/backend/manager/apps/status-history/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/backend/manager/apps/status-history/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/backend/manager/apps/status-history/tsconfig.app.json b/backend/manager/apps/status-history/tsconfig.app.json new file mode 100644 index 0000000..add4fb4 --- /dev/null +++ b/backend/manager/apps/status-history/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "../../dist/apps/status-history" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/apps/statuses/src/main.ts b/backend/manager/apps/statuses/src/main.ts new file mode 100644 index 0000000..f646e44 --- /dev/null +++ b/backend/manager/apps/statuses/src/main.ts @@ -0,0 +1,8 @@ +import { NestFactory } from '@nestjs/core'; +import { StatusesModule } from './statuses.module'; + +async function bootstrap() { + const app = await NestFactory.create(StatusesModule); + await app.listen(process.env.port ?? 3000); +} +bootstrap(); diff --git a/backend/manager/apps/statuses/src/statuses.controller.spec.ts b/backend/manager/apps/statuses/src/statuses.controller.spec.ts new file mode 100644 index 0000000..7b7f3fc --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusesController } from './statuses.controller'; +import { StatusesService } from './statuses.service'; + +describe('StatusesController', () => { + let statusesController: StatusesController; + + beforeEach(async () => { + const app: TestingModule = await Test.createTestingModule({ + controllers: [StatusesController], + providers: [StatusesService], + }).compile(); + + statusesController = app.get(StatusesController); + }); + + describe('root', () => { + it('should return "Hello World!"', () => { + expect(statusesController.getHello()).toBe('Hello World!'); + }); + }); +}); diff --git a/backend/manager/apps/statuses/src/statuses.controller.ts b/backend/manager/apps/statuses/src/statuses.controller.ts new file mode 100644 index 0000000..f7df158 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { StatusesService } from './statuses.service'; + +@Controller() +export class StatusesController { + constructor(private readonly statusesService: StatusesService) {} + + @Get() + getHello(): string { + return this.statusesService.getHello(); + } +} diff --git a/backend/manager/apps/statuses/src/statuses.module.ts b/backend/manager/apps/statuses/src/statuses.module.ts new file mode 100644 index 0000000..658ec4b --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { StatusesController } from './statuses.controller'; +import { StatusesService } from './statuses.service'; + +@Module({ + imports: [], + controllers: [StatusesController], + providers: [StatusesService], +}) +export class StatusesModule {} diff --git a/backend/manager/apps/statuses/src/statuses.service.ts b/backend/manager/apps/statuses/src/statuses.service.ts new file mode 100644 index 0000000..30ed455 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class StatusesService { + getHello(): string { + return 'Hello World!'; + } +} diff --git a/backend/manager/apps/statuses/test/app.e2e-spec.ts b/backend/manager/apps/statuses/test/app.e2e-spec.ts new file mode 100644 index 0000000..171e4d2 --- /dev/null +++ b/backend/manager/apps/statuses/test/app.e2e-spec.ts @@ -0,0 +1,24 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { INestApplication } from '@nestjs/common'; +import * as request from 'supertest'; +import { StatusesModule } from './../src/statuses.module'; + +describe('StatusesController (e2e)', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture: TestingModule = await Test.createTestingModule({ + imports: [StatusesModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('/ (GET)', () => { + return request(app.getHttpServer()) + .get('/') + .expect(200) + .expect('Hello World!'); + }); +}); diff --git a/backend/manager/apps/statuses/test/jest-e2e.json b/backend/manager/apps/statuses/test/jest-e2e.json new file mode 100644 index 0000000..e9d912f --- /dev/null +++ b/backend/manager/apps/statuses/test/jest-e2e.json @@ -0,0 +1,9 @@ +{ + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": ".", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } +} diff --git a/backend/manager/apps/statuses/tsconfig.app.json b/backend/manager/apps/statuses/tsconfig.app.json new file mode 100644 index 0000000..8abc728 --- /dev/null +++ b/backend/manager/apps/statuses/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": false, + "outDir": "../../dist/apps/statuses" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/eslint.config.mjs b/backend/manager/eslint.config.mjs new file mode 100644 index 0000000..4e9f827 --- /dev/null +++ b/backend/manager/eslint.config.mjs @@ -0,0 +1,35 @@ +// @ts-check +import eslint from '@eslint/js'; +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; +import globals from 'globals'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + { + ignores: ['eslint.config.mjs'], + }, + eslint.configs.recommended, + ...tseslint.configs.recommendedTypeChecked, + eslintPluginPrettierRecommended, + { + languageOptions: { + globals: { + ...globals.node, + ...globals.jest, + }, + sourceType: 'commonjs', + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + rules: { + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-floating-promises': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + "prettier/prettier": ["error", { endOfLine: "auto" }], + }, + }, +); diff --git a/backend/manager/libs/contracts/src/contracts.module.ts b/backend/manager/libs/contracts/src/contracts.module.ts new file mode 100644 index 0000000..f25c9de --- /dev/null +++ b/backend/manager/libs/contracts/src/contracts.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { ContractsService } from './contracts.service'; + +@Module({ + providers: [ContractsService], + exports: [ContractsService], +}) +export class ContractsModule {} diff --git a/backend/manager/libs/contracts/src/contracts.service.spec.ts b/backend/manager/libs/contracts/src/contracts.service.spec.ts new file mode 100644 index 0000000..8950ec4 --- /dev/null +++ b/backend/manager/libs/contracts/src/contracts.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ContractsService } from './contracts.service'; + +describe('ContractsService', () => { + let service: ContractsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ContractsService], + }).compile(); + + service = module.get(ContractsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/libs/contracts/src/contracts.service.ts b/backend/manager/libs/contracts/src/contracts.service.ts new file mode 100644 index 0000000..cbed8ae --- /dev/null +++ b/backend/manager/libs/contracts/src/contracts.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class ContractsService {} diff --git a/backend/manager/libs/contracts/src/index.ts b/backend/manager/libs/contracts/src/index.ts new file mode 100644 index 0000000..33b915a --- /dev/null +++ b/backend/manager/libs/contracts/src/index.ts @@ -0,0 +1,2 @@ +export * from './contracts.module'; +export * from './contracts.service'; diff --git a/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts b/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts new file mode 100644 index 0000000..a3d7d5f --- /dev/null +++ b/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts @@ -0,0 +1 @@ +export const MANAGER_NAMESPACE = 'manager-api-gateway'; \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/patients.constants.ts b/backend/manager/libs/contracts/src/patients/patients.constants.ts new file mode 100644 index 0000000..ff507da --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/patients.constants.ts @@ -0,0 +1,2 @@ +export const SERVICE_NAME = Symbol('PATIENTS_SERVICE'); +export const QUEUE_NAME = 'patients_queue'; \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/patients.namespace.ts b/backend/manager/libs/contracts/src/patients/patients.namespace.ts new file mode 100644 index 0000000..b481877 --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/patients.namespace.ts @@ -0,0 +1 @@ +export const PATIENTS_NAMESPACE = 'patients'; \ No newline at end of file diff --git a/backend/manager/libs/contracts/tsconfig.lib.json b/backend/manager/libs/contracts/tsconfig.lib.json new file mode 100644 index 0000000..f0b647f --- /dev/null +++ b/backend/manager/libs/contracts/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "../../dist/libs/contracts" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/nest-cli.json b/backend/manager/nest-cli.json new file mode 100644 index 0000000..ec6d973 --- /dev/null +++ b/backend/manager/nest-cli.json @@ -0,0 +1,77 @@ +{ + "$schema": "https://json.schemastore.org/nest-cli", + "collection": "@nestjs/schematics", + "sourceRoot": "apps/manager-api-gateway/src", + "compilerOptions": { + "deleteOutDir": true, + "webpack": true, + "tsConfigPath": "apps/manager-api-gateway/tsconfig.app.json" + }, + "monorepo": true, + "root": "apps/manager-api-gateway", + "projects": { + "config": { + "type": "library", + "root": "libs/config", + "entryFile": "index", + "sourceRoot": "libs/config/src", + "compilerOptions": { + "tsConfigPath": "libs/config/tsconfig.lib.json" + } + }, + "contracts": { + "type": "library", + "root": "libs/contracts", + "entryFile": "index", + "sourceRoot": "libs/contracts/src", + "compilerOptions": { + "tsConfigPath": "libs/contracts/tsconfig.lib.json" + } + }, + "manager-api-gateway": { + "type": "application", + "root": "apps/manager-api-gateway", + "entryFile": "main", + "sourceRoot": "apps/manager-api-gateway/src", + "compilerOptions": { + "tsConfigPath": "apps/manager-api-gateway/tsconfig.app.json" + } + }, + "patients": { + "type": "application", + "root": "apps/patients", + "entryFile": "main", + "sourceRoot": "apps/patients/src", + "compilerOptions": { + "tsConfigPath": "apps/patients/tsconfig.app.json" + } + }, + "providers": { + "type": "application", + "root": "apps/providers", + "entryFile": "main", + "sourceRoot": "apps/providers/src", + "compilerOptions": { + "tsConfigPath": "apps/providers/tsconfig.app.json" + } + }, + "status-history": { + "type": "application", + "root": "apps/status-history", + "entryFile": "main", + "sourceRoot": "apps/status-history/src", + "compilerOptions": { + "tsConfigPath": "apps/status-history/tsconfig.app.json" + } + }, + "statuses": { + "type": "application", + "root": "apps/statuses", + "entryFile": "main", + "sourceRoot": "apps/statuses/src", + "compilerOptions": { + "tsConfigPath": "apps/statuses/tsconfig.app.json" + } + } + } +} \ No newline at end of file diff --git a/backend/manager/package-lock.json b/backend/manager/package-lock.json new file mode 100644 index 0000000..cd89b07 --- /dev/null +++ b/backend/manager/package-lock.json @@ -0,0 +1,10607 @@ +{ + "name": "manager", + "version": "0.0.1", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "manager", + "version": "0.0.1", + "license": "UNLICENSED", + "dependencies": { + "@nestjs/common": "^11.0.1", + "@nestjs/config": "^4.0.2", + "@nestjs/core": "^11.0.1", + "@nestjs/microservices": "^11.1.7", + "@nestjs/platform-express": "^11.0.1", + "amqp-connection-manager": "^5.0.0", + "amqplib": "^0.10.9", + "dotenv": "^17.2.3", + "reflect-metadata": "^0.2.2", + "rxjs": "^7.8.1", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.18.0", + "@nestjs/cli": "^11.0.0", + "@nestjs/schematics": "^11.0.0", + "@nestjs/testing": "^11.0.1", + "@types/express": "^5.0.0", + "@types/jest": "^30.0.0", + "@types/node": "^22.10.7", + "@types/supertest": "^6.0.2", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2", + "globals": "^16.0.0", + "jest": "^30.0.0", + "prettier": "^3.4.2", + "source-map-support": "^0.5.21", + "supertest": "^7.0.0", + "ts-jest": "^29.2.5", + "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", + "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", + "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-19.2.15.tgz", + "integrity": "sha512-1ESFmFGMpGQmalDB3t2EtmWDGv6gOFYBMxmHO2f1KI/UDl8UmZnCGL4mD3EWo8Hv0YIsZ9wOH9Q7ZHNYjeSpzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "@angular-devkit/schematics": "19.2.15", + "@inquirer/prompts": "7.3.2", + "ansi-colors": "4.1.3", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "bin": { + "schematics": "bin/schematics.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics-cli/node_modules/@inquirer/prompts": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", + "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.2", + "@inquirer/confirm": "^5.1.6", + "@inquirer/editor": "^4.2.7", + "@inquirer/expand": "^4.0.9", + "@inquirer/input": "^4.1.6", + "@inquirer/number": "^3.0.9", + "@inquirer/password": "^4.0.9", + "@inquirer/rawlist": "^4.0.9", + "@inquirer/search": "^3.0.9", + "@inquirer/select": "^4.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", + "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", + "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", + "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", + "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", + "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@emnapi/core": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.6.0.tgz", + "integrity": "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.6.0.tgz", + "integrity": "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", + "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@inquirer/ansi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", + "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.0.tgz", + "integrity": "sha512-5+Q3PKH35YsnoPTh75LucALdAxom6xh5D1oeY561x4cqBuH24ZFVyFREPe14xgnrtmGu3EEt1dIi60wRVSnGCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.19", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", + "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", + "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.21", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.21.tgz", + "integrity": "sha512-MjtjOGjr0Kh4BciaFShYpZ1s9400idOdvQ5D7u7lE6VztPFoyLcVNE5dXBmEEIQq5zi4B9h2kU+q7AVBxJMAkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/external-editor": "^1.0.2", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.21.tgz", + "integrity": "sha512-+mScLhIcbPFmuvU3tAGBed78XvYHSvCl6dBiYMlzCLhpr0bzGzd8tfivMMeqND6XZiaZ1tgusbUHJEfc6YzOdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", + "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", + "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.5.tgz", + "integrity": "sha512-7GoWev7P6s7t0oJbenH0eQ0ThNdDJbEAEtVt9vsrYZ9FulIokvd823yLyhQlWHJPGce1wzP53ttfdCZmonMHyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.21.tgz", + "integrity": "sha512-5QWs0KGaNMlhbdhOSCFfKsW+/dcAVC2g4wT/z2MCiZM47uLgatC5N20kpkDQf7dHx+XFct/MJvvNGy6aYJn4Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.21", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.21.tgz", + "integrity": "sha512-xxeW1V5SbNFNig2pLfetsDb0svWlKuhmr7MPJZMYuDnCTkpVBI+X/doudg4pznc1/U+yYmWFFOi4hNvGgUo7EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.0.tgz", + "integrity": "sha512-JHwGbQ6wjf1dxxnalDYpZwZxUEosT+6CPGD9Zh4sm9WXdtUp9XODCQD3NjSTmu+0OAyxWXNOqf0spjIymJa2Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.2.0", + "@inquirer/confirm": "^5.1.14", + "@inquirer/editor": "^4.2.15", + "@inquirer/expand": "^4.0.17", + "@inquirer/input": "^4.2.1", + "@inquirer/number": "^3.0.17", + "@inquirer/password": "^4.0.17", + "@inquirer/rawlist": "^4.1.5", + "@inquirer/search": "^3.1.0", + "@inquirer/select": "^4.3.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.9.tgz", + "integrity": "sha512-AWpxB7MuJrRiSfTKGJ7Y68imYt8P9N3Gaa7ySdkFj1iWjr6WfbGAhdZvw/UnhFXTHITJzxGUI9k8IX7akAEBCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.0.tgz", + "integrity": "sha512-a5SzB/qrXafDX1Z4AZW3CsVoiNxcIYCzYP7r9RzrfMpaLpB+yWi5U8BWagZyLmwR0pKbbL5umnGRd0RzGVI8bQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.0.tgz", + "integrity": "sha512-kaC3FHsJZvVyIjYBs5Ih8y8Bj4P/QItQWrZW22WJax7zTN+ZPXVGuOM55vzbdCP9zKUiBd9iEJVdesujfF+cAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.1", + "@inquirer/core": "^10.3.0", + "@inquirer/figures": "^1.0.14", + "@inquirer/type": "^3.0.9", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", + "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", + "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", + "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.2.0", + "jest-config": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-resolve-dependencies": "30.2.0", + "jest-runner": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "jest-watcher": "30.2.0", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.2.0", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@jest/reporters/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lukeed/csprng": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz", + "integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@nestjs/cli": { + "version": "11.0.10", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-11.0.10.tgz", + "integrity": "sha512-4waDT0yGWANg0pKz4E47+nUrqIJv/UqrZ5wLPkCqc7oMGRMWKAaw1NDZ9rKsaqhqvxb2LfI5+uXOWr4yi94DOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "@angular-devkit/schematics": "19.2.15", + "@angular-devkit/schematics-cli": "19.2.15", + "@inquirer/prompts": "7.8.0", + "@nestjs/schematics": "^11.0.1", + "ansis": "4.1.0", + "chokidar": "4.0.3", + "cli-table3": "0.6.5", + "commander": "4.1.1", + "fork-ts-checker-webpack-plugin": "9.1.0", + "glob": "11.0.3", + "node-emoji": "1.11.0", + "ora": "5.4.1", + "tree-kill": "1.2.2", + "tsconfig-paths": "4.2.0", + "tsconfig-paths-webpack-plugin": "4.2.0", + "typescript": "5.8.3", + "webpack": "5.100.2", + "webpack-node-externals": "3.0.0" + }, + "bin": { + "nest": "bin/nest.js" + }, + "engines": { + "node": ">= 20.11" + }, + "peerDependencies": { + "@swc/cli": "^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0", + "@swc/core": "^1.3.62" + }, + "peerDependenciesMeta": { + "@swc/cli": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@nestjs/cli/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/@nestjs/cli/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@nestjs/cli/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nestjs/cli/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@nestjs/cli/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/@nestjs/cli/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@nestjs/cli/node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/@nestjs/cli/node_modules/webpack": { + "version": "5.100.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.2.tgz", + "integrity": "sha512-QaNKAvGCDRh3wW1dsDjeMdDXwZm2vqq3zn6Pvq4rHOEOGSaUMgOOjG2Y9ZbIGzpfkJk9ZYTHpDqgDfeBDcnLaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.2", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/@nestjs/common": { + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.7.tgz", + "integrity": "sha512-lwlObwGgIlpXSXYOTpfzdCepUyWomz6bv9qzGzzvpgspUxkj0Uz0fUJcvD44V8Ps7QhKW3lZBoYbXrH25UZrbA==", + "license": "MIT", + "dependencies": { + "file-type": "21.0.0", + "iterare": "1.2.1", + "load-esm": "1.0.3", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "class-transformer": ">=0.4.1", + "class-validator": ">=0.13.2", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, + "node_modules/@nestjs/config": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz", + "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==", + "license": "MIT", + "dependencies": { + "dotenv": "16.4.7", + "dotenv-expand": "12.0.1", + "lodash": "4.17.21" + }, + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "rxjs": "^7.1.0" + } + }, + "node_modules/@nestjs/config/node_modules/dotenv": { + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/@nestjs/core": { + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.7.tgz", + "integrity": "sha512-TyXFOwjhHv/goSgJ8i20K78jwTM0iSpk9GBcC2h3mf4MxNy+znI8m7nWjfoACjTkb89cTwDQetfTHtSfGLLaiA==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nuxt/opencollective": "0.4.1", + "fast-safe-stringify": "2.1.1", + "iterare": "1.2.1", + "path-to-regexp": "8.3.0", + "tslib": "2.8.1", + "uid": "2.0.2" + }, + "engines": { + "node": ">= 20" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + } + } + }, + "node_modules/@nestjs/microservices": { + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-11.1.7.tgz", + "integrity": "sha512-Oc+Uqsx5Br0aCZOaQ4n+ykiI3q1nUNZ2zwM6WRxVYG5BWfeicXS0b68abg9LRblLmRJ5pX7NynE86YKNuN20nQ==", + "license": "MIT", + "dependencies": { + "iterare": "1.2.1", + "tslib": "2.8.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@grpc/grpc-js": "*", + "@nestjs/common": "^11.0.0", + "@nestjs/core": "^11.0.0", + "@nestjs/websockets": "^11.0.0", + "amqp-connection-manager": "*", + "amqplib": "*", + "cache-manager": "*", + "ioredis": "*", + "kafkajs": "*", + "mqtt": "*", + "nats": "*", + "reflect-metadata": "^0.1.12 || ^0.2.0", + "rxjs": "^7.1.0" + }, + "peerDependenciesMeta": { + "@grpc/grpc-js": { + "optional": true + }, + "@nestjs/websockets": { + "optional": true + }, + "amqp-connection-manager": { + "optional": true + }, + "amqplib": { + "optional": true + }, + "cache-manager": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "kafkajs": { + "optional": true + }, + "mqtt": { + "optional": true + }, + "nats": { + "optional": true + } + } + }, + "node_modules/@nestjs/platform-express": { + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-11.1.7.tgz", + "integrity": "sha512-5T+GLdvTiGPKB4/P4PM9ftKUKNHJy8ThEFhZA3vQnXVL7Vf0rDr07TfVTySVu+XTh85m1lpFVuyFM6u6wLNsRA==", + "license": "MIT", + "dependencies": { + "cors": "2.8.5", + "express": "5.1.0", + "multer": "2.0.2", + "path-to-regexp": "8.3.0", + "tslib": "2.8.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/core": "^11.0.0" + } + }, + "node_modules/@nestjs/schematics": { + "version": "11.0.9", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-11.0.9.tgz", + "integrity": "sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.17", + "@angular-devkit/schematics": "19.2.17", + "comment-json": "4.4.1", + "jsonc-parser": "3.3.1", + "pluralize": "8.0.0" + }, + "peerDependencies": { + "typescript": ">=4.8.2" + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.17.tgz", + "integrity": "sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.17.tgz", + "integrity": "sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.17", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@nestjs/schematics/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nestjs/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@nestjs/testing": { + "version": "11.1.7", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-11.1.7.tgz", + "integrity": "sha512-QbtrgSlc3QVo6RHNxTTlyhaiobLLy8kvhOlgWHsoXRknybuRs7vZg4k5mo3ye6pITGeT3CrWIRpZjUsh5Wps5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "2.8.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nest" + }, + "peerDependencies": { + "@nestjs/common": "^11.0.0", + "@nestjs/core": "^11.0.0", + "@nestjs/microservices": "^11.0.0", + "@nestjs/platform-express": "^11.0.0" + }, + "peerDependenciesMeta": { + "@nestjs/microservices": { + "optional": true + }, + "@nestjs/platform-express": { + "optional": true + } + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nuxt/opencollective": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz", + "integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==", + "license": "MIT", + "dependencies": { + "consola": "^3.2.3" + }, + "bin": { + "opencollective": "bin/opencollective.js" + }, + "engines": { + "node": "^14.18.0 || >=16.10.0", + "npm": ">=5.10.0" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", + "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@tokenizer/inflate": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", + "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "fflate": "^0.8.2", + "token-types": "^6.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "license": "MIT" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.3.tgz", + "integrity": "sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz", + "integrity": "sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.18.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz", + "integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.0.tgz", + "integrity": "sha512-zBF6vZJn1IaMpg3xUF25VK3gd3l8zwE0ZLRX7dsQyQi+jp4E8mMDJNGDYnYse+bQhYwWERTxVwHpi3dMOq7RKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.9.tgz", + "integrity": "sha512-dOTIuqpWLyl3BBXU3maNQsS4A3zuuoYRNIvYSxxhebPfXg2mzWQEPne/nlJ37yOse6uGgR386uTpdsx4D0QZWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/superagent": { + "version": "8.1.9", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.9.tgz", + "integrity": "sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/supertest": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.3.tgz", + "integrity": "sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.2.tgz", + "integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/type-utils": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.2", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.2.tgz", + "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.2.tgz", + "integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.2", + "@typescript-eslint/types": "^8.46.2", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.2.tgz", + "integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.2.tgz", + "integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.2.tgz", + "integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/utils": "8.46.2", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.2.tgz", + "integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.2.tgz", + "integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.46.2", + "@typescript-eslint/tsconfig-utils": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/visitor-keys": "8.46.2", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.2.tgz", + "integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.2", + "@typescript-eslint/types": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.2.tgz", + "integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.46.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", + "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/amqp-connection-manager": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/amqp-connection-manager/-/amqp-connection-manager-5.0.0.tgz", + "integrity": "sha512-88yQzqa5RSBgnLl504XjvCQJ7d+osskdwvg35Lwm1LRbfLjNU9p7SQUMSP82BB7mseiq9tIUPJ3HE3eXQbpjEw==", + "license": "MIT", + "dependencies": { + "promise-breaker": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0", + "npm": ">5.0.0" + }, + "peerDependencies": { + "amqplib": "*" + } + }, + "node_modules/amqplib": { + "version": "0.10.9", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.10.9.tgz", + "integrity": "sha512-jwSftI4QjS3mizvnSnOrPGYiUnm1vI2OP1iXeOUz5pb74Ua0nbf6nPyyTzuiCLEE3fMpaJORXh2K/TQ08H5xGA==", + "license": "MIT", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "url-parse": "~1.5.10" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansis": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.1.0.tgz", + "integrity": "sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/append-field": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", + "integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==", + "license": "MIT" + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-timsort": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", + "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", + "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "30.2.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", + "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", + "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.19.tgz", + "integrity": "sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.0", + "type-is": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==", + "license": "MIT" + }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", + "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz", + "integrity": "sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/comment-json": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.4.1.tgz", + "integrity": "sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-timsort": "^1.0.3", + "core-util-is": "^1.0.3", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/consola": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", + "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/content-disposition": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", + "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", + "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz", + "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==", + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.239", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.239.tgz", + "integrity": "sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", + "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.1", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.38.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz", + "integrity": "sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/express": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.0", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fflate": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", + "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", + "license": "MIT" + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/file-type": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-21.0.0.tgz", + "integrity": "sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==", + "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.2.7", + "strtok3": "^10.2.2", + "token-types": "^6.0.0", + "uint8array-extras": "^1.4.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.1.0.tgz", + "integrity": "sha512-mpafl89VFPJmhnJ1ssH+8wmM2b50n+Rew5x42NeI2U78aRWgtkEtGmctp7iT16UjquJTjorEmIfESj3DxdW84Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^4.0.1", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formidable": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-monkey": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.1.0.tgz", + "integrity": "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/glob/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterare": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz", + "integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==", + "license": "ISC", + "engines": { + "node": ">=6" + } + }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", + "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/types": "30.2.0", + "import-local": "^3.2.0", + "jest-cli": "30.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", + "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.2.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", + "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "p-limit": "^3.1.0", + "pretty-format": "30.2.0", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-cli": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", + "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", + "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.2.0", + "@jest/types": "30.2.0", + "babel-jest": "30.2.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-circus": "30.2.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-runner": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "micromatch": "^4.0.8", + "parse-json": "^5.2.0", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/jest-config/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-config/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jest-config/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-config/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", + "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "jest-util": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", + "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", + "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "micromatch": "^4.0.8", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-leak-detector": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", + "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", + "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", + "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", + "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/environment": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-leak-detector": "30.2.0", + "jest-message-util": "30.2.0", + "jest-resolve": "30.2.0", + "jest-runtime": "30.2.0", + "jest-util": "30.2.0", + "jest-watcher": "30.2.0", + "jest-worker": "30.2.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", + "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/globals": "30.2.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/jest-runtime/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-runtime/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/jest-runtime/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-runtime/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/jest-snapshot": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", + "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "pretty-format": "30.2.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", + "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", + "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.2.0", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", + "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.2.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-esm": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz", + "integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + }, + { + "type": "buymeacoffee", + "url": "https://buymeacoffee.com/borewit" + } + ], + "license": "MIT", + "engines": { + "node": ">=13.2.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/multer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/multer/-/multer-2.0.2.tgz", + "integrity": "sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==", + "license": "MIT", + "dependencies": { + "append-field": "^1.0.0", + "busboy": "^1.6.0", + "concat-stream": "^2.0.0", + "mkdirp": "^0.5.6", + "object-assign": "^4.1.1", + "type-is": "^1.6.18", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">= 10.16.0" + } + }, + "node_modules/multer/node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/multer/node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.2.tgz", + "integrity": "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/promise-breaker": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/promise-breaker/-/promise-breaker-6.0.0.tgz", + "integrity": "sha512-BthzO9yTPswGf7etOBiHCVuugs2N01/Q/94dIPls48z2zCmrnDptUUZzfIb+41xq0MnYZ/BzmOd6ikDR4ibNZA==", + "license": "MIT" + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", + "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.7.0", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "license": "Apache-2.0" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "license": "MIT" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strtok3": { + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.4.tgz", + "integrity": "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==", + "license": "MIT", + "dependencies": { + "@tokenizer/token": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/superagent": { + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.3.tgz", + "integrity": "sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.4", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.11.2" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.1.4.tgz", + "integrity": "sha512-tjLPs7dVyqgItVFirHYqe2T+MfWc2VOBQ8QFKKbWTA3PU7liZR8zoSpAi/C1k1ilm9RsXIKYf197oap9wXGVYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^10.2.3" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.44.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.0.tgz", + "integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser-webpack-plugin/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-types": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.1.tgz", + "integrity": "sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==", + "license": "MIT", + "dependencies": { + "@borewit/text-codec": "^0.1.0", + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-jest": { + "version": "29.4.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.5.tgz", + "integrity": "sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-loader": { + "version": "9.5.4", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.4.tgz", + "integrity": "sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", + "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz", + "integrity": "sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tapable": "^2.2.1", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.46.2", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.2.tgz", + "integrity": "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.46.2", + "@typescript-eslint/parser": "8.46.2", + "@typescript-eslint/typescript-estree": "8.46.2", + "@typescript-eslint/utils": "8.46.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uid": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz", + "integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==", + "license": "MIT", + "dependencies": { + "@lukeed/csprng": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uint8array-extras": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz", + "integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "license": "MIT", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "5.102.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.102.1.tgz", + "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.26.3", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-node-externals": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-3.0.0.tgz", + "integrity": "sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/webpack/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/backend/manager/package.json b/backend/manager/package.json new file mode 100644 index 0000000..ad01a12 --- /dev/null +++ b/backend/manager/package.json @@ -0,0 +1,85 @@ +{ + "name": "manager", + "version": "0.0.1", + "description": "", + "author": "", + "private": true, + "license": "UNLICENSED", + "scripts": { + "build": "nest build", + "format": "prettier --write \"apps/**/*.ts\" \"libs/**/*.ts\"", + "start": "nest start", + "start:dev": "nest start --watch", + "start:debug": "nest start --debug --watch", + "start:prod": "node dist/apps/manager/main", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", + "test": "jest", + "test:watch": "jest --watch", + "test:cov": "jest --coverage", + "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", + "test:e2e": "jest --config ./apps/manager/test/jest-e2e.json" + }, + "dependencies": { + "@nestjs/common": "^11.0.1", + "@nestjs/config": "^4.0.2", + "@nestjs/core": "^11.0.1", + "@nestjs/microservices": "^11.1.7", + "@nestjs/platform-express": "^11.0.1", + "amqp-connection-manager": "^5.0.0", + "amqplib": "^0.10.9", + "dotenv": "^17.2.3", + "reflect-metadata": "^0.2.2", + "rxjs": "^7.8.1", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "^9.18.0", + "@nestjs/cli": "^11.0.0", + "@nestjs/schematics": "^11.0.0", + "@nestjs/testing": "^11.0.1", + "@types/express": "^5.0.0", + "@types/jest": "^30.0.0", + "@types/node": "^22.10.7", + "@types/supertest": "^6.0.2", + "eslint": "^9.18.0", + "eslint-config-prettier": "^10.0.1", + "eslint-plugin-prettier": "^5.2.2", + "globals": "^16.0.0", + "jest": "^30.0.0", + "prettier": "^3.4.2", + "source-map-support": "^0.5.21", + "supertest": "^7.0.0", + "ts-jest": "^29.2.5", + "ts-loader": "^9.5.2", + "ts-node": "^10.9.2", + "tsconfig-paths": "^4.2.0", + "typescript": "^5.7.3", + "typescript-eslint": "^8.20.0" + }, + "jest": { + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "rootDir": ".", + "testRegex": ".*\\.spec\\.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + }, + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageDirectory": "./coverage", + "testEnvironment": "node", + "roots": [ + "/apps/", + "/libs/" + ], + "moduleNameMapper": { + "^@app/config(|/.*)$": "/libs/config/src/$1", + "^@app/contracts(|/.*)$": "/libs/contracts/src/$1" + } + } +} \ No newline at end of file diff --git a/backend/manager/tsconfig.build.json b/backend/manager/tsconfig.build.json new file mode 100644 index 0000000..64f86c6 --- /dev/null +++ b/backend/manager/tsconfig.build.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] +} diff --git a/backend/manager/tsconfig.json b/backend/manager/tsconfig.json new file mode 100644 index 0000000..9b52763 --- /dev/null +++ b/backend/manager/tsconfig.json @@ -0,0 +1,39 @@ +{ + "compilerOptions": { + "module": "nodenext", + "moduleResolution": "nodenext", + "resolvePackageJsonExports": true, + "esModuleInterop": true, + "isolatedModules": true, + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "ES2023", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./", + "incremental": true, + "skipLibCheck": true, + "strictNullChecks": true, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": false, + "strictBindCallApply": false, + "noFallthroughCasesInSwitch": false, + "paths": { + "@app/config": [ + "libs/config/src" + ], + "@app/config/*": [ + "libs/config/src/*" + ], + "@app/contracts": [ + "libs/contracts/src" + ], + "@app/contracts/*": [ + "libs/contracts/src/*" + ] + } + } +} \ No newline at end of file From 516c9ea7a1d419d4dc8ea0471f52f5d2360fc877 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 07:14:55 -0500 Subject: [PATCH 02/52] =?UTF-8?q?=E2=9C=A8=20feat(logger):=20agregar=20m?= =?UTF-8?q?=C3=B3dulo=20de=20logger=20y=20servicio=20de=20registro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/manager-api-gateway/src/main.ts | 5 ++ .../src/manager-api-gateway.module.ts | 9 ++- .../src/constants/logger-symbol.constants.ts | 1 + backend/manager/libs/logger/src/index.ts | 2 + .../manager/libs/logger/src/logger.module.ts | 8 +++ .../libs/logger/src/logger.provider.ts | 8 +++ .../libs/logger/src/logger.service.spec.ts | 17 +++++ .../manager/libs/logger/src/logger.service.ts | 62 +++++++++++++++++++ backend/manager/libs/logger/tsconfig.lib.json | 9 +++ backend/manager/nest-cli.json | 9 +++ backend/manager/package.json | 5 +- backend/manager/tsconfig.json | 3 + 12 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 backend/manager/libs/logger/src/constants/logger-symbol.constants.ts create mode 100644 backend/manager/libs/logger/src/index.ts create mode 100644 backend/manager/libs/logger/src/logger.module.ts create mode 100644 backend/manager/libs/logger/src/logger.provider.ts create mode 100644 backend/manager/libs/logger/src/logger.service.spec.ts create mode 100644 backend/manager/libs/logger/src/logger.service.ts create mode 100644 backend/manager/libs/logger/tsconfig.lib.json diff --git a/backend/manager/apps/manager-api-gateway/src/main.ts b/backend/manager/apps/manager-api-gateway/src/main.ts index cd447f0..2e24553 100644 --- a/backend/manager/apps/manager-api-gateway/src/main.ts +++ b/backend/manager/apps/manager-api-gateway/src/main.ts @@ -1,10 +1,15 @@ import { NestFactory } from '@nestjs/core'; import { ManagerApiGatewayModule } from './manager-api-gateway.module'; import { envs } from './config/envs'; +import { LoggerService } from '@nestjs/common'; +import { LOGGER_SERVICE_SYMBOL } from '@app/logger/constants/logger-symbol.constants'; async function bootstrap() { const app = await NestFactory.create(ManagerApiGatewayModule); + const logger = app.get(LOGGER_SERVICE_SYMBOL); + app.useLogger(logger); + await app.listen(envs.PORT); } bootstrap(); diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts index 8d014c9..547d691 100644 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -1,11 +1,10 @@ import { Module } from '@nestjs/common'; -import { ManagerApiGatewayController } from './manager-api-gateway.controller'; -import { ManagerApiGatewayService } from './manager-api-gateway.service'; import { PatientsModule } from './patients/patients.module'; +import { LoggerModule } from '@app/logger'; @Module({ - imports: [PatientsModule], - controllers: [ManagerApiGatewayController], - providers: [ManagerApiGatewayService], + imports: [PatientsModule, LoggerModule], + controllers: [], + providers: [], }) export class ManagerApiGatewayModule {} diff --git a/backend/manager/libs/logger/src/constants/logger-symbol.constants.ts b/backend/manager/libs/logger/src/constants/logger-symbol.constants.ts new file mode 100644 index 0000000..c9bac29 --- /dev/null +++ b/backend/manager/libs/logger/src/constants/logger-symbol.constants.ts @@ -0,0 +1 @@ +export const LOGGER_SERVICE_SYMBOL = Symbol('LOGGER_SERVICE'); \ No newline at end of file diff --git a/backend/manager/libs/logger/src/index.ts b/backend/manager/libs/logger/src/index.ts new file mode 100644 index 0000000..bbf7c26 --- /dev/null +++ b/backend/manager/libs/logger/src/index.ts @@ -0,0 +1,2 @@ +export * from './logger.module'; +export * from './logger.service'; diff --git a/backend/manager/libs/logger/src/logger.module.ts b/backend/manager/libs/logger/src/logger.module.ts new file mode 100644 index 0000000..39dff3d --- /dev/null +++ b/backend/manager/libs/logger/src/logger.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { loggerProvider } from './logger.provider'; + +@Module({ + providers: [loggerProvider], + exports: [loggerProvider], +}) +export class LoggerModule {} diff --git a/backend/manager/libs/logger/src/logger.provider.ts b/backend/manager/libs/logger/src/logger.provider.ts new file mode 100644 index 0000000..c1aa0c6 --- /dev/null +++ b/backend/manager/libs/logger/src/logger.provider.ts @@ -0,0 +1,8 @@ +import { AppLogger } from './logger.service'; +import { LOGGER_SERVICE_SYMBOL } from './constants/logger-symbol.constants'; +import { Provider } from '@nestjs/common'; + +export const loggerProvider: Provider = { + provide: LOGGER_SERVICE_SYMBOL, + useClass: AppLogger +}; \ No newline at end of file diff --git a/backend/manager/libs/logger/src/logger.service.spec.ts b/backend/manager/libs/logger/src/logger.service.spec.ts new file mode 100644 index 0000000..1e24d4f --- /dev/null +++ b/backend/manager/libs/logger/src/logger.service.spec.ts @@ -0,0 +1,17 @@ +import { Test, TestingModule } from '@nestjs/testing'; + +describe('AppLogger', () => { + let service: AppLogger; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [AppLogger], + }).compile(); + + service = module.get(AppLogger); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/libs/logger/src/logger.service.ts b/backend/manager/libs/logger/src/logger.service.ts new file mode 100644 index 0000000..8c9b1c8 --- /dev/null +++ b/backend/manager/libs/logger/src/logger.service.ts @@ -0,0 +1,62 @@ +import { Injectable, LoggerService } from '@nestjs/common'; +import { appendFileSync, existsSync, mkdirSync } from 'fs'; +import { resolve } from 'path'; + +type LogParam = string | number | boolean | object | null | undefined; + +@Injectable() +export class AppLogger implements LoggerService { + private readonly logDir: string; + private readonly logFile: string; + + constructor() { + this.logDir = resolve(process.cwd(), 'logs'); + if (!existsSync(this.logDir)) { + mkdirSync(this.logDir, { recursive: true }); + } + this.logFile = resolve(this.logDir, 'workflow.log'); + } + + private formatParam(param: unknown): string { + if (typeof param === 'object') return JSON.stringify(param); + return String(param); + } + + private writeToFile(level: string, message: unknown, optionalParams: unknown[]) { + const timestamp = new Date().toISOString(); + const formatted = `[${timestamp}] [${level}] ${this.formatParam(message)} ${optionalParams + .map(this.formatParam) + .join(' ')}\n`; + appendFileSync(this.logFile, formatted); + } + + log(message: LogParam, ...optionalParams: LogParam[]) { + console.log('[LOG]', message, ...optionalParams); + this.writeToFile('LOG', message, optionalParams); + } + + error(message: LogParam, ...optionalParams: LogParam[]) { + console.error('[ERROR]', message, ...optionalParams); + this.writeToFile('ERROR', message, optionalParams); + } + + warn(message: LogParam, ...optionalParams: LogParam[]) { + console.warn('[WARN]', message, ...optionalParams); + this.writeToFile('WARN', message, optionalParams); + } + + debug(message: LogParam, ...optionalParams: LogParam[]) { + console.debug('[DEBUG]', message, ...optionalParams); + this.writeToFile('DEBUG', message, optionalParams); + } + + verbose(message: LogParam, ...optionalParams: LogParam[]) { + console.info('[VERBOSE]', message, ...optionalParams); + this.writeToFile('VERBOSE', message, optionalParams); + } + + fatal(message: LogParam, ...optionalParams: LogParam[]) { + console.error('[FATAL]', message, ...optionalParams); + this.writeToFile('FATAL', message, optionalParams); + } +} \ No newline at end of file diff --git a/backend/manager/libs/logger/tsconfig.lib.json b/backend/manager/libs/logger/tsconfig.lib.json new file mode 100644 index 0000000..cd7c5b5 --- /dev/null +++ b/backend/manager/libs/logger/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "../../dist/libs/logger" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/nest-cli.json b/backend/manager/nest-cli.json index ec6d973..18b7219 100644 --- a/backend/manager/nest-cli.json +++ b/backend/manager/nest-cli.json @@ -28,6 +28,15 @@ "tsConfigPath": "libs/contracts/tsconfig.lib.json" } }, + "logger": { + "type": "library", + "root": "libs/logger", + "entryFile": "index", + "sourceRoot": "libs/logger/src", + "compilerOptions": { + "tsConfigPath": "libs/logger/tsconfig.lib.json" + } + }, "manager-api-gateway": { "type": "application", "root": "apps/manager-api-gateway", diff --git a/backend/manager/package.json b/backend/manager/package.json index ad01a12..d37455d 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -79,7 +79,8 @@ ], "moduleNameMapper": { "^@app/config(|/.*)$": "/libs/config/src/$1", - "^@app/contracts(|/.*)$": "/libs/contracts/src/$1" + "^@app/contracts(|/.*)$": "/libs/contracts/src/$1", + "^@app/logger(|/.*)$": "/libs/logger/src/$1" } } -} \ No newline at end of file +} diff --git a/backend/manager/tsconfig.json b/backend/manager/tsconfig.json index 9b52763..45a7490 100644 --- a/backend/manager/tsconfig.json +++ b/backend/manager/tsconfig.json @@ -33,6 +33,9 @@ ], "@app/contracts/*": [ "libs/contracts/src/*" + ], + "@app/logger/*": [ + "libs/logger/src/*" ] } } From 2773af98e53195a40257f3aa1ec53614cf8c4fa9 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 07:15:20 -0500 Subject: [PATCH 03/52] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20chore(api):=20eli?= =?UTF-8?q?minar=20controlador=20y=20servicio=20de=20ManagerApiGateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager-api-gateway.controller.spec.ts | 22 ------------------- .../src/manager-api-gateway.controller.ts | 12 ---------- .../src/manager-api-gateway.service.ts | 9 -------- 3 files changed, 43 deletions(-) delete mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts delete mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts delete mode 100644 backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts deleted file mode 100644 index d0fd7c7..0000000 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ManagerApiGatewayController } from './manager-api-gateway.controller'; -import { ManagerApiGatewayService } from './manager-api-gateway.service'; - -describe('ManagerApiGatewayController', () => { - let managerApiGatewayController: ManagerApiGatewayController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [ManagerApiGatewayController], - providers: [ManagerApiGatewayService], - }).compile(); - - managerApiGatewayController = app.get(ManagerApiGatewayController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(managerApiGatewayController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts deleted file mode 100644 index 9b0bf37..0000000 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { PatientsService } from './patients/patients.service'; - -@Controller('api') -export class ManagerApiGatewayController { - constructor(private readonly patientService: PatientsService) {} - - @Get('hello') - getHello(): string { - return this.patientService.getHello(); - } -} diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts deleted file mode 100644 index b710192..0000000 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Get, Injectable } from '@nestjs/common'; - -@Injectable() -export class ManagerApiGatewayService { - - getHello(): string { - return 'Hello World!'; - } -} From c50282c35e49fdc28c1c4982ca91cee0ecbfd61d Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 07:16:11 -0500 Subject: [PATCH 04/52] =?UTF-8?q?=F0=9F=94=A7=20fix(module):=20corregir=20?= =?UTF-8?q?importaci=C3=B3n=20del=20LoggerModule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/manager-api-gateway/src/manager-api-gateway.module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts index 547d691..6bd06ac 100644 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; import { PatientsModule } from './patients/patients.module'; -import { LoggerModule } from '@app/logger'; +import { LoggerModule } from '@app/logger/logger.module'; @Module({ imports: [PatientsModule, LoggerModule], From 28f6c12cb4bbff758c2b27bbf8d86778ba04e9c1 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 08:39:10 -0500 Subject: [PATCH 05/52] =?UTF-8?q?=E2=9C=A8=20feat(custom-class-validator):?= =?UTF-8?q?=20add=20module=20and=20service=20with=20validation=20decorator?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/custom-class-validator.module.ts | 8 + .../custom-class-validator.service.spec.ts | 18 ++ .../src/custom-class-validator.service.ts | 4 + .../src/custom-class-validator.ts | 158 ++++++++++++++++++ .../libs/custom-class-validator/src/index.ts | 2 + .../custom-class-validator/tsconfig.lib.json | 9 + 6 files changed, 199 insertions(+) create mode 100644 backend/manager/libs/custom-class-validator/src/custom-class-validator.module.ts create mode 100644 backend/manager/libs/custom-class-validator/src/custom-class-validator.service.spec.ts create mode 100644 backend/manager/libs/custom-class-validator/src/custom-class-validator.service.ts create mode 100644 backend/manager/libs/custom-class-validator/src/custom-class-validator.ts create mode 100644 backend/manager/libs/custom-class-validator/src/index.ts create mode 100644 backend/manager/libs/custom-class-validator/tsconfig.lib.json diff --git a/backend/manager/libs/custom-class-validator/src/custom-class-validator.module.ts b/backend/manager/libs/custom-class-validator/src/custom-class-validator.module.ts new file mode 100644 index 0000000..2f77dd6 --- /dev/null +++ b/backend/manager/libs/custom-class-validator/src/custom-class-validator.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; +import { CustomClassValidatorService } from './custom-class-validator.service'; + +@Module({ + providers: [CustomClassValidatorService], + exports: [CustomClassValidatorService], +}) +export class CustomClassValidatorModule {} diff --git a/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.spec.ts b/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.spec.ts new file mode 100644 index 0000000..ab18728 --- /dev/null +++ b/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { CustomClassValidatorService } from './custom-class-validator.service'; + +describe('CustomClassValidatorService', () => { + let service: CustomClassValidatorService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [CustomClassValidatorService], + }).compile(); + + service = module.get(CustomClassValidatorService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.ts b/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.ts new file mode 100644 index 0000000..b76b50e --- /dev/null +++ b/backend/manager/libs/custom-class-validator/src/custom-class-validator.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class CustomClassValidatorService {} diff --git a/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts b/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts new file mode 100644 index 0000000..26d4962 --- /dev/null +++ b/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts @@ -0,0 +1,158 @@ +import { + IsNumberOptions, + ValidationOptions, + ArrayMaxSize as _ArrayMaxSize, + IsArray as _IsArray, + ArrayNotEmpty as _ArrayNotEmpty, + IsBoolean as _IsBoolean, + IsDate as _IsDate, + IsDateString as _IsDateString, + IsIn as _IsIn, + IsMongoId as _IsMongoId, + IsNotEmpty as _IsNotEmpty, + IsNumber as _IsNumber, + IsUUID as _IsUUID, + IsEmail as _IsEmail, + IsObject as _IsObject, + IsOptional as _IsOptional, + IsString as _IsString, + IsStrongPassword as _IsStrongPassword, + Matches as _Matches, + IsInt as _IsInt, + Max as _Max, + MaxLength as _MaxLength, + Min as _Min, + MinLength as _MinLength +} from 'class-validator'; +import { IsISO8601Options } from 'validator'; + +export const IsMongoId = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsMongoId({ + ...validationOptions, + message: ' - El campo $property no tiene un formato adecuado' + }); + +export const IsNotEmpty = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsNotEmpty({ ...validationOptions, message: ' - El campo $property es requerido' }); + +export const IsOptional = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsOptional({ ...validationOptions, message: ' - El campo $property es opcional' }); + +export const IsArray = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsArray({ ...validationOptions, message: ' - El campo $property debe ser un arreglo' }); + +export const ArrayNotEmpty = (validationOptions?: ValidationOptions): PropertyDecorator => + _ArrayNotEmpty({ + ...validationOptions, + message: ' - El campo $property no puede estar vacío' + }); + +export const IsString = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsString({ + ...validationOptions, + message: ' - El campo $property debe ser una cadena de texto' + }); + +export const IsEmail = (validationOptions?: ValidationOptions): PropertyDecorator => + function (object: Object, propertyName: string) { + const _IsEmail = require('class-validator').IsEmail; + _IsEmail({ ...validationOptions, message: ' - El campo $property no tiene un formato de correo electrónico válido' })(object, propertyName); + }; + +export const IsUUID = (version?: validator.UUIDVersion | undefined, validationOptions?: ValidationOptions): PropertyDecorator => + _IsUUID(version, { + ...validationOptions, + message: ' - El campo $property debe ser un UUID válido' + }); + +export const IsNumber = ( + options?: IsNumberOptions, + validationOptions?: ValidationOptions +): PropertyDecorator => + _IsNumber( + { ...options }, + { ...validationOptions, message: ' - El campo $property debe ser un número' } + ); + +export const IsBoolean = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsBoolean({ + ...validationOptions, + message: ' - El campo $property debe ser un booleano' + }); + +export const IsDateString = ( + options?: IsISO8601Options, + validationOptions?: ValidationOptions +): PropertyDecorator => + _IsDateString( + { ...options }, + { ...validationOptions, message: ' - El campo $property debe ser una fecha válida' } + ); + +export const Matches = ( + pattern: RegExp, + validationOptions?: ValidationOptions +): PropertyDecorator => + _Matches(pattern, { + ...validationOptions, + message: ' - El campo $property contiene caracteres no permitidos' + }); + +export const IsInt = ( + validationOptions?: ValidationOptions +): PropertyDecorator => _IsInt({ + ...validationOptions, + message: ' - El campo $property debe ser un número entero' + }); + +export const Max = (maxValue: number, validationOptions?: ValidationOptions): PropertyDecorator => + _Max(maxValue, { + ...validationOptions, + message: ' - El campo $property permite un valor máximo de $constraint1' + }); + +export const Min = (minValue: number, validationOptions?: ValidationOptions): PropertyDecorator => + _Min(minValue, { + ...validationOptions, + message: ' - El campo $property permite un valor mínimo de $constraint1' + }); + +export const MaxLength = (max: number, validationOptions?: ValidationOptions): PropertyDecorator => + _MaxLength(max, { + ...validationOptions, + message: + ' - El campo $property permite una longitud máxima de $constraint1 caracteres "${value}"' + }); + +export const MinLength = (min: number, validationOptions?: ValidationOptions): PropertyDecorator => + _MinLength(min, { + ...validationOptions, + message: ' - El campo $property permite una longitud mínima de $constraint1 caracteres' + }); + +export const IsIn = ( + values: readonly unknown[], + validationOptions?: ValidationOptions +): PropertyDecorator => + _IsIn(values, { + ...validationOptions, + message: ' - El campo $property debe ser de uno de los siguientes tipos $constraint1' + }); + +export const IsDate = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsDate({ ...validationOptions, message: ' - El campo $property debe ser una fecha válida' }); + +export const IsObject = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsObject({ ...validationOptions, message: ' - El campo $property debe ser un objeto' }); + +export const IsStrongPassword = (validationOptions?: ValidationOptions): PropertyDecorator => + _IsStrongPassword({}, { ...validationOptions, message: 'Debes ingresar una contraseña segura' }); + +export const ArrayMaxSize = ( + size: number, + validationOptions?: ValidationOptions +): PropertyDecorator => + _ArrayMaxSize(size, { + ...validationOptions, + message: `El campo $property no acepta mas de ${size} elementos` + }); diff --git a/backend/manager/libs/custom-class-validator/src/index.ts b/backend/manager/libs/custom-class-validator/src/index.ts new file mode 100644 index 0000000..67ef0cc --- /dev/null +++ b/backend/manager/libs/custom-class-validator/src/index.ts @@ -0,0 +1,2 @@ +export * from './custom-class-validator.module'; +export * from './custom-class-validator.service'; diff --git a/backend/manager/libs/custom-class-validator/tsconfig.lib.json b/backend/manager/libs/custom-class-validator/tsconfig.lib.json new file mode 100644 index 0000000..2d3c1be --- /dev/null +++ b/backend/manager/libs/custom-class-validator/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "../../dist/libs/custom-class-validator" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} From 74fbe64b0a7000523aa8b991924bcb24407ac259 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 08:39:40 -0500 Subject: [PATCH 06/52] =?UTF-8?q?=E2=9C=A8=20feat(dto):=20add=20basic=20DT?= =?UTF-8?q?Os=20for=20patient,=20provider,=20status,=20and=20status=20hist?= =?UTF-8?q?ory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/patients/DTO/create-patient.dto.ts | 18 ++++++++++++++++++ .../src/patients/DTO/update-patient.dto.ts | 4 ++++ .../src/providers/DTO/create-provider.dto.ts | 9 +++++++++ .../src/providers/DTO/update-provider.dto.ts | 4 ++++ .../DTO/create-status-history.dto.ts | 12 ++++++++++++ .../DTO/update-status-history.dto.ts | 4 ++++ .../src/statuses/DTO/create-status.dto.ts | 13 +++++++++++++ .../src/statuses/DTO/update-status.dto.ts | 4 ++++ 8 files changed, 68 insertions(+) create mode 100644 backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts create mode 100644 backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts create mode 100644 backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts create mode 100644 backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts create mode 100644 backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts create mode 100644 backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts create mode 100644 backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts create mode 100644 backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts diff --git a/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts b/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts new file mode 100644 index 0000000..18e922a --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts @@ -0,0 +1,18 @@ +import { IsEmail, IsString, IsUUID } from "@app/custom-class-validator/custom-class-validator"; + +export class CreatePatientDto { + @IsString() + full_name: string; + + @IsEmail() + email: string; + + @IsString() + phone: string; + + @IsUUID() + provider_id: string; + + @IsUUID() + status_id: string; +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts b/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts new file mode 100644 index 0000000..70a3e1e --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreatePatientDto } from './create-patient.dto'; + +export class UpdatePatientDto extends PartialType(CreatePatientDto) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts new file mode 100644 index 0000000..73c9680 --- /dev/null +++ b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts @@ -0,0 +1,9 @@ +import { IsString } from "@app/custom-class-validator/custom-class-validator"; + +export class CreateProviderDto { + @IsString() + full_name: string; + + @IsString() + specialty: string; +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts b/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts new file mode 100644 index 0000000..6cff519 --- /dev/null +++ b/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateProviderDto } from './create-provider.dto'; + +export class UpdateProviderDto extends PartialType(CreateProviderDto) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts b/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts new file mode 100644 index 0000000..823e398 --- /dev/null +++ b/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts @@ -0,0 +1,12 @@ +import { IsDateString, IsUUID } from "@app/custom-class-validator/custom-class-validator"; + +export class CreateStatusHistoryDto { + @IsUUID() + patient_id: string; + + @IsUUID() + status_id: string; + + @IsDateString() + changed_at: string; +} diff --git a/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts b/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts new file mode 100644 index 0000000..a872a8c --- /dev/null +++ b/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateStatusHistoryDto } from './create-status-history.dto'; + +export class UpdateStatusHistoryDto extends PartialType(CreateStatusHistoryDto) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts b/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts new file mode 100644 index 0000000..b3f3cf5 --- /dev/null +++ b/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts @@ -0,0 +1,13 @@ +import { IsInt, IsOptional, IsString, IsUUID } from "@app/custom-class-validator/custom-class-validator"; + +export class CreateStatusDto { + @IsString() + name: string; + + @IsUUID() + @IsOptional() + parent_id?: string; + + @IsInt() + order: number; +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts b/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts new file mode 100644 index 0000000..793fbb1 --- /dev/null +++ b/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts @@ -0,0 +1,4 @@ +import { PartialType } from '@nestjs/mapped-types'; +import { CreateStatusDto } from './create-status.dto'; + +export class UpdateStatusDto extends PartialType(CreateStatusDto) {} \ No newline at end of file From c16ce65c12fd76c8121696f067902c7225152ef2 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 13:15:39 -0500 Subject: [PATCH 07/52] =?UTF-8?q?=E2=9C=A8=20feat(providers):=20implement?= =?UTF-8?q?=20Providers=20module,=20controller,=20and=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/manager-api-gateway.module.ts | 3 +- .../providers/providers.controller.spec.ts | 18 ++++++ .../src/providers/providers.controller.ts | 39 ++++++++++++ .../src/providers/providers.module.ts | 14 +++++ .../src/providers/providers.service.spec.ts | 18 ++++++ .../src/providers/providers.service.ts | 61 +++++++++++++++++++ .../src/shared-client/shared-client.module.ts | 2 +- backend/manager/apps/providers/config/envs.ts | 19 ++++++ backend/manager/apps/providers/src/main.ts | 17 +++++- .../providers/src/providers.controller.ts | 30 +++++++-- .../apps/providers/src/providers.service.ts | 20 +++++- 11 files changed, 231 insertions(+), 10 deletions(-) create mode 100644 backend/manager/apps/manager-api-gateway/src/providers/providers.controller.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/providers/providers.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/providers/providers.service.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts create mode 100644 backend/manager/apps/providers/config/envs.ts diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts index 6bd06ac..5a9b492 100644 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -1,9 +1,10 @@ import { Module } from '@nestjs/common'; import { PatientsModule } from './patients/patients.module'; import { LoggerModule } from '@app/logger/logger.module'; +import { ProvidersModule } from './providers/providers.module'; @Module({ - imports: [PatientsModule, LoggerModule], + imports: [PatientsModule, LoggerModule, ProvidersModule], controllers: [], providers: [], }) diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.spec.ts new file mode 100644 index 0000000..9b6576b --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ProvidersController } from './providers.controller'; + +describe('ProvidersController', () => { + let controller: ProvidersController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [ProvidersController], + }).compile(); + + controller = module.get(ProvidersController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts new file mode 100644 index 0000000..f87b2c1 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts @@ -0,0 +1,39 @@ +import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; +import { ProvidersService } from './providers.service'; +import { Observable } from 'rxjs'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; + +@Controller('providers') +export class ProvidersController { + constructor(private readonly providersService: ProvidersService) {} + + @Get() + findAll(): Observable { + return this.providersService.findAll(); + } + + @Get(':id') + findOne(@Param('id') id: string): Observable { + return this.providersService.findOne(id); + } + + @Post() + create(@Body() createProviderDto: CreateProviderDto) { + return this.providersService.create(createProviderDto); + } + + @Put(':id') + update( + @Param('id') id: string, + @Body() updateProviderDto: UpdateProviderDto, + ): Observable { + return this.providersService.update(id, updateProviderDto); + } + + @Delete(':id') + remove(@Param('id') id: string): Observable<{ message: string }> { + return this.providersService.remove(id); + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.module.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.module.ts new file mode 100644 index 0000000..4643e5a --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { ProvidersController } from './providers.controller'; +import { ProvidersService } from './providers.service'; +import { SharedClientModule } from '../shared-client/shared-client.module'; +import { PROVIDERS_QUEUE_NAME, PROVIDERS_SERVICE_NAME } from '@app/contracts/providers/providers.constants'; + +@Module({ + imports: [ + SharedClientModule.register(PROVIDERS_SERVICE_NAME, PROVIDERS_QUEUE_NAME), + ], + controllers: [ProvidersController], + providers: [ProvidersService] +}) +export class ProvidersModule {} diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.spec.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.spec.ts new file mode 100644 index 0000000..2a5f755 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ProvidersService } from './providers.service'; + +describe('ProvidersService', () => { + let service: ProvidersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProvidersService], + }).compile(); + + service = module.get(ProvidersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts new file mode 100644 index 0000000..b1ff661 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts @@ -0,0 +1,61 @@ +import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; +import { PROVIDERS_SERVICE_NAME } from '@app/contracts/providers/providers.constants'; +import { Inject, Injectable, NotFoundException } from '@nestjs/common'; +import { ClientProxy } from '@nestjs/microservices'; +import { map, Observable } from 'rxjs'; + +@Injectable() +export class ProvidersService { + constructor(@Inject(PROVIDERS_SERVICE_NAME) private readonly client: ClientProxy) {} + + findAll(): Observable { + return this.client.send(PROVIDERS_PATTERNS.FIND_ALL, {}).pipe( + map((providers) => { + if (!providers) { + throw new NotFoundException('No se encontraron proveedores'); + } + return providers; + }), + ); + } + + findOne(id: string): Observable { + return this.client.send(PROVIDERS_PATTERNS.FIND_ONE, { id }).pipe( + map((provider) => { + if (!provider) { + throw new NotFoundException(`Proveedor con id ${id} no encontrado`); + } + return provider; + }), + ); + } + + create(createProviderDto: any): Observable { + return this.client.send("providerscreate", createProviderDto); + } + + update(id: string, updateProviderDto: any): Observable { + return this.client + .send(PROVIDERS_PATTERNS.UPDATE, { id, ...updateProviderDto }) + .pipe( + map((updated) => { + if (!updated) { + throw new NotFoundException(`Proveedor con id ${id} no encontrado`); + } + return updated; + }), + ); + } + + remove(id: string): Observable<{ message: string }> { + return this.client.send(PROVIDERS_PATTERNS.REMOVE, { id }).pipe( + map((deleted) => { + if (!deleted) { + throw new NotFoundException(`Proveedor con id ${id} no encontrado`); + } + return { message: 'Proveedor eliminado correctamente' }; + }), + ); + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts b/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts index 979e25f..a0f9b4b 100644 --- a/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/shared-client/shared-client.module.ts @@ -15,7 +15,7 @@ export class SharedClientModule { options: { urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], queue, - queueOptions: { durable: false }, + queueOptions: { durable: true }, }, }, ]), diff --git a/backend/manager/apps/providers/config/envs.ts b/backend/manager/apps/providers/config/envs.ts new file mode 100644 index 0000000..00beea4 --- /dev/null +++ b/backend/manager/apps/providers/config/envs.ts @@ -0,0 +1,19 @@ +import { PROVIDERS_NAMESPACE } from '@app/contracts/providers/providers.constants'; +import { config } from 'dotenv'; +import { resolve } from 'path'; +import { number, object, string } from 'yup'; + +config({ + path: resolve(process.cwd(), `apps/${PROVIDERS_NAMESPACE}/.env`), +}); + +const envVarsSchema = object({ + NODE_ENV: string().oneOf(['dev', 'prod', 'test']).default('dev'), + HOST: string().default('0.0.0.0'), + PORT: number().default(3000), + RMQ_USER: string().default('guest'), + RMQ_PASSWORD: string().default('guest'), + RABBITMQ_URL: string().default('localhost:5672'), +}).noUnknown(); + +export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/providers/src/main.ts b/backend/manager/apps/providers/src/main.ts index 7866130..09fce56 100644 --- a/backend/manager/apps/providers/src/main.ts +++ b/backend/manager/apps/providers/src/main.ts @@ -1,8 +1,21 @@ import { NestFactory } from '@nestjs/core'; import { ProvidersModule } from './providers.module'; +import { MicroserviceOptions, Transport } from '@nestjs/microservices'; +import { envs } from '../config/envs'; +import { PROVIDERS_QUEUE_NAME } from '@app/contracts/providers/providers.constants'; async function bootstrap() { - const app = await NestFactory.create(ProvidersModule); - await app.listen(process.env.port ?? 3000); + + const app = await NestFactory.createMicroservice(ProvidersModule, { + transport: Transport.RMQ, + options: { + urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], + queue: PROVIDERS_QUEUE_NAME, + queueOptions: { + durable: true, + } + }, + }); + await app.listen(); } bootstrap(); diff --git a/backend/manager/apps/providers/src/providers.controller.ts b/backend/manager/apps/providers/src/providers.controller.ts index 78f9537..7e2046d 100644 --- a/backend/manager/apps/providers/src/providers.controller.ts +++ b/backend/manager/apps/providers/src/providers.controller.ts @@ -1,12 +1,34 @@ -import { Controller, Get } from '@nestjs/common'; +import { Controller } from '@nestjs/common'; import { ProvidersService } from './providers.service'; +import { MessagePattern } from '@nestjs/microservices'; +import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; @Controller() export class ProvidersController { constructor(private readonly providersService: ProvidersService) {} - @Get() - getHello(): string { - return this.providersService.getHello(); + @MessagePattern(PROVIDERS_PATTERNS.FIND_ALL) + findAll() { + return this.providersService.findAll(); + } + + @MessagePattern(PROVIDERS_PATTERNS.FIND_ONE) + findOne(data: { id: string }) { + return this.providersService.findOne(data.id); + } + + @MessagePattern(PROVIDERS_PATTERNS.CREATE) + create(data: any) { + return this.providersService.create(data); + } + + @MessagePattern(PROVIDERS_PATTERNS.UPDATE) + update(data: { id: string; updateProviderDto: any }) { + return this.providersService.update(data.id, data.updateProviderDto); + } + + @MessagePattern(PROVIDERS_PATTERNS.REMOVE) + remove(data: { id: string }) { + return this.providersService.remove(data.id); } } diff --git a/backend/manager/apps/providers/src/providers.service.ts b/backend/manager/apps/providers/src/providers.service.ts index 5a2da0a..ab8d911 100644 --- a/backend/manager/apps/providers/src/providers.service.ts +++ b/backend/manager/apps/providers/src/providers.service.ts @@ -2,7 +2,23 @@ import { Injectable } from '@nestjs/common'; @Injectable() export class ProvidersService { - getHello(): string { - return 'Hello World!'; + findAll() { + return []; + } + + findOne(id: string) { + return { id }; + } + + create(data: any) { + return { id: 'new-id', ...data }; + } + + update(id: string, data: any) { + return { id, ...data }; + } + + remove(id: string) { + return true; } } From 94107a1f18e5d093dd52797e4f77012b42887ee4 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 15:19:15 -0500 Subject: [PATCH 08/52] =?UTF-8?q?=E2=9C=A8=20feat(providers):=20refactor?= =?UTF-8?q?=20Providers=20module=20and=20add=20new=20DTOs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/providers/providers.controller.ts | 7 ++-- .../src/providers/providers.service.ts | 15 +++++--- backend/manager/apps/patients/src/main.ts | 2 +- backend/manager/apps/providers/config/envs.ts | 14 ++++--- backend/manager/apps/providers/src/main.ts | 4 +- .../providers/src/providers-app.module.ts | 24 ++++++++++++ .../providers/src/providers.controller.ts | 34 ----------------- .../apps/providers/src/providers.module.ts | 10 ----- .../apps/providers/src/providers.service.ts | 24 ------------ .../providers.controller.spec.ts | 12 +++--- .../src/providers/providers.controller.ts | 38 +++++++++++++++++++ .../src/providers/DTO/create-provider.dto.ts | 1 + .../src/providers/DTO/update-provider.dto.ts | 10 ++++- .../src/providers/entities/provider.entity.ts | 16 ++++++++ .../providers/patterns/providers.patterns.ts | 8 ++++ .../src/providers/providers.constants.ts | 3 ++ 16 files changed, 127 insertions(+), 95 deletions(-) create mode 100644 backend/manager/apps/providers/src/providers-app.module.ts delete mode 100644 backend/manager/apps/providers/src/providers.controller.ts delete mode 100644 backend/manager/apps/providers/src/providers.module.ts delete mode 100644 backend/manager/apps/providers/src/providers.service.ts rename backend/manager/apps/providers/src/{ => providers}/providers.controller.spec.ts (51%) create mode 100644 backend/manager/apps/providers/src/providers/providers.controller.ts create mode 100644 backend/manager/libs/contracts/src/providers/entities/provider.entity.ts create mode 100644 backend/manager/libs/contracts/src/providers/patterns/providers.patterns.ts create mode 100644 backend/manager/libs/contracts/src/providers/providers.constants.ts diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts index f87b2c1..67ad370 100644 --- a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts @@ -1,9 +1,10 @@ import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; import { ProvidersService } from './providers.service'; import { Observable } from 'rxjs'; -import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; @Controller('providers') export class ProvidersController { @@ -15,7 +16,7 @@ export class ProvidersController { } @Get(':id') - findOne(@Param('id') id: string): Observable { + findOne(@Param() id: IdDto): Observable { return this.providersService.findOne(id); } @@ -26,7 +27,7 @@ export class ProvidersController { @Put(':id') update( - @Param('id') id: string, + @Param() id: IdDto, @Body() updateProviderDto: UpdateProviderDto, ): Observable { return this.providersService.update(id, updateProviderDto); diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts index b1ff661..7ff1cb3 100644 --- a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts @@ -1,3 +1,6 @@ +import { IdDto } from '@app/contracts/global-dto/id.dto'; +import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; import { PROVIDERS_SERVICE_NAME } from '@app/contracts/providers/providers.constants'; @@ -20,8 +23,8 @@ export class ProvidersService { ); } - findOne(id: string): Observable { - return this.client.send(PROVIDERS_PATTERNS.FIND_ONE, { id }).pipe( + findOne(id: IdDto): Observable { + return this.client.send(PROVIDERS_PATTERNS.FIND_ONE, id).pipe( map((provider) => { if (!provider) { throw new NotFoundException(`Proveedor con id ${id} no encontrado`); @@ -31,13 +34,13 @@ export class ProvidersService { ); } - create(createProviderDto: any): Observable { - return this.client.send("providerscreate", createProviderDto); + create(createProviderDto: CreateProviderDto): Observable { + return this.client.send(PROVIDERS_PATTERNS.CREATE, createProviderDto); } - update(id: string, updateProviderDto: any): Observable { + update(id: IdDto, updateProviderDto: UpdateProviderDto): Observable { return this.client - .send(PROVIDERS_PATTERNS.UPDATE, { id, ...updateProviderDto }) + .send(PROVIDERS_PATTERNS.UPDATE, { ...id, ...updateProviderDto }) .pipe( map((updated) => { if (!updated) { diff --git a/backend/manager/apps/patients/src/main.ts b/backend/manager/apps/patients/src/main.ts index 5d8451b..81136be 100644 --- a/backend/manager/apps/patients/src/main.ts +++ b/backend/manager/apps/patients/src/main.ts @@ -10,7 +10,7 @@ async function bootstrap() { urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], queue: 'patients_queue', queueOptions: { - durable: false, + durable: true, } }, }); diff --git a/backend/manager/apps/providers/config/envs.ts b/backend/manager/apps/providers/config/envs.ts index 00beea4..0055051 100644 --- a/backend/manager/apps/providers/config/envs.ts +++ b/backend/manager/apps/providers/config/envs.ts @@ -8,12 +8,14 @@ config({ }); const envVarsSchema = object({ - NODE_ENV: string().oneOf(['dev', 'prod', 'test']).default('dev'), - HOST: string().default('0.0.0.0'), - PORT: number().default(3000), - RMQ_USER: string().default('guest'), - RMQ_PASSWORD: string().default('guest'), - RABBITMQ_URL: string().default('localhost:5672'), + RMQ_USER: string().required(), + RMQ_PASSWORD: string().required(), + RABBITMQ_URL: string().required(), + DB_HOST: string().required(), + DB_PORT: number().required(), + DB_USERNAME: string().required(), + DB_PASSWORD: string().required(), + DB_DATABASE: string().required(), }).noUnknown(); export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/providers/src/main.ts b/backend/manager/apps/providers/src/main.ts index 09fce56..ee5bf13 100644 --- a/backend/manager/apps/providers/src/main.ts +++ b/backend/manager/apps/providers/src/main.ts @@ -1,12 +1,12 @@ import { NestFactory } from '@nestjs/core'; -import { ProvidersModule } from './providers.module'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { envs } from '../config/envs'; import { PROVIDERS_QUEUE_NAME } from '@app/contracts/providers/providers.constants'; +import { ProvidersAppModule } from './providers-app.module'; async function bootstrap() { - const app = await NestFactory.createMicroservice(ProvidersModule, { + const app = await NestFactory.createMicroservice(ProvidersAppModule, { transport: Transport.RMQ, options: { urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], diff --git a/backend/manager/apps/providers/src/providers-app.module.ts b/backend/manager/apps/providers/src/providers-app.module.ts new file mode 100644 index 0000000..dccfc37 --- /dev/null +++ b/backend/manager/apps/providers/src/providers-app.module.ts @@ -0,0 +1,24 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { envs } from '../config/envs'; +import { ProvidersModule } from './providers/providers.module'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; + +@Module({ + imports: [ + TypeOrmModule.forRoot({ + type: 'postgres', + host: envs.DB_HOST, + port: envs.DB_PORT, + username: envs.DB_USERNAME, + password: envs.DB_PASSWORD, + database: envs.DB_DATABASE, + entities: [Provider], + synchronize: true, + }), + ProvidersModule + ], + controllers: [], + providers: [], +}) +export class ProvidersAppModule {} diff --git a/backend/manager/apps/providers/src/providers.controller.ts b/backend/manager/apps/providers/src/providers.controller.ts deleted file mode 100644 index 7e2046d..0000000 --- a/backend/manager/apps/providers/src/providers.controller.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Controller } from '@nestjs/common'; -import { ProvidersService } from './providers.service'; -import { MessagePattern } from '@nestjs/microservices'; -import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; - -@Controller() -export class ProvidersController { - constructor(private readonly providersService: ProvidersService) {} - - @MessagePattern(PROVIDERS_PATTERNS.FIND_ALL) - findAll() { - return this.providersService.findAll(); - } - - @MessagePattern(PROVIDERS_PATTERNS.FIND_ONE) - findOne(data: { id: string }) { - return this.providersService.findOne(data.id); - } - - @MessagePattern(PROVIDERS_PATTERNS.CREATE) - create(data: any) { - return this.providersService.create(data); - } - - @MessagePattern(PROVIDERS_PATTERNS.UPDATE) - update(data: { id: string; updateProviderDto: any }) { - return this.providersService.update(data.id, data.updateProviderDto); - } - - @MessagePattern(PROVIDERS_PATTERNS.REMOVE) - remove(data: { id: string }) { - return this.providersService.remove(data.id); - } -} diff --git a/backend/manager/apps/providers/src/providers.module.ts b/backend/manager/apps/providers/src/providers.module.ts deleted file mode 100644 index 32d7bf2..0000000 --- a/backend/manager/apps/providers/src/providers.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ProvidersController } from './providers.controller'; -import { ProvidersService } from './providers.service'; - -@Module({ - imports: [], - controllers: [ProvidersController], - providers: [ProvidersService], -}) -export class ProvidersModule {} diff --git a/backend/manager/apps/providers/src/providers.service.ts b/backend/manager/apps/providers/src/providers.service.ts deleted file mode 100644 index ab8d911..0000000 --- a/backend/manager/apps/providers/src/providers.service.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class ProvidersService { - findAll() { - return []; - } - - findOne(id: string) { - return { id }; - } - - create(data: any) { - return { id: 'new-id', ...data }; - } - - update(id: string, data: any) { - return { id, ...data }; - } - - remove(id: string) { - return true; - } -} diff --git a/backend/manager/apps/providers/src/providers.controller.spec.ts b/backend/manager/apps/providers/src/providers/providers.controller.spec.ts similarity index 51% rename from backend/manager/apps/providers/src/providers.controller.spec.ts rename to backend/manager/apps/providers/src/providers/providers.controller.spec.ts index 1087832..29e5178 100644 --- a/backend/manager/apps/providers/src/providers.controller.spec.ts +++ b/backend/manager/apps/providers/src/providers/providers.controller.spec.ts @@ -3,20 +3,18 @@ import { ProvidersController } from './providers.controller'; import { ProvidersService } from './providers.service'; describe('ProvidersController', () => { - let providersController: ProvidersController; + let controller: ProvidersController; beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ + const module: TestingModule = await Test.createTestingModule({ controllers: [ProvidersController], providers: [ProvidersService], }).compile(); - providersController = app.get(ProvidersController); + controller = module.get(ProvidersController); }); - describe('root', () => { - it('should return "Hello World!"', () => { - expect(providersController.getHello()).toBe('Hello World!'); - }); + it('should be defined', () => { + expect(controller).toBeDefined(); }); }); diff --git a/backend/manager/apps/providers/src/providers/providers.controller.ts b/backend/manager/apps/providers/src/providers/providers.controller.ts new file mode 100644 index 0000000..52d0c84 --- /dev/null +++ b/backend/manager/apps/providers/src/providers/providers.controller.ts @@ -0,0 +1,38 @@ +import { Controller } from '@nestjs/common'; +import { MessagePattern, Payload } from '@nestjs/microservices'; +import { ProvidersService } from './providers.service'; +import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { UpdateProviderWithIdDto } from '@app/contracts/providers/DTO/update-provider.dto'; +import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; + +@Controller() +export class ProvidersController { + constructor(private readonly providersService: ProvidersService) {} + + @MessagePattern(PROVIDERS_PATTERNS.CREATE) + create(@Payload() createProviderDto: CreateProviderDto) { + return this.providersService.create(createProviderDto); + } + + @MessagePattern(PROVIDERS_PATTERNS.FIND_ALL) + findAll() { + return this.providersService.findAll(); + } + + @MessagePattern(PROVIDERS_PATTERNS.FIND_ONE) + findOne(@Payload() { id }: IdDto) { + return this.providersService.findOne(id); + } + + @MessagePattern(PROVIDERS_PATTERNS.UPDATE) + update(@Payload() updateProviderDto: UpdateProviderWithIdDto) { + const { id, ...updateData } = updateProviderDto; + return this.providersService.update(id, updateData); + } + + @MessagePattern(PROVIDERS_PATTERNS.REMOVE) + remove(@Payload() id: string) { + return this.providersService.remove(id); + } +} diff --git a/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts index 73c9680..baac183 100644 --- a/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts +++ b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts @@ -1,6 +1,7 @@ import { IsString } from "@app/custom-class-validator/custom-class-validator"; export class CreateProviderDto { + @IsString() full_name: string; diff --git a/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts b/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts index 6cff519..c7eaf35 100644 --- a/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts +++ b/backend/manager/libs/contracts/src/providers/DTO/update-provider.dto.ts @@ -1,4 +1,10 @@ -import { PartialType } from '@nestjs/mapped-types'; +import { IntersectionType, PartialType } from '@nestjs/mapped-types'; import { CreateProviderDto } from './create-provider.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; -export class UpdateProviderDto extends PartialType(CreateProviderDto) {} \ No newline at end of file +export class UpdateProviderDto extends PartialType(CreateProviderDto) {} + +export class UpdateProviderWithIdDto extends IntersectionType( + IdDto, + UpdateProviderDto, +) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/providers/entities/provider.entity.ts b/backend/manager/libs/contracts/src/providers/entities/provider.entity.ts new file mode 100644 index 0000000..592664a --- /dev/null +++ b/backend/manager/libs/contracts/src/providers/entities/provider.entity.ts @@ -0,0 +1,16 @@ +import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn } from 'typeorm'; + +@Entity('providers') +export class Provider { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ type: 'varchar', length: 255 }) + full_name: string; + + @Column({ type: 'varchar', length: 255 }) + specialty: string; + + @CreateDateColumn({ type: 'timestamp with time zone' }) + created_at: Date; +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/providers/patterns/providers.patterns.ts b/backend/manager/libs/contracts/src/providers/patterns/providers.patterns.ts new file mode 100644 index 0000000..cb6006b --- /dev/null +++ b/backend/manager/libs/contracts/src/providers/patterns/providers.patterns.ts @@ -0,0 +1,8 @@ + +export const PROVIDERS_PATTERNS = { + FIND_ALL: 'providers.findAll', + FIND_ONE: 'providers.findOne', + CREATE: 'providers.create', + UPDATE: 'providers.update', + REMOVE: 'providers.remove' +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/providers/providers.constants.ts b/backend/manager/libs/contracts/src/providers/providers.constants.ts new file mode 100644 index 0000000..156f9bb --- /dev/null +++ b/backend/manager/libs/contracts/src/providers/providers.constants.ts @@ -0,0 +1,3 @@ +export const PROVIDERS_SERVICE_NAME = Symbol('PROVIDERS_SERVICE'); +export const PROVIDERS_QUEUE_NAME = 'providers_queue'; +export const PROVIDERS_NAMESPACE = 'providers'; \ No newline at end of file From daa3350ff432c822f776fe12849cf86753e69b72 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 15:20:15 -0500 Subject: [PATCH 09/52] feat: add new start scripts and update dependencies - Added scripts for starting individual services: manager-api-gateway, patients, and providers. - Introduced a script to start all services concurrently. - Updated package.json to include new dependencies: @nestjs/mapped-types, @nestjs/typeorm, class-transformer, class-validator, pg, and typeorm. - Added concurrently as a dev dependency for running multiple scripts. - Updated tsconfig.json to include path mappings for custom-class-validator. --- backend/manager/nest-cli.json | 9 + backend/manager/package-lock.json | 889 ++++++++++++++++++++++++++---- backend/manager/package.json | 12 + backend/manager/tsconfig.json | 9 + 4 files changed, 826 insertions(+), 93 deletions(-) diff --git a/backend/manager/nest-cli.json b/backend/manager/nest-cli.json index 18b7219..c637ea2 100644 --- a/backend/manager/nest-cli.json +++ b/backend/manager/nest-cli.json @@ -28,6 +28,15 @@ "tsConfigPath": "libs/contracts/tsconfig.lib.json" } }, + "custom-class-validator": { + "type": "library", + "root": "libs/custom-class-validator", + "entryFile": "index", + "sourceRoot": "libs/custom-class-validator/src", + "compilerOptions": { + "tsConfigPath": "libs/custom-class-validator/tsconfig.lib.json" + } + }, "logger": { "type": "library", "root": "libs/logger", diff --git a/backend/manager/package-lock.json b/backend/manager/package-lock.json index cd89b07..ee61443 100644 --- a/backend/manager/package-lock.json +++ b/backend/manager/package-lock.json @@ -12,13 +12,19 @@ "@nestjs/common": "^11.0.1", "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", + "@nestjs/mapped-types": "^2.1.0", "@nestjs/microservices": "^11.1.7", "@nestjs/platform-express": "^11.0.1", + "@nestjs/typeorm": "^11.0.0", "amqp-connection-manager": "^5.0.0", "amqplib": "^0.10.9", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", "dotenv": "^17.2.3", + "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", + "typeorm": "^0.3.27", "yup": "^1.7.1" }, "devDependencies": { @@ -31,6 +37,7 @@ "@types/jest": "^30.0.0", "@types/node": "^22.10.7", "@types/supertest": "^6.0.2", + "concurrently": "^9.2.1", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.2", @@ -732,7 +739,7 @@ "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" @@ -745,7 +752,7 @@ "version": "0.3.9", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", @@ -1372,7 +1379,6 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -1390,7 +1396,6 @@ "version": "6.2.3", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -1403,14 +1408,12 @@ "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, "license": "MIT" }, "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -1428,7 +1431,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -2014,7 +2016,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -2035,7 +2037,7 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -2401,6 +2403,26 @@ } } }, + "node_modules/@nestjs/mapped-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", + "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/microservices": { "version": "11.1.7", "resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-11.1.7.tgz", @@ -2606,6 +2628,19 @@ } } }, + "node_modules/@nestjs/typeorm": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-11.0.0.tgz", + "integrity": "sha512-SOeUQl70Lb2OfhGkvnh4KXWlsd+zA08RuuQgT7kKbzivngxzSo1Oc7Usu5VxCxACQC9wc2l9esOHILSJeK7rJA==", + "license": "MIT", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "@nestjs/core": "^10.0.0 || ^11.0.0", + "reflect-metadata": "^0.1.13 || ^0.2.0", + "rxjs": "^7.2.0", + "typeorm": "^0.3.0" + } + }, "node_modules/@noble/hashes": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", @@ -2687,7 +2722,6 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, "license": "MIT", "optional": true, "engines": { @@ -2734,6 +2768,12 @@ "@sinonjs/commons": "^3.0.1" } }, + "node_modules/@sqltools/formatter": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@sqltools/formatter/-/formatter-1.2.5.tgz", + "integrity": "sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==", + "license": "MIT" + }, "node_modules/@tokenizer/inflate": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", @@ -2762,28 +2802,28 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tsconfig/node16": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/@tybys/wasm-util": { @@ -2994,7 +3034,7 @@ "version": "22.18.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz", "integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -3078,6 +3118,12 @@ "@types/superagent": "^8.1.0" } }, + "node_modules/@types/validator": { + "version": "13.15.3", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.3.tgz", + "integrity": "sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==", + "license": "MIT" + }, "node_modules/@types/yargs": { "version": "17.0.33", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", @@ -3821,7 +3867,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, + "devOptional": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -3857,7 +3903,7 @@ "version": "8.3.4", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -3994,7 +4040,6 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -4007,7 +4052,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -4056,6 +4100,15 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/app-root-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz", + "integrity": "sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, "node_modules/append-field": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz", @@ -4066,7 +4119,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/argparse": { @@ -4097,6 +4150,21 @@ "dev": true, "license": "MIT" }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-jest": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", @@ -4200,14 +4268,12 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, "license": "MIT" }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, "funding": [ { "type": "github", @@ -4416,6 +4482,24 @@ "node": ">= 0.8" } }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -4569,6 +4653,23 @@ "dev": true, "license": "MIT" }, + "node_modules/class-transformer": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz", + "integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==", + "license": "MIT" + }, + "node_modules/class-validator": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.2.tgz", + "integrity": "sha512-3kMVRF2io8N8pY1IFIXlho9r8IPUUIfHe2hYVtiebvAzU2XeQFXTv+XI4WX+TnXmtwXMDcjngcpkiPM0O9PvLw==", + "license": "MIT", + "dependencies": { + "@types/validator": "^13.11.8", + "libphonenumber-js": "^1.11.1", + "validator": "^13.9.0" + } + }, "node_modules/cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -4625,7 +4726,6 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -4640,7 +4740,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4650,7 +4749,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -4663,7 +4761,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -4709,7 +4806,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -4722,7 +4818,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, "license": "MIT" }, "node_modules/combined-stream": { @@ -4795,6 +4890,47 @@ "typedarray": "^0.0.6" } }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/consola": { "version": "3.4.2", "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", @@ -4908,14 +5044,13 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -4926,6 +5061,12 @@ "node": ">= 8" } }, + "node_modules/dayjs": { + "version": "1.11.18", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz", + "integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==", + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -4947,7 +5088,6 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", - "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -4988,6 +5128,23 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5032,7 +5189,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -5095,7 +5252,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true, "license": "MIT" }, "node_modules/ee-first": { @@ -5128,7 +5284,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, "license": "MIT" }, "node_modules/encodeurl": { @@ -5221,7 +5376,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -5787,11 +5941,25 @@ "dev": true, "license": "ISC" }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -5975,7 +6143,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -6182,6 +6349,18 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -6198,7 +6377,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -6391,6 +6569,18 @@ "dev": true, "license": "MIT" }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6405,7 +6595,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6473,6 +6662,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -6486,11 +6690,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { @@ -7492,6 +7701,12 @@ "node": ">= 0.8.0" } }, + "node_modules/libphonenumber-js": { + "version": "1.12.24", + "resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.24.tgz", + "integrity": "sha512-l5IlyL9AONj4voSd7q9xkuQOL4u8Ty44puTic7J88CmdXkxfGsRfoVLXHCxppwehgpb/Chdb80FFehHqjN3ItQ==", + "license": "MIT" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -7625,7 +7840,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, + "devOptional": true, "license": "ISC" }, "node_modules/makeerror": { @@ -7805,7 +8020,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -8162,7 +8376,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/parent-module": { @@ -8230,7 +8443,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -8283,6 +8495,95 @@ "node": ">=8" } }, + "node_modules/pg": { + "version": "8.16.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", + "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.1", + "pg-pool": "^3.10.1", + "pg-protocol": "^1.10.3", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.7" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", + "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", + "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", + "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", + "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -8392,40 +8693,88 @@ "node": ">=4" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" } }, - "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", - "dev": true, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "node": ">=4" } }, - "node_modules/prettier-linter-helpers": { + "node_modules/postgres-bytea": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" }, "engines": { "node": ">=6.0.0" @@ -8632,7 +8981,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8873,17 +9221,53 @@ "node": ">= 18" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -8896,12 +9280,24 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -8978,7 +9374,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -9028,6 +9423,15 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -9035,6 +9439,22 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/sql-highlight": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sql-highlight/-/sql-highlight-6.1.0.tgz", + "integrity": "sha512-ed7OK4e9ywpE7pgRMkMQmZDPKSVdm0oX5IEtZiKnFucSF0zu6c80GZBe38UqHuVhTWJ9xsKgSMjCG2bml86KvA==", + "funding": [ + "https://github.com/scriptcoded/sql-highlight?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/scriptcoded" + } + ], + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -9125,7 +9545,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9141,7 +9560,6 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9156,7 +9574,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9166,7 +9583,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9179,7 +9595,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9189,7 +9604,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9202,7 +9616,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -9219,7 +9632,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9232,7 +9644,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9592,6 +10003,20 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -9752,7 +10177,7 @@ "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, + "devOptional": true, "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", @@ -9889,17 +10314,259 @@ "node": ">= 0.6" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", "license": "MIT" }, + "node_modules/typeorm": { + "version": "0.3.27", + "resolved": "https://registry.npmjs.org/typeorm/-/typeorm-0.3.27.tgz", + "integrity": "sha512-pNV1bn+1n8qEe8tUNsNdD8ejuPcMAg47u2lUGnbsajiNUr3p2Js1XLKQjBMH0yMRMDfdX8T+fIRejFmIwy9x4A==", + "license": "MIT", + "dependencies": { + "@sqltools/formatter": "^1.2.5", + "ansis": "^3.17.0", + "app-root-path": "^3.1.0", + "buffer": "^6.0.3", + "dayjs": "^1.11.13", + "debug": "^4.4.0", + "dedent": "^1.6.0", + "dotenv": "^16.4.7", + "glob": "^10.4.5", + "sha.js": "^2.4.12", + "sql-highlight": "^6.0.0", + "tslib": "^2.8.1", + "uuid": "^11.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "typeorm": "cli.js", + "typeorm-ts-node-commonjs": "cli-ts-node-commonjs.js", + "typeorm-ts-node-esm": "cli-ts-node-esm.js" + }, + "engines": { + "node": ">=16.13.0" + }, + "funding": { + "url": "https://opencollective.com/typeorm" + }, + "peerDependencies": { + "@google-cloud/spanner": "^5.18.0 || ^6.0.0 || ^7.0.0", + "@sap/hana-client": "^2.14.22", + "better-sqlite3": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0", + "ioredis": "^5.0.4", + "mongodb": "^5.8.0 || ^6.0.0", + "mssql": "^9.1.1 || ^10.0.1 || ^11.0.1", + "mysql2": "^2.2.5 || ^3.0.1", + "oracledb": "^6.3.0", + "pg": "^8.5.1", + "pg-native": "^3.0.0", + "pg-query-stream": "^4.0.0", + "redis": "^3.1.1 || ^4.0.0 || ^5.0.14", + "reflect-metadata": "^0.1.14 || ^0.2.0", + "sql.js": "^1.4.0", + "sqlite3": "^5.0.3", + "ts-node": "^10.7.0", + "typeorm-aurora-data-api-driver": "^2.0.0 || ^3.0.0" + }, + "peerDependenciesMeta": { + "@google-cloud/spanner": { + "optional": true + }, + "@sap/hana-client": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "mssql": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "pg-query-stream": { + "optional": true + }, + "redis": { + "optional": true + }, + "sql.js": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "ts-node": { + "optional": true + }, + "typeorm-aurora-data-api-driver": { + "optional": true + } + } + }, + "node_modules/typeorm/node_modules/ansis": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz", + "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==", + "license": "ISC", + "engines": { + "node": ">=14" + } + }, + "node_modules/typeorm/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typeorm/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/typeorm/node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/typeorm/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/typeorm/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/typeorm/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/typeorm/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -9975,7 +10642,7 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/universalify": { @@ -10089,11 +10756,24 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/v8-to-istanbul": { @@ -10111,6 +10791,15 @@ "node": ">=10.12.0" } }, + "node_modules/validator": { + "version": "13.15.15", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", + "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -10359,7 +11048,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -10371,6 +11059,27 @@ "node": ">= 8" } }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", @@ -10408,7 +11117,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -10426,7 +11134,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10436,7 +11143,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -10501,7 +11207,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -10518,7 +11223,6 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -10537,7 +11241,6 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -10547,7 +11250,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, + "devOptional": true, "license": "MIT", "engines": { "node": ">=6" diff --git a/backend/manager/package.json b/backend/manager/package.json index d37455d..a701a10 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -12,6 +12,10 @@ "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/apps/manager/main", + "start:gateway": "nest start manager-api-gateway --watch", + "start:patients": "nest start patients --watch", + "start:providers": "nest start providers --watch", + "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\"", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", @@ -23,13 +27,19 @@ "@nestjs/common": "^11.0.1", "@nestjs/config": "^4.0.2", "@nestjs/core": "^11.0.1", + "@nestjs/mapped-types": "^2.1.0", "@nestjs/microservices": "^11.1.7", "@nestjs/platform-express": "^11.0.1", + "@nestjs/typeorm": "^11.0.0", "amqp-connection-manager": "^5.0.0", "amqplib": "^0.10.9", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.2", "dotenv": "^17.2.3", + "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", + "typeorm": "^0.3.27", "yup": "^1.7.1" }, "devDependencies": { @@ -42,6 +52,7 @@ "@types/jest": "^30.0.0", "@types/node": "^22.10.7", "@types/supertest": "^6.0.2", + "concurrently": "^9.2.1", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-prettier": "^5.2.2", @@ -80,6 +91,7 @@ "moduleNameMapper": { "^@app/config(|/.*)$": "/libs/config/src/$1", "^@app/contracts(|/.*)$": "/libs/contracts/src/$1", + "^@app/custom-class-validator(|/.*)$": "/libs/custom-class-validator/src/$1", "^@app/logger(|/.*)$": "/libs/logger/src/$1" } } diff --git a/backend/manager/tsconfig.json b/backend/manager/tsconfig.json index 45a7490..5caea97 100644 --- a/backend/manager/tsconfig.json +++ b/backend/manager/tsconfig.json @@ -34,6 +34,15 @@ "@app/contracts/*": [ "libs/contracts/src/*" ], + "@app/custom-class-validator": [ + "libs/custom-class-validator/src" + ], + "@app/custom-class-validator/*": [ + "libs/custom-class-validator/src/*" + ], + "@app/logger/": [ + "libs/logger/src" + ], "@app/logger/*": [ "libs/logger/src/*" ] From 19a81541bbd04719251ef041db7678ef7faa1281 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 15:20:39 -0500 Subject: [PATCH 10/52] =?UTF-8?q?=E2=9C=A8=20feat(main):=20add=20global=20?= =?UTF-8?q?validation=20pipe=20with=20whitelist=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/apps/manager-api-gateway/src/main.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/manager/apps/manager-api-gateway/src/main.ts b/backend/manager/apps/manager-api-gateway/src/main.ts index 2e24553..583009c 100644 --- a/backend/manager/apps/manager-api-gateway/src/main.ts +++ b/backend/manager/apps/manager-api-gateway/src/main.ts @@ -1,12 +1,16 @@ import { NestFactory } from '@nestjs/core'; import { ManagerApiGatewayModule } from './manager-api-gateway.module'; import { envs } from './config/envs'; -import { LoggerService } from '@nestjs/common'; +import { LoggerService, ValidationPipe } from '@nestjs/common'; import { LOGGER_SERVICE_SYMBOL } from '@app/logger/constants/logger-symbol.constants'; async function bootstrap() { const app = await NestFactory.create(ManagerApiGatewayModule); + app.useGlobalPipes(new ValidationPipe({ + whitelist: true, + })); + const logger = app.get(LOGGER_SERVICE_SYMBOL); app.useLogger(logger); From b232f24a19642aa3d6bed76a7aca837c51586ffc Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 15:22:10 -0500 Subject: [PATCH 11/52] =?UTF-8?q?=F0=9F=97=91=EF=B8=8F=20chore(contracts):?= =?UTF-8?q?=20remove=20unused=20Contracts=20module=20and=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../libs/contracts/src/contracts.module.ts | 8 -------- .../contracts/src/contracts.service.spec.ts | 18 ------------------ .../libs/contracts/src/contracts.service.ts | 4 ---- .../manager-api-gateway/manager.namespace.ts | 1 - .../src/patients/patients.namespace.ts | 1 - 5 files changed, 32 deletions(-) delete mode 100644 backend/manager/libs/contracts/src/contracts.module.ts delete mode 100644 backend/manager/libs/contracts/src/contracts.service.spec.ts delete mode 100644 backend/manager/libs/contracts/src/contracts.service.ts delete mode 100644 backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts delete mode 100644 backend/manager/libs/contracts/src/patients/patients.namespace.ts diff --git a/backend/manager/libs/contracts/src/contracts.module.ts b/backend/manager/libs/contracts/src/contracts.module.ts deleted file mode 100644 index f25c9de..0000000 --- a/backend/manager/libs/contracts/src/contracts.module.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ContractsService } from './contracts.service'; - -@Module({ - providers: [ContractsService], - exports: [ContractsService], -}) -export class ContractsModule {} diff --git a/backend/manager/libs/contracts/src/contracts.service.spec.ts b/backend/manager/libs/contracts/src/contracts.service.spec.ts deleted file mode 100644 index 8950ec4..0000000 --- a/backend/manager/libs/contracts/src/contracts.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { ContractsService } from './contracts.service'; - -describe('ContractsService', () => { - let service: ContractsService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ContractsService], - }).compile(); - - service = module.get(ContractsService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/backend/manager/libs/contracts/src/contracts.service.ts b/backend/manager/libs/contracts/src/contracts.service.ts deleted file mode 100644 index cbed8ae..0000000 --- a/backend/manager/libs/contracts/src/contracts.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class ContractsService {} diff --git a/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts b/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts deleted file mode 100644 index a3d7d5f..0000000 --- a/backend/manager/libs/contracts/src/manager-api-gateway/manager.namespace.ts +++ /dev/null @@ -1 +0,0 @@ -export const MANAGER_NAMESPACE = 'manager-api-gateway'; \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/patients.namespace.ts b/backend/manager/libs/contracts/src/patients/patients.namespace.ts deleted file mode 100644 index b481877..0000000 --- a/backend/manager/libs/contracts/src/patients/patients.namespace.ts +++ /dev/null @@ -1 +0,0 @@ -export const PATIENTS_NAMESPACE = 'patients'; \ No newline at end of file From a53cba3c81095295198eef42b51b62de379f3c49 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 15:23:07 -0500 Subject: [PATCH 12/52] =?UTF-8?q?=E2=9C=A8=20feat(providers):=20implement?= =?UTF-8?q?=20Providers=20module,=20service,=20and=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/providers/providers.module.ts | 14 ++++++++ .../src/providers/providers.service.spec.ts | 18 ++++++++++ .../src/providers/providers.service.ts | 35 +++++++++++++++++++ .../libs/contracts/src/global-dto/id.dto.ts | 7 ++++ 4 files changed, 74 insertions(+) create mode 100644 backend/manager/apps/providers/src/providers/providers.module.ts create mode 100644 backend/manager/apps/providers/src/providers/providers.service.spec.ts create mode 100644 backend/manager/apps/providers/src/providers/providers.service.ts create mode 100644 backend/manager/libs/contracts/src/global-dto/id.dto.ts diff --git a/backend/manager/apps/providers/src/providers/providers.module.ts b/backend/manager/apps/providers/src/providers/providers.module.ts new file mode 100644 index 0000000..a4c48b8 --- /dev/null +++ b/backend/manager/apps/providers/src/providers/providers.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { ProvidersService } from './providers.service'; +import { ProvidersController } from './providers.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Provider]) + ], + controllers: [ProvidersController], + providers: [ProvidersService], +}) +export class ProvidersModule {} diff --git a/backend/manager/apps/providers/src/providers/providers.service.spec.ts b/backend/manager/apps/providers/src/providers/providers.service.spec.ts new file mode 100644 index 0000000..2a5f755 --- /dev/null +++ b/backend/manager/apps/providers/src/providers/providers.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { ProvidersService } from './providers.service'; + +describe('ProvidersService', () => { + let service: ProvidersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ProvidersService], + }).compile(); + + service = module.get(ProvidersService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/providers/src/providers/providers.service.ts b/backend/manager/apps/providers/src/providers/providers.service.ts new file mode 100644 index 0000000..5c45b80 --- /dev/null +++ b/backend/manager/apps/providers/src/providers/providers.service.ts @@ -0,0 +1,35 @@ +import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; + +@Injectable() +export class ProvidersService { + constructor( + @InjectRepository(Provider) + private providersRepository: Repository, + ) {} + + create(createProviderDto: CreateProviderDto) { + const provider = this.providersRepository.create(createProviderDto); + return this.providersRepository.save(provider); + } + + findAll() { + return this.providersRepository.find(); + } + + findOne(id: string) { + return this.providersRepository.findOne({ where: { id } }); + } + + update(id: string, updateProviderDto: UpdateProviderDto) { + return this.providersRepository.update(id, updateProviderDto); + } + + remove(id: string) { + return this.providersRepository.delete(id); + } +} diff --git a/backend/manager/libs/contracts/src/global-dto/id.dto.ts b/backend/manager/libs/contracts/src/global-dto/id.dto.ts new file mode 100644 index 0000000..493af22 --- /dev/null +++ b/backend/manager/libs/contracts/src/global-dto/id.dto.ts @@ -0,0 +1,7 @@ +import { IsUUID } from "@app/custom-class-validator/custom-class-validator"; + +export class IdDto { + + @IsUUID() + id: string; +} \ No newline at end of file From 0eba2446db9ba3a76cf7623e6b13bfa56e13a2c2 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 17:25:02 -0500 Subject: [PATCH 13/52] =?UTF-8?q?=E2=9C=A8=20feat(standard-response):=20ad?= =?UTF-8?q?d=20standard=20response=20library=20and=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/libs/standard-response/src/index.ts | 1 + .../libs/standard-response/src/standard-response.ts | 7 +++++++ backend/manager/libs/standard-response/tsconfig.lib.json | 9 +++++++++ backend/manager/nest-cli.json | 9 +++++++++ backend/manager/tsconfig.json | 6 ++++++ 5 files changed, 32 insertions(+) create mode 100644 backend/manager/libs/standard-response/src/index.ts create mode 100644 backend/manager/libs/standard-response/src/standard-response.ts create mode 100644 backend/manager/libs/standard-response/tsconfig.lib.json diff --git a/backend/manager/libs/standard-response/src/index.ts b/backend/manager/libs/standard-response/src/index.ts new file mode 100644 index 0000000..453ddee --- /dev/null +++ b/backend/manager/libs/standard-response/src/index.ts @@ -0,0 +1 @@ +export * from './standard-response'; diff --git a/backend/manager/libs/standard-response/src/standard-response.ts b/backend/manager/libs/standard-response/src/standard-response.ts new file mode 100644 index 0000000..cd6b5ac --- /dev/null +++ b/backend/manager/libs/standard-response/src/standard-response.ts @@ -0,0 +1,7 @@ +export function standardResponse( + message = '', + data: T | null = null, + success = true, +) { + return { message, success, data }; +} \ No newline at end of file diff --git a/backend/manager/libs/standard-response/tsconfig.lib.json b/backend/manager/libs/standard-response/tsconfig.lib.json new file mode 100644 index 0000000..de08e70 --- /dev/null +++ b/backend/manager/libs/standard-response/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "declaration": true, + "outDir": "../../dist/libs/standard-response" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] +} diff --git a/backend/manager/nest-cli.json b/backend/manager/nest-cli.json index c637ea2..c86d84e 100644 --- a/backend/manager/nest-cli.json +++ b/backend/manager/nest-cli.json @@ -73,6 +73,15 @@ "tsConfigPath": "apps/providers/tsconfig.app.json" } }, + "standard-response": { + "type": "library", + "root": "libs/standard-response", + "entryFile": "index", + "sourceRoot": "libs/standard-response/src", + "compilerOptions": { + "tsConfigPath": "libs/standard-response/tsconfig.lib.json" + } + }, "status-history": { "type": "application", "root": "apps/status-history", diff --git a/backend/manager/tsconfig.json b/backend/manager/tsconfig.json index 5caea97..e5d8e5e 100644 --- a/backend/manager/tsconfig.json +++ b/backend/manager/tsconfig.json @@ -45,6 +45,12 @@ ], "@app/logger/*": [ "libs/logger/src/*" + ], + "@app/standard-response": [ + "libs/standard-response/src" + ], + "@app/standard-response/*": [ + "libs/standard-response/src/*" ] } } From e853e8741920c763154c46cb7b7c9258f8df0ff3 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 17:27:22 -0500 Subject: [PATCH 14/52] =?UTF-8?q?=E2=9C=A8=20feat(statuses):=20implement?= =?UTF-8?q?=20CRUD=20operations=20and=20messaging=20patterns=20for=20statu?= =?UTF-8?q?ses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/statuses/statuses.controller.spec.ts | 18 +++ .../src/statuses/statuses.controller.ts | 103 ++++++++++++++++++ .../src/statuses/statuses.module.ts | 14 +++ .../src/statuses/statuses.service.spec.ts | 18 +++ .../src/statuses/statuses.service.ts | 34 ++++++ backend/manager/apps/statuses/src/main.ts | 18 ++- .../apps/statuses/src/statuses-app.module.ts | 24 ++++ .../apps/statuses/src/statuses.controller.ts | 12 -- .../apps/statuses/src/statuses.module.ts | 10 -- .../apps/statuses/src/statuses.service.ts | 8 -- .../statuses.controller.spec.ts | 12 +- .../src/statuses/statuses.controller.ts | 37 +++++++ .../statuses/src/statuses/statuses.dao.ts | 42 +++++++ .../statuses/src/statuses/statuses.module.ts | 15 +++ .../src/statuses/statuses.service.spec.ts | 18 +++ .../statuses/src/statuses/statuses.service.ts | 60 ++++++++++ .../src/statuses/DTO/update-status.dto.ts | 10 +- .../src/statuses/entities/status.entity.ts | 20 ++++ .../statuses/patterns/statuses.patterns.ts | 7 ++ .../src/statuses/statuses.constants.ts | 3 + backend/manager/package.json | 8 +- 21 files changed, 446 insertions(+), 45 deletions(-) create mode 100644 backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/statuses/statuses.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.ts create mode 100644 backend/manager/apps/statuses/src/statuses-app.module.ts delete mode 100644 backend/manager/apps/statuses/src/statuses.controller.ts delete mode 100644 backend/manager/apps/statuses/src/statuses.module.ts delete mode 100644 backend/manager/apps/statuses/src/statuses.service.ts rename backend/manager/apps/statuses/src/{ => statuses}/statuses.controller.spec.ts (51%) create mode 100644 backend/manager/apps/statuses/src/statuses/statuses.controller.ts create mode 100644 backend/manager/apps/statuses/src/statuses/statuses.dao.ts create mode 100644 backend/manager/apps/statuses/src/statuses/statuses.module.ts create mode 100644 backend/manager/apps/statuses/src/statuses/statuses.service.spec.ts create mode 100644 backend/manager/apps/statuses/src/statuses/statuses.service.ts create mode 100644 backend/manager/libs/contracts/src/statuses/entities/status.entity.ts create mode 100644 backend/manager/libs/contracts/src/statuses/patterns/statuses.patterns.ts create mode 100644 backend/manager/libs/contracts/src/statuses/statuses.constants.ts diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.spec.ts new file mode 100644 index 0000000..6e56fb1 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusesController } from './statuses.controller'; + +describe('StatusesController', () => { + let controller: StatusesController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StatusesController], + }).compile(); + + controller = module.get(StatusesController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts new file mode 100644 index 0000000..ac9ae40 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts @@ -0,0 +1,103 @@ +import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; +import { StatusesService } from './statuses.service'; +import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; +import { UpdateStatusDto } from '@app/contracts/statuses/DTO/update-status.dto'; +import { lastValueFrom } from 'rxjs'; +import { standardResponse } from '@app/standard-response'; + +@Controller('statuses') +export class StatusesController { + constructor(private readonly statusesService: StatusesService) {} + + @Post() + async create(@Body() createStatusDto: CreateStatusDto) { + try { + const result = await lastValueFrom( + this.statusesService.create(createStatusDto) + ); + + return standardResponse( + 'Se creó el estado correctamente', + result + ); + } catch (error) { + return standardResponse( + 'Falló la creación del estado', + null, + false + ); + } + } + + @Get() + async findAll() { + try { + const result = await lastValueFrom( + this.statusesService.findAll() + ); + return standardResponse( + 'Estados obtenidos correctamente', + result + ); + } catch (error) { + return standardResponse( + 'Falló la obtención de los estados', + null + ); + } + } + + @Get(':id') + async findOne(@Param('id') id: string) { + try { + const result = await lastValueFrom( + this.statusesService.findOne(id) + ); + return standardResponse( + 'Estado obtenido correctamente', + result + ); + } catch (error) { + return standardResponse( + 'Falló la obtención del estado', + null + ); + } + } + + @Put(':id') + async update(@Param('id') id: string, @Body() updateStatusDto: UpdateStatusDto) { + try { + const result = await lastValueFrom( + this.statusesService.update(id, updateStatusDto) + ); + return standardResponse( + 'Estado actualizado correctamente', + result + ); + } catch (error) { + return standardResponse( + 'Falló la actualización del estado', + null + ); + } + } + + @Delete(':id') + async remove(@Param('id') id: string) { + try { + const result = await lastValueFrom( + this.statusesService.remove(id) + ); + return standardResponse( + 'Estado eliminado correctamente', + result + ); + } catch (error) { + return standardResponse( + 'Falló la eliminación del estado', + null + ); + } + } +} diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.module.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.module.ts new file mode 100644 index 0000000..d03e9c3 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { StatusesController } from './statuses.controller'; +import { StatusesService } from './statuses.service'; +import { SharedClientModule } from '../shared-client/shared-client.module'; +import { STATUSES_QUEUE_NAME, STATUSES_SERVICE_NAME } from '@app/contracts/statuses/statuses.constants'; + +@Module({ + imports: [ + SharedClientModule.register(STATUSES_SERVICE_NAME, STATUSES_QUEUE_NAME), + ], + controllers: [StatusesController], + providers: [StatusesService], +}) +export class StatusesModule {} diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.spec.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.spec.ts new file mode 100644 index 0000000..4dfed28 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusesService } from './statuses.service'; + +describe('StatusesService', () => { + let service: StatusesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [StatusesService], + }).compile(); + + service = module.get(StatusesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.ts new file mode 100644 index 0000000..20491f4 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.service.ts @@ -0,0 +1,34 @@ +import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; +import { UpdateStatusDto } from '@app/contracts/statuses/DTO/update-status.dto'; +import { Status } from '@app/contracts/statuses/entities/status.entity'; +import { STATUSES_PATTERNS } from '@app/contracts/statuses/patterns/statuses.patterns'; +import { STATUSES_SERVICE_NAME } from '@app/contracts/statuses/statuses.constants'; +import { Inject, Injectable } from '@nestjs/common'; +import { ClientProxy } from '@nestjs/microservices'; +import { Observable } from 'rxjs'; + +@Injectable() +export class StatusesService { + + constructor(@Inject(STATUSES_SERVICE_NAME) private readonly client: ClientProxy) {} + + findAll() { + return this.client.send(STATUSES_PATTERNS.FIND_ALL, {}); + } + + findOne(id: string) { + return this.client.send(STATUSES_PATTERNS.FIND_ONE, { id }); + } + + create(createStatusDto: CreateStatusDto): Observable { + return this.client.send(STATUSES_PATTERNS.CREATE, createStatusDto); + } + + update(id: string, updateStatusDto: UpdateStatusDto) { + return this.client.send(STATUSES_PATTERNS.UPDATE, { id, ...updateStatusDto }); + } + + remove(id: string) { + return this.client.send(STATUSES_PATTERNS.REMOVE, { id }); + } +} diff --git a/backend/manager/apps/statuses/src/main.ts b/backend/manager/apps/statuses/src/main.ts index f646e44..12295b4 100644 --- a/backend/manager/apps/statuses/src/main.ts +++ b/backend/manager/apps/statuses/src/main.ts @@ -1,8 +1,20 @@ import { NestFactory } from '@nestjs/core'; -import { StatusesModule } from './statuses.module'; +import { MicroserviceOptions, Transport } from '@nestjs/microservices'; +import { envs } from '../config/envs'; +import { STATUSES_QUEUE_NAME } from '@app/contracts/statuses/statuses.constants'; +import { StatusesAppModule } from './statuses-app.module'; async function bootstrap() { - const app = await NestFactory.create(StatusesModule); - await app.listen(process.env.port ?? 3000); + const app = await NestFactory.createMicroservice(StatusesAppModule, { + transport: Transport.RMQ, + options: { + urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], + queue: STATUSES_QUEUE_NAME, + queueOptions: { + durable: true, + } + }, + }); + await app.listen(); } bootstrap(); diff --git a/backend/manager/apps/statuses/src/statuses-app.module.ts b/backend/manager/apps/statuses/src/statuses-app.module.ts new file mode 100644 index 0000000..75fa79f --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses-app.module.ts @@ -0,0 +1,24 @@ +import { Module } from '@nestjs/common'; +import { StatusesModule } from './statuses/statuses.module'; +import { envs } from '../config/envs'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Status } from '@app/contracts/statuses/entities/status.entity'; + +@Module({ + imports: [ + TypeOrmModule.forRoot({ + type: 'postgres', + host: envs.DB_HOST, + port: envs.DB_PORT, + username: envs.DB_USERNAME, + password: envs.DB_PASSWORD, + database: envs.DB_DATABASE, + entities: [Status], + synchronize: true, + }), + StatusesModule + ], + controllers: [], + providers: [], +}) +export class StatusesAppModule {} diff --git a/backend/manager/apps/statuses/src/statuses.controller.ts b/backend/manager/apps/statuses/src/statuses.controller.ts deleted file mode 100644 index f7df158..0000000 --- a/backend/manager/apps/statuses/src/statuses.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { StatusesService } from './statuses.service'; - -@Controller() -export class StatusesController { - constructor(private readonly statusesService: StatusesService) {} - - @Get() - getHello(): string { - return this.statusesService.getHello(); - } -} diff --git a/backend/manager/apps/statuses/src/statuses.module.ts b/backend/manager/apps/statuses/src/statuses.module.ts deleted file mode 100644 index 658ec4b..0000000 --- a/backend/manager/apps/statuses/src/statuses.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { StatusesController } from './statuses.controller'; -import { StatusesService } from './statuses.service'; - -@Module({ - imports: [], - controllers: [StatusesController], - providers: [StatusesService], -}) -export class StatusesModule {} diff --git a/backend/manager/apps/statuses/src/statuses.service.ts b/backend/manager/apps/statuses/src/statuses.service.ts deleted file mode 100644 index 30ed455..0000000 --- a/backend/manager/apps/statuses/src/statuses.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class StatusesService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/backend/manager/apps/statuses/src/statuses.controller.spec.ts b/backend/manager/apps/statuses/src/statuses/statuses.controller.spec.ts similarity index 51% rename from backend/manager/apps/statuses/src/statuses.controller.spec.ts rename to backend/manager/apps/statuses/src/statuses/statuses.controller.spec.ts index 7b7f3fc..9278139 100644 --- a/backend/manager/apps/statuses/src/statuses.controller.spec.ts +++ b/backend/manager/apps/statuses/src/statuses/statuses.controller.spec.ts @@ -3,20 +3,18 @@ import { StatusesController } from './statuses.controller'; import { StatusesService } from './statuses.service'; describe('StatusesController', () => { - let statusesController: StatusesController; + let controller: StatusesController; beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ + const module: TestingModule = await Test.createTestingModule({ controllers: [StatusesController], providers: [StatusesService], }).compile(); - statusesController = app.get(StatusesController); + controller = module.get(StatusesController); }); - describe('root', () => { - it('should return "Hello World!"', () => { - expect(statusesController.getHello()).toBe('Hello World!'); - }); + it('should be defined', () => { + expect(controller).toBeDefined(); }); }); diff --git a/backend/manager/apps/statuses/src/statuses/statuses.controller.ts b/backend/manager/apps/statuses/src/statuses/statuses.controller.ts new file mode 100644 index 0000000..fcabd96 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses/statuses.controller.ts @@ -0,0 +1,37 @@ +import { Controller } from '@nestjs/common'; +import { MessagePattern, Payload } from '@nestjs/microservices'; +import { StatusesService } from './statuses.service'; +import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; +import { UpdateStatusWithIdDto } from '@app/contracts/statuses/DTO/update-status.dto'; +import { STATUSES_PATTERNS } from '@app/contracts/statuses/patterns/statuses.patterns'; + +@Controller() +export class StatusesController { + constructor(private readonly statusesService: StatusesService) {} + + @MessagePattern(STATUSES_PATTERNS.CREATE) + create(@Payload() createStatusDto: CreateStatusDto) { + return this.statusesService.create(createStatusDto); + } + + @MessagePattern(STATUSES_PATTERNS.FIND_ALL) + findAll() { + return this.statusesService.findAll(); + } + + @MessagePattern(STATUSES_PATTERNS.FIND_ONE) + findOne(@Payload() id: string) { + return this.statusesService.findOne(id); + } + + @MessagePattern(STATUSES_PATTERNS.UPDATE) + update(@Payload() updateStatusDto: UpdateStatusWithIdDto) { + const { id, ...updateData } = updateStatusDto; + return this.statusesService.update(id, updateData); + } + + @MessagePattern(STATUSES_PATTERNS.REMOVE) + remove(@Payload() id: string) { + return this.statusesService.remove(id); + } +} diff --git a/backend/manager/apps/statuses/src/statuses/statuses.dao.ts b/backend/manager/apps/statuses/src/statuses/statuses.dao.ts new file mode 100644 index 0000000..b058cc1 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses/statuses.dao.ts @@ -0,0 +1,42 @@ +import { CreateStatusDto } from "@app/contracts/statuses/DTO/create-status.dto"; +import { UpdateStatusDto } from "@app/contracts/statuses/DTO/update-status.dto"; +import { Status } from "@app/contracts/statuses/entities/status.entity"; +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +@Injectable() +export class StatusesDao { + constructor( + @InjectRepository(Status) + private statusesRepository: Repository, + ) {} + + create(createStatusDto: CreateStatusDto) { + const status = this.statusesRepository.create(createStatusDto); + return this.statusesRepository.save(status); + } + + findAll() { + return this.statusesRepository.find(); + } + findOne(id: string) { + return this.statusesRepository.findOne({ where: { id } }); + } + update(id: string, updateStatusDto: UpdateStatusDto) { + return this.statusesRepository.update(id, updateStatusDto); + } + remove(id: string) { + return this.statusesRepository.delete(id); + } + + async isOrderUnique(parentId: string | null, order: number | null): Promise { + + if(!parentId || order === null) return true; + + const existingStatus = await this.statusesRepository.findOne({ + where: { parent_id: parentId, order }, + }); + return !existingStatus; + } +} diff --git a/backend/manager/apps/statuses/src/statuses/statuses.module.ts b/backend/manager/apps/statuses/src/statuses/statuses.module.ts new file mode 100644 index 0000000..19f6860 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses/statuses.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { StatusesService } from './statuses.service'; +import { StatusesController } from './statuses.controller'; +import { Status } from '@app/contracts/statuses/entities/status.entity'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { StatusesDao } from './statuses.dao'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Status]) + ], + controllers: [StatusesController], + providers: [StatusesService, StatusesDao], +}) +export class StatusesModule {} diff --git a/backend/manager/apps/statuses/src/statuses/statuses.service.spec.ts b/backend/manager/apps/statuses/src/statuses/statuses.service.spec.ts new file mode 100644 index 0000000..4dfed28 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses/statuses.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusesService } from './statuses.service'; + +describe('StatusesService', () => { + let service: StatusesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [StatusesService], + }).compile(); + + service = module.get(StatusesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/statuses/src/statuses/statuses.service.ts b/backend/manager/apps/statuses/src/statuses/statuses.service.ts new file mode 100644 index 0000000..d5b3221 --- /dev/null +++ b/backend/manager/apps/statuses/src/statuses/statuses.service.ts @@ -0,0 +1,60 @@ +import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; +import { UpdateStatusDto } from '@app/contracts/statuses/DTO/update-status.dto'; +import { Injectable } from '@nestjs/common'; +import { StatusesDao } from './statuses.dao'; + +@Injectable() +export class StatusesService { + constructor(private statusesDao: StatusesDao) {} + + async create(createStatusDto: CreateStatusDto) { + await this.validateUniqueOrder( + createStatusDto.parent_id || null, + createStatusDto.order || null, + ); + + return this.statusesDao.create(createStatusDto); + } + + async findAll() { + return this.statusesDao.findAll(); + } + + async findOne(id: string) { + return this.statusesDao.findOne(id); + } + + async update(id: string, updateStatusDto: UpdateStatusDto) { + + const currentStatus = await this.statusesDao.findOne(id); + if (!currentStatus) { + throw new Error('Status not found'); + } + + if(currentStatus.order !== updateStatusDto.order){ + await this.validateUniqueOrder( + updateStatusDto.parent_id || null, + updateStatusDto.order || null, + ); + } + + const updated = await this.statusesDao.update(id, updateStatusDto); + return { + updated: !!updated.affected, + }; + } + + async remove(id: string) { + return this.statusesDao.remove(id); + } + + private async validateUniqueOrder( + parentId: string | null, + order: number | null, + ): Promise { + const isUnique = await this.statusesDao.isOrderUnique(parentId, order); + if (!isUnique) { + throw new Error('Order must be unique within the same parent status'); + } + } +} diff --git a/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts b/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts index 793fbb1..20c9033 100644 --- a/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts +++ b/backend/manager/libs/contracts/src/statuses/DTO/update-status.dto.ts @@ -1,4 +1,10 @@ -import { PartialType } from '@nestjs/mapped-types'; +import { IntersectionType, PartialType } from '@nestjs/mapped-types'; import { CreateStatusDto } from './create-status.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; -export class UpdateStatusDto extends PartialType(CreateStatusDto) {} \ No newline at end of file +export class UpdateStatusDto extends PartialType(CreateStatusDto) {} + +export class UpdateStatusWithIdDto extends IntersectionType( + IdDto, + UpdateStatusDto, +) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/entities/status.entity.ts b/backend/manager/libs/contracts/src/statuses/entities/status.entity.ts new file mode 100644 index 0000000..c6d4606 --- /dev/null +++ b/backend/manager/libs/contracts/src/statuses/entities/status.entity.ts @@ -0,0 +1,20 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, +} from 'typeorm'; + +@Entity('statuses') +export class Status { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ type: 'varchar', length: 100 }) + name: string; + + @Column('uuid', { nullable: true }) + parent_id: string | null; + + @Column({ type: 'int', default: 0 }) + order: number; +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/patterns/statuses.patterns.ts b/backend/manager/libs/contracts/src/statuses/patterns/statuses.patterns.ts new file mode 100644 index 0000000..1488194 --- /dev/null +++ b/backend/manager/libs/contracts/src/statuses/patterns/statuses.patterns.ts @@ -0,0 +1,7 @@ +export const STATUSES_PATTERNS = { + FIND_ALL: 'statuses.findAll', + FIND_ONE: 'statuses.findOne', + CREATE: 'statuses.create', + UPDATE: 'statuses.update', + REMOVE: 'statuses.remove' +} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/statuses.constants.ts b/backend/manager/libs/contracts/src/statuses/statuses.constants.ts new file mode 100644 index 0000000..8b04d9c --- /dev/null +++ b/backend/manager/libs/contracts/src/statuses/statuses.constants.ts @@ -0,0 +1,3 @@ +export const STATUSES_SERVICE_NAME = Symbol('STATUSES_SERVICE'); +export const STATUSES_QUEUE_NAME = 'statuses_queue'; +export const STATUSES_NAMESPACE = 'statuses'; \ No newline at end of file diff --git a/backend/manager/package.json b/backend/manager/package.json index a701a10..b829913 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -15,7 +15,8 @@ "start:gateway": "nest start manager-api-gateway --watch", "start:patients": "nest start patients --watch", "start:providers": "nest start providers --watch", - "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\"", + "start:statuses": "nest start statuses --watch", + "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\" \"npm run start:statuses\"", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", @@ -92,7 +93,8 @@ "^@app/config(|/.*)$": "/libs/config/src/$1", "^@app/contracts(|/.*)$": "/libs/contracts/src/$1", "^@app/custom-class-validator(|/.*)$": "/libs/custom-class-validator/src/$1", - "^@app/logger(|/.*)$": "/libs/logger/src/$1" + "^@app/logger(|/.*)$": "/libs/logger/src/$1", + "^@app/standard-response(|/.*)$": "/libs/standard-response/src/$1" } } -} +} \ No newline at end of file From c0c20b9c0e3297152dda3c3df2337f9baeb8bf16 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 17:32:46 -0500 Subject: [PATCH 15/52] =?UTF-8?q?=E2=9C=A8=20feat(statuses):=20update=20fi?= =?UTF-8?q?ndOne=20method=20to=20use=20IdDto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager-api-gateway/src/statuses/statuses.controller.ts | 3 ++- .../manager/apps/statuses/src/statuses/statuses.controller.ts | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts index ac9ae40..af44da6 100644 --- a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts @@ -4,6 +4,7 @@ import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; import { UpdateStatusDto } from '@app/contracts/statuses/DTO/update-status.dto'; import { lastValueFrom } from 'rxjs'; import { standardResponse } from '@app/standard-response'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; @Controller('statuses') export class StatusesController { @@ -48,7 +49,7 @@ export class StatusesController { } @Get(':id') - async findOne(@Param('id') id: string) { + async findOne(@Param() { id }: IdDto) { try { const result = await lastValueFrom( this.statusesService.findOne(id) diff --git a/backend/manager/apps/statuses/src/statuses/statuses.controller.ts b/backend/manager/apps/statuses/src/statuses/statuses.controller.ts index fcabd96..b1005bc 100644 --- a/backend/manager/apps/statuses/src/statuses/statuses.controller.ts +++ b/backend/manager/apps/statuses/src/statuses/statuses.controller.ts @@ -4,6 +4,7 @@ import { StatusesService } from './statuses.service'; import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; import { UpdateStatusWithIdDto } from '@app/contracts/statuses/DTO/update-status.dto'; import { STATUSES_PATTERNS } from '@app/contracts/statuses/patterns/statuses.patterns'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; @Controller() export class StatusesController { @@ -20,7 +21,7 @@ export class StatusesController { } @MessagePattern(STATUSES_PATTERNS.FIND_ONE) - findOne(@Payload() id: string) { + findOne(@Payload() { id }: IdDto) { return this.statusesService.findOne(id); } From eb22a7e60532b8e8aa0f96bc223949cdcb543b58 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 18:22:46 -0500 Subject: [PATCH 16/52] =?UTF-8?q?=E2=9C=A8=20feat(providers):=20enhance=20?= =?UTF-8?q?CRUD=20operations=20with=20standard=20responses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/providers/providers.controller.ts | 99 ++++++++++++++++--- .../src/providers/providers.service.ts | 70 +++++-------- 2 files changed, 112 insertions(+), 57 deletions(-) diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts index 67ad370..7f86150 100644 --- a/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.controller.ts @@ -1,40 +1,111 @@ -import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Logger, Param, Post, Put } from '@nestjs/common'; import { ProvidersService } from './providers.service'; -import { Observable } from 'rxjs'; +import { lastValueFrom } from 'rxjs'; import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; -import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { IdDto } from '@app/contracts/global-dto/id.dto'; +import { standardResponse } from '@app/standard-response'; @Controller('providers') export class ProvidersController { + + private readonly logger = new Logger(ProvidersController.name); + constructor(private readonly providersService: ProvidersService) {} @Get() - findAll(): Observable { - return this.providersService.findAll(); + async findAll(){ + try { + const result = await lastValueFrom(this.providersService.findAll()); + return standardResponse( + 'Proveedores obtenidos correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener los proveedores: ' + error.message); + return standardResponse( + 'Falló la obtención de los proveedores', + null + ); + } } @Get(':id') - findOne(@Param() id: IdDto): Observable { - return this.providersService.findOne(id); + async findOne(@Param() id: IdDto) { + try { + const result = await lastValueFrom( + this.providersService.findOne(id) + ); + return standardResponse( + 'Proveedor obtenido correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener el proveedor: ' + error.message); + return standardResponse( + 'Falló la obtención del proveedor', + null + ); + } } @Post() - create(@Body() createProviderDto: CreateProviderDto) { - return this.providersService.create(createProviderDto); + async create(@Body() createProviderDto: CreateProviderDto) { + try { + const result = await lastValueFrom( + this.providersService.create(createProviderDto) + ); + return standardResponse( + 'Proveedor creado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al crear el proveedor: ' + error.message); + return standardResponse( + 'Falló la creación del proveedor', + null + ); + } } @Put(':id') - update( + async update( @Param() id: IdDto, @Body() updateProviderDto: UpdateProviderDto, - ): Observable { - return this.providersService.update(id, updateProviderDto); + ) { + try { + const result = await lastValueFrom( + this.providersService.update(id, updateProviderDto) + ); + return standardResponse( + 'Proveedor actualizado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al actualizar el proveedor: ' + error.message); + return standardResponse( + 'Falló la actualización del proveedor', + null + ); + } } @Delete(':id') - remove(@Param('id') id: string): Observable<{ message: string }> { - return this.providersService.remove(id); + async remove(@Param('id') id: string) { + try { + const result = await lastValueFrom( + this.providersService.remove(id) + ); + return standardResponse( + 'Proveedor eliminado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al eliminar el proveedor: ' + error.message); + return standardResponse( + 'Falló la eliminación del proveedor', + null + ); + } } } diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts index 7ff1cb3..0a592a5 100644 --- a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts @@ -4,61 +4,45 @@ import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider. import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; import { PROVIDERS_SERVICE_NAME } from '@app/contracts/providers/providers.constants'; -import { Inject, Injectable, NotFoundException } from '@nestjs/common'; +import { standardResponse } from '@app/standard-response'; +import { Inject, Injectable, Logger } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; -import { map, Observable } from 'rxjs'; +import { catchError, map, Observable, of } from 'rxjs'; @Injectable() export class ProvidersService { - constructor(@Inject(PROVIDERS_SERVICE_NAME) private readonly client: ClientProxy) {} - findAll(): Observable { - return this.client.send(PROVIDERS_PATTERNS.FIND_ALL, {}).pipe( - map((providers) => { - if (!providers) { - throw new NotFoundException('No se encontraron proveedores'); - } - return providers; - }), - ); - } + private readonly logger = new Logger(); + + constructor( + @Inject(PROVIDERS_SERVICE_NAME) private readonly client: ClientProxy, + ) {} - findOne(id: IdDto): Observable { - return this.client.send(PROVIDERS_PATTERNS.FIND_ONE, id).pipe( - map((provider) => { - if (!provider) { - throw new NotFoundException(`Proveedor con id ${id} no encontrado`); - } - return provider; - }), - ); + findAll() { + return this.client.send(PROVIDERS_PATTERNS.FIND_ALL, {}) } - create(createProviderDto: CreateProviderDto): Observable { - return this.client.send(PROVIDERS_PATTERNS.CREATE, createProviderDto); + findOne(id: IdDto) { + return this.client.send(PROVIDERS_PATTERNS.FIND_ONE, id); } - update(id: IdDto, updateProviderDto: UpdateProviderDto): Observable { + create(createProviderDto: CreateProviderDto) { + return this.client + .send(PROVIDERS_PATTERNS.CREATE, createProviderDto); +} + + update( + id: IdDto, + updateProviderDto: UpdateProviderDto, + ) { return this.client - .send(PROVIDERS_PATTERNS.UPDATE, { ...id, ...updateProviderDto }) - .pipe( - map((updated) => { - if (!updated) { - throw new NotFoundException(`Proveedor con id ${id} no encontrado`); - } - return updated; - }), - ); + .send(PROVIDERS_PATTERNS.UPDATE, { + ...id, + ...updateProviderDto, + }); } - remove(id: string): Observable<{ message: string }> { - return this.client.send(PROVIDERS_PATTERNS.REMOVE, { id }).pipe( - map((deleted) => { - if (!deleted) { - throw new NotFoundException(`Proveedor con id ${id} no encontrado`); - } - return { message: 'Proveedor eliminado correctamente' }; - }), - ); + remove(id: string) { + return this.client.send(PROVIDERS_PATTERNS.REMOVE, { id }); } } From cc63d3a9371f20c29624057189f5da4ffd766891 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 18:23:17 -0500 Subject: [PATCH 17/52] =?UTF-8?q?=E2=9C=A8=20feat(statuses):=20add=20loggi?= =?UTF-8?q?ng=20for=20error=20handling=20in=20CRUD=20operations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/statuses/statuses.controller.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts index af44da6..397eaac 100644 --- a/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/statuses/statuses.controller.ts @@ -1,4 +1,4 @@ -import { Body, Controller, Delete, Get, Param, Post, Put } from '@nestjs/common'; +import { Body, Controller, Delete, Get, Logger, Param, Post, Put } from '@nestjs/common'; import { StatusesService } from './statuses.service'; import { CreateStatusDto } from '@app/contracts/statuses/DTO/create-status.dto'; import { UpdateStatusDto } from '@app/contracts/statuses/DTO/update-status.dto'; @@ -8,6 +8,9 @@ import { IdDto } from '@app/contracts/global-dto/id.dto'; @Controller('statuses') export class StatusesController { + + private readonly logger = new Logger(StatusesController.name); + constructor(private readonly statusesService: StatusesService) {} @Post() @@ -22,6 +25,7 @@ export class StatusesController { result ); } catch (error) { + this.logger.error('Error al crear el estado: ' + error.message); return standardResponse( 'Falló la creación del estado', null, @@ -41,6 +45,7 @@ export class StatusesController { result ); } catch (error) { + this.logger.error('Error al obtener los estados: ' + error.message); return standardResponse( 'Falló la obtención de los estados', null @@ -59,6 +64,7 @@ export class StatusesController { result ); } catch (error) { + this.logger.error('Error al obtener el estado: ' + error.message); return standardResponse( 'Falló la obtención del estado', null @@ -77,6 +83,7 @@ export class StatusesController { result ); } catch (error) { + this.logger.error('Error al actualizar el estado: ' + error.message); return standardResponse( 'Falló la actualización del estado', null @@ -95,6 +102,7 @@ export class StatusesController { result ); } catch (error) { + this.logger.error('Error al eliminar el estado: ' + error.message); return standardResponse( 'Falló la eliminación del estado', null From 86cb30657375dc228660ab5c1b3a3eec58e601f5 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 19:59:01 -0500 Subject: [PATCH 18/52] =?UTF-8?q?=E2=9C=A8=20feat(patients):=20implement?= =?UTF-8?q?=20CRUD=20operations=20and=20messaging=20patterns?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/manager-api-gateway.module.ts | 3 +- .../src/patients/patients.controller.ts | 124 +++++++++++++++++- .../src/patients/patients.module.ts | 7 +- .../src/patients/patients.service.ts | 28 +++- .../manager/apps/patients/src/config/envs.ts | 16 ++- backend/manager/apps/patients/src/main.ts | 4 +- .../apps/patients/src/patients-app.module.ts | 22 ++++ .../apps/patients/src/patients.controller.ts | 15 --- .../apps/patients/src/patients.module.ts | 10 -- .../apps/patients/src/patients.service.ts | 8 -- .../patients.controller.spec.ts | 12 +- .../src/patients/patients.controller.ts | 37 ++++++ .../patients/src/patients/patients.dao.ts | 37 ++++++ .../patients/src/patients/patients.module.ts | 15 +++ .../src/patients/patients.service.spec.ts | 18 +++ .../patients/src/patients/patients.service.ts | 29 ++++ .../providers/src/providers/providers.dao.ts | 37 ++++++ .../src/providers/providers.module.ts | 3 +- .../src/providers/providers.service.ts | 19 ++- .../src/patients/DTO/update-patient.dto.ts | 10 +- .../src/patients/entities/patient.entity.ts | 30 +++++ .../src/patients/patients.constants.ts | 5 +- .../patients/patterns/patients.patterns.ts | 8 ++ 23 files changed, 417 insertions(+), 80 deletions(-) create mode 100644 backend/manager/apps/patients/src/patients-app.module.ts delete mode 100644 backend/manager/apps/patients/src/patients.controller.ts delete mode 100644 backend/manager/apps/patients/src/patients.module.ts delete mode 100644 backend/manager/apps/patients/src/patients.service.ts rename backend/manager/apps/patients/src/{ => patients}/patients.controller.spec.ts (51%) create mode 100644 backend/manager/apps/patients/src/patients/patients.controller.ts create mode 100644 backend/manager/apps/patients/src/patients/patients.dao.ts create mode 100644 backend/manager/apps/patients/src/patients/patients.module.ts create mode 100644 backend/manager/apps/patients/src/patients/patients.service.spec.ts create mode 100644 backend/manager/apps/patients/src/patients/patients.service.ts create mode 100644 backend/manager/apps/providers/src/providers/providers.dao.ts create mode 100644 backend/manager/libs/contracts/src/patients/entities/patient.entity.ts create mode 100644 backend/manager/libs/contracts/src/patients/patterns/patients.patterns.ts diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts index 5a9b492..bd2ab60 100644 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -2,9 +2,10 @@ import { Module } from '@nestjs/common'; import { PatientsModule } from './patients/patients.module'; import { LoggerModule } from '@app/logger/logger.module'; import { ProvidersModule } from './providers/providers.module'; +import { StatusesModule } from './statuses/statuses.module'; @Module({ - imports: [PatientsModule, LoggerModule, ProvidersModule], + imports: [PatientsModule, LoggerModule, ProvidersModule, StatusesModule], controllers: [], providers: [], }) diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts index edee84d..913cb39 100644 --- a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts @@ -1,13 +1,125 @@ -import { Controller, Get } from '@nestjs/common'; +import { + Controller, + Get, + Post, + Put, + Delete, + Param, + Body, + Inject, + Logger +} from '@nestjs/common'; import { PatientsService } from './patients.service'; +import { CreatePatientDto } from '@app/contracts/patients/DTO/create-patient.dto'; +import { UpdatePatientDto } from '@app/contracts/patients/DTO/update-patient.dto'; +import { lastValueFrom } from 'rxjs'; +import { PATIENTS_SERVICE_NAME } from '@app/contracts/patients/patients.constants'; +import { ClientProxy } from '@nestjs/microservices'; +import { standardResponse } from '@app/standard-response'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; @Controller('patients') export class PatientsController { - constructor(private readonly patientService: PatientsService) {} + private readonly logger = new Logger(PatientsController.name); - @Get('hello') - getHello(): string { - return this.patientService.getHello(); + constructor( + private readonly patientsService: PatientsService, + @Inject(PATIENTS_SERVICE_NAME) private readonly client: ClientProxy, + ) {} + + @Get() + async findAll() { + try { + const result = await lastValueFrom(this.patientsService.findAll()); + return standardResponse( + 'Pacientes obtenidos correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener los pacientes: ' + error.message); + return standardResponse( + 'Falló la obtención de los pacientes', + null + ); + } + } + + @Get(':id') + async findOne(@Param() {id}: IdDto) { + try { + const result = await lastValueFrom( + this.patientsService.findOne(id) + ); + return standardResponse( + 'Paciente obtenido correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener el paciente: ' + error.message); + return standardResponse( + 'Falló la obtención del paciente', + null + ); + } + } + + @Post() + async create(@Body() createPatientDto: CreatePatientDto) { + try { + const result = await lastValueFrom( + this.patientsService.create(createPatientDto) + ); + return standardResponse( + 'Paciente creado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al crear el paciente: ' + error.message); + return standardResponse( + 'Falló la creación del paciente', + null + ); + } + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updatePatientDto: UpdatePatientDto, + ) { + try { + const result = await lastValueFrom( + this.patientsService.update(id, updatePatientDto) + ); + return standardResponse( + 'Paciente actualizado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al actualizar el paciente: ' + error.message); + return standardResponse( + 'Falló la actualización del paciente', + null + ); + } + } + @Delete(':id') + async remove(@Param('id') id: string) { + try { + const result = await lastValueFrom( + this.patientsService.remove(id) + ); + return standardResponse( + 'Paciente eliminado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al eliminar el paciente: ' + error.message); + return standardResponse( + 'Falló la eliminación del paciente', + null + ); + } } -} +} \ No newline at end of file diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts index 4d0d126..4c6e330 100644 --- a/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.module.ts @@ -2,11 +2,14 @@ import { Module } from '@nestjs/common'; import { PatientsService } from './patients.service'; import { SharedClientModule } from '../shared-client/shared-client.module'; import { PatientsController } from './patients.controller'; -import { QUEUE_NAME, SERVICE_NAME } from '@app/contracts/patients/patients.constants'; +import { + PATIENTS_QUEUE_NAME, + PATIENTS_SERVICE_NAME, +} from '@app/contracts/patients/patients.constants'; @Module({ imports: [ - SharedClientModule.register(SERVICE_NAME, QUEUE_NAME) + SharedClientModule.register(PATIENTS_SERVICE_NAME, PATIENTS_QUEUE_NAME), ], providers: [PatientsService], exports: [PatientsService], diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts index 8fed8e6..40335b4 100644 --- a/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.service.ts @@ -1,17 +1,31 @@ -import { SERVICE_NAME } from '@app/contracts/patients/patients.constants'; +import { Patient } from '@app/contracts/patients/entities/patient.entity'; +import { PATIENTS_SERVICE_NAME } from '@app/contracts/patients/patients.constants'; +import { PATIENTS_PATTERNS } from '@app/contracts/patients/patterns/patients.patterns'; import { Inject, Injectable } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; +import { Observable } from 'rxjs'; @Injectable() export class PatientsService { + constructor(@Inject(PATIENTS_SERVICE_NAME) private readonly client: ClientProxy) {} - constructor( - @Inject(SERVICE_NAME) private readonly client: ClientProxy - ) {} + findAll(): Observable { + return this.client.send(PATIENTS_PATTERNS.FIND_ALL, {}); + } + + findOne(id: string): Observable { + return this.client.send(PATIENTS_PATTERNS.FIND_ONE, { id }); + } + create(createPatientDto: any): Observable { + return this.client.send(PATIENTS_PATTERNS.CREATE, createPatientDto); + } + + update(id: string, updatePatientDto: any): Observable { + return this.client.send(PATIENTS_PATTERNS.UPDATE, { id, ...updatePatientDto }); + } - getHello(): string { - this.client.emit('get_hello', { message: 'ping' }); - return 'Hello from Patients Service!'; + remove(id: string): Observable { + return this.client.send(PATIENTS_PATTERNS.REMOVE, { id }); } } diff --git a/backend/manager/apps/patients/src/config/envs.ts b/backend/manager/apps/patients/src/config/envs.ts index f69162e..2b46ca8 100644 --- a/backend/manager/apps/patients/src/config/envs.ts +++ b/backend/manager/apps/patients/src/config/envs.ts @@ -1,4 +1,4 @@ -import { PATIENTS_NAMESPACE } from '@app/contracts/patients/patients.namespace'; +import { PATIENTS_NAMESPACE } from '@app/contracts/patients/patients.constants'; import { config } from 'dotenv'; import { resolve } from 'path'; import { number, object, string } from 'yup'; @@ -8,12 +8,14 @@ config({ }); const envVarsSchema = object({ - NODE_ENV: string().oneOf(['dev', 'prod', 'test']).default('dev'), - HOST: string().default('0.0.0.0'), - PORT: number().default(3000), - RMQ_USER: string().default('guest'), - RMQ_PASSWORD: string().default('guest'), - RABBITMQ_URL: string().default('localhost:5672'), + RMQ_USER: string().required(), + RMQ_PASSWORD: string().required(), + RABBITMQ_URL: string().required(), + DB_HOST: string().required(), + DB_PORT: number().required(), + DB_USERNAME: string().required(), + DB_PASSWORD: string().required(), + DB_DATABASE: string().required(), }).noUnknown(); export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/patients/src/main.ts b/backend/manager/apps/patients/src/main.ts index 81136be..b8839a7 100644 --- a/backend/manager/apps/patients/src/main.ts +++ b/backend/manager/apps/patients/src/main.ts @@ -1,10 +1,10 @@ import { NestFactory } from '@nestjs/core'; -import { PatientsModule } from './patients.module'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; import { envs } from './config/envs'; +import { PatientsAppModule } from './patients-app.module'; async function bootstrap() { - const app = await NestFactory.createMicroservice(PatientsModule, { + const app = await NestFactory.createMicroservice(PatientsAppModule, { transport: Transport.RMQ, options: { urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], diff --git a/backend/manager/apps/patients/src/patients-app.module.ts b/backend/manager/apps/patients/src/patients-app.module.ts new file mode 100644 index 0000000..da95b65 --- /dev/null +++ b/backend/manager/apps/patients/src/patients-app.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { envs } from './config/envs'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { Patient } from '@app/contracts/patients/entities/patient.entity'; +import { PatientsModule } from './patients/patients.module'; + +@Module({ + imports: [ + TypeOrmModule.forRoot({ + type: 'postgres', + host: envs.DB_HOST, + port: envs.DB_PORT, + username: envs.DB_USERNAME, + password: envs.DB_PASSWORD, + database: envs.DB_DATABASE, + entities: [Patient], + synchronize: true, + }), + PatientsModule + ], +}) +export class PatientsAppModule {} diff --git a/backend/manager/apps/patients/src/patients.controller.ts b/backend/manager/apps/patients/src/patients.controller.ts deleted file mode 100644 index d4f3a1f..0000000 --- a/backend/manager/apps/patients/src/patients.controller.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { PatientsService } from './patients.service'; -import { MessagePattern } from '@nestjs/microservices'; - -@Controller() -export class PatientsController { - constructor(private readonly patientsService: PatientsService) {} - - @MessagePattern('get_hello') - handleHello(data: any) { - console.log('📩 Received from gateway:', data); - return 'Hello from Patients Microservice!'; - } -} - diff --git a/backend/manager/apps/patients/src/patients.module.ts b/backend/manager/apps/patients/src/patients.module.ts deleted file mode 100644 index a9f53eb..0000000 --- a/backend/manager/apps/patients/src/patients.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { PatientsController } from './patients.controller'; -import { PatientsService } from './patients.service'; - -@Module({ - imports: [], - controllers: [PatientsController], - providers: [PatientsService], -}) -export class PatientsModule {} diff --git a/backend/manager/apps/patients/src/patients.service.ts b/backend/manager/apps/patients/src/patients.service.ts deleted file mode 100644 index a8aa3d6..0000000 --- a/backend/manager/apps/patients/src/patients.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class PatientsService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/backend/manager/apps/patients/src/patients.controller.spec.ts b/backend/manager/apps/patients/src/patients/patients.controller.spec.ts similarity index 51% rename from backend/manager/apps/patients/src/patients.controller.spec.ts rename to backend/manager/apps/patients/src/patients/patients.controller.spec.ts index a9d5357..0217553 100644 --- a/backend/manager/apps/patients/src/patients.controller.spec.ts +++ b/backend/manager/apps/patients/src/patients/patients.controller.spec.ts @@ -3,20 +3,18 @@ import { PatientsController } from './patients.controller'; import { PatientsService } from './patients.service'; describe('PatientsController', () => { - let patientsController: PatientsController; + let controller: PatientsController; beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ + const module: TestingModule = await Test.createTestingModule({ controllers: [PatientsController], providers: [PatientsService], }).compile(); - patientsController = app.get(PatientsController); + controller = module.get(PatientsController); }); - describe('root', () => { - it('should return "Hello World!"', () => { - expect(patientsController.getHello()).toBe('Hello World!'); - }); + it('should be defined', () => { + expect(controller).toBeDefined(); }); }); diff --git a/backend/manager/apps/patients/src/patients/patients.controller.ts b/backend/manager/apps/patients/src/patients/patients.controller.ts new file mode 100644 index 0000000..5152c98 --- /dev/null +++ b/backend/manager/apps/patients/src/patients/patients.controller.ts @@ -0,0 +1,37 @@ +import { Controller } from '@nestjs/common'; +import { MessagePattern } from '@nestjs/microservices'; +import { PatientsService } from './patients.service'; +import { PATIENTS_PATTERNS } from '@app/contracts/patients/patterns/patients.patterns'; +import { UpdatePatientWithIdDto } from '@app/contracts/patients/DTO/update-patient.dto'; +import { CreatePatientDto } from '@app/contracts/patients/DTO/create-patient.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; + +@Controller() +export class PatientsController { + constructor(private readonly patientsService: PatientsService) {} + + @MessagePattern(PATIENTS_PATTERNS.CREATE) + create(createPatientDto: CreatePatientDto) { + return this.patientsService.create(createPatientDto); + } + + @MessagePattern(PATIENTS_PATTERNS.FIND_ALL) + findAll() { + return this.patientsService.findAll(); + } + @MessagePattern(PATIENTS_PATTERNS.FIND_ONE) + findOne({id}: IdDto) { + return this.patientsService.findOne(id); + } + + @MessagePattern(PATIENTS_PATTERNS.UPDATE) + update(updatePatientDto: UpdatePatientWithIdDto) { + const { id, ...updateData } = updatePatientDto; + return this.patientsService.update(id, updateData); + } + + @MessagePattern(PATIENTS_PATTERNS.REMOVE) + remove(id: string) { + return this.patientsService.remove(id); + } +} diff --git a/backend/manager/apps/patients/src/patients/patients.dao.ts b/backend/manager/apps/patients/src/patients/patients.dao.ts new file mode 100644 index 0000000..6300f21 --- /dev/null +++ b/backend/manager/apps/patients/src/patients/patients.dao.ts @@ -0,0 +1,37 @@ +import { CreatePatientDto } from "@app/contracts/patients/DTO/create-patient.dto"; +import { Patient } from "@app/contracts/patients/entities/patient.entity"; +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +@Injectable() +export class PatientsDao { + + constructor( + @InjectRepository(Patient) + private patientsRepository: Repository + ) {} + + create(patient: CreatePatientDto) { + const newPatient = this.patientsRepository.create(patient); + return this.patientsRepository.save(newPatient); + } + + findAll() { + return this.patientsRepository.find(); + } + + findOne(id: string) { + return this.patientsRepository.findOne({ where: { id } }); + } + + async update(id: string, patient: Partial) { + const updatedPatient = await this.patientsRepository.update(id, patient); + return !!updatedPatient.affected; + } + + async remove(id: string) { + const deletedPatient = await this.patientsRepository.delete(id); + return !!deletedPatient.affected; + } +} \ No newline at end of file diff --git a/backend/manager/apps/patients/src/patients/patients.module.ts b/backend/manager/apps/patients/src/patients/patients.module.ts new file mode 100644 index 0000000..4abbe17 --- /dev/null +++ b/backend/manager/apps/patients/src/patients/patients.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { PatientsService } from './patients.service'; +import { PatientsController } from './patients.controller'; +import { PatientsDao } from './patients.dao'; +import { Patient } from '@app/contracts/patients/entities/patient.entity'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Patient]) + ], + controllers: [PatientsController], + providers: [PatientsService, PatientsDao], +}) +export class PatientsModule {} diff --git a/backend/manager/apps/patients/src/patients/patients.service.spec.ts b/backend/manager/apps/patients/src/patients/patients.service.spec.ts new file mode 100644 index 0000000..b1a661a --- /dev/null +++ b/backend/manager/apps/patients/src/patients/patients.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { PatientsService } from './patients.service'; + +describe('PatientsService', () => { + let service: PatientsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [PatientsService], + }).compile(); + + service = module.get(PatientsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/patients/src/patients/patients.service.ts b/backend/manager/apps/patients/src/patients/patients.service.ts new file mode 100644 index 0000000..3b71eea --- /dev/null +++ b/backend/manager/apps/patients/src/patients/patients.service.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@nestjs/common'; +import { CreatePatientDto } from '@app/contracts/patients/DTO/create-patient.dto'; +import { UpdatePatientDto } from '@app/contracts/patients/DTO/update-patient.dto'; +import { PatientsDao } from './patients.dao'; + +@Injectable() +export class PatientsService { + constructor(private patientsDao: PatientsDao) {} + + create(createPatientDto: CreatePatientDto) { + return this.patientsDao.create(createPatientDto); + } + + findAll() { + return this.patientsDao.findAll(); + } + + findOne(id: string) { + return this.patientsDao.findOne(id); + } + + async update(id: string, updatePatientDto: UpdatePatientDto) { + return this.patientsDao.update(id, updatePatientDto); + } + + async remove(id: string) { + return this.patientsDao.remove(id); + } +} diff --git a/backend/manager/apps/providers/src/providers/providers.dao.ts b/backend/manager/apps/providers/src/providers/providers.dao.ts new file mode 100644 index 0000000..fc00898 --- /dev/null +++ b/backend/manager/apps/providers/src/providers/providers.dao.ts @@ -0,0 +1,37 @@ +import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; +import { Repository } from 'typeorm'; + +@Injectable() +export class ProvidersDao { + + constructor( + @InjectRepository(Provider) + private providersRepository: Repository + ) {} + + create(provider: CreateProviderDto) { + const newProvider = this.providersRepository.create(provider); + return this.providersRepository.save(newProvider); + } + + findAll() { + return this.providersRepository.find(); + } + + findOne(id: string) { + return this.providersRepository.findOne({ where: { id } }); + } + + async update(id: string, provider: Partial) { + const updatedProvider = await this.providersRepository.update(id, provider); + return !!updatedProvider.affected; + } + + async remove(id: string) { + const deletedProvider = await this.providersRepository.delete(id); + return !!deletedProvider.affected; + } +} diff --git a/backend/manager/apps/providers/src/providers/providers.module.ts b/backend/manager/apps/providers/src/providers/providers.module.ts index a4c48b8..7174f53 100644 --- a/backend/manager/apps/providers/src/providers/providers.module.ts +++ b/backend/manager/apps/providers/src/providers/providers.module.ts @@ -3,12 +3,13 @@ import { ProvidersService } from './providers.service'; import { ProvidersController } from './providers.controller'; import { TypeOrmModule } from '@nestjs/typeorm'; import { Provider } from '@app/contracts/providers/entities/provider.entity'; +import { ProvidersDao } from './providers.dao'; @Module({ imports: [ TypeOrmModule.forFeature([Provider]) ], controllers: [ProvidersController], - providers: [ProvidersService], + providers: [ProvidersService, ProvidersDao], }) export class ProvidersModule {} diff --git a/backend/manager/apps/providers/src/providers/providers.service.ts b/backend/manager/apps/providers/src/providers/providers.service.ts index 5c45b80..e052efd 100644 --- a/backend/manager/apps/providers/src/providers/providers.service.ts +++ b/backend/manager/apps/providers/src/providers/providers.service.ts @@ -4,32 +4,31 @@ import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; +import { ProvidersDao } from './providers.dao'; @Injectable() export class ProvidersService { constructor( - @InjectRepository(Provider) - private providersRepository: Repository, + private providersDao: ProvidersDao ) {} create(createProviderDto: CreateProviderDto) { - const provider = this.providersRepository.create(createProviderDto); - return this.providersRepository.save(provider); + return this.providersDao.create(createProviderDto); } findAll() { - return this.providersRepository.find(); + return this.providersDao.findAll(); } findOne(id: string) { - return this.providersRepository.findOne({ where: { id } }); + return this.providersDao.findOne(id); } - update(id: string, updateProviderDto: UpdateProviderDto) { - return this.providersRepository.update(id, updateProviderDto); + async update(id: string, updateProviderDto: UpdateProviderDto) { + return this.providersDao.update(id, updateProviderDto); } - remove(id: string) { - return this.providersRepository.delete(id); + async remove(id: string) { + return this.providersDao.remove(id); } } diff --git a/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts b/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts index 70a3e1e..f3fc867 100644 --- a/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts +++ b/backend/manager/libs/contracts/src/patients/DTO/update-patient.dto.ts @@ -1,4 +1,10 @@ -import { PartialType } from '@nestjs/mapped-types'; +import { IntersectionType, PartialType } from '@nestjs/mapped-types'; import { CreatePatientDto } from './create-patient.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; -export class UpdatePatientDto extends PartialType(CreatePatientDto) {} \ No newline at end of file +export class UpdatePatientDto extends PartialType(CreatePatientDto) {} + +export class UpdatePatientWithIdDto extends IntersectionType( + IdDto, + UpdatePatientDto, +) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/entities/patient.entity.ts b/backend/manager/libs/contracts/src/patients/entities/patient.entity.ts new file mode 100644 index 0000000..00944c6 --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/entities/patient.entity.ts @@ -0,0 +1,30 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, +} from 'typeorm'; + +@Entity('patients') +export class Patient { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ type: 'varchar', length: 255 }) + full_name: string; + + @Column({ type: 'varchar', length: 255, unique: true }) + email: string; + + @Column({ type: 'varchar', length: 50 }) + phone: string; + + @Column('uuid') + provider_id: string; + + @Column('uuid') + status_id: string; + + @CreateDateColumn({ type: 'timestamp with time zone' }) + created_at: Date; +} diff --git a/backend/manager/libs/contracts/src/patients/patients.constants.ts b/backend/manager/libs/contracts/src/patients/patients.constants.ts index ff507da..fc3548a 100644 --- a/backend/manager/libs/contracts/src/patients/patients.constants.ts +++ b/backend/manager/libs/contracts/src/patients/patients.constants.ts @@ -1,2 +1,3 @@ -export const SERVICE_NAME = Symbol('PATIENTS_SERVICE'); -export const QUEUE_NAME = 'patients_queue'; \ No newline at end of file +export const PATIENTS_SERVICE_NAME = Symbol('PATIENTS_SERVICE'); +export const PATIENTS_QUEUE_NAME = 'patients_queue'; +export const PATIENTS_NAMESPACE = 'patients'; \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/patients/patterns/patients.patterns.ts b/backend/manager/libs/contracts/src/patients/patterns/patients.patterns.ts new file mode 100644 index 0000000..19d501e --- /dev/null +++ b/backend/manager/libs/contracts/src/patients/patterns/patients.patterns.ts @@ -0,0 +1,8 @@ + +export const PATIENTS_PATTERNS = { + FIND_ALL: 'patients.findAll', + FIND_ONE: 'patients.findOne', + CREATE: 'patients.create', + UPDATE: 'patients.update', + REMOVE: 'patients.remove' +} \ No newline at end of file From 9b50a20077d911b0fd4c3a38366f0e2cc3a87313 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 21:16:08 -0500 Subject: [PATCH 19/52] =?UTF-8?q?=E2=9C=A8=20feat(status-histories):=20imp?= =?UTF-8?q?lement=20CRUD=20operations=20and=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../status-histories.controller.spec.ts | 18 ++++ .../status-histories.controller.ts | 101 ++++++++++++++++++ .../status-histories.module.ts | 14 +++ .../status-histories.service.spec.ts | 18 ++++ .../status-histories.service.ts | 38 +++++++ .../apps/status-histories/config/envs.ts | 21 ++++ .../manager/apps/status-histories/src/main.ts | 20 ++++ .../src/status-histories-app.module.ts | 22 ++++ .../status-histories.controller.spec.ts | 20 ++++ .../status-histories.controller.ts | 38 +++++++ .../status-histories/status-histories.dao.ts | 36 +++++++ .../status-histories.module.ts | 15 +++ .../status-histories.service.spec.ts | 18 ++++ .../status-histories.service.ts | 32 ++++++ .../test/app.e2e-spec.ts | 6 +- .../test/jest-e2e.json | 0 .../tsconfig.app.json | 2 +- .../manager/apps/status-history/src/main.ts | 8 -- .../src/status-history.controller.spec.ts | 22 ---- .../src/status-history.controller.ts | 12 --- .../src/status-history.module.ts | 10 -- .../src/status-history.service.ts | 8 -- .../DTO/create-status-history.dto.ts | 3 - .../DTO/update-status-history.dto.ts | 10 +- .../entities/status-history.entity.ts | 21 ++++ .../patterns/status-histories.patterns.ts | 7 ++ .../status-histories.constants.ts | 3 + backend/manager/package.json | 3 +- 28 files changed, 456 insertions(+), 70 deletions(-) create mode 100644 backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.module.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.spec.ts create mode 100644 backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.ts create mode 100644 backend/manager/apps/status-histories/config/envs.ts create mode 100644 backend/manager/apps/status-histories/src/main.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories-app.module.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.controller.spec.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.controller.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.dao.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.module.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.service.spec.ts create mode 100644 backend/manager/apps/status-histories/src/status-histories/status-histories.service.ts rename backend/manager/apps/{status-history => status-histories}/test/app.e2e-spec.ts (75%) rename backend/manager/apps/{status-history => status-histories}/test/jest-e2e.json (100%) rename backend/manager/apps/{status-history => status-histories}/tsconfig.app.json (78%) delete mode 100644 backend/manager/apps/status-history/src/main.ts delete mode 100644 backend/manager/apps/status-history/src/status-history.controller.spec.ts delete mode 100644 backend/manager/apps/status-history/src/status-history.controller.ts delete mode 100644 backend/manager/apps/status-history/src/status-history.module.ts delete mode 100644 backend/manager/apps/status-history/src/status-history.service.ts create mode 100644 backend/manager/libs/contracts/src/status-history/entities/status-history.entity.ts create mode 100644 backend/manager/libs/contracts/src/status-history/patterns/status-histories.patterns.ts create mode 100644 backend/manager/libs/contracts/src/status-history/status-histories.constants.ts diff --git a/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.spec.ts b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.spec.ts new file mode 100644 index 0000000..7255a91 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusHistoriesController } from './status-histories.controller'; + +describe('StatusHistoriesController', () => { + let controller: StatusHistoriesController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StatusHistoriesController], + }).compile(); + + controller = module.get(StatusHistoriesController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.ts b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.ts new file mode 100644 index 0000000..ffdaa07 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.controller.ts @@ -0,0 +1,101 @@ +import { Body, Controller, Delete, Get, Logger, Param, Post, Put } from '@nestjs/common'; +import { StatusHistoriesService } from './status-histories.service'; +import { lastValueFrom } from 'rxjs'; +import { standardResponse } from '@app/standard-response'; +import { CreateStatusHistoryDto } from '@app/contracts/status-history/DTO/create-status-history.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; +import { UpdateStatusHistoryDto } from '@app/contracts/status-history/DTO/update-status-history.dto'; + +@Controller('status-histories') +export class StatusHistoriesController { + + private readonly logger = new Logger(StatusHistoriesController.name); + + constructor(private readonly statusHistoriesService: StatusHistoriesService) {} + + @Get() + async findAll() { + try { + const result = await lastValueFrom(this.statusHistoriesService.findAll()); + return standardResponse( + 'Historiales de estado obtenidos correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener los historiales de estado: ' + error.message); + return standardResponse( + 'Falló la obtención de los historiales de estado', + null + ); + } + } + + @Get(':id') + async findOne(@Param() {id}: IdDto) { + try { + const result = await lastValueFrom(this.statusHistoriesService.findOne(id)); + return standardResponse( + 'Historial de estado obtenido correctamente', + result + ); + } catch (error) { + this.logger.error('Error al obtener el historial de estado: ' + error.message); + return standardResponse( + 'Falló la obtención del historial de estado', + null + ); + } + } + + @Post() + async create(@Body() createStatusHistoryDto: CreateStatusHistoryDto) { + try { + const result = await lastValueFrom(this.statusHistoriesService.create(createStatusHistoryDto)); + return standardResponse( + 'Historial de estado creado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al crear el historial de estado: ' + error.message); + return standardResponse( + 'Falló la creación del historial de estado', + null + ); + } + } + + @Put(':id') + async update(@Param() id: IdDto, @Body() updateStatusHistoryDto: UpdateStatusHistoryDto) { + try { + const result = await lastValueFrom(this.statusHistoriesService.update(id, updateStatusHistoryDto)); + return standardResponse( + 'Historial de estado actualizado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al actualizar el historial de estado: ' + error.message); + return standardResponse( + 'Falló la actualización del historial de estado', + null + ); + } + } + + @Delete(':id') + async remove(@Param('id') id: string) { + try { + const result = await lastValueFrom(this.statusHistoriesService.remove(id)); + return standardResponse( + 'Historial de estado eliminado correctamente', + result + ); + } catch (error) { + this.logger.error('Error al eliminar el historial de estado: ' + error.message); + return standardResponse( + 'Falló la eliminación del historial de estado', + null + ); + } + } + +} diff --git a/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.module.ts b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.module.ts new file mode 100644 index 0000000..41bc172 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common'; +import { StatusHistoriesController } from './status-histories.controller'; +import { StatusHistoriesService } from './status-histories.service'; +import { STATUS_HISTORIES_QUEUE_NAME, STATUS_HISTORIES_SERVICE_NAME } from '@app/contracts/status-history/status-histories.constants'; +import { SharedClientModule } from '../shared-client/shared-client.module'; + +@Module({ + imports: [ + SharedClientModule.register(STATUS_HISTORIES_SERVICE_NAME, STATUS_HISTORIES_QUEUE_NAME), + ], + controllers: [StatusHistoriesController], + providers: [StatusHistoriesService] +}) +export class StatusHistoriesModule {} diff --git a/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.spec.ts b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.spec.ts new file mode 100644 index 0000000..2844409 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusHistoriesService } from './status-histories.service'; + +describe('StatusHistoriesService', () => { + let service: StatusHistoriesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [StatusHistoriesService], + }).compile(); + + service = module.get(StatusHistoriesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.ts b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.ts new file mode 100644 index 0000000..f77cc37 --- /dev/null +++ b/backend/manager/apps/manager-api-gateway/src/status-histories/status-histories.service.ts @@ -0,0 +1,38 @@ +import { IdDto } from '@app/contracts/global-dto/id.dto'; +import { CreateStatusHistoryDto } from '@app/contracts/status-history/DTO/create-status-history.dto'; +import { UpdateStatusHistoryDto } from '@app/contracts/status-history/DTO/update-status-history.dto'; +import { StatusHistory } from '@app/contracts/status-history/entities/status-history.entity'; +import { STATUS_HISTORIES_PATTERNS } from '@app/contracts/status-history/patterns/status-histories.patterns'; +import { STATUS_HISTORIES_SERVICE_NAME } from '@app/contracts/status-history/status-histories.constants'; +import { Inject, Injectable } from '@nestjs/common'; +import { ClientProxy } from '@nestjs/microservices'; + +@Injectable() +export class StatusHistoriesService { + constructor( + @Inject(STATUS_HISTORIES_SERVICE_NAME) private readonly client: ClientProxy + ) {} + + findAll() { + return this.client.send(STATUS_HISTORIES_PATTERNS.FIND_ALL, {}); + } + + findOne(id: string) { + return this.client.send(STATUS_HISTORIES_PATTERNS.FIND_ONE, { id }); + } + + create(createStatusHistoryDto: CreateStatusHistoryDto) { + return this.client.send(STATUS_HISTORIES_PATTERNS.CREATE, createStatusHistoryDto); + } + + update(id: IdDto, updateStatusHistoryDto: UpdateStatusHistoryDto) { + return this.client.send(STATUS_HISTORIES_PATTERNS.UPDATE, { + ...id, + ...updateStatusHistoryDto, + }); + } + + remove(id: string) { + return this.client.send(STATUS_HISTORIES_PATTERNS.REMOVE, { id }); + } +} diff --git a/backend/manager/apps/status-histories/config/envs.ts b/backend/manager/apps/status-histories/config/envs.ts new file mode 100644 index 0000000..000864d --- /dev/null +++ b/backend/manager/apps/status-histories/config/envs.ts @@ -0,0 +1,21 @@ +import { STATUS_HISTORIES_NAMESPACE } from '@app/contracts/status-history/status-histories.constants'; +import { config } from 'dotenv'; +import { resolve } from 'path'; +import { number, object, string } from 'yup'; + +config({ + path: resolve(process.cwd(), `apps/${STATUS_HISTORIES_NAMESPACE}/.env`), +}); + +const envVarsSchema = object({ + RMQ_USER: string().required(), + RMQ_PASSWORD: string().required(), + RABBITMQ_URL: string().required(), + DB_HOST: string().required(), + DB_PORT: number().required(), + DB_USERNAME: string().required(), + DB_PASSWORD: string().required(), + DB_DATABASE: string().required(), +}).noUnknown(); + +export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/status-histories/src/main.ts b/backend/manager/apps/status-histories/src/main.ts new file mode 100644 index 0000000..f413a49 --- /dev/null +++ b/backend/manager/apps/status-histories/src/main.ts @@ -0,0 +1,20 @@ +import { NestFactory } from '@nestjs/core'; +import { MicroserviceOptions, Transport } from '@nestjs/microservices'; +import { envs } from '../config/envs'; +import { STATUS_HISTORIES_QUEUE_NAME } from '@app/contracts/status-history/status-histories.constants'; +import { StatusHistoriesAppModule } from './status-histories-app.module'; + +async function bootstrap() { + const app = await NestFactory.createMicroservice(StatusHistoriesAppModule, { + transport: Transport.RMQ, + options: { + urls: [`amqp://${envs.RMQ_USER}:${envs.RMQ_PASSWORD}@${envs.RABBITMQ_URL}`], + queue: STATUS_HISTORIES_QUEUE_NAME, + queueOptions: { + durable: true, + } + }, + }); + await app.listen(); +} +bootstrap(); diff --git a/backend/manager/apps/status-histories/src/status-histories-app.module.ts b/backend/manager/apps/status-histories/src/status-histories-app.module.ts new file mode 100644 index 0000000..6e1a379 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories-app.module.ts @@ -0,0 +1,22 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { envs } from '../config/envs'; +import { StatusHistory } from '@app/contracts/status-history/entities/status-history.entity'; +import { StatusHistoriesModule } from './status-histories/status-histories.module'; + +@Module({ + imports: [ + TypeOrmModule.forRoot({ + type: 'postgres', + host: envs.DB_HOST, + port: envs.DB_PORT, + username: envs.DB_USERNAME, + password: envs.DB_PASSWORD, + database: envs.DB_DATABASE, + entities: [StatusHistory], + synchronize: true, + }), + StatusHistoriesModule, + ], +}) +export class StatusHistoriesAppModule {} diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.spec.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.spec.ts new file mode 100644 index 0000000..a316098 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.spec.ts @@ -0,0 +1,20 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusHistoriesController } from './status-histories.controller'; +import { StatusHistoriesService } from './status-histories.service'; + +describe('StatusHistoriesController', () => { + let controller: StatusHistoriesController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StatusHistoriesController], + providers: [StatusHistoriesService], + }).compile(); + + controller = module.get(StatusHistoriesController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.ts new file mode 100644 index 0000000..7174cb3 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.controller.ts @@ -0,0 +1,38 @@ +import { Controller } from '@nestjs/common'; +import { MessagePattern, Payload } from '@nestjs/microservices'; +import { StatusHistoriesService } from './status-histories.service'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; +import { CreateStatusHistoryDto } from '@app/contracts/status-history/DTO/create-status-history.dto'; +import { UpdateStatusHistoryWithIdDto } from '@app/contracts/status-history/DTO/update-status-history.dto'; +import { STATUS_HISTORIES_PATTERNS } from '@app/contracts/status-history/patterns/status-histories.patterns'; + +@Controller() +export class StatusHistoriesController { + constructor(private readonly statusHistoriesService: StatusHistoriesService) {} + + @MessagePattern(STATUS_HISTORIES_PATTERNS.CREATE) + create(@Payload() createStatusHistoryDto: CreateStatusHistoryDto) { + return this.statusHistoriesService.create(createStatusHistoryDto); + } + + @MessagePattern(STATUS_HISTORIES_PATTERNS.FIND_ALL) + findAll() { + return this.statusHistoriesService.findAll(); + } + + @MessagePattern(STATUS_HISTORIES_PATTERNS.FIND_ONE) + findOne(@Payload() {id}: IdDto) { + return this.statusHistoriesService.findOne(id); + } + + @MessagePattern(STATUS_HISTORIES_PATTERNS.UPDATE) + update(@Payload() updateStatusHistoryDto: UpdateStatusHistoryWithIdDto) { + const { id, ...updateData } = updateStatusHistoryDto; + return this.statusHistoriesService.update(id, updateData); + } + + @MessagePattern(STATUS_HISTORIES_PATTERNS.REMOVE) + remove(@Payload() {id}: IdDto) { + return this.statusHistoriesService.remove(id); + } +} diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.dao.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.dao.ts new file mode 100644 index 0000000..5200604 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.dao.ts @@ -0,0 +1,36 @@ +import { CreateStatusHistoryDto } from "@app/contracts/status-history/DTO/create-status-history.dto"; +import { UpdateStatusHistoryDto } from "@app/contracts/status-history/DTO/update-status-history.dto"; +import { StatusHistory } from "@app/contracts/status-history/entities/status-history.entity"; +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +@Injectable() +export class StatusHistoriesDao { + constructor( + @InjectRepository(StatusHistory) + private statusHistoriesRepository: Repository + ) {} + + create(statusHistory: CreateStatusHistoryDto) { + const newStatusHistory = this.statusHistoriesRepository.create(statusHistory); + return this.statusHistoriesRepository.save(newStatusHistory); + } + findAll() { + return this.statusHistoriesRepository.find(); + } + findOne(id: string) { + return this.statusHistoriesRepository.findOne({ where: { id } }); + } + + async update(id: string, statusHistory: UpdateStatusHistoryDto) { + const updatedStatusHistory = await this.statusHistoriesRepository.update(id, statusHistory); + return !!updatedStatusHistory.affected; + } + + async remove(id: string) { + const deletedStatusHistory = await this.statusHistoriesRepository.delete(id); + return !!deletedStatusHistory.affected; + } + +} \ No newline at end of file diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.module.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.module.ts new file mode 100644 index 0000000..3446127 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common'; +import { StatusHistoriesService } from './status-histories.service'; +import { StatusHistoriesController } from './status-histories.controller'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { StatusHistory } from '@app/contracts/status-history/entities/status-history.entity'; +import { StatusHistoriesDao } from './status-histories.dao'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([StatusHistory]), + ], + controllers: [StatusHistoriesController], + providers: [StatusHistoriesService, StatusHistoriesDao], +}) +export class StatusHistoriesModule {} diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.service.spec.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.service.spec.ts new file mode 100644 index 0000000..2844409 --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StatusHistoriesService } from './status-histories.service'; + +describe('StatusHistoriesService', () => { + let service: StatusHistoriesService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [StatusHistoriesService], + }).compile(); + + service = module.get(StatusHistoriesService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/backend/manager/apps/status-histories/src/status-histories/status-histories.service.ts b/backend/manager/apps/status-histories/src/status-histories/status-histories.service.ts new file mode 100644 index 0000000..3c5b1af --- /dev/null +++ b/backend/manager/apps/status-histories/src/status-histories/status-histories.service.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@nestjs/common'; +import { StatusHistoriesDao } from './status-histories.dao'; +import { CreateStatusHistoryDto } from '@app/contracts/status-history/DTO/create-status-history.dto'; +import { UpdateStatusHistoryDto } from '@app/contracts/status-history/DTO/update-status-history.dto'; + +@Injectable() +export class StatusHistoriesService { + constructor( + private statusHistoriesDao: StatusHistoriesDao + ) {} + + create(createStatusHistoryDto: CreateStatusHistoryDto) { + return this.statusHistoriesDao.create(createStatusHistoryDto); + } + + findAll() { + return this.statusHistoriesDao.findAll(); + } + + findOne(id: string) { + return this.statusHistoriesDao.findOne(id); + } + + async update(id: string, updateStatusHistoryDto: UpdateStatusHistoryDto) { + return this.statusHistoriesDao.update(id, updateStatusHistoryDto); + } + + async remove(id: string) { + return this.statusHistoriesDao.remove(id); + } + +} diff --git a/backend/manager/apps/status-history/test/app.e2e-spec.ts b/backend/manager/apps/status-histories/test/app.e2e-spec.ts similarity index 75% rename from backend/manager/apps/status-history/test/app.e2e-spec.ts rename to backend/manager/apps/status-histories/test/app.e2e-spec.ts index 1802558..4108b5d 100644 --- a/backend/manager/apps/status-history/test/app.e2e-spec.ts +++ b/backend/manager/apps/status-histories/test/app.e2e-spec.ts @@ -1,14 +1,14 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; -import { StatusHistoryModule } from './../src/status-history.module'; +import { StatusHistoriesModule } from './../src/status-histories.module'; -describe('StatusHistoryController (e2e)', () => { +describe('StatusHistoriesController (e2e)', () => { let app: INestApplication; beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ - imports: [StatusHistoryModule], + imports: [StatusHistoriesModule], }).compile(); app = moduleFixture.createNestApplication(); diff --git a/backend/manager/apps/status-history/test/jest-e2e.json b/backend/manager/apps/status-histories/test/jest-e2e.json similarity index 100% rename from backend/manager/apps/status-history/test/jest-e2e.json rename to backend/manager/apps/status-histories/test/jest-e2e.json diff --git a/backend/manager/apps/status-history/tsconfig.app.json b/backend/manager/apps/status-histories/tsconfig.app.json similarity index 78% rename from backend/manager/apps/status-history/tsconfig.app.json rename to backend/manager/apps/status-histories/tsconfig.app.json index add4fb4..6522220 100644 --- a/backend/manager/apps/status-history/tsconfig.app.json +++ b/backend/manager/apps/status-histories/tsconfig.app.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "declaration": false, - "outDir": "../../dist/apps/status-history" + "outDir": "../../dist/apps/status-histories" }, "include": ["src/**/*"], "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] diff --git a/backend/manager/apps/status-history/src/main.ts b/backend/manager/apps/status-history/src/main.ts deleted file mode 100644 index 3454734..0000000 --- a/backend/manager/apps/status-history/src/main.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { NestFactory } from '@nestjs/core'; -import { StatusHistoryModule } from './status-history.module'; - -async function bootstrap() { - const app = await NestFactory.create(StatusHistoryModule); - await app.listen(process.env.port ?? 3000); -} -bootstrap(); diff --git a/backend/manager/apps/status-history/src/status-history.controller.spec.ts b/backend/manager/apps/status-history/src/status-history.controller.spec.ts deleted file mode 100644 index a62856a..0000000 --- a/backend/manager/apps/status-history/src/status-history.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { StatusHistoryController } from './status-history.controller'; -import { StatusHistoryService } from './status-history.service'; - -describe('StatusHistoryController', () => { - let statusHistoryController: StatusHistoryController; - - beforeEach(async () => { - const app: TestingModule = await Test.createTestingModule({ - controllers: [StatusHistoryController], - providers: [StatusHistoryService], - }).compile(); - - statusHistoryController = app.get(StatusHistoryController); - }); - - describe('root', () => { - it('should return "Hello World!"', () => { - expect(statusHistoryController.getHello()).toBe('Hello World!'); - }); - }); -}); diff --git a/backend/manager/apps/status-history/src/status-history.controller.ts b/backend/manager/apps/status-history/src/status-history.controller.ts deleted file mode 100644 index e2834e6..0000000 --- a/backend/manager/apps/status-history/src/status-history.controller.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Controller, Get } from '@nestjs/common'; -import { StatusHistoryService } from './status-history.service'; - -@Controller() -export class StatusHistoryController { - constructor(private readonly statusHistoryService: StatusHistoryService) {} - - @Get() - getHello(): string { - return this.statusHistoryService.getHello(); - } -} diff --git a/backend/manager/apps/status-history/src/status-history.module.ts b/backend/manager/apps/status-history/src/status-history.module.ts deleted file mode 100644 index eb5310f..0000000 --- a/backend/manager/apps/status-history/src/status-history.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { StatusHistoryController } from './status-history.controller'; -import { StatusHistoryService } from './status-history.service'; - -@Module({ - imports: [], - controllers: [StatusHistoryController], - providers: [StatusHistoryService], -}) -export class StatusHistoryModule {} diff --git a/backend/manager/apps/status-history/src/status-history.service.ts b/backend/manager/apps/status-history/src/status-history.service.ts deleted file mode 100644 index 33bf1c4..0000000 --- a/backend/manager/apps/status-history/src/status-history.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class StatusHistoryService { - getHello(): string { - return 'Hello World!'; - } -} diff --git a/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts b/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts index 823e398..68c354e 100644 --- a/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts +++ b/backend/manager/libs/contracts/src/status-history/DTO/create-status-history.dto.ts @@ -6,7 +6,4 @@ export class CreateStatusHistoryDto { @IsUUID() status_id: string; - - @IsDateString() - changed_at: string; } diff --git a/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts b/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts index a872a8c..2b08ff5 100644 --- a/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts +++ b/backend/manager/libs/contracts/src/status-history/DTO/update-status-history.dto.ts @@ -1,4 +1,10 @@ -import { PartialType } from '@nestjs/mapped-types'; +import { IntersectionType, PartialType } from '@nestjs/mapped-types'; import { CreateStatusHistoryDto } from './create-status-history.dto'; +import { IdDto } from '@app/contracts/global-dto/id.dto'; -export class UpdateStatusHistoryDto extends PartialType(CreateStatusHistoryDto) {} \ No newline at end of file +export class UpdateStatusHistoryDto extends PartialType(CreateStatusHistoryDto) {} + +export class UpdateStatusHistoryWithIdDto extends IntersectionType( + IdDto, + UpdateStatusHistoryDto, +) {} \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/status-history/entities/status-history.entity.ts b/backend/manager/libs/contracts/src/status-history/entities/status-history.entity.ts new file mode 100644 index 0000000..73e063f --- /dev/null +++ b/backend/manager/libs/contracts/src/status-history/entities/status-history.entity.ts @@ -0,0 +1,21 @@ +import { + Entity, + Column, + PrimaryGeneratedColumn, + CreateDateColumn, +} from 'typeorm'; + +@Entity('status_history') +export class StatusHistory { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column('uuid') + patient_id: string; + + @Column('uuid') + status_id: string; + + @CreateDateColumn({ type: 'timestamp with time zone' }) + changed_at: Date; +} diff --git a/backend/manager/libs/contracts/src/status-history/patterns/status-histories.patterns.ts b/backend/manager/libs/contracts/src/status-history/patterns/status-histories.patterns.ts new file mode 100644 index 0000000..77356be --- /dev/null +++ b/backend/manager/libs/contracts/src/status-history/patterns/status-histories.patterns.ts @@ -0,0 +1,7 @@ +export const STATUS_HISTORIES_PATTERNS = { + FIND_ALL: 'status-histories.findAll', + FIND_ONE: 'status-histories.findOne', + CREATE: 'status-histories.create', + UPDATE: 'status-histories.update', + REMOVE: 'status-histories.remove' +} diff --git a/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts b/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts new file mode 100644 index 0000000..c761cfd --- /dev/null +++ b/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts @@ -0,0 +1,3 @@ +export const STATUS_HISTORIES_SERVICE_NAME = Symbol('STATUS_HISTORIES_SERVICE'); +export const STATUS_HISTORIES_QUEUE_NAME = 'status_histories_queue'; +export const STATUS_HISTORIES_NAMESPACE = 'status_histories'; \ No newline at end of file diff --git a/backend/manager/package.json b/backend/manager/package.json index b829913..bca42f8 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -16,7 +16,8 @@ "start:patients": "nest start patients --watch", "start:providers": "nest start providers --watch", "start:statuses": "nest start statuses --watch", - "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\" \"npm run start:statuses\"", + "start:histories": "nest start status-histories --watch", + "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\" \"npm run start:statuses\" \"npm run start:histories\"", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", From 4e7317d32d8e4458b86a0c8db19dfae734686105 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 21:16:51 -0500 Subject: [PATCH 20/52] =?UTF-8?q?=E2=9C=A8=20refactor(providers):=20clean?= =?UTF-8?q?=20up=20imports=20and=20logger=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager-api-gateway/src/providers/providers.service.ts | 6 +----- .../manager/apps/providers/src/providers/providers.dao.ts | 3 ++- .../apps/providers/src/providers/providers.service.ts | 3 --- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts index 0a592a5..dddd689 100644 --- a/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts +++ b/backend/manager/apps/manager-api-gateway/src/providers/providers.service.ts @@ -4,16 +4,12 @@ import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider. import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { PROVIDERS_PATTERNS } from '@app/contracts/providers/patterns/providers.patterns'; import { PROVIDERS_SERVICE_NAME } from '@app/contracts/providers/providers.constants'; -import { standardResponse } from '@app/standard-response'; -import { Inject, Injectable, Logger } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { ClientProxy } from '@nestjs/microservices'; -import { catchError, map, Observable, of } from 'rxjs'; @Injectable() export class ProvidersService { - private readonly logger = new Logger(); - constructor( @Inject(PROVIDERS_SERVICE_NAME) private readonly client: ClientProxy, ) {} diff --git a/backend/manager/apps/providers/src/providers/providers.dao.ts b/backend/manager/apps/providers/src/providers/providers.dao.ts index fc00898..9ea18d3 100644 --- a/backend/manager/apps/providers/src/providers/providers.dao.ts +++ b/backend/manager/apps/providers/src/providers/providers.dao.ts @@ -1,4 +1,5 @@ import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; +import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; @@ -25,7 +26,7 @@ export class ProvidersDao { return this.providersRepository.findOne({ where: { id } }); } - async update(id: string, provider: Partial) { + async update(id: string, provider: UpdateProviderDto) { const updatedProvider = await this.providersRepository.update(id, provider); return !!updatedProvider.affected; } diff --git a/backend/manager/apps/providers/src/providers/providers.service.ts b/backend/manager/apps/providers/src/providers/providers.service.ts index e052efd..b9f8fbc 100644 --- a/backend/manager/apps/providers/src/providers/providers.service.ts +++ b/backend/manager/apps/providers/src/providers/providers.service.ts @@ -1,9 +1,6 @@ import { CreateProviderDto } from '@app/contracts/providers/DTO/create-provider.dto'; import { UpdateProviderDto } from '@app/contracts/providers/DTO/update-provider.dto'; -import { Provider } from '@app/contracts/providers/entities/provider.entity'; import { Injectable } from '@nestjs/common'; -import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; import { ProvidersDao } from './providers.dao'; @Injectable() From 9c2e8281c87ec5ffa072edb405347838a99a9471 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 21:17:07 -0500 Subject: [PATCH 21/52] =?UTF-8?q?=E2=9C=A8=20feat(status-histories):=20add?= =?UTF-8?q?=20application=20configuration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/nest-cli.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/backend/manager/nest-cli.json b/backend/manager/nest-cli.json index c86d84e..be2dce4 100644 --- a/backend/manager/nest-cli.json +++ b/backend/manager/nest-cli.json @@ -82,6 +82,15 @@ "tsConfigPath": "libs/standard-response/tsconfig.lib.json" } }, + "status-histories": { + "type": "application", + "root": "apps/status-histories", + "entryFile": "main", + "sourceRoot": "apps/status-histories/src", + "compilerOptions": { + "tsConfigPath": "apps/status-histories/tsconfig.app.json" + } + }, "status-history": { "type": "application", "root": "apps/status-history", From 4718b057f09531590116a5a5520448da659a2f33 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 21:17:21 -0500 Subject: [PATCH 22/52] =?UTF-8?q?=E2=9C=A8=20feat(manager-api-gateway):=20?= =?UTF-8?q?add=20StatusHistoriesModule=20to=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/manager-api-gateway/src/manager-api-gateway.module.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts index bd2ab60..e8a3ebb 100644 --- a/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts +++ b/backend/manager/apps/manager-api-gateway/src/manager-api-gateway.module.ts @@ -3,9 +3,10 @@ import { PatientsModule } from './patients/patients.module'; import { LoggerModule } from '@app/logger/logger.module'; import { ProvidersModule } from './providers/providers.module'; import { StatusesModule } from './statuses/statuses.module'; +import { StatusHistoriesModule } from './status-histories/status-histories.module'; @Module({ - imports: [PatientsModule, LoggerModule, ProvidersModule, StatusesModule], + imports: [PatientsModule, LoggerModule, ProvidersModule, StatusesModule, StatusHistoriesModule], controllers: [], providers: [], }) From 1dab48fa781da41d0709b3a7f0de0d2491308872 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 21:18:01 -0500 Subject: [PATCH 23/52] =?UTF-8?q?=E2=9C=A8=20feat(envs):=20add=20environme?= =?UTF-8?q?nt=20configuration=20for=20statuses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager-api-gateway/src/config/envs.ts | 7 ++++++- backend/manager/apps/statuses/config/envs.ts | 21 +++++++++++++++++++ .../manager-api-gateway/manager.constants.ts | 1 + 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 backend/manager/apps/statuses/config/envs.ts create mode 100644 backend/manager/libs/contracts/src/manager-api-gateway/manager.constants.ts diff --git a/backend/manager/apps/manager-api-gateway/src/config/envs.ts b/backend/manager/apps/manager-api-gateway/src/config/envs.ts index b3392df..bf152b3 100644 --- a/backend/manager/apps/manager-api-gateway/src/config/envs.ts +++ b/backend/manager/apps/manager-api-gateway/src/config/envs.ts @@ -1,4 +1,4 @@ -import { MANAGER_NAMESPACE } from '@app/contracts/manager-api-gateway/manager.namespace'; +import { MANAGER_NAMESPACE } from '@app/contracts/manager-api-gateway/manager.constants'; import { config } from 'dotenv'; import { resolve } from 'path'; import { number, object, string } from 'yup'; @@ -14,6 +14,11 @@ const envVarsSchema = object({ RMQ_USER: string().default('guest'), RMQ_PASSWORD: string().default('guest'), RABBITMQ_URL: string().default('localhost:5672'), + DB_HOST: string().default('localhost'), + DB_PORT: number().default(5432), + DB_USERNAME: string().default('root'), + DB_PASSWORD: string().default('root'), + DB_DATABASE: string().default('test'), }).noUnknown(); export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/apps/statuses/config/envs.ts b/backend/manager/apps/statuses/config/envs.ts new file mode 100644 index 0000000..0055051 --- /dev/null +++ b/backend/manager/apps/statuses/config/envs.ts @@ -0,0 +1,21 @@ +import { PROVIDERS_NAMESPACE } from '@app/contracts/providers/providers.constants'; +import { config } from 'dotenv'; +import { resolve } from 'path'; +import { number, object, string } from 'yup'; + +config({ + path: resolve(process.cwd(), `apps/${PROVIDERS_NAMESPACE}/.env`), +}); + +const envVarsSchema = object({ + RMQ_USER: string().required(), + RMQ_PASSWORD: string().required(), + RABBITMQ_URL: string().required(), + DB_HOST: string().required(), + DB_PORT: number().required(), + DB_USERNAME: string().required(), + DB_PASSWORD: string().required(), + DB_DATABASE: string().required(), +}).noUnknown(); + +export const envs = envVarsSchema.validateSync(process.env); diff --git a/backend/manager/libs/contracts/src/manager-api-gateway/manager.constants.ts b/backend/manager/libs/contracts/src/manager-api-gateway/manager.constants.ts new file mode 100644 index 0000000..a3d7d5f --- /dev/null +++ b/backend/manager/libs/contracts/src/manager-api-gateway/manager.constants.ts @@ -0,0 +1 @@ +export const MANAGER_NAMESPACE = 'manager-api-gateway'; \ No newline at end of file From 81153e093df5cc6888dab39eb98d5f5e57228dc0 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Thu, 23 Oct 2025 22:14:14 -0500 Subject: [PATCH 24/52] =?UTF-8?q?=E2=9C=A8=20feat(statuses):=20add=20datab?= =?UTF-8?q?ase=20migrations=20and=20seeding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/apps/statuses/config/envs.ts | 4 +-- .../1729999999999-CreateStatusesTable.ts | 27 +++++++++++++++++ .../migrations/1761272799047-SeedStatuses.ts | 23 ++++++++++++++ .../apps/statuses/database/typeorm.config.ts | 16 ++++++++++ .../statuses/src/statuses/statuses.dao.ts | 2 +- backend/manager/docker-compose.dev.yml | 30 +++++++++++++++++++ backend/manager/init-conf/db-init/db-init.sql | 11 +++++++ .../status-histories.constants.ts | 4 +-- backend/manager/package-lock.json | 2 +- backend/manager/package.json | 5 ++-- 10 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 backend/manager/apps/statuses/database/migrations/1729999999999-CreateStatusesTable.ts create mode 100644 backend/manager/apps/statuses/database/migrations/1761272799047-SeedStatuses.ts create mode 100644 backend/manager/apps/statuses/database/typeorm.config.ts create mode 100644 backend/manager/docker-compose.dev.yml create mode 100644 backend/manager/init-conf/db-init/db-init.sql diff --git a/backend/manager/apps/statuses/config/envs.ts b/backend/manager/apps/statuses/config/envs.ts index 0055051..47bb1f4 100644 --- a/backend/manager/apps/statuses/config/envs.ts +++ b/backend/manager/apps/statuses/config/envs.ts @@ -1,10 +1,10 @@ -import { PROVIDERS_NAMESPACE } from '@app/contracts/providers/providers.constants'; +import { STATUSES_NAMESPACE } from '@app/contracts/statuses/statuses.constants'; import { config } from 'dotenv'; import { resolve } from 'path'; import { number, object, string } from 'yup'; config({ - path: resolve(process.cwd(), `apps/${PROVIDERS_NAMESPACE}/.env`), + path: resolve(process.cwd(), `apps/${STATUSES_NAMESPACE}/.env`), }); const envVarsSchema = object({ diff --git a/backend/manager/apps/statuses/database/migrations/1729999999999-CreateStatusesTable.ts b/backend/manager/apps/statuses/database/migrations/1729999999999-CreateStatusesTable.ts new file mode 100644 index 0000000..4ab6058 --- /dev/null +++ b/backend/manager/apps/statuses/database/migrations/1729999999999-CreateStatusesTable.ts @@ -0,0 +1,27 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class CreateStatusesTable1729999999999 implements MigrationInterface { + name = 'CreateStatusesTable1729999999999'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + `); + + await queryRunner.query(` + CREATE TABLE public.statuses ( + id uuid DEFAULT uuid_generate_v4() NOT NULL, + name varchar(100) NOT NULL, + parent_id uuid NULL, + "order" int4 DEFAULT 0 NOT NULL, + CONSTRAINT "PK_2fd3770acdb67736f1a3e3d5399" PRIMARY KEY (id) + ); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DROP TABLE IF EXISTS public.statuses; + `); + } +} \ No newline at end of file diff --git a/backend/manager/apps/statuses/database/migrations/1761272799047-SeedStatuses.ts b/backend/manager/apps/statuses/database/migrations/1761272799047-SeedStatuses.ts new file mode 100644 index 0000000..b1ca93d --- /dev/null +++ b/backend/manager/apps/statuses/database/migrations/1761272799047-SeedStatuses.ts @@ -0,0 +1,23 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class SeedStatuses1730000000000 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + INSERT INTO statuses (id, name, parent_id, "order") + VALUES + (uuid_generate_v4(), 'Scheduled', NULL, 1), + (uuid_generate_v4(), 'Checked-In', NULL, 2), + (uuid_generate_v4(), 'In Consultation', NULL, 3), + (uuid_generate_v4(), 'Cancelled', NULL, 4), + (uuid_generate_v4(), 'No-Show', NULL, 5); + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + DELETE FROM statuses WHERE name IN ( + 'Scheduled', 'Checked-In', 'In Consultation', 'Cancelled', 'No-Show' + ); + `); + } +} \ No newline at end of file diff --git a/backend/manager/apps/statuses/database/typeorm.config.ts b/backend/manager/apps/statuses/database/typeorm.config.ts new file mode 100644 index 0000000..0e3062b --- /dev/null +++ b/backend/manager/apps/statuses/database/typeorm.config.ts @@ -0,0 +1,16 @@ +import { DataSource } from 'typeorm'; +import { envs } from '../config/envs'; +import { Status } from '@app/contracts/statuses/entities/status.entity'; + +export default new DataSource({ + type: 'postgres', + host: envs.DB_HOST || 'localhost', + port: envs.DB_PORT || 5432, + username: envs.DB_USERNAME || 'postgres', + password: envs.DB_PASSWORD || 'postgres', + database: envs.DB_DATABASE || 'manager', + entities: [Status], + migrations: [__dirname + '/migrations/*{.ts,.js}'], + synchronize: false, + logging: true, +}); \ No newline at end of file diff --git a/backend/manager/apps/statuses/src/statuses/statuses.dao.ts b/backend/manager/apps/statuses/src/statuses/statuses.dao.ts index b058cc1..4862387 100644 --- a/backend/manager/apps/statuses/src/statuses/statuses.dao.ts +++ b/backend/manager/apps/statuses/src/statuses/statuses.dao.ts @@ -32,7 +32,7 @@ export class StatusesDao { async isOrderUnique(parentId: string | null, order: number | null): Promise { - if(!parentId || order === null) return true; + if(!parentId || !order) return true; const existingStatus = await this.statusesRepository.findOne({ where: { parent_id: parentId, order }, diff --git a/backend/manager/docker-compose.dev.yml b/backend/manager/docker-compose.dev.yml new file mode 100644 index 0000000..876730c --- /dev/null +++ b/backend/manager/docker-compose.dev.yml @@ -0,0 +1,30 @@ +version: "3.8" + +services: + rabbitmq: + image: rabbitmq:3-management + container_name: rabbitmq + ports: + - "5672:5672" + - "15672:15672" + environment: + RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASS} + volumes: + - rabbitmq_data:/var/lib/rabbitmq + + postgres: + image: postgres:16 + container_name: postgres + ports: + - "${POSTGRES_PORT}:5432" + environment: + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - pgdata:/var/lib/postgresql/data + - ./init-conf/db-init:/docker-entrypoint-initdb.d + +volumes: + rabbitmq_data: + pgdata: \ No newline at end of file diff --git a/backend/manager/init-conf/db-init/db-init.sql b/backend/manager/init-conf/db-init/db-init.sql new file mode 100644 index 0000000..281d10b --- /dev/null +++ b/backend/manager/init-conf/db-init/db-init.sql @@ -0,0 +1,11 @@ +CREATE DATABASE manager_db; +CREATE DATABASE provider_db; +CREATE DATABASE patient_db; +CREATE DATABASE status_db; +CREATE DATABASE status_history_db; + +GRANT ALL PRIVILEGES ON DATABASE manager_db TO marioch; +GRANT ALL PRIVILEGES ON DATABASE provider_db TO marioch; +GRANT ALL PRIVILEGES ON DATABASE patient_db TO marioch; +GRANT ALL PRIVILEGES ON DATABASE status_db TO marioch; +GRANT ALL PRIVILEGES ON DATABASE status_history_db TO marioch; \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts b/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts index c761cfd..ada0e6c 100644 --- a/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts +++ b/backend/manager/libs/contracts/src/status-history/status-histories.constants.ts @@ -1,3 +1,3 @@ export const STATUS_HISTORIES_SERVICE_NAME = Symbol('STATUS_HISTORIES_SERVICE'); -export const STATUS_HISTORIES_QUEUE_NAME = 'status_histories_queue'; -export const STATUS_HISTORIES_NAMESPACE = 'status_histories'; \ No newline at end of file +export const STATUS_HISTORIES_QUEUE_NAME = 'status-histories_queue'; +export const STATUS_HISTORIES_NAMESPACE = 'status-histories'; \ No newline at end of file diff --git a/backend/manager/package-lock.json b/backend/manager/package-lock.json index ee61443..9c2d260 100644 --- a/backend/manager/package-lock.json +++ b/backend/manager/package-lock.json @@ -24,7 +24,6 @@ "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "typeorm": "^0.3.27", "yup": "^1.7.1" }, "devDependencies": { @@ -50,6 +49,7 @@ "ts-loader": "^9.5.2", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", + "typeorm": "^0.3.27", "typescript": "^5.7.3", "typescript-eslint": "^8.20.0" } diff --git a/backend/manager/package.json b/backend/manager/package.json index bca42f8..6798fc7 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -12,6 +12,7 @@ "start:dev": "nest start --watch", "start:debug": "nest start --debug --watch", "start:prod": "node dist/apps/manager/main", + "typeorm:statuses": "npx ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli.js -d apps/statuses/database/typeorm.config.ts migration:run", "start:gateway": "nest start manager-api-gateway --watch", "start:patients": "nest start patients --watch", "start:providers": "nest start providers --watch", @@ -41,7 +42,6 @@ "pg": "^8.16.3", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", - "typeorm": "^0.3.27", "yup": "^1.7.1" }, "devDependencies": { @@ -67,6 +67,7 @@ "ts-loader": "^9.5.2", "ts-node": "^10.9.2", "tsconfig-paths": "^4.2.0", + "typeorm": "^0.3.27", "typescript": "^5.7.3", "typescript-eslint": "^8.20.0" }, @@ -98,4 +99,4 @@ "^@app/standard-response(|/.*)$": "/libs/standard-response/src/$1" } } -} \ No newline at end of file +} From 4e4fad23ea9e94a164ef740bfa874e91ef9bcd14 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 06:01:39 -0500 Subject: [PATCH 25/52] =?UTF-8?q?=F0=9F=8E=89=20Begin=20Front=20End?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/libs/contracts/src/index.ts | 4 +- frontend/manager-app/README.md | 16 + frontend/manager-app/eslint.config.js | 29 + frontend/manager-app/index.html | 13 + frontend/manager-app/package-lock.json | 3563 +++++++++++++++++ frontend/manager-app/package.json | 35 + frontend/manager-app/public/vite.svg | 1 + frontend/manager-app/src/App.css | 42 + frontend/manager-app/src/App.jsx | 16 + frontend/manager-app/src/assets/react.svg | 1 + frontend/manager-app/src/index.css | 70 + frontend/manager-app/src/main.jsx | 10 + .../src/pages/dashboard/DashboardPage.jsx | 23 + .../patient-history/PatientHistoryPage.jsx | 9 + .../patient-list/PatientListPage.jsx | 9 + .../PatientUpdateControl.jsx | 12 + .../pages/dashboard/patient/PatientPage.jsx | 9 + .../provider-list/ProviderListPage.jsx | 12 + .../pages/dashboard/provider/ProviderPage.jsx | 12 + frontend/manager-app/src/router/router.jsx | 59 + .../manager-app/src/router/routesLazyLoad.jsx | 25 + frontend/manager-app/vite.config.js | 8 + 22 files changed, 3976 insertions(+), 2 deletions(-) create mode 100644 frontend/manager-app/README.md create mode 100644 frontend/manager-app/eslint.config.js create mode 100644 frontend/manager-app/index.html create mode 100644 frontend/manager-app/package-lock.json create mode 100644 frontend/manager-app/package.json create mode 100644 frontend/manager-app/public/vite.svg create mode 100644 frontend/manager-app/src/App.css create mode 100644 frontend/manager-app/src/App.jsx create mode 100644 frontend/manager-app/src/assets/react.svg create mode 100644 frontend/manager-app/src/index.css create mode 100644 frontend/manager-app/src/main.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/DashboardPage.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/patient-history/PatientHistoryPage.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/patient-update-control/PatientUpdateControl.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx create mode 100644 frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx create mode 100644 frontend/manager-app/src/router/router.jsx create mode 100644 frontend/manager-app/src/router/routesLazyLoad.jsx create mode 100644 frontend/manager-app/vite.config.js diff --git a/backend/manager/libs/contracts/src/index.ts b/backend/manager/libs/contracts/src/index.ts index 33b915a..15c1e83 100644 --- a/backend/manager/libs/contracts/src/index.ts +++ b/backend/manager/libs/contracts/src/index.ts @@ -1,2 +1,2 @@ -export * from './contracts.module'; -export * from './contracts.service'; +// export * from './contracts.module'; +// export * from './contracts.service'; diff --git a/frontend/manager-app/README.md b/frontend/manager-app/README.md new file mode 100644 index 0000000..18bc70e --- /dev/null +++ b/frontend/manager-app/README.md @@ -0,0 +1,16 @@ +# React + Vite + +This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. + +Currently, two official plugins are available: + +- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh +- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh + +## React Compiler + +The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). + +## Expanding the ESLint configuration + +If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. diff --git a/frontend/manager-app/eslint.config.js b/frontend/manager-app/eslint.config.js new file mode 100644 index 0000000..cee1e2c --- /dev/null +++ b/frontend/manager-app/eslint.config.js @@ -0,0 +1,29 @@ +import js from '@eslint/js' +import globals from 'globals' +import reactHooks from 'eslint-plugin-react-hooks' +import reactRefresh from 'eslint-plugin-react-refresh' +import { defineConfig, globalIgnores } from 'eslint/config' + +export default defineConfig([ + globalIgnores(['dist']), + { + files: ['**/*.{js,jsx}'], + extends: [ + js.configs.recommended, + reactHooks.configs['recommended-latest'], + reactRefresh.configs.vite, + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser, + parserOptions: { + ecmaVersion: 'latest', + ecmaFeatures: { jsx: true }, + sourceType: 'module', + }, + }, + rules: { + 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }], + }, + }, +]) diff --git a/frontend/manager-app/index.html b/frontend/manager-app/index.html new file mode 100644 index 0000000..ea945a4 --- /dev/null +++ b/frontend/manager-app/index.html @@ -0,0 +1,13 @@ + + + + + + + Manager + + +
+ + + diff --git a/frontend/manager-app/package-lock.json b/frontend/manager-app/package-lock.json new file mode 100644 index 0000000..ec24b8a --- /dev/null +++ b/frontend/manager-app/package-lock.json @@ -0,0 +1,3563 @@ +{ + "name": "manager-app", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "manager-app", + "version": "0.0.0", + "dependencies": { + "@tailwindcss/vite": "^4.1.16", + "clsx": "^2.1.1", + "formik": "^2.4.6", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-router": "^7.9.4", + "react-router-dom": "^7.9.4", + "tailwindcss": "^4.1.16", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "vite": "^7.1.7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", + "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", + "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", + "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", + "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", + "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", + "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", + "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", + "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", + "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", + "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", + "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", + "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", + "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", + "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", + "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", + "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", + "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", + "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", + "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", + "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", + "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", + "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", + "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", + "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", + "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", + "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", + "integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", + "integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", + "integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", + "integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.16.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.38", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.38.tgz", + "integrity": "sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz", + "integrity": "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz", + "integrity": "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz", + "integrity": "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz", + "integrity": "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz", + "integrity": "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz", + "integrity": "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz", + "integrity": "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz", + "integrity": "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz", + "integrity": "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz", + "integrity": "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz", + "integrity": "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz", + "integrity": "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz", + "integrity": "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz", + "integrity": "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz", + "integrity": "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz", + "integrity": "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz", + "integrity": "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz", + "integrity": "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz", + "integrity": "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz", + "integrity": "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz", + "integrity": "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz", + "integrity": "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tailwindcss/node": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.16.tgz", + "integrity": "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.1", + "lightningcss": "1.30.2", + "magic-string": "^0.30.19", + "source-map-js": "^1.2.1", + "tailwindcss": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.16.tgz", + "integrity": "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-arm64": "4.1.16", + "@tailwindcss/oxide-darwin-x64": "4.1.16", + "@tailwindcss/oxide-freebsd-x64": "4.1.16", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", + "@tailwindcss/oxide-linux-x64-musl": "4.1.16", + "@tailwindcss/oxide-wasm32-wasi": "4.1.16", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.16.tgz", + "integrity": "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.16.tgz", + "integrity": "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.16.tgz", + "integrity": "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.16.tgz", + "integrity": "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.16.tgz", + "integrity": "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.16.tgz", + "integrity": "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.16.tgz", + "integrity": "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.16.tgz", + "integrity": "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.16.tgz", + "integrity": "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.16.tgz", + "integrity": "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.7", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.16.tgz", + "integrity": "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.16.tgz", + "integrity": "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tailwindcss/vite": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.16.tgz", + "integrity": "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg==", + "license": "MIT", + "dependencies": { + "@tailwindcss/node": "4.1.16", + "@tailwindcss/oxide": "4.1.16", + "tailwindcss": "4.1.16" + }, + "peerDependencies": { + "vite": "^5.2.0 || ^6 || ^7" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.7.tgz", + "integrity": "sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==", + "license": "MIT", + "dependencies": { + "hoist-non-react-statics": "^3.3.0" + }, + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", + "license": "MIT", + "dependencies": { + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz", + "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.0.4.tgz", + "integrity": "sha512-La0KD0vGkVkSk6K+piWDKRUyg8Rl5iAIKRMH0vMJI0Eg47bq1eOxmoObAaQG37WMW9MSyk7Cs8EIWwJC1PtzKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.4", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.38", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.20.tgz", + "integrity": "sha512-JMWsdF+O8Orq3EMukbUN1QfbLK9mX2CkUmQBcW2T0s8OmdAUL5LLM/6wFwSrqXzlXB13yhyK9gTKS1rIizOduQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.27.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.27.0.tgz", + "integrity": "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.19", + "caniuse-lite": "^1.0.30001751", + "electron-to-chromium": "^1.5.238", + "node-releases": "^2.0.26", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001751", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", + "integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", + "integrity": "sha512-OBwbZjWgrCOH+g6uJsA2/7Twpas2OlepS9uvByJjR2datRDuKGYeD+nP8lBBks2qnB7bGJNHDUx7c/YLaT3QMQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/esbuild": { + "version": "0.25.11", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", + "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.11", + "@esbuild/android-arm": "0.25.11", + "@esbuild/android-arm64": "0.25.11", + "@esbuild/android-x64": "0.25.11", + "@esbuild/darwin-arm64": "0.25.11", + "@esbuild/darwin-x64": "0.25.11", + "@esbuild/freebsd-arm64": "0.25.11", + "@esbuild/freebsd-x64": "0.25.11", + "@esbuild/linux-arm": "0.25.11", + "@esbuild/linux-arm64": "0.25.11", + "@esbuild/linux-ia32": "0.25.11", + "@esbuild/linux-loong64": "0.25.11", + "@esbuild/linux-mips64el": "0.25.11", + "@esbuild/linux-ppc64": "0.25.11", + "@esbuild/linux-riscv64": "0.25.11", + "@esbuild/linux-s390x": "0.25.11", + "@esbuild/linux-x64": "0.25.11", + "@esbuild/netbsd-arm64": "0.25.11", + "@esbuild/netbsd-x64": "0.25.11", + "@esbuild/openbsd-arm64": "0.25.11", + "@esbuild/openbsd-x64": "0.25.11", + "@esbuild/openharmony-arm64": "0.25.11", + "@esbuild/sunos-x64": "0.25.11", + "@esbuild/win32-arm64": "0.25.11", + "@esbuild/win32-ia32": "0.25.11", + "@esbuild/win32-x64": "0.25.11" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.38.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", + "integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.1", + "@eslint/core": "^0.16.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.38.0", + "@eslint/plugin-kit": "^0.4.0", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", + "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=8.40" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/formik": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", + "integrity": "sha512-A+2EI7U7aG296q2TLGvNapDNTZp1khVt5Vk0Q/fyfSROss0V/V6+txt2aJnwEos44IxTCW/LYAi/zgWzlevj+g==", + "funding": [ + { + "type": "individual", + "url": "https://opencollective.com/formik" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.1", + "deepmerge": "^2.1.1", + "hoist-non-react-statics": "^3.3.0", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "react-fast-compare": "^2.0.1", + "tiny-warning": "^1.0.2", + "tslib": "^2.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lightningcss": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", + "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.30.2", + "lightningcss-darwin-arm64": "1.30.2", + "lightningcss-darwin-x64": "1.30.2", + "lightningcss-freebsd-x64": "1.30.2", + "lightningcss-linux-arm-gnueabihf": "1.30.2", + "lightningcss-linux-arm64-gnu": "1.30.2", + "lightningcss-linux-arm64-musl": "1.30.2", + "lightningcss-linux-x64-gnu": "1.30.2", + "lightningcss-linux-x64-musl": "1.30.2", + "lightningcss-win32-arm64-msvc": "1.30.2", + "lightningcss-win32-x64-msvc": "1.30.2" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", + "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", + "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", + "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", + "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", + "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", + "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", + "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", + "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", + "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", + "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.30.2", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", + "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", + "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, + "node_modules/react-fast-compare": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", + "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==", + "license": "MIT" + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.4.tgz", + "integrity": "sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.4.tgz", + "integrity": "sha512-f30P6bIkmYvnHHa5Gcu65deIXoA2+r3Eb6PJIAddvsT9aGlchMatJ51GgpU470aSqRRbFX22T70yQNUGuW3DfA==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.4" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/rollup": { + "version": "4.52.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz", + "integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.52.5", + "@rollup/rollup-android-arm64": "4.52.5", + "@rollup/rollup-darwin-arm64": "4.52.5", + "@rollup/rollup-darwin-x64": "4.52.5", + "@rollup/rollup-freebsd-arm64": "4.52.5", + "@rollup/rollup-freebsd-x64": "4.52.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", + "@rollup/rollup-linux-arm-musleabihf": "4.52.5", + "@rollup/rollup-linux-arm64-gnu": "4.52.5", + "@rollup/rollup-linux-arm64-musl": "4.52.5", + "@rollup/rollup-linux-loong64-gnu": "4.52.5", + "@rollup/rollup-linux-ppc64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-gnu": "4.52.5", + "@rollup/rollup-linux-riscv64-musl": "4.52.5", + "@rollup/rollup-linux-s390x-gnu": "4.52.5", + "@rollup/rollup-linux-x64-gnu": "4.52.5", + "@rollup/rollup-linux-x64-musl": "4.52.5", + "@rollup/rollup-openharmony-arm64": "4.52.5", + "@rollup/rollup-win32-arm64-msvc": "4.52.5", + "@rollup/rollup-win32-ia32-msvc": "4.52.5", + "@rollup/rollup-win32-x64-gnu": "4.52.5", + "@rollup/rollup-win32-x64-msvc": "4.52.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "license": "MIT" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tailwindcss": { + "version": "4.1.16", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", + "integrity": "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA==", + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, + "node_modules/tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz", + "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yup": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz", + "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + } + } +} diff --git a/frontend/manager-app/package.json b/frontend/manager-app/package.json new file mode 100644 index 0000000..1ea5177 --- /dev/null +++ b/frontend/manager-app/package.json @@ -0,0 +1,35 @@ +{ + "name": "manager-app", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@tailwindcss/vite": "^4.1.16", + "clsx": "^2.1.1", + "formik": "^2.4.6", + "prop-types": "^15.8.1", + "react": "^19.1.1", + "react-dom": "^19.1.1", + "react-router": "^7.9.4", + "react-router-dom": "^7.9.4", + "tailwindcss": "^4.1.16", + "yup": "^1.7.1" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@types/react": "^19.1.16", + "@types/react-dom": "^19.1.9", + "@vitejs/plugin-react": "^5.0.4", + "eslint": "^9.36.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.22", + "globals": "^16.4.0", + "vite": "^7.1.7" + } +} diff --git a/frontend/manager-app/public/vite.svg b/frontend/manager-app/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/frontend/manager-app/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/manager-app/src/App.css b/frontend/manager-app/src/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/frontend/manager-app/src/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/frontend/manager-app/src/App.jsx b/frontend/manager-app/src/App.jsx new file mode 100644 index 0000000..fe18f95 --- /dev/null +++ b/frontend/manager-app/src/App.jsx @@ -0,0 +1,16 @@ +import { Suspense } from 'react'; +import { + RouterProvider, +} from "react-router"; +import './App.css' +import { router } from './router/router'; + +function App() { + return ( + Cargando...}> + + + ); +} + +export default App diff --git a/frontend/manager-app/src/assets/react.svg b/frontend/manager-app/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/frontend/manager-app/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/frontend/manager-app/src/index.css b/frontend/manager-app/src/index.css new file mode 100644 index 0000000..444f889 --- /dev/null +++ b/frontend/manager-app/src/index.css @@ -0,0 +1,70 @@ +@import "tailwindcss"; + +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/frontend/manager-app/src/main.jsx b/frontend/manager-app/src/main.jsx new file mode 100644 index 0000000..b9a1a6d --- /dev/null +++ b/frontend/manager-app/src/main.jsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' + +createRoot(document.getElementById('root')).render( + + + , +) diff --git a/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx b/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx new file mode 100644 index 0000000..157224c --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx @@ -0,0 +1,23 @@ +import { Outlet, NavLink } from "react-router-dom"; + +const DashboardPage = () => { + return ( +
+ + +
+ +
+ ); +}; + +DashboardPage.propTypes = {} + +export default DashboardPage \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/patient-history/PatientHistoryPage.jsx b/frontend/manager-app/src/pages/dashboard/patient-history/PatientHistoryPage.jsx new file mode 100644 index 0000000..a86b1a9 --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/patient-history/PatientHistoryPage.jsx @@ -0,0 +1,9 @@ +const PatientHistoryPage = props => { + return ( +
PatientHistoryPage
+ ) +} + +PatientHistoryPage.propTypes = {} + +export default PatientHistoryPage \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx b/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx new file mode 100644 index 0000000..a40dac0 --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx @@ -0,0 +1,9 @@ +const PatientListPage = props => { + return ( +
PatientListPage
+ ) +} + +PatientListPage.propTypes = {} + +export default PatientListPage \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/patient-update-control/PatientUpdateControl.jsx b/frontend/manager-app/src/pages/dashboard/patient-update-control/PatientUpdateControl.jsx new file mode 100644 index 0000000..377b93b --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/patient-update-control/PatientUpdateControl.jsx @@ -0,0 +1,12 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const PatientUpdateControl = props => { + return ( +
PatientUpdateControl
+ ) +} + +PatientUpdateControl.propTypes = {} + +export default PatientUpdateControl \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx b/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx new file mode 100644 index 0000000..1132420 --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx @@ -0,0 +1,9 @@ +const PatientPage = () => { + return ( +
PatientPage
+ ) +} + +PatientPage.propTypes = {} + +export default PatientPage \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx b/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx new file mode 100644 index 0000000..9e36fd8 --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx @@ -0,0 +1,12 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const ProviderListPage = props => { + return ( +
ProviderListPage
+ ) +} + +ProviderListPage.propTypes = {} + +export default ProviderListPage \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx new file mode 100644 index 0000000..07199b3 --- /dev/null +++ b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx @@ -0,0 +1,12 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const ProviderPage = props => { + return ( +
ProviderPage
+ ) +} + +ProviderPage.propTypes = {} + +export default ProviderPage \ No newline at end of file diff --git a/frontend/manager-app/src/router/router.jsx b/frontend/manager-app/src/router/router.jsx new file mode 100644 index 0000000..5a65701 --- /dev/null +++ b/frontend/manager-app/src/router/router.jsx @@ -0,0 +1,59 @@ +import { createHashRouter, Navigate } from "react-router-dom"; +import DashboardPage from "../pages/dashboard/DashboardPage"; +import { + PatientHistoryPage, + PatientListPage, + PatientPage, + PatientUpdateControl, + ProviderListPage, + ProviderPage +} from "./routesLazyLoad"; + +export const router = createHashRouter([ + { + path: '/', + element: , + }, + { + path: '/dashboard', + element: , + children: [ + { + index: true, + element: , + }, + { + path: 'patient', + element: , + }, + { + path: 'provider', + element: , + }, + { + path: 'patient-list', + element: , + }, + { + path: 'provider-list', + element: , + }, + { + path: 'patient-update-control', + element: , + }, + { + path: 'patient-history', + element: , + }, + { + path: '*', + element: , + }, + ], + }, + { + path: '*', + element: , + }, +]); \ No newline at end of file diff --git a/frontend/manager-app/src/router/routesLazyLoad.jsx b/frontend/manager-app/src/router/routesLazyLoad.jsx new file mode 100644 index 0000000..2837809 --- /dev/null +++ b/frontend/manager-app/src/router/routesLazyLoad.jsx @@ -0,0 +1,25 @@ +import { lazy } from 'react'; + +export const PatientPage = lazy( + () => import('../pages/dashboard/patient/PatientPage') +); + +export const ProviderPage = lazy( + () => import('../pages/dashboard/provider/ProviderPage') +); + +export const PatientUpdateControl = lazy( + () => import('../pages/dashboard/patient-update-control/PatientUpdateControl') +); + +export const PatientHistoryPage = lazy( + () => import('../pages/dashboard/patient-history/PatientHistoryPage') +); + +export const PatientListPage = lazy( + () => import('../pages/dashboard/patient-list/PatientListPage') +); + +export const ProviderListPage = lazy( + () => import('../pages/dashboard/provider-list/ProviderListPage') +); \ No newline at end of file diff --git a/frontend/manager-app/vite.config.js b/frontend/manager-app/vite.config.js new file mode 100644 index 0000000..808fb67 --- /dev/null +++ b/frontend/manager-app/vite.config.js @@ -0,0 +1,8 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' +import tailwindcss from '@tailwindcss/vite' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react(), tailwindcss(),], +}) From a8101fa9f29c74ccb88b79dd0ef78aa2a819e996 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 07:22:31 -0500 Subject: [PATCH 26/52] =?UTF-8?q?=E2=9C=A8=20feat(ui):=20add=20GenericButt?= =?UTF-8?q?on,=20GenericDropdown,=20and=20GenericTextInput=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generic/form-items/GenericButton.jsx | 41 +++++++++ .../generic/form-items/GenericDropdown.jsx | 79 ++++++++++++++++ .../generic/form-items/GenericTextInput.jsx | 92 +++++++++++++++++++ 3 files changed, 212 insertions(+) create mode 100644 frontend/manager-app/src/components/generic/form-items/GenericButton.jsx create mode 100644 frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx create mode 100644 frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx diff --git a/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx new file mode 100644 index 0000000..37811b0 --- /dev/null +++ b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx @@ -0,0 +1,41 @@ +import PropTypes from 'prop-types' + +const GenericButton = ({ + children, + onClick, + type = "button", + disabled = false, + variant = "primary", + className = "", +}) => { + const baseStyle = + "px-4 py-2 rounded-lg font-semibold transition-all duration-200 focus:outline-none"; + + const variants = { + primary: "bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300", + secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300 disabled:bg-gray-200", + danger: "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300", + }; + + return ( + + ); +}; + +GenericButton.propTypes = { + children: PropTypes.node.isRequired, + onClick: PropTypes.func, + type: PropTypes.oneOf(["button", "submit", "reset"]), + disabled: PropTypes.bool, + variant: PropTypes.oneOf(["primary", "secondary", "danger"]), + className: PropTypes.string, +}; + +export default GenericButton; \ No newline at end of file diff --git a/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx new file mode 100644 index 0000000..eb4e39c --- /dev/null +++ b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx @@ -0,0 +1,79 @@ +import PropTypes from "prop-types"; + +const variants = { + primary: "bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300", + secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300 disabled:bg-gray-200", + danger: "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300", +}; + +const sizes = { + sm: "px-2 py-1 text-sm", + md: "px-3 py-2 text-base", + lg: "px-4 py-3 text-lg", +}; + +const GenericDropdown = ({ + label, + options = [], + value, + onChange, + placeholder = "Seleccionar...", + variant = "primary", + size = "md", + disabled = false, + className = "", +}) => { + return ( +
+ {label && ( + + )} + + +
+ ); +}; + +GenericDropdown.propTypes = { + label: PropTypes.string, + options: PropTypes.arrayOf( + PropTypes.oneOfType([ + PropTypes.string, + PropTypes.shape({ + label: PropTypes.string, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + }), + ]) + ).isRequired, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + onChange: PropTypes.func.isRequired, + placeholder: PropTypes.string, + variant: PropTypes.oneOf(["primary", "secondary", "danger"]), + size: PropTypes.oneOf(["sm", "md", "lg"]), + disabled: PropTypes.bool, + className: PropTypes.string, +}; + +export default GenericDropdown; \ No newline at end of file diff --git a/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx b/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx new file mode 100644 index 0000000..e8b816e --- /dev/null +++ b/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx @@ -0,0 +1,92 @@ +import PropTypes from "prop-types"; + +const variants = { + primary: + "border-gray-300 focus:border-blue-500 focus:ring-blue-400 text-gray-900", + secondary: + "border-gray-200 bg-gray-50 text-gray-700 focus:border-gray-400 focus:ring-gray-300", + danger: + "border-red-300 text-red-700 focus:border-red-500 focus:ring-red-400", +}; + +const sizes = { + sm: "px-2 py-1 text-sm rounded-lg", + md: "px-3 py-2 text-base rounded-xl", + lg: "px-4 py-3 text-lg rounded-2xl", +}; + +const GenericTextInput = ({ + name, + label = "", + dataType = "text", + form, + placeholder, + variant = "primary", + size = "md", + disabled = false, + className = "", + persistence = null +}) => { + const value = form.values[name]; + const error = form.touched[name] && form.errors[name]; + + const handleOnChange = (e) => { + form.setFieldValue(name, e.target.value); + if(!persistence) return; + persistence(e.target.value); + } + + return ( +
+ {label && ( + + )} + +
+ handleOnChange(e)} + onBlur={form.handleBlur} + placeholder={placeholder || ""} + disabled={disabled} + autoComplete="off" + className={`w-full border bg-transparent focus:outline-none focus:ring-2 transition-all duration-150 ${variants[variant]} ${sizes[size]} ${ + error ? "border-red-500 ring-red-200" : "" + } ${dataType === "percentage" ? "pr-8" : ""} ${className}`} + /> +
+ + {error &&

{form.errors[name]}

} +
+ ); +}; + +GenericTextInput.propTypes = { + name: PropTypes.string.isRequired, + label: PropTypes.string, + dataType: PropTypes.string, + placeholder: PropTypes.string, + form: PropTypes.shape({ + values: PropTypes.object.isRequired, + errors: PropTypes.object, + touched: PropTypes.object, + handleChange: PropTypes.func.isRequired, + handleBlur: PropTypes.func.isRequired, + setFieldValue: PropTypes.func, + setFieldTouched: PropTypes.func, + }).isRequired, + variant: PropTypes.oneOf(["primary", "secondary", "danger"]), + size: PropTypes.oneOf(["sm", "md", "lg"]), + disabled: PropTypes.bool, + className: PropTypes.string +}; + +export default GenericTextInput; From b1ed7f479cd83e71c9c0b489b72ad48f6f966067 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 07:22:53 -0500 Subject: [PATCH 27/52] =?UTF-8?q?=E2=9C=A8=20feat(validation):=20add=20inj?= =?UTF-8?q?ection=20validation=20method?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/src/App.jsx | 5 +++ .../src/utils/validation/injectionValidate.js | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 frontend/manager-app/src/utils/validation/injectionValidate.js diff --git a/frontend/manager-app/src/App.jsx b/frontend/manager-app/src/App.jsx index fe18f95..feaa1ae 100644 --- a/frontend/manager-app/src/App.jsx +++ b/frontend/manager-app/src/App.jsx @@ -4,8 +4,13 @@ import { } from "react-router"; import './App.css' import { router } from './router/router'; +import { addMethod, string } from 'yup'; +import { injectionValidate } from './utils/validation/injectionValidate'; function App() { + + addMethod(string, 'isNotInjection', injectionValidate); + return ( Cargando...}> diff --git a/frontend/manager-app/src/utils/validation/injectionValidate.js b/frontend/manager-app/src/utils/validation/injectionValidate.js new file mode 100644 index 0000000..e72606e --- /dev/null +++ b/frontend/manager-app/src/utils/validation/injectionValidate.js @@ -0,0 +1,36 @@ +const injectionParts = [ + '.?', + '\\bjavascript\\b|\\bscript\\b|\\.html|\\bfetch\\b|\\blocalstorage\\.setItem\\b|\\bsessionstorage\\.setItem\\b', + 'jquery\\b|\\$\\.(ajax|get|post)\\s*\\(.*\\)', + 'document\\.cookie', + '\\bxmlhttprequest\\b|\\bgetcurrentposition\\b|\\bsettimeout\\b|\\bsetinterval\\b', + '\\binnerhtml\\b|\\bouterhtml\\b|\\binsertadjacenthtml\\b|\\biframe\\b|document\\.(write|writeln)', + 'domparser\\.parsefromstring|embed(?=\\s*\\b(src|type)\\b)|object|onclick|addeventlistener', + 'onchange|onblur|onkeypress|onkeydown|onkeyup|navigator|onload|onerror', + '\\b(SELECT|INSERT INTO|UPDATE|DELETE|WHERE)\\b', + '\\b(EXEC\\s*\\(|EXECUTE\\s*\\(|CAST\\s*\\(|CONVERT\\s*\\(|DECLARE\\s*\\(|WAITFOR\\s*DELAY)\\b', + '(?:FROM|SELECT|WHERE)\\s+.\\b(COUNT|SUM|AVG)\\b.(?:FROM|GROUP BY|HAVING)', + 'base64|encodeURIComponent|decodeURIComponent', + '\\b(ou=|uid=|cn=|dc=)\\b', + '(?:system\\(|exec\\(|passthru\\(|shell_exec\\(|`)[^)]\\b(cmd|curl|wget|powershell)\\b[^)]\\)', + '@import|@charset|@media|@font-face', + ' Date: Fri, 24 Oct 2025 07:23:26 -0500 Subject: [PATCH 28/52] =?UTF-8?q?=E2=9C=A8=20feat(provider):=20add=20initi?= =?UTF-8?q?al=20values,=20validation=20schema,=20and=20provider=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/form-constants/initialValues.js | 4 +++ .../form-constants/validationSchema.js | 6 ++++ .../hooks/dashboard/provider/useProvider.jsx | 23 +++++++++++++ .../pages/dashboard/provider/ProviderPage.jsx | 33 ++++++++++++++++-- .../src/stores/provider/providerStore.js | 34 +++++++++++++++++++ 5 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js create mode 100644 frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js create mode 100644 frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx create mode 100644 frontend/manager-app/src/stores/provider/providerStore.js diff --git a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js new file mode 100644 index 0000000..934ffcf --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js @@ -0,0 +1,4 @@ +export const initialValues = { + fullName: "", + specialty: "", +} \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js new file mode 100644 index 0000000..09e5d9e --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js @@ -0,0 +1,6 @@ +import { object, string } from 'yup'; + +export const validationSchema = object({ + fullName: string().max(50).isNotInjection().required("Full name is required"), + specialty: string().max(50).isNotInjection().required("Specialty is required"), +}); \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx new file mode 100644 index 0000000..a0b14c4 --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx @@ -0,0 +1,23 @@ +import { useFormik } from "formik" +import { initialValues } from "./constants/form-constants/initialValues" +import { validationSchema } from "./constants/form-constants/validationSchema" +import { useProviderStore } from "../../../stores/provider/providerStore"; +import { setInitialValues } from "../../../utils/form/setInitialValues"; + +export const useProvider = () => { + + const providerStore = useProviderStore(state => state); + + const onSubmit = () => {} + + const form = useFormik({ + initialValues: setInitialValues(providerStore, initialValues), + validationSchema, + onSubmit + }) + + return { + form, + providerStore + } +} \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx index 07199b3..be4657b 100644 --- a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx @@ -1,9 +1,38 @@ -import React from 'react' import PropTypes from 'prop-types' +import { useProvider } from '../../../hooks/dashboard/provider/useProvider' +import GenericTextInput from '../../../components/generic/form-items/GenericTextInput'; +import GenericButton from '../../../components/generic/form-items/GenericButton'; const ProviderPage = props => { + + const {form, providerStore} = useProvider(); + return ( -
ProviderPage
+ +
+

Create new Doctor (Provider)

+ + + + + Create + + ) } diff --git a/frontend/manager-app/src/stores/provider/providerStore.js b/frontend/manager-app/src/stores/provider/providerStore.js new file mode 100644 index 0000000..5bfeffa --- /dev/null +++ b/frontend/manager-app/src/stores/provider/providerStore.js @@ -0,0 +1,34 @@ +import { create } from 'zustand'; +import { createJSONStorage, devtools, persist } from 'zustand/middleware'; +import { encryptLocalStorage } from '../helpers/encryptLocalStorage'; + +const storeApi = (set) => ({ + id: "", + fullName: "", + specialty: "", + + setId: (id) => { + set({ id }); + }, + + setFullName: (fullName) => { + set({ fullName }); + }, + + setSpecialty: (specialty) => { + set({ specialty }); + }, + + clearMenuData: () => { + set({ id: "", fullName: "", specialty: "" }); + } +}); + +export const useProviderStore = create( + devtools( + persist(storeApi, { + name: 'provider-storage', + storage: createJSONStorage(() => encryptLocalStorage) + }) + ) +); \ No newline at end of file From f96bc7656af117c2ee7a1df8a7169b66489b9511 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 07:23:35 -0500 Subject: [PATCH 29/52] =?UTF-8?q?=E2=9C=A8=20feat(storage):=20add=20encryp?= =?UTF-8?q?tLocalStorage=20helper=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/stores/helpers/encryptLocalStorage.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 frontend/manager-app/src/stores/helpers/encryptLocalStorage.js diff --git a/frontend/manager-app/src/stores/helpers/encryptLocalStorage.js b/frontend/manager-app/src/stores/helpers/encryptLocalStorage.js new file mode 100644 index 0000000..833754f --- /dev/null +++ b/frontend/manager-app/src/stores/helpers/encryptLocalStorage.js @@ -0,0 +1,16 @@ +import secureLocalStorage from 'react-secure-storage'; + +export const encryptLocalStorage = { + + getItem: (name) => { + return secureLocalStorage.getItem(name); + }, + + setItem: (name, value) => { + secureLocalStorage.setItem(name, value); + }, + + removeItem: (name) => { + secureLocalStorage.removeItem(name); + } +}; From 34dfa932566e52bcda12a2d522e18f692c1d2981 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 07:23:48 -0500 Subject: [PATCH 30/52] =?UTF-8?q?=E2=9C=A8=20feat(utils):=20add=20setIniti?= =?UTF-8?q?alValues=20function?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/src/utils/form/setInitialValues.js | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 frontend/manager-app/src/utils/form/setInitialValues.js diff --git a/frontend/manager-app/src/utils/form/setInitialValues.js b/frontend/manager-app/src/utils/form/setInitialValues.js new file mode 100644 index 0000000..c202bb6 --- /dev/null +++ b/frontend/manager-app/src/utils/form/setInitialValues.js @@ -0,0 +1,6 @@ +export const setInitialValues = (store, initialValues) => { + return Object.keys(initialValues).reduce((acc, key) => { + acc[key] = store[key] || initialValues[key]; + return acc; + }, {}); +} \ No newline at end of file From 6a7d8a1d04d22c1d27c316165dd24a8219afc993 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 07:23:59 -0500 Subject: [PATCH 31/52] =?UTF-8?q?=E2=9C=A8=20feat(dependencies):=20add=20r?= =?UTF-8?q?eact-query,=20react-secure-storage,=20and=20zustand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/package-lock.json | 82 +++++++++++++++++++++++++- frontend/manager-app/package.json | 5 +- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/frontend/manager-app/package-lock.json b/frontend/manager-app/package-lock.json index ec24b8a..d00eec9 100644 --- a/frontend/manager-app/package-lock.json +++ b/frontend/manager-app/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.5", "clsx": "^2.1.1", "formik": "^2.4.6", "prop-types": "^15.8.1", @@ -16,8 +17,10 @@ "react-dom": "^19.1.1", "react-router": "^7.9.4", "react-router-dom": "^7.9.4", + "react-secure-storage": "^1.3.2", "tailwindcss": "^4.1.16", - "yup": "^1.7.1" + "yup": "^1.7.1", + "zustand": "^5.0.8" }, "devDependencies": { "@eslint/js": "^9.36.0", @@ -1533,6 +1536,32 @@ "vite": "^5.2.0 || ^6 || ^7" } }, + "node_modules/@tanstack/query-core": { + "version": "5.90.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.5.tgz", + "integrity": "sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.5.tgz", + "integrity": "sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -1883,6 +1912,12 @@ "node": ">= 8" } }, + "node_modules/crypto-js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", + "license": "MIT" + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -2883,6 +2918,12 @@ "dev": true, "license": "MIT" }, + "node_modules/murmurhash-js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz", + "integrity": "sha512-TvmkNhkv8yct0SVBSy+o8wYzXjE4Zz3PCesbfs8HiCXXdcTuocApFv11UWlNFWKYsP2okqrhb7JNlSm9InBhIw==", + "license": "MIT" + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -3171,6 +3212,16 @@ "react-dom": ">=18" } }, + "node_modules/react-secure-storage": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/react-secure-storage/-/react-secure-storage-1.3.2.tgz", + "integrity": "sha512-pNCyksbLXWIYRS9vCzERXdIMErtx9Ik70TPtLKivcq44+zYybbxA72wpp5ivghK9Xe0gRku2w/7zBy/9n+RtKA==", + "license": "MIT", + "dependencies": { + "crypto-js": "^4.1.1", + "murmurhash-js": "^1.0.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -3558,6 +3609,35 @@ "toposort": "^2.0.2", "type-fest": "^2.19.0" } + }, + "node_modules/zustand": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", + "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/frontend/manager-app/package.json b/frontend/manager-app/package.json index 1ea5177..6e9f7cf 100644 --- a/frontend/manager-app/package.json +++ b/frontend/manager-app/package.json @@ -11,6 +11,7 @@ }, "dependencies": { "@tailwindcss/vite": "^4.1.16", + "@tanstack/react-query": "^5.90.5", "clsx": "^2.1.1", "formik": "^2.4.6", "prop-types": "^15.8.1", @@ -18,8 +19,10 @@ "react-dom": "^19.1.1", "react-router": "^7.9.4", "react-router-dom": "^7.9.4", + "react-secure-storage": "^1.3.2", "tailwindcss": "^4.1.16", - "yup": "^1.7.1" + "yup": "^1.7.1", + "zustand": "^5.0.8" }, "devDependencies": { "@eslint/js": "^9.36.0", From d3aafe37480186a8d34c66c90cb06f6cfda6ce92 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:40:44 -0500 Subject: [PATCH 32/52] =?UTF-8?q?=E2=9C=A8=20feat(dto):=20add=20MaxLength?= =?UTF-8?q?=20validation=20to=20patient,=20provider,=20and=20status=20DTOs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/patients/DTO/create-patient.dto.ts | 5 ++- .../src/providers/DTO/create-provider.dto.ts | 4 +- .../src/statuses/DTO/create-status.dto.ts | 4 +- .../src/custom-class-validator.ts | 40 +++++++++---------- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts b/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts index 18e922a..f51bcce 100644 --- a/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts +++ b/backend/manager/libs/contracts/src/patients/DTO/create-patient.dto.ts @@ -1,13 +1,16 @@ -import { IsEmail, IsString, IsUUID } from "@app/custom-class-validator/custom-class-validator"; +import { IsEmail, IsString, IsUUID, MaxLength } from "@app/custom-class-validator/custom-class-validator"; export class CreatePatientDto { @IsString() + @MaxLength(50) full_name: string; @IsEmail() + @MaxLength(50) email: string; @IsString() + @MaxLength(15) phone: string; @IsUUID() diff --git a/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts index baac183..b63e31d 100644 --- a/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts +++ b/backend/manager/libs/contracts/src/providers/DTO/create-provider.dto.ts @@ -1,10 +1,12 @@ -import { IsString } from "@app/custom-class-validator/custom-class-validator"; +import { IsString, MaxLength } from "@app/custom-class-validator/custom-class-validator"; export class CreateProviderDto { @IsString() + @MaxLength(50) full_name: string; @IsString() + @MaxLength(50) specialty: string; } \ No newline at end of file diff --git a/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts b/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts index b3f3cf5..96892bd 100644 --- a/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts +++ b/backend/manager/libs/contracts/src/statuses/DTO/create-status.dto.ts @@ -1,7 +1,8 @@ -import { IsInt, IsOptional, IsString, IsUUID } from "@app/custom-class-validator/custom-class-validator"; +import { IsInt, IsOptional, IsString, IsUUID, Max, MaxLength } from "@app/custom-class-validator/custom-class-validator"; export class CreateStatusDto { @IsString() + @MaxLength(50) name: string; @IsUUID() @@ -9,5 +10,6 @@ export class CreateStatusDto { parent_id?: string; @IsInt() + @Max(9999999999) order: number; } \ No newline at end of file diff --git a/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts b/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts index 26d4962..a9e1264 100644 --- a/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts +++ b/backend/manager/libs/custom-class-validator/src/custom-class-validator.ts @@ -29,40 +29,40 @@ import { IsISO8601Options } from 'validator'; export const IsMongoId = (validationOptions?: ValidationOptions): PropertyDecorator => _IsMongoId({ ...validationOptions, - message: ' - El campo $property no tiene un formato adecuado' + message: 'El campo $property no tiene un formato adecuado' }); export const IsNotEmpty = (validationOptions?: ValidationOptions): PropertyDecorator => - _IsNotEmpty({ ...validationOptions, message: ' - El campo $property es requerido' }); + _IsNotEmpty({ ...validationOptions, message: 'El campo $property es requerido' }); export const IsOptional = (validationOptions?: ValidationOptions): PropertyDecorator => - _IsOptional({ ...validationOptions, message: ' - El campo $property es opcional' }); + _IsOptional({ ...validationOptions, message: 'El campo $property es opcional' }); export const IsArray = (validationOptions?: ValidationOptions): PropertyDecorator => - _IsArray({ ...validationOptions, message: ' - El campo $property debe ser un arreglo' }); + _IsArray({ ...validationOptions, message: 'El campo $property debe ser un arreglo' }); export const ArrayNotEmpty = (validationOptions?: ValidationOptions): PropertyDecorator => _ArrayNotEmpty({ ...validationOptions, - message: ' - El campo $property no puede estar vacío' + message: 'El campo $property no puede estar vacío' }); export const IsString = (validationOptions?: ValidationOptions): PropertyDecorator => _IsString({ ...validationOptions, - message: ' - El campo $property debe ser una cadena de texto' + message: 'El campo $property debe ser una cadena de texto' }); export const IsEmail = (validationOptions?: ValidationOptions): PropertyDecorator => function (object: Object, propertyName: string) { const _IsEmail = require('class-validator').IsEmail; - _IsEmail({ ...validationOptions, message: ' - El campo $property no tiene un formato de correo electrónico válido' })(object, propertyName); + _IsEmail({ ...validationOptions, message: 'El campo $property no tiene un formato de correo electrónico válido' })(object, propertyName); }; export const IsUUID = (version?: validator.UUIDVersion | undefined, validationOptions?: ValidationOptions): PropertyDecorator => _IsUUID(version, { ...validationOptions, - message: ' - El campo $property debe ser un UUID válido' + message: 'El campo $property debe ser un UUID válido' }); export const IsNumber = ( @@ -71,13 +71,13 @@ export const IsNumber = ( ): PropertyDecorator => _IsNumber( { ...options }, - { ...validationOptions, message: ' - El campo $property debe ser un número' } + { ...validationOptions, message: 'El campo $property debe ser un número' } ); export const IsBoolean = (validationOptions?: ValidationOptions): PropertyDecorator => _IsBoolean({ ...validationOptions, - message: ' - El campo $property debe ser un booleano' + message: 'El campo $property debe ser un booleano' }); export const IsDateString = ( @@ -86,7 +86,7 @@ export const IsDateString = ( ): PropertyDecorator => _IsDateString( { ...options }, - { ...validationOptions, message: ' - El campo $property debe ser una fecha válida' } + { ...validationOptions, message: 'El campo $property debe ser una fecha válida' } ); export const Matches = ( @@ -95,39 +95,39 @@ export const Matches = ( ): PropertyDecorator => _Matches(pattern, { ...validationOptions, - message: ' - El campo $property contiene caracteres no permitidos' + message: 'El campo $property contiene caracteres no permitidos' }); export const IsInt = ( validationOptions?: ValidationOptions ): PropertyDecorator => _IsInt({ ...validationOptions, - message: ' - El campo $property debe ser un número entero' + message: 'El campo $property debe ser un número entero' }); export const Max = (maxValue: number, validationOptions?: ValidationOptions): PropertyDecorator => _Max(maxValue, { ...validationOptions, - message: ' - El campo $property permite un valor máximo de $constraint1' + message: 'El campo $property permite un valor máximo de $constraint1' }); export const Min = (minValue: number, validationOptions?: ValidationOptions): PropertyDecorator => _Min(minValue, { ...validationOptions, - message: ' - El campo $property permite un valor mínimo de $constraint1' + message: 'El campo $property permite un valor mínimo de $constraint1' }); export const MaxLength = (max: number, validationOptions?: ValidationOptions): PropertyDecorator => _MaxLength(max, { ...validationOptions, message: - ' - El campo $property permite una longitud máxima de $constraint1 caracteres "${value}"' + 'El campo $property permite una longitud máxima de $constraint1 caracteres' }); export const MinLength = (min: number, validationOptions?: ValidationOptions): PropertyDecorator => _MinLength(min, { ...validationOptions, - message: ' - El campo $property permite una longitud mínima de $constraint1 caracteres' + message: 'El campo $property permite una longitud mínima de $constraint1 caracteres' }); export const IsIn = ( @@ -136,14 +136,14 @@ export const IsIn = ( ): PropertyDecorator => _IsIn(values, { ...validationOptions, - message: ' - El campo $property debe ser de uno de los siguientes tipos $constraint1' + message: 'El campo $property debe ser de uno de los siguientes tipos $constraint1' }); export const IsDate = (validationOptions?: ValidationOptions): PropertyDecorator => - _IsDate({ ...validationOptions, message: ' - El campo $property debe ser una fecha válida' }); + _IsDate({ ...validationOptions, message: 'El campo $property debe ser una fecha válida' }); export const IsObject = (validationOptions?: ValidationOptions): PropertyDecorator => - _IsObject({ ...validationOptions, message: ' - El campo $property debe ser un objeto' }); + _IsObject({ ...validationOptions, message: 'El campo $property debe ser un objeto' }); export const IsStrongPassword = (validationOptions?: ValidationOptions): PropertyDecorator => _IsStrongPassword({}, { ...validationOptions, message: 'Debes ingresar una contraseña segura' }); From 2c81f6a9e05a97ae6bdd4b3df60303dd96dd3a79 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:40:54 -0500 Subject: [PATCH 33/52] =?UTF-8?q?=E2=9C=A8=20feat(main):=20enable=20CORS?= =?UTF-8?q?=20for=20API=20gateway?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/apps/manager-api-gateway/src/main.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/manager/apps/manager-api-gateway/src/main.ts b/backend/manager/apps/manager-api-gateway/src/main.ts index 583009c..dd134a0 100644 --- a/backend/manager/apps/manager-api-gateway/src/main.ts +++ b/backend/manager/apps/manager-api-gateway/src/main.ts @@ -7,6 +7,8 @@ import { LOGGER_SERVICE_SYMBOL } from '@app/logger/constants/logger-symbol.const async function bootstrap() { const app = await NestFactory.create(ManagerApiGatewayModule); + app.enableCors(); + app.useGlobalPipes(new ValidationPipe({ whitelist: true, })); From 919d3006b764bc81a147539d62eb4b5f6a8a5663 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:45:55 -0500 Subject: [PATCH 34/52] =?UTF-8?q?=E2=9C=A8=20feat(provider):=20standardize?= =?UTF-8?q?=20naming=20for=20full=5Fname=20in=20forms=20and=20store?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/form-constants/initialValues.js | 2 +- .../form-constants/validationSchema.js | 2 +- .../hooks/dashboard/provider/useProvider.jsx | 22 +++++++--- .../pages/dashboard/provider/ProviderPage.jsx | 41 ++++++++++--------- .../src/services/provider/providerService.js | 12 ++++++ .../src/stores/provider/providerStore.js | 8 ++-- 6 files changed, 56 insertions(+), 31 deletions(-) create mode 100644 frontend/manager-app/src/services/provider/providerService.js diff --git a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js index 934ffcf..7f05cfe 100644 --- a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js +++ b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/initialValues.js @@ -1,4 +1,4 @@ export const initialValues = { - fullName: "", + full_name: "", specialty: "", } \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js index 09e5d9e..6365d10 100644 --- a/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js +++ b/frontend/manager-app/src/hooks/dashboard/provider/constants/form-constants/validationSchema.js @@ -1,6 +1,6 @@ import { object, string } from 'yup'; export const validationSchema = object({ - fullName: string().max(50).isNotInjection().required("Full name is required"), + full_name: string().max(50).isNotInjection().required("Full name is required"), specialty: string().max(50).isNotInjection().required("Specialty is required"), }); \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx index a0b14c4..46bd963 100644 --- a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx +++ b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx @@ -1,14 +1,18 @@ -import { useFormik } from "formik" -import { initialValues } from "./constants/form-constants/initialValues" -import { validationSchema } from "./constants/form-constants/validationSchema" +import { useFormik } from "formik"; +import { useQuery } from '@tanstack/react-query'; +import { initialValues } from "./constants/form-constants/initialValues"; +import { validationSchema } from "./constants/form-constants/validationSchema"; import { useProviderStore } from "../../../stores/provider/providerStore"; import { setInitialValues } from "../../../utils/form/setInitialValues"; +import { createProvider } from "../../../services/provider/providerService"; export const useProvider = () => { const providerStore = useProviderStore(state => state); - const onSubmit = () => {} + const onSubmit = () => { + refetch(); + } const form = useFormik({ initialValues: setInitialValues(providerStore, initialValues), @@ -16,8 +20,16 @@ export const useProvider = () => { onSubmit }) + const { data, isLoading, refetch } = useQuery({ + queryKey: ['create-provider', form.values], + queryFn: createProvider, + enabled: false, + }) + return { form, - providerStore + providerStore, + isLoading, + onSubmit } } \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx index be4657b..518bff7 100644 --- a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx @@ -1,16 +1,22 @@ -import PropTypes from 'prop-types' -import { useProvider } from '../../../hooks/dashboard/provider/useProvider' -import GenericTextInput from '../../../components/generic/form-items/GenericTextInput'; -import GenericButton from '../../../components/generic/form-items/GenericButton'; +import PropTypes from "prop-types"; +import { useProvider } from "../../../hooks/dashboard/provider/useProvider"; +import GenericTextInput from "../../../components/generic/form-items/GenericTextInput"; +import GenericButton from "../../../components/generic/form-items/GenericButton"; +import GenericProgressBar from "../../../components/generic/ui/GenericProgressBar"; -const ProviderPage = props => { +const ProviderPage = (props) => { + const { form, providerStore, isLoading } = useProvider(); - const {form, providerStore} = useProvider(); - - return ( + if (isLoading) return ; -
-

Create new Doctor (Provider)

+ return ( + +

+ Create new Doctor (Provider) +

{ form={form} persistence={providerStore.setSpecialty} /> - + Create - ) -} + ); +}; -ProviderPage.propTypes = {} +ProviderPage.propTypes = {}; -export default ProviderPage \ No newline at end of file +export default ProviderPage; diff --git a/frontend/manager-app/src/services/provider/providerService.js b/frontend/manager-app/src/services/provider/providerService.js new file mode 100644 index 0000000..d5432e7 --- /dev/null +++ b/frontend/manager-app/src/services/provider/providerService.js @@ -0,0 +1,12 @@ +import axios from 'axios'; +import { BASE_URL } from '../../../config/envs'; + +export const createProvider = async ({ queryKey }) => { + const [_, params] = queryKey; + try { + const response = await axios.post(`${BASE_URL}/providers`, params); + return response.data; + } catch (error) { + throw error; + } +}; \ No newline at end of file diff --git a/frontend/manager-app/src/stores/provider/providerStore.js b/frontend/manager-app/src/stores/provider/providerStore.js index 5bfeffa..70914e7 100644 --- a/frontend/manager-app/src/stores/provider/providerStore.js +++ b/frontend/manager-app/src/stores/provider/providerStore.js @@ -4,15 +4,15 @@ import { encryptLocalStorage } from '../helpers/encryptLocalStorage'; const storeApi = (set) => ({ id: "", - fullName: "", + full_name: "", specialty: "", setId: (id) => { set({ id }); }, - setFullName: (fullName) => { - set({ fullName }); + setFullName: (full_name) => { + set({ full_name }); }, setSpecialty: (specialty) => { @@ -20,7 +20,7 @@ const storeApi = (set) => ({ }, clearMenuData: () => { - set({ id: "", fullName: "", specialty: "" }); + set({ id: "", full_name: "", specialty: "" }); } }); From b1b3fd04f0cc93005c7aa71abdd3132580ab6772 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:46:31 -0500 Subject: [PATCH 35/52] =?UTF-8?q?=E2=9C=A8=20feat(query-client):=20add=20Q?= =?UTF-8?q?ueryClient=20setup=20with=20error=20handling?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/src/App.jsx | 28 ++++++++++--------- .../query-client/queryClientService.js | 28 +++++++++++++++++++ 2 files changed, 43 insertions(+), 13 deletions(-) create mode 100644 frontend/manager-app/src/services/query-client/queryClientService.js diff --git a/frontend/manager-app/src/App.jsx b/frontend/manager-app/src/App.jsx index feaa1ae..93efc25 100644 --- a/frontend/manager-app/src/App.jsx +++ b/frontend/manager-app/src/App.jsx @@ -1,21 +1,23 @@ -import { Suspense } from 'react'; -import { - RouterProvider, -} from "react-router"; -import './App.css' -import { router } from './router/router'; -import { addMethod, string } from 'yup'; -import { injectionValidate } from './utils/validation/injectionValidate'; +import { Suspense } from "react"; +import { RouterProvider } from "react-router"; +import "./App.css"; +import { router } from "./router/router"; +import { addMethod, string } from "yup"; +import { injectionValidate } from "./utils/validation/injectionValidate"; +import { QueryClientProvider } from "@tanstack/react-query"; +import { queryClient } from "./services/query-client/queryClientService"; +import GenericProgressBar from "./components/generic/ui/GenericProgressBar"; function App() { - - addMethod(string, 'isNotInjection', injectionValidate); + addMethod(string, "isNotInjection", injectionValidate); return ( - Cargando...}> - + }> + + + ); } -export default App +export default App; diff --git a/frontend/manager-app/src/services/query-client/queryClientService.js b/frontend/manager-app/src/services/query-client/queryClientService.js new file mode 100644 index 0000000..e3f5595 --- /dev/null +++ b/frontend/manager-app/src/services/query-client/queryClientService.js @@ -0,0 +1,28 @@ +import { QueryCache, QueryClient } from "@tanstack/react-query"; +import { errorAlert } from "../alert/alertService"; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: false + } + }, + queryCache: new QueryCache({ + onError: (error) => { + let message = ''; + + const messageIsString = typeof error.response.data.message === 'string'; + const messageIsArray = Array.isArray(error.response.data.message); + + if (!error.response.data.message || (!messageIsString && !messageIsArray)) { + message = 'Ha ocurrido un error inesperado.'; + } else if(messageIsString) { + message = error.response.data.message; + } else if(messageIsArray) { + message = error.response.data.message[0]; + } + + errorAlert({ message }); + }, + }), + }); \ No newline at end of file From 354f436a2ba7a2421df3ad1d82104f250cc59623 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:46:47 -0500 Subject: [PATCH 36/52] =?UTF-8?q?=E2=9C=A8=20feat(alert):=20implement=20al?= =?UTF-8?q?ert=20service=20with=20toast=20and=20modal=20alerts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/services/alert/alertService.js | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 frontend/manager-app/src/services/alert/alertService.js diff --git a/frontend/manager-app/src/services/alert/alertService.js b/frontend/manager-app/src/services/alert/alertService.js new file mode 100644 index 0000000..b54f10e --- /dev/null +++ b/frontend/manager-app/src/services/alert/alertService.js @@ -0,0 +1,58 @@ +import Swal from 'sweetalert2'; + +export const toast = ({ icon, title, message }) => { + Swal.fire({ + icon, + title, + text: message, + toast: true, + position: 'bottom-end', + showConfirmButton: false, + timer: 3000, + timerProgressBar: true, + iconColor: '#0072CE' + }); +}; + +export const errorAlert = ({ + message = 'Ha ocurrido un error inesperado.', + confirmButtonText = 'Ok', + allowEscapeKey = true, + allowOutsideClick = true +}) => { + const formattedMessage = message.replace(/(?:\r\n|\r|\n)/g, '
'); + Swal.fire({ + icon: 'error', + title: '¡Error!', + html: formattedMessage, + confirmButtonText, + confirmButtonColor: '#0072CE', + allowEscapeKey, + allowOutsideClick + }); +}; + +export const confirmAlert = async ({ icon, title, message }) => { + const result = await Swal.fire({ + icon, + title, + text: message, + showCancelButton: true, + confirmButtonText: 'Si', + cancelButtonText: 'Cancelar', + confirmButtonColor: '#0072CE', + cancelButtonColor: '#002855' + }); + + return result.isConfirmed; +}; + +export const infoAlert = ({ icon, title, message, confirmButtonText = 'Ok' }) => { + Swal.fire({ + icon, + title, + text: message ?? '', + confirmButtonText, + confirmButtonColor: '#0072CE' + }); +}; From 896f90599a080ea6eeb8cf920962eeb480bb8e2e Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:47:06 -0500 Subject: [PATCH 37/52] =?UTF-8?q?=E2=9C=A8=20feat(ui):=20add=20GenericProg?= =?UTF-8?q?ressBar=20component=20with=20nprogress=20integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/package-lock.json | 298 ++++++++++++++++++ frontend/manager-app/package.json | 3 + .../generic/ui/GenericProgressBar.jsx | 15 + .../src/components/generic/ui/loadCounter.js | 28 ++ 4 files changed, 344 insertions(+) create mode 100644 frontend/manager-app/src/components/generic/ui/GenericProgressBar.jsx create mode 100644 frontend/manager-app/src/components/generic/ui/loadCounter.js diff --git a/frontend/manager-app/package-lock.json b/frontend/manager-app/package-lock.json index d00eec9..de8d2fd 100644 --- a/frontend/manager-app/package-lock.json +++ b/frontend/manager-app/package-lock.json @@ -10,14 +10,17 @@ "dependencies": { "@tailwindcss/vite": "^4.1.16", "@tanstack/react-query": "^5.90.5", + "axios": "^1.12.2", "clsx": "^2.1.1", "formik": "^2.4.6", + "nprogress": "^0.2.0", "prop-types": "^15.8.1", "react": "^19.1.1", "react-dom": "^19.1.1", "react-router": "^7.9.4", "react-router-dom": "^7.9.4", "react-secure-storage": "^1.3.2", + "sweetalert2": "^11.26.3", "tailwindcss": "^4.1.16", "yup": "^1.7.1", "zustand": "^5.0.8" @@ -1735,6 +1738,23 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz", + "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1797,6 +1817,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1874,6 +1907,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1958,6 +2003,15 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -1967,6 +2021,20 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.240", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.240.tgz", @@ -1987,6 +2055,51 @@ "node": ">=10.13.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.11", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", @@ -2317,6 +2430,42 @@ "dev": true, "license": "ISC" }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/formik": { "version": "2.4.6", "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", @@ -2356,6 +2505,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2366,6 +2524,43 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -2392,6 +2587,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2408,6 +2615,45 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", @@ -2898,6 +3144,36 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -2956,6 +3232,12 @@ "dev": true, "license": "MIT" }, + "node_modules/nprogress": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", + "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", + "license": "MIT" + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -3121,6 +3403,12 @@ "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", "license": "MIT" }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3353,6 +3641,16 @@ "node": ">=8" } }, + "node_modules/sweetalert2": { + "version": "11.26.3", + "resolved": "https://registry.npmjs.org/sweetalert2/-/sweetalert2-11.26.3.tgz", + "integrity": "sha512-VU0hGw/WfI9h7Mh+SCsDlWgtxDwWZ6ccqS7QcO8zEeWnwplN1GptcLstq76OluUBSLUza6ldvKd3558OhjpJ9A==", + "license": "MIT", + "funding": { + "type": "individual", + "url": "https://github.com/sponsors/limonte" + } + }, "node_modules/tailwindcss": { "version": "4.1.16", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.16.tgz", diff --git a/frontend/manager-app/package.json b/frontend/manager-app/package.json index 6e9f7cf..7cb736e 100644 --- a/frontend/manager-app/package.json +++ b/frontend/manager-app/package.json @@ -12,14 +12,17 @@ "dependencies": { "@tailwindcss/vite": "^4.1.16", "@tanstack/react-query": "^5.90.5", + "axios": "^1.12.2", "clsx": "^2.1.1", "formik": "^2.4.6", + "nprogress": "^0.2.0", "prop-types": "^15.8.1", "react": "^19.1.1", "react-dom": "^19.1.1", "react-router": "^7.9.4", "react-router-dom": "^7.9.4", "react-secure-storage": "^1.3.2", + "sweetalert2": "^11.26.3", "tailwindcss": "^4.1.16", "yup": "^1.7.1", "zustand": "^5.0.8" diff --git a/frontend/manager-app/src/components/generic/ui/GenericProgressBar.jsx b/frontend/manager-app/src/components/generic/ui/GenericProgressBar.jsx new file mode 100644 index 0000000..6a83043 --- /dev/null +++ b/frontend/manager-app/src/components/generic/ui/GenericProgressBar.jsx @@ -0,0 +1,15 @@ +import 'nprogress/nprogress.css'; +import { useEffect } from 'react'; +import { decrement, increment } from './loadCounter'; + +export default function GenericProgressBar() { + useEffect(() => { + increment(); + + return () => { + decrement(); + }; + }, []); + + return null; +} \ No newline at end of file diff --git a/frontend/manager-app/src/components/generic/ui/loadCounter.js b/frontend/manager-app/src/components/generic/ui/loadCounter.js new file mode 100644 index 0000000..aa099ba --- /dev/null +++ b/frontend/manager-app/src/components/generic/ui/loadCounter.js @@ -0,0 +1,28 @@ +import nprogress from 'nprogress'; + +let counter = 0; +let delayTimeout = {}; + +function checkProgress() { + if (counter > 0) { + clearTimeout(delayTimeout); + nprogress.start(); + } else { + delayTimeout = setTimeout(() => { + nprogress.done(); + }, 200); + } +} + +export function increment() { + counter += 1; + checkProgress(); +} + +export function decrement() { + counter -= 1; + if (counter < 0) { + counter = 0; + } + checkProgress(); +} From 8f5c33d02aa906bf2e19ca1454f8fa6be169a0f2 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 09:47:16 -0500 Subject: [PATCH 38/52] =?UTF-8?q?=E2=9C=A8=20feat(env):=20add=20BASE=5FURL?= =?UTF-8?q?=20configuration=20from=20environment?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/config/envs.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 frontend/manager-app/config/envs.js diff --git a/frontend/manager-app/config/envs.js b/frontend/manager-app/config/envs.js new file mode 100644 index 0000000..bb5d07c --- /dev/null +++ b/frontend/manager-app/config/envs.js @@ -0,0 +1 @@ +export const BASE_URL = import.meta.env.VITE_API_URL; \ No newline at end of file From c387c4ce3a37091d556a89ecfc27f1882d5d5397 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 11:52:11 -0500 Subject: [PATCH 39/52] =?UTF-8?q?=E2=9C=A8=20feat(ui):=20add=20GenericCard?= =?UTF-8?q?=20and=20GenericCardList=20components?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generic/form-items/GenericButton.jsx | 2 +- .../generic/form-items/GenericDropdown.jsx | 33 ++++++++++--- .../generic/form-items/GenericTextInput.jsx | 26 +++++----- .../src/components/generic/ui/GenericCard.jsx | 29 ++++++++++++ .../components/generic/ui/GenericCardList.jsx | 47 +++++++++++++++++++ 5 files changed, 119 insertions(+), 18 deletions(-) create mode 100644 frontend/manager-app/src/components/generic/ui/GenericCard.jsx create mode 100644 frontend/manager-app/src/components/generic/ui/GenericCardList.jsx diff --git a/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx index 37811b0..5e9b10b 100644 --- a/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx +++ b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx @@ -2,11 +2,11 @@ import PropTypes from 'prop-types' const GenericButton = ({ children, - onClick, type = "button", disabled = false, variant = "primary", className = "", + onClick = () => {} }) => { const baseStyle = "px-4 py-2 rounded-lg font-semibold transition-all duration-200 focus:outline-none"; diff --git a/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx index eb4e39c..f748bab 100644 --- a/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx +++ b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx @@ -13,16 +13,26 @@ const sizes = { }; const GenericDropdown = ({ + form, + name, label, options = [], - value, - onChange, placeholder = "Seleccionar...", variant = "primary", size = "md", disabled = false, className = "", + persistence = null }) => { + + const value = form.values[name]; + + const handleChange = (e) => { + form.setFieldValue(name, e.target.value); + if(!persistence) return; + persistence(e.target.value); + }; + return (
{label && ( @@ -36,7 +46,7 @@ const GenericDropdown = ({ @@ -57,6 +67,16 @@ const GenericDropdown = ({ }; GenericDropdown.propTypes = { + form: PropTypes.shape({ + values: PropTypes.object.isRequired, + errors: PropTypes.object, + touched: PropTypes.object, + handleChange: PropTypes.func.isRequired, + handleBlur: PropTypes.func.isRequired, + setFieldValue: PropTypes.func, + setFieldTouched: PropTypes.func, + }).isRequired, + name: PropTypes.string.isRequired, label: PropTypes.string, options: PropTypes.arrayOf( PropTypes.oneOfType([ @@ -74,6 +94,7 @@ GenericDropdown.propTypes = { size: PropTypes.oneOf(["sm", "md", "lg"]), disabled: PropTypes.bool, className: PropTypes.string, + persistence: PropTypes.func, }; export default GenericDropdown; \ No newline at end of file diff --git a/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx b/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx index e8b816e..012c8fc 100644 --- a/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx +++ b/frontend/manager-app/src/components/generic/form-items/GenericTextInput.jsx @@ -5,8 +5,7 @@ const variants = { "border-gray-300 focus:border-blue-500 focus:ring-blue-400 text-gray-900", secondary: "border-gray-200 bg-gray-50 text-gray-700 focus:border-gray-400 focus:ring-gray-300", - danger: - "border-red-300 text-red-700 focus:border-red-500 focus:ring-red-400", + danger: "border-red-300 text-red-700 focus:border-red-500 focus:ring-red-400", }; const sizes = { @@ -25,16 +24,16 @@ const GenericTextInput = ({ size = "md", disabled = false, className = "", - persistence = null + persistence = null, }) => { const value = form.values[name]; const error = form.touched[name] && form.errors[name]; const handleOnChange = (e) => { form.setFieldValue(name, e.target.value); - if(!persistence) return; + if (!persistence) return; persistence(e.target.value); - } + }; return (
@@ -53,18 +52,22 @@ const GenericTextInput = ({ name={name} type={dataType || "text"} value={value ?? ""} - onChange={(e) => handleOnChange(e)} + onChange={handleOnChange} onBlur={form.handleBlur} placeholder={placeholder || ""} disabled={disabled} autoComplete="off" - className={`w-full border bg-transparent focus:outline-none focus:ring-2 transition-all duration-150 ${variants[variant]} ${sizes[size]} ${ - error ? "border-red-500 ring-red-200" : "" - } ${dataType === "percentage" ? "pr-8" : ""} ${className}`} + className={`w-full border bg-transparent focus:outline-none focus:ring-2 transition-all duration-150 ${ + variants[variant] + } ${sizes[size]} ${error ? "border-red-500 ring-red-200" : ""} ${ + dataType === "percentage" ? "pr-8" : "" + } ${className}`} />
- {error &&

{form.errors[name]}

} + {error && ( +

{form.errors[name]}

+ )}
); }; @@ -86,7 +89,8 @@ GenericTextInput.propTypes = { variant: PropTypes.oneOf(["primary", "secondary", "danger"]), size: PropTypes.oneOf(["sm", "md", "lg"]), disabled: PropTypes.bool, - className: PropTypes.string + className: PropTypes.string, + persistence: PropTypes.func, }; export default GenericTextInput; diff --git a/frontend/manager-app/src/components/generic/ui/GenericCard.jsx b/frontend/manager-app/src/components/generic/ui/GenericCard.jsx new file mode 100644 index 0000000..5ce1769 --- /dev/null +++ b/frontend/manager-app/src/components/generic/ui/GenericCard.jsx @@ -0,0 +1,29 @@ +import PropTypes from "prop-types"; + +const GenericCard = ({ + title, + subtitle, + children, + actions, +}) => { + return ( +
+

{title}

+ + {subtitle &&
{subtitle}
} + + {children &&
{children}
} + + {actions &&
{actions}
} +
+ ); +}; + +GenericCard.propTypes = { + title: PropTypes.string.isRequired, + subtitle: PropTypes.string, + children: PropTypes.node, + actions: PropTypes.node, +}; + +export default GenericCard; diff --git a/frontend/manager-app/src/components/generic/ui/GenericCardList.jsx b/frontend/manager-app/src/components/generic/ui/GenericCardList.jsx new file mode 100644 index 0000000..221d0d6 --- /dev/null +++ b/frontend/manager-app/src/components/generic/ui/GenericCardList.jsx @@ -0,0 +1,47 @@ +import PropTypes from "prop-types"; +import GenericCard from "./GenericCard"; + +const GenericCardList = ({ + title= '', + items = [], + actions = null +}) => { + return ( +
+

+ {title} List +

+ + {items.length === 0 ? ( +
+ There are no {title} available. +
+ ) : ( +
+ {items.map((item) => ( + + ))} +
+ )} +
+ ); +}; + +GenericCardList.propTypes = { + title: PropTypes.string, + items: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + subtitle: PropTypes.string, + }) + ), + actions: PropTypes.arrayOf(PropTypes.node) +}; + +export default GenericCardList; From 08b732426203bf7eb1222d6ee537bf9c27650135 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 11:54:10 -0500 Subject: [PATCH 40/52] =?UTF-8?q?=E2=9C=A8=20feat(provider):=20implement?= =?UTF-8?q?=20useProviderList=20hook=20and=20update=20ProviderListPage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../provider-list/useProviderList.jsx | 27 +++++++++ .../hooks/dashboard/provider/useProvider.jsx | 22 +++++++- .../provider-list/ProviderListPage.jsx | 24 +++++--- .../pages/dashboard/provider/ProviderPage.jsx | 56 +++++++++---------- .../src/services/provider/providerService.js | 11 +++- 5 files changed, 98 insertions(+), 42 deletions(-) create mode 100644 frontend/manager-app/src/hooks/dashboard/provider-list/useProviderList.jsx diff --git a/frontend/manager-app/src/hooks/dashboard/provider-list/useProviderList.jsx b/frontend/manager-app/src/hooks/dashboard/provider-list/useProviderList.jsx new file mode 100644 index 0000000..9522d0e --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/provider-list/useProviderList.jsx @@ -0,0 +1,27 @@ +import { useQuery } from "@tanstack/react-query"; +import { getAllProviders } from "../../../services/provider/providerService"; +import { useEffect, useState } from "react"; +import { createCardListItems } from "../../../utils/transforms/createCardListItems"; +import { QUERY_KEYS } from "../../../utils/constants/query-key-constants/queryKeyConstants"; + +export const useProviderList = () => { + + const [providerList, setProviderList] = useState([]) + + const { data, isLoading, isSuccess } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_PROVIDERS], + queryFn: getAllProviders + }) + + useEffect(()=>{ + if(!isSuccess) return; + + setProviderList(createCardListItems(data.data, 'full_name', 'specialty')); + }, [isSuccess]) + + return { + providerList, + isLoading, + isSuccess + } +} diff --git a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx index 46bd963..6708683 100644 --- a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx +++ b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx @@ -1,3 +1,4 @@ +import { useEffect } from "react"; import { useFormik } from "formik"; import { useQuery } from '@tanstack/react-query'; import { initialValues } from "./constants/form-constants/initialValues"; @@ -5,6 +6,8 @@ import { validationSchema } from "./constants/form-constants/validationSchema"; import { useProviderStore } from "../../../stores/provider/providerStore"; import { setInitialValues } from "../../../utils/form/setInitialValues"; import { createProvider } from "../../../services/provider/providerService"; +import { infoAlert } from "../../../services/alert/alertService"; +import { QUERY_KEYS } from "../../../utils/constants/query-key-constants/queryKeyConstants"; export const useProvider = () => { @@ -20,12 +23,25 @@ export const useProvider = () => { onSubmit }) - const { data, isLoading, refetch } = useQuery({ - queryKey: ['create-provider', form.values], + const { data, isLoading, refetch, isSuccess } = useQuery({ + queryKey: [QUERY_KEYS.CREATE_PROVIDER, form.values], queryFn: createProvider, - enabled: false, + enabled: false }) + useEffect(() => { + if(!isSuccess) return; + + infoAlert({ + icon: 'success', + title: 'Proveedor creado', + message: 'El proveedor ha sido creado exitosamente.' + }); + + form.resetForm(); + }, [isSuccess]) + + return { form, providerStore, diff --git a/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx b/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx index 9e36fd8..c31170c 100644 --- a/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/provider-list/ProviderListPage.jsx @@ -1,12 +1,18 @@ -import React from 'react' -import PropTypes from 'prop-types' +import GenericCardList from "../../../components/generic/ui/GenericCardList"; +import GenericProgressBar from "../../../components/generic/ui/GenericProgressBar"; +import { useProviderList } from "../../../hooks/dashboard/provider-list/useProviderList"; -const ProviderListPage = props => { - return ( -
ProviderListPage
- ) -} +const ProviderListPage = () => { + const { providerList, isSuccess } = useProviderList(); + + if (!isSuccess) return ; -ProviderListPage.propTypes = {} + return ( + + ); +}; -export default ProviderListPage \ No newline at end of file +export default ProviderListPage; \ No newline at end of file diff --git a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx index 518bff7..ceb1e6d 100644 --- a/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/provider/ProviderPage.jsx @@ -1,42 +1,40 @@ -import PropTypes from "prop-types"; import { useProvider } from "../../../hooks/dashboard/provider/useProvider"; import GenericTextInput from "../../../components/generic/form-items/GenericTextInput"; import GenericButton from "../../../components/generic/form-items/GenericButton"; import GenericProgressBar from "../../../components/generic/ui/GenericProgressBar"; -const ProviderPage = (props) => { +const ProviderPage = () => { const { form, providerStore, isLoading } = useProvider(); - if (isLoading) return ; - return ( -
-

- Create new Doctor (Provider) -

+ <> + {isLoading && } + +

+ Create new Doctor (Provider) +

- - - - Create - - + + + + Create + + + ); }; -ProviderPage.propTypes = {}; - export default ProviderPage; diff --git a/frontend/manager-app/src/services/provider/providerService.js b/frontend/manager-app/src/services/provider/providerService.js index d5432e7..f7c1b1f 100644 --- a/frontend/manager-app/src/services/provider/providerService.js +++ b/frontend/manager-app/src/services/provider/providerService.js @@ -9,4 +9,13 @@ export const createProvider = async ({ queryKey }) => { } catch (error) { throw error; } -}; \ No newline at end of file +}; + +export const getAllProviders = async () => { + try { + const response = await axios.get(`${BASE_URL}/providers`); + return response.data; + } catch (error) { + throw error; + } +}; From c322f7dda6475c0af45ce508543c010eb2ac058d Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:08:23 -0500 Subject: [PATCH 41/52] =?UTF-8?q?=E2=9C=A8=20feat(utils):=20add=20createCa?= =?UTF-8?q?rdListItems=20and=20createDropdownItems=20functions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/utils/transforms/createCardListItems.js | 7 +++++++ .../src/utils/transforms/createDropdownItems.js | 6 ++++++ 2 files changed, 13 insertions(+) create mode 100644 frontend/manager-app/src/utils/transforms/createCardListItems.js create mode 100644 frontend/manager-app/src/utils/transforms/createDropdownItems.js diff --git a/frontend/manager-app/src/utils/transforms/createCardListItems.js b/frontend/manager-app/src/utils/transforms/createCardListItems.js new file mode 100644 index 0000000..efdc165 --- /dev/null +++ b/frontend/manager-app/src/utils/transforms/createCardListItems.js @@ -0,0 +1,7 @@ +export const createCardListItems = (dataArray, titleKey, subtitleKey, idKey = 'id') => { + return dataArray.map(item => ({ + id: item[idKey], + title: item[titleKey], + subtitle: item[subtitleKey] + })); +}; diff --git a/frontend/manager-app/src/utils/transforms/createDropdownItems.js b/frontend/manager-app/src/utils/transforms/createDropdownItems.js new file mode 100644 index 0000000..9e1f5a7 --- /dev/null +++ b/frontend/manager-app/src/utils/transforms/createDropdownItems.js @@ -0,0 +1,6 @@ +export const createDropdownItems = (dataArray, idKey, nameKey) => { + return dataArray.map(item => ({ + id: item[idKey], + name: item[nameKey] + })); +} \ No newline at end of file From c6d75f262e6df822c64bfee4096eae2e592bf511 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:08:48 -0500 Subject: [PATCH 42/52] =?UTF-8?q?=E2=9C=A8=20feat(provider):=20update=20cr?= =?UTF-8?q?eateProvider=20to=20use=20values=20parameter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../manager-app/src/services/provider/providerService.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/manager-app/src/services/provider/providerService.js b/frontend/manager-app/src/services/provider/providerService.js index f7c1b1f..c240800 100644 --- a/frontend/manager-app/src/services/provider/providerService.js +++ b/frontend/manager-app/src/services/provider/providerService.js @@ -1,10 +1,9 @@ import axios from 'axios'; import { BASE_URL } from '../../../config/envs'; -export const createProvider = async ({ queryKey }) => { - const [_, params] = queryKey; +export const createProvider = async (values) => { try { - const response = await axios.post(`${BASE_URL}/providers`, params); + const response = await axios.post(`${BASE_URL}/providers`, values); return response.data; } catch (error) { throw error; From 4bb568c3f20e1a1ad846a791a48a365167a20c5b Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:09:06 -0500 Subject: [PATCH 43/52] =?UTF-8?q?=E2=9C=A8=20feat(ui):=20update=20layout?= =?UTF-8?q?=20styles=20for=20responsiveness?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/manager-app/src/App.css | 2 +- frontend/manager-app/src/App.jsx | 4 +++- frontend/manager-app/src/index.css | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/manager-app/src/App.css b/frontend/manager-app/src/App.css index b9d355d..fc57115 100644 --- a/frontend/manager-app/src/App.css +++ b/frontend/manager-app/src/App.css @@ -1,5 +1,5 @@ #root { - max-width: 1280px; + width: 100dvw; margin: 0 auto; padding: 2rem; text-align: center; diff --git a/frontend/manager-app/src/App.jsx b/frontend/manager-app/src/App.jsx index 93efc25..527b860 100644 --- a/frontend/manager-app/src/App.jsx +++ b/frontend/manager-app/src/App.jsx @@ -14,7 +14,9 @@ function App() { return ( }> - +
+ +
); diff --git a/frontend/manager-app/src/index.css b/frontend/manager-app/src/index.css index 444f889..2b7e34f 100644 --- a/frontend/manager-app/src/index.css +++ b/frontend/manager-app/src/index.css @@ -29,6 +29,7 @@ body { display: flex; place-items: center; min-width: 320px; + max-width: 100dvw; min-height: 100vh; } From b95ebe0ffcbc8fd860b19d4be4b247d57d4f2d66 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:09:46 -0500 Subject: [PATCH 44/52] =?UTF-8?q?=E2=9C=A8=20feat(ui):=20enhance=20Generic?= =?UTF-8?q?Button=20and=20GenericDropdown=20styles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generic/form-items/GenericButton.jsx | 11 +++-- .../generic/form-items/GenericDropdown.jsx | 42 ++++++++----------- .../components/generic/ui/GenericListItem.jsx | 27 ++++++++++++ 3 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 frontend/manager-app/src/components/generic/ui/GenericListItem.jsx diff --git a/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx index 5e9b10b..b86eb1d 100644 --- a/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx +++ b/frontend/manager-app/src/components/generic/form-items/GenericButton.jsx @@ -9,12 +9,15 @@ const GenericButton = ({ onClick = () => {} }) => { const baseStyle = - "px-4 py-2 rounded-lg font-semibold transition-all duration-200 focus:outline-none"; + "px-4 py-2 rounded-lg font-semibold transition-all duration-200 focus:outline-none shadow-md active:scale-95"; const variants = { - primary: "bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300", - secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300 disabled:bg-gray-200", - danger: "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300", + primary: + "bg-gradient-to-r from-blue-400 to-blue-500 text-white hover:from-blue-500 hover:to-blue-600 disabled:from-blue-200 disabled:to-blue-300", + secondary: + "bg-gray-200 text-gray-800 hover:bg-gray-300 disabled:bg-gray-200", + danger: + "bg-gradient-to-r from-red-500 to-red-600 text-white hover:from-red-600 hover:to-red-700 disabled:from-red-300 disabled:to-red-400", }; return ( diff --git a/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx index f748bab..1a9e494 100644 --- a/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx +++ b/frontend/manager-app/src/components/generic/form-items/GenericDropdown.jsx @@ -1,9 +1,12 @@ import PropTypes from "prop-types"; const variants = { - primary: "bg-blue-600 text-white hover:bg-blue-700 disabled:bg-blue-300", - secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300 disabled:bg-gray-200", - danger: "bg-red-600 text-white hover:bg-red-700 disabled:bg-red-300", + primary: + "bg-white border-blue-300 text-gray-800 focus:border-blue-400 focus:ring-2 focus:ring-blue-200 hover:border-blue-400 disabled:bg-gray-100 disabled:text-gray-400", + secondary: + "bg-gray-50 border-gray-300 text-gray-800 focus:border-gray-400 focus:ring-2 focus:ring-gray-200 hover:border-gray-400 disabled:bg-gray-100 disabled:text-gray-400", + danger: + "bg-white border-red-300 text-gray-800 focus:border-red-400 focus:ring-2 focus:ring-red-200 hover:border-red-400 disabled:bg-gray-100 disabled:text-gray-400", }; const sizes = { @@ -17,20 +20,18 @@ const GenericDropdown = ({ name, label, options = [], - placeholder = "Seleccionar...", + placeholder = "Please select...", variant = "primary", size = "md", disabled = false, className = "", - persistence = null + persistence = null, }) => { - const value = form.values[name]; const handleChange = (e) => { form.setFieldValue(name, e.target.value); - if(!persistence) return; - persistence(e.target.value); + if (persistence) persistence(e.target.value); }; return ( @@ -48,17 +49,16 @@ const GenericDropdown = ({ value={value ?? ""} onChange={handleChange} disabled={disabled} - className={`rounded-2xl border border-gray-300 focus:ring-2 focus:ring-blue-400 outline-none cursor-pointer transition-all duration-150 ${variants[variant]} ${sizes[size]} ${className}`} + className={`rounded-lg border outline-none cursor-pointer transition-all duration-150 ${variants[variant]} ${sizes[size]} ${className}`} > {placeholder && ( )} - {options.map((option) => ( - ))} @@ -68,27 +68,21 @@ const GenericDropdown = ({ GenericDropdown.propTypes = { form: PropTypes.shape({ - values: PropTypes.object.isRequired, - errors: PropTypes.object, - touched: PropTypes.object, - handleChange: PropTypes.func.isRequired, - handleBlur: PropTypes.func.isRequired, - setFieldValue: PropTypes.func, - setFieldTouched: PropTypes.func, - }).isRequired, - name: PropTypes.string.isRequired, + values: PropTypes.object.isRequired, + setFieldValue: PropTypes.func, + }).isRequired, + name: PropTypes.string.isRequired, label: PropTypes.string, options: PropTypes.arrayOf( PropTypes.oneOfType([ PropTypes.string, PropTypes.shape({ + id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + name: PropTypes.string, label: PropTypes.string, - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), }), ]) ).isRequired, - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - onChange: PropTypes.func.isRequired, placeholder: PropTypes.string, variant: PropTypes.oneOf(["primary", "secondary", "danger"]), size: PropTypes.oneOf(["sm", "md", "lg"]), diff --git a/frontend/manager-app/src/components/generic/ui/GenericListItem.jsx b/frontend/manager-app/src/components/generic/ui/GenericListItem.jsx new file mode 100644 index 0000000..9d1a2f0 --- /dev/null +++ b/frontend/manager-app/src/components/generic/ui/GenericListItem.jsx @@ -0,0 +1,27 @@ +import PropTypes from "prop-types"; + +const GenericListItem = ({ title, subtitle, provider, status, action, onClick }) => { + return ( +
  • + {title} + {subtitle} + {provider || "-"} + {status || "-"} +
    {action}
    +
  • + ); +}; + +GenericListItem.propTypes = { + title: PropTypes.string.isRequired, + subtitle: PropTypes.string, + provider: PropTypes.string, + status: PropTypes.string, + action: PropTypes.node, + onClick: PropTypes.func, +}; + +export default GenericListItem; \ No newline at end of file From ae7e5c4be00c1c2a41c7e5829bd4ed387dc6da8c Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:10:48 -0500 Subject: [PATCH 45/52] =?UTF-8?q?=E2=9C=A8=20feat(patient):=20implement=20?= =?UTF-8?q?patient=20creation=20and=20list=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/patients/patients.controller.ts | 8 +- .../dashboard/patient-list/usePatientList.jsx | 36 +++++++++ .../constants/form-constants/initialValues.js | 7 ++ .../form-constants/validationSchema.js | 9 +++ .../hooks/dashboard/patient/usePatient.jsx | 81 +++++++++++++++++++ .../patient-list/PatientListPage.jsx | 77 ++++++++++++++++-- .../pages/dashboard/patient/PatientPage.jsx | 63 +++++++++++++-- .../src/services/patient/patientService.js | 20 +++++ .../src/stores/patient/patientStore.js | 49 +++++++++++ 9 files changed, 334 insertions(+), 16 deletions(-) create mode 100644 frontend/manager-app/src/hooks/dashboard/patient-list/usePatientList.jsx create mode 100644 frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/initialValues.js create mode 100644 frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/validationSchema.js create mode 100644 frontend/manager-app/src/hooks/dashboard/patient/usePatient.jsx create mode 100644 frontend/manager-app/src/services/patient/patientService.js create mode 100644 frontend/manager-app/src/stores/patient/patientStore.js diff --git a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts index 913cb39..82fbb2a 100644 --- a/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts +++ b/backend/manager/apps/manager-api-gateway/src/patients/patients.controller.ts @@ -7,7 +7,8 @@ import { Param, Body, Inject, - Logger + Logger, + BadRequestException } from '@nestjs/common'; import { PatientsService } from './patients.service'; import { CreatePatientDto } from '@app/contracts/patients/DTO/create-patient.dto'; @@ -76,10 +77,7 @@ export class PatientsController { ); } catch (error) { this.logger.error('Error al crear el paciente: ' + error.message); - return standardResponse( - 'Falló la creación del paciente', - null - ); + throw new BadRequestException('Falló la creación del paciente'); } } diff --git a/frontend/manager-app/src/hooks/dashboard/patient-list/usePatientList.jsx b/frontend/manager-app/src/hooks/dashboard/patient-list/usePatientList.jsx new file mode 100644 index 0000000..0fd1b2e --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/patient-list/usePatientList.jsx @@ -0,0 +1,36 @@ +import { getAllPatients } from "../../../services/patient/patientService"; +import { useQuery } from "@tanstack/react-query"; +import { QUERY_KEYS } from "../../../utils/constants/query-key-constants/queryKeyConstants"; +import { getAllProviders } from "../../../services/provider/providerService"; +import { getAllStatuses } from "../../../services/status/statusService"; + +export const usePatientList = () => { + const { + data: fetchedProviders, + isLoading: providersLoading + } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_PROVIDERS], + queryFn: getAllProviders, + }); + + const { + data: fetchStatuses, + isLoading: statusesLoading + } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_STATUSES], + queryFn: getAllStatuses, + }); + + const { data: response, isSuccess } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_PATIENTS], + queryFn: getAllPatients, + }); + + return { + isLoading: providersLoading || statusesLoading, + patientList: response?.data || [], + statuses: fetchStatuses?.data || [], + providers: fetchedProviders?.data || [], + isSuccess, + }; +}; diff --git a/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/initialValues.js b/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/initialValues.js new file mode 100644 index 0000000..fbd3b3c --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/initialValues.js @@ -0,0 +1,7 @@ +export const initialValues = { + full_name: "", + email: "", + phone: "", + provider_id: "", + status_id: "", +}; \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/validationSchema.js b/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/validationSchema.js new file mode 100644 index 0000000..89d5a58 --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/patient/constants/form-constants/validationSchema.js @@ -0,0 +1,9 @@ +import { object, string } from 'yup'; + +export const validationSchema = object({ + full_name: string().max(50).isNotInjection().required("Full name is required"), + email: string().email("Invalid email format").max(100).isNotInjection().required("Email is required"), + phone: string().max(15).isNotInjection().required("Phone number is required"), + provider_id: string().uuid("Invalid provider ID").required("Provider ID is required"), + status_id: string().uuid("Invalid status ID").required("Status ID is required"), +}); \ No newline at end of file diff --git a/frontend/manager-app/src/hooks/dashboard/patient/usePatient.jsx b/frontend/manager-app/src/hooks/dashboard/patient/usePatient.jsx new file mode 100644 index 0000000..65a47d8 --- /dev/null +++ b/frontend/manager-app/src/hooks/dashboard/patient/usePatient.jsx @@ -0,0 +1,81 @@ +import { useMutation, useQuery } from "@tanstack/react-query"; +import { getAllProviders } from "../../../services/provider/providerService"; +import { usePatientStore } from "../../../stores/patient/patientStore"; +import { QUERY_KEYS } from "../../../utils/constants/query-key-constants/queryKeyConstants"; +import { initialValues } from "./constants/form-constants/initialValues"; +import { getAllStatuses } from "../../../services/status/statusService"; +import { useFormik } from "formik"; +import { setInitialValues } from "../../../utils/form/setInitialValues"; +import { validationSchema } from "./constants/form-constants/validationSchema"; +import { useEffect, useState } from "react"; +import { createDropdownItems } from "../../../utils/transforms/createDropdownItems"; +import { createPatient } from "../../../services/patient/patientService"; +import { errorAlert, infoAlert } from "../../../services/alert/alertService"; + +export const usePatient = () => { + const [statuses, setStatuses] = useState([]); + const [providers, setProviders] = useState([]); + + const { + data: fetchedProviders, + isLoading: providersLoading, + isSuccess: providersSuccess, + } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_PROVIDERS], + queryFn: getAllProviders, + }); + + const { + data: fetchStatuses, + isLoading: statusesLoading, + isSuccess: statusesSuccess, + } = useQuery({ + queryKey: [QUERY_KEYS.GET_ALL_STATUSES], + queryFn: getAllStatuses, + }); + + const patientStore = usePatientStore((state) => state); + + const onSubmit = () => { + createPatientMutation.mutate(form.values); + }; + + const form = useFormik({ + initialValues: setInitialValues(patientStore, initialValues), + validationSchema, + onSubmit, + }); + + const createPatientMutation = useMutation({ + mutationFn: createPatient, + onError: () => { + errorAlert({ message: 'Error creating this patient' }); + }, + onSuccess: () => { + infoAlert({ + icon: 'success', + title: 'Patient created', + message: 'The patient has been created successfully.' + }) + form.resetForm(); + } + }); + + useEffect(() => { + if (!statusesSuccess) return; + setStatuses(fetchStatuses.data); + }, [statusesSuccess]); + + useEffect(() => { + if (!providersSuccess) return; + setProviders(createDropdownItems(fetchedProviders.data, "id", "full_name")); + }, [providersSuccess]); + + return { + form, + statuses, + providers, + isLoading: providersLoading || statusesLoading || createPatientMutation.isLoading, + patientStore, + }; +}; diff --git a/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx b/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx index a40dac0..199b713 100644 --- a/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/patient-list/PatientListPage.jsx @@ -1,9 +1,74 @@ -const PatientListPage = props => { +import GenericProgressBar from "../../../components/generic/ui/GenericProgressBar"; +import { usePatientList } from "../../../hooks/dashboard/patient-list/usePatientList"; + +const PatientListPage = () => { + const { patientList, isSuccess, providers, statuses } = usePatientList(); + + if (!isSuccess) return ; + return ( -
    PatientListPage
    - ) -} +
      +
    • + Nombre + Email + Provider + Status + Acciones +
    • + + {patientList.map((patient) => { + + console.log('statuses.filter(s => s.parent_id === patient.status_id)****', statuses.filter(s => s.parent_id === patient.status_id)) + + const providerName = + providers.find((p) => p.id === patient.provider_id)?.full_name || "-"; + const statusName = + statuses.find((s) => s.id === patient.status_id)?.name || "-"; + + return ( +
    • + {/* Campo: Nombre */} +
      + + Nombre: + + + {patient.full_name} + +
      + +
      + + Email: + + {patient.email} +
      + +
      + + Provider: + + {providerName} +
      -PatientListPage.propTypes = {} +
      + + Status: + + {statusName} +
      +
      + Change Status (Pendiente) +
      +
    • + ); + })} +
    + ); +}; -export default PatientListPage \ No newline at end of file +export default PatientListPage; diff --git a/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx b/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx index 1132420..f97df53 100644 --- a/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/patient/PatientPage.jsx @@ -1,9 +1,62 @@ +import GenericButton from "../../../components/generic/form-items/GenericButton"; +import GenericDropdown from "../../../components/generic/form-items/GenericDropdown"; +import GenericTextInput from "../../../components/generic/form-items/GenericTextInput"; +import GenericProgressBar from "../../../components/generic/ui/GenericProgressBar"; +import { usePatient } from "../../../hooks/dashboard/patient/usePatient"; + const PatientPage = () => { + const { statuses, providers, patientStore, patient, isLoading, error, form } = + usePatient(); + + if (isLoading) return ; + return ( -
    PatientPage
    - ) -} +
    +

    + Create new Patient +

    + + + + + + + Create + + + ); +}; -PatientPage.propTypes = {} +PatientPage.propTypes = {}; -export default PatientPage \ No newline at end of file +export default PatientPage; diff --git a/frontend/manager-app/src/services/patient/patientService.js b/frontend/manager-app/src/services/patient/patientService.js new file mode 100644 index 0000000..3d3c6f2 --- /dev/null +++ b/frontend/manager-app/src/services/patient/patientService.js @@ -0,0 +1,20 @@ +import axios from 'axios'; +import { BASE_URL } from '../../../config/envs'; + +export const createPatient = async (values) => { + try { + const response = await axios.post(`${BASE_URL}/patients`, values); + return response.data; + } catch (error) { + throw error; + } +}; + +export const getAllPatients = async () => { + try { + const response = await axios.get(`${BASE_URL}/patients`); + return response.data; + } catch (error) { + throw error; + } +}; diff --git a/frontend/manager-app/src/stores/patient/patientStore.js b/frontend/manager-app/src/stores/patient/patientStore.js new file mode 100644 index 0000000..7e1988c --- /dev/null +++ b/frontend/manager-app/src/stores/patient/patientStore.js @@ -0,0 +1,49 @@ +import { create } from 'zustand'; +import { createJSONStorage, devtools, persist } from 'zustand/middleware'; +import { encryptLocalStorage } from '../helpers/encryptLocalStorage'; + +const storeApi = (set) => ({ + + id: "", + full_name: "", + email: "", + phone: "", + provider_id: "", + status_id: "", + + setId: (id) => { + set({ id }); + }, + + setFullName: (full_name) => { + set({ full_name }); + }, + + setEmail: (email) => { + set({ email }); + }, + setPhone: (phone) => { + set({ phone }); + }, + + setProviderId: (provider_id) => { + set({ provider_id }); + }, + + setStatusId: (status_id) => { + set({ status_id }); + }, + + clearMenuData: () => { + set({ id: "", full_name: "", email: "", phone: "", provider_id: "", status_id: "" }); + } +}); + +export const usePatientStore = create( + devtools( + persist(storeApi, { + name: 'patient-storage', + storage: createJSONStorage(() => encryptLocalStorage) + }) + ) +); \ No newline at end of file From 098d163ac534fc8d6f45993d81fdd3d0b475f532 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:10:55 -0500 Subject: [PATCH 46/52] =?UTF-8?q?=E2=9C=A8=20feat(provider):=20refactor=20?= =?UTF-8?q?useProvider=20hook=20for=20clarity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hooks/dashboard/provider/useProvider.jsx | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx index 6708683..f917da8 100644 --- a/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx +++ b/frontend/manager-app/src/hooks/dashboard/provider/useProvider.jsx @@ -1,51 +1,46 @@ -import { useEffect } from "react"; import { useFormik } from "formik"; -import { useQuery } from '@tanstack/react-query'; +import { useMutation } from "@tanstack/react-query"; import { initialValues } from "./constants/form-constants/initialValues"; import { validationSchema } from "./constants/form-constants/validationSchema"; import { useProviderStore } from "../../../stores/provider/providerStore"; import { setInitialValues } from "../../../utils/form/setInitialValues"; import { createProvider } from "../../../services/provider/providerService"; import { infoAlert } from "../../../services/alert/alertService"; -import { QUERY_KEYS } from "../../../utils/constants/query-key-constants/queryKeyConstants"; export const useProvider = () => { - - const providerStore = useProviderStore(state => state); + const providerStore = useProviderStore((state) => state); const onSubmit = () => { - refetch(); - } + createProviderMutation.mutate(form.values); + }; const form = useFormik({ initialValues: setInitialValues(providerStore, initialValues), validationSchema, - onSubmit - }) - - const { data, isLoading, refetch, isSuccess } = useQuery({ - queryKey: [QUERY_KEYS.CREATE_PROVIDER, form.values], - queryFn: createProvider, - enabled: false - }) - - useEffect(() => { - if(!isSuccess) return; + onSubmit, + }); + const handleOnSaveSuccess = () => { infoAlert({ - icon: 'success', - title: 'Proveedor creado', - message: 'El proveedor ha sido creado exitosamente.' + icon: "success", + title: "Provider created", + message: "The provider has been created successfully.", }); - form.resetForm(); - }, [isSuccess]) - + } + + const createProviderMutation = useMutation({ + mutationFn: createProvider, + onError: () => { + errorAlert({ message: "Error creating this provider" }); + }, + onSuccess: handleOnSaveSuccess + }); return { form, providerStore, - isLoading, - onSubmit - } -} \ No newline at end of file + loading: createProviderMutation.isLoading, + onSubmit, + }; +}; From 64fb0495ab63fc8dcf45e970b0f40200f5a420f5 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:11:04 -0500 Subject: [PATCH 47/52] =?UTF-8?q?=E2=9C=A8=20feat(status):=20add=20status?= =?UTF-8?q?=20service=20and=20store=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/services/status/statusService.js | 11 ++++++ .../src/stores/status/statusStore.js | 39 +++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 frontend/manager-app/src/services/status/statusService.js create mode 100644 frontend/manager-app/src/stores/status/statusStore.js diff --git a/frontend/manager-app/src/services/status/statusService.js b/frontend/manager-app/src/services/status/statusService.js new file mode 100644 index 0000000..f71645f --- /dev/null +++ b/frontend/manager-app/src/services/status/statusService.js @@ -0,0 +1,11 @@ +import axios from 'axios'; +import { BASE_URL } from '../../../config/envs'; + +export const getAllStatuses = async () => { + try { + const response = await axios.get(`${BASE_URL}/statuses`); + return response.data; + } catch (error) { + throw error; + } +}; diff --git a/frontend/manager-app/src/stores/status/statusStore.js b/frontend/manager-app/src/stores/status/statusStore.js new file mode 100644 index 0000000..ae8223d --- /dev/null +++ b/frontend/manager-app/src/stores/status/statusStore.js @@ -0,0 +1,39 @@ +import { create } from "zustand"; +import { createJSONStorage, devtools, persist } from "zustand/middleware"; +import { encryptLocalStorage } from "../helpers/encryptLocalStorage"; + +const storeApi = (set) => ({ + id: "", + name: "", + parent_id: "", + order: "", + + setId: (id) => { + set({ id }); + }, + + setName: (name) => { + set({ name }); + }, + + setParentId: (parent_id) => { + set({ parent_id }); + }, + + setOrder: (order) => { + set({ order }); + }, + + clearData: () => { + set({ id: "", name: "", parent_id: "", order: "" }); + } +}); + +export const useStatusStore = create( + devtools( + persist(storeApi, { + name: "status-storage", + storage: createJSONStorage(() => encryptLocalStorage) + }) + ) +); From 8e498a96cb2afed941c6621c64c0dcfa858fd562 Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:11:21 -0500 Subject: [PATCH 48/52] =?UTF-8?q?=E2=9C=A8=20feat(constants):=20add=20quer?= =?UTF-8?q?y=20keys=20for=20providers,=20patients,=20and=20statuses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constants/query-key-constants/queryKeyConstants.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 frontend/manager-app/src/utils/constants/query-key-constants/queryKeyConstants.js diff --git a/frontend/manager-app/src/utils/constants/query-key-constants/queryKeyConstants.js b/frontend/manager-app/src/utils/constants/query-key-constants/queryKeyConstants.js new file mode 100644 index 0000000..9f51d68 --- /dev/null +++ b/frontend/manager-app/src/utils/constants/query-key-constants/queryKeyConstants.js @@ -0,0 +1,8 @@ +export const QUERY_KEYS = { + GET_ALL_PROVIDERS: "get-all-providers", + GET_ALL_PATIENTS: "get-all-patients", + CREATE_PROVIDER: "create-provider", + CREATE_PATIENT: "create-patient", + GET_ALL_STATUSES: "get-all-statuses", + CREATE_STATUS: "create-status" +} \ No newline at end of file From a95e06cdf4b53ba73e9a6a2cde97ae1e04a9b8ea Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:11:32 -0500 Subject: [PATCH 49/52] =?UTF-8?q?=E2=9C=A8=20feat(dashboard):=20enhance=20?= =?UTF-8?q?navigation=20with=20responsive=20design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/dashboard/DashboardPage.jsx | 106 +++++++++++++++--- 1 file changed, 92 insertions(+), 14 deletions(-) diff --git a/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx b/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx index 157224c..a1181c9 100644 --- a/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx +++ b/frontend/manager-app/src/pages/dashboard/DashboardPage.jsx @@ -1,23 +1,101 @@ +import { useState } from "react"; import { Outlet, NavLink } from "react-router-dom"; +const navItems = [ + { to: "patient", label: "Patient" }, + { to: "provider", label: "Provider" }, + { to: "patient-list", label: "Patient List" }, + { to: "provider-list", label: "Provider List" }, + { to: "patient-update-control", label: "Update Control" }, + { to: "patient-history", label: "History" }, +]; + const DashboardPage = () => { + const [isOpen, setIsOpen] = useState(false); + return ( -
    - - -
    - +
    +
    +
    + +
    + +
    +
    + {navItems.map((item) => ( + setIsOpen(false)} + className={({ isActive }) => + `block px-3 py-2 rounded-md text-base font-medium transition-colors duration-150 ease-in-out ${ + isActive + ? "bg-blue-500 text-white" + : "text-gray-700 hover:bg-gray-200 hover:text-blue-600" + }` + } + > + {item.label} + + ))} +
    +
    +
    + +
    + +
    ); }; -DashboardPage.propTypes = {} +DashboardPage.propTypes = {}; -export default DashboardPage \ No newline at end of file +export default DashboardPage; \ No newline at end of file From 77cd8662f27b47d3e7374bb17b22b87ba15fecee Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 15:25:37 -0500 Subject: [PATCH 50/52] =?UTF-8?q?=E2=9C=A8=20feat(package):=20add=20create?= =?UTF-8?q?-envs=20script=20for=20environment=20setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/manager/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/manager/package.json b/backend/manager/package.json index 6798fc7..cfca5b9 100644 --- a/backend/manager/package.json +++ b/backend/manager/package.json @@ -19,6 +19,7 @@ "start:statuses": "nest start statuses --watch", "start:histories": "nest start status-histories --watch", "start:all": "concurrently \"npm run start:gateway\" \"npm run start:patients\" \"npm run start:providers\" \"npm run start:statuses\" \"npm run start:histories\"", + "create-envs": "bash ../../create-envs.sh", "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "test": "jest", "test:watch": "jest --watch", From f76eb5df4c3b207a4e3751918458cc9a250de59b Mon Sep 17 00:00:00 2001 From: "mario.cuberos@grupokonecta.com" Date: Fri, 24 Oct 2025 16:24:46 -0500 Subject: [PATCH 51/52] =?UTF-8?q?=E2=9C=A8=20docs:=20actualizar=20README?= =?UTF-8?q?=20para=20reflejar=20cambios=20en=20la=20estructura=20del=20pro?= =?UTF-8?q?yecto?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 211 +++++++++++++++++++++++++++++------------------------- 1 file changed, 114 insertions(+), 97 deletions(-) diff --git a/README.md b/README.md index 06ecbce..9a68386 100644 --- a/README.md +++ b/README.md @@ -1,138 +1,155 @@ -## Technical Challenge -### Background +# Manager -At VIP Medical Group, we are building a new internal module for our Medwork platform—a system that allows our staff to register patients, assign them to doctors (providers), and track their clinical status throughout their care journey. +This repository contains a microservices system with a frontend in React/Vite and a backend in NestJS, using PostgreSQL and RabbitMQ as supporting services. -In this challenge, you’ll simulate part of this module by creating a full-stack application that allows managing patients, providers, and clinical statuses with a parent-child hierarchy. +## Architecture and Design Decisions -We are **not evaluating specific tools or patterns**. We simply want to understand how you think, how you code, and how you approach real-world problems. Be yourself. +- Microservices: Each backend module runs as an independent microservice. +- RabbitMQ: Used for asynchronous communication and background task processing. +- PostgreSQL: Centralized relational database for all services. -### What You Need to Build +- Frontend: Vite application for fast reloads and agile development. -A functional **full stack application** with the ability to: +## Prerequisites -1. Create patients and providers -2. Assign a provider to a patient -3. Change the patient’s clinical status (with hierarchy) -4. Display the status change history of a patient +- Docker and Docker Compose installed +- Node.js version 18 or higher +- npm +## Steps to Run the Project Locally +1. Generate the environment files -### Database Schema +- Copy the create-envs.sh file to the root of the repository -You must implement these 4 tables exactly as described below: +- Run the following command in the terminal. This will create all necessary .env files (content of create-envs.sh file is at the end of this readme): -#### 1. `patients` +`` ./create-envs.sh `` -| Field | Type | -| ------------ | --------- | -| id | UUID | -| full\_name | string | -| email | string | -| phone | string | -| provider\_id | UUID (FK) | -| status\_id | UUID (FK) | -| created\_at | datetime | -#### 2. `providers` +2. Start backend services -| Field | Type | -| ----------- | -------- | -| id | UUID | -| full\_name | string | -| specialty | string | -| created\_at | datetime | +- Go to the backend folder: -#### 3. `statuses` +`` cd backend/manager `` -| Field | Type | -| ---------- | ------------------------------- | -| id | UUID | -| name | string | -| parent\_id | UUID (nullable, FK to statuses) | -| order | integer | +- Start the RabbitMQ and PostgreSQL images: -> This table allows parent-child status relationships. +`` docker compose -f docker-compose.dev.yml up -d `` -#### 4. `status_history` +- Install backend dependencies: +`` npm install `` -| Field | Type | -| ----------- | --------- | -| id | UUID | -| patient\_id | UUID (FK) | -| status\_id | UUID (FK) | -| changed\_at | datetime | +- Run the database migrations: +`` npm run typeorm:statuses `` +- Start all microservices: +`` npm run start:all `` +3. Start the frontend -### Preloaded Statuses +- Open another terminal and go to the frontend folder: +`` cd frontend/manager-app `` -These statuses must be preloaded in the database: +- Install frontend dependencies: +`` npm install `` -* `Scheduled` +- Start the frontend with Vite: +`` npm run dev `` - * `Checked-In` - * `In Consultation` - * `Cancelled` - * `No-Show` +### Recommended content of ./create-envs.sh -You can use a seed script or migrations to insert them. +``` +#!/bin/bash +# Backend manager root .env +cat > backend/manager/.env < backend/manager/apps/manager-api-gateway/.env < backend/manager/apps/patients/.env < backend/manager/apps/providers/.env < backend/manager/apps/status-histories/.env < backend/manager/apps/statuses/.env < **Optional screen:** Provider list view. - - - -### Submission Instructions - -* You will receive a Git repository link for the base project. -* **Fork the repository**, complete your work in a new branch, and **submit a pull request** to share your solution. -* Include a `README.md` with: - - * Clear instructions to run the project locally - * A short explanation of your architecture or design decisions - * A seed script to preload providers and statuses - - - -### Time Expectation - -You should spend no more than **8 hours** on this task. - -Don’t worry if you can’t finish everything. What matters most is **how far you get** and **how you approach the problem**. +DB_HOST=localhost +DB_PORT=5437 +DB_USERNAME=marioch +DB_PASSWORD=marioch123 +DB_DATABASE=status_db +EOL + +# Frontend .env.local +cat > frontend/manager-app/.env.local < Date: Fri, 24 Oct 2025 16:38:09 -0500 Subject: [PATCH 52/52] =?UTF-8?q?=E2=9C=A8=20docs:=20agregar=20secciones?= =?UTF-8?q?=20de=20capturas=20de=20pantalla=20al=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 ++++++++++++ screenshots/creation-alert.png | Bin 0 -> 11154 bytes screenshots/patient-creation.png | Bin 0 -> 15454 bytes screenshots/patient-list.png | Bin 0 -> 15578 bytes screenshots/provider-creation.png | Bin 0 -> 13253 bytes screenshots/provider-list.png | Bin 0 -> 14063 bytes 6 files changed, 12 insertions(+) create mode 100644 screenshots/creation-alert.png create mode 100644 screenshots/patient-creation.png create mode 100644 screenshots/patient-list.png create mode 100644 screenshots/provider-creation.png create mode 100644 screenshots/provider-list.png diff --git a/README.md b/README.md index 9a68386..954991c 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,18 @@ echo "Todos los archivos .env fueron creados correctamente." ``` +## Screenshots + +![Provider creation](./screenshots/provider-creation.png) + +![Patient creation](./screenshots/patient-creation.png) + +![Patient list](./screenshots/patient-list.png) + +![Provider list](./screenshots/provider-list.png) + +![Creation alert](./screenshots/creation-alert.png) + ## Authors diff --git a/screenshots/creation-alert.png b/screenshots/creation-alert.png new file mode 100644 index 0000000000000000000000000000000000000000..5a70da67c8c5fd71486a898fe2e2753cb21edded GIT binary patch literal 11154 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 P%VKP3cC8$8@9Dn*S~Gn< literal 0 HcmV?d00001 diff --git a/screenshots/patient-creation.png b/screenshots/patient-creation.png new file mode 100644 index 0000000000000000000000000000000000000000..213a7a45310f88de09f241158a846c15da9095b2 GIT binary patch literal 15454 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 SuYunLgAj@u@KS}xul^f*?qjzA literal 0 HcmV?d00001 diff --git a/screenshots/patient-list.png b/screenshots/patient-list.png new file mode 100644 index 0000000000000000000000000000000000000000..5e8f13c37d21561187c2c10d5f556c11d113e4c1 GIT binary patch literal 15578 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 literal 0 HcmV?d00001 diff --git a/screenshots/provider-list.png b/screenshots/provider-list.png new file mode 100644 index 0000000000000000000000000000000000000000..562ec6cc6aa49d981adc3763947597bf9107fc4d GIT binary patch literal 14063 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 dCH!(90U(>|D*;`R#2CJFZ(3){{Wj9K-K^N literal 0 HcmV?d00001