From 88baf22e6fc7f51b4b82ea0273d2643f0a98a387 Mon Sep 17 00:00:00 2001 From: Liam Lloyd-Tucker Date: Fri, 26 Jun 2026 15:01:12 -0700 Subject: [PATCH] Switch to vitest Jest doesn't officially support ESM. We'd like to move this repo to ESM, as that appears to be the way of the future (and we have some dependencies that in their latest releases only offer ESM support). To that end, this commit replaces Jest with Vitest. --- AGENTS.md | 164 +- README.md | 2 +- eslint.config.mjs | 15 +- jest.config.js | 5 - package-lock.json | 12295 +++++++--------- package.json | 13 +- packages/access_copy_attacher/Dockerfile | 2 +- packages/access_copy_attacher/jest.config.js | 7 - packages/access_copy_attacher/package.json | 2 +- .../access_copy_attacher/src/index.test.ts | 83 +- .../access_copy_attacher/vitest.config.ts | 1 + packages/account_space_updater/Dockerfile | 2 +- packages/account_space_updater/jest.config.js | 7 - packages/account_space_updater/package.json | 2 +- .../account_space_updater/src/index.test.ts | 21 +- .../account_space_updater/vitest.config.ts | 1 + packages/api/Dockerfile | 2 +- packages/api/Dockerfile.test | 2 +- packages/api/jest.config.js | 12 - packages/api/jest.db.teardown.ts | 43 - packages/api/package.json | 12 +- packages/api/src/__mocks__/database.ts | 7 +- packages/api/src/access/permission.test.ts | 19 +- .../create_storage_adjustments.test.ts | 15 +- .../account/controller/get_accounts.test.ts | 11 +- .../controller/get_signup_details.test.ts | 21 +- .../account/controller/leave_archive.test.ts | 19 +- .../account/controller/update_tags.test.ts | 31 +- packages/api/src/account/service.test.ts | 9 +- packages/api/src/account/validators.test.ts | 1 + packages/api/src/admin/controller.test.ts | 92 +- packages/api/src/admin/validators.test.ts | 1 + .../controller/backfill_ledger.test.ts | 27 +- .../archive/controller/get_featured.test.ts | 7 +- .../get_payer_account_storage.test.ts | 11 +- .../controller/get_public_tags.test.ts | 9 +- .../controller/get_shared_folders.test.ts | 21 +- .../archive/controller/make_featured.test.ts | 9 +- .../controller/search_archives.test.ts | 11 +- .../src/archive/controller/unfeature.test.ts | 9 +- .../archive/controller/update_archive.test.ts | 9 +- packages/api/src/archive/validators.test.ts | 1 + packages/api/src/database_util.test.ts | 1 + packages/api/src/directive/controller.test.ts | 150 +- .../api/src/directive/service/utils.test.ts | 3 +- packages/api/src/directive/validators.test.ts | 1 + packages/api/src/email/service.test.ts | 67 +- packages/api/src/event/controller.test.ts | 55 +- .../api/src/feature_flag/controller.test.ts | 84 +- .../api/src/feature_flag/validators.test.ts | 1 + .../src/folder/controller/get_folder.test.ts | 13 +- .../controller/get_folder_children.test.ts | 7 +- .../controller/get_folder_share_links.test.ts | 21 +- .../folder/controller/patch_folder.test.ts | 99 +- packages/api/src/folder/service.test.ts | 1 + packages/api/src/folder/validators.test.ts | 1 + packages/api/src/fusionauth.test.ts | 1 + packages/api/src/health/controller.test.ts | 5 +- packages/api/src/idpuser/controller.test.ts | 99 +- packages/api/src/legacy_client.test.ts | 3 +- .../api/src/legacy_contact/controller.test.ts | 33 +- .../api/src/legacy_contact/validators.test.ts | 1 + packages/api/src/location/service.test.ts | 33 +- .../api/src/middleware/authentication.test.ts | 293 +- .../api/src/middleware/extract_ip.test.ts | 9 +- .../api/src/middleware/handleError.test.ts | 13 +- .../middleware/handleValidationError.test.ts | 9 +- packages/api/src/promo/controller.test.ts | 47 +- .../src/record/controller/copy_record.test.ts | 96 +- .../controller/get_record_share_links.test.ts | 21 +- .../src/record/controller/get_records.test.ts | 13 +- .../controller/get_single_record.test.ts | 13 +- .../record/controller/update_record.test.ts | 70 +- packages/api/src/record/validators.test.ts | 1 + .../api/src/share_link/controller.test.ts | 97 +- .../api/src/share_link/validators.test.ts | 1 + packages/api/src/storage/controller.test.ts | 95 +- .../src/storage_purchase/controller.test.ts | 164 +- packages/api/src/validators/shared.test.ts | 1 + .../api/src/validators/validator_util.test.ts | 1 + packages/api/test/middleware_mocks.ts | 159 +- packages/api/test/mock_sql.ts | 38 + packages/api/vitest.config.ts | 28 + .../{jest.db.setup.ts => vitest.db.setup.ts} | 43 +- ...{jest.env.setup.js => vitest.env.setup.js} | 0 packages/archivematica-utils/jest.config.js | 7 - packages/archivematica-utils/package.json | 2 +- .../archivematica-utils/src/index.test.ts | 3 +- packages/archivematica-utils/vitest.config.ts | 1 + packages/archivematica_cleanup/Dockerfile | 2 +- packages/archivematica_cleanup/jest.config.js | 7 - packages/archivematica_cleanup/package.json | 2 +- .../archivematica_cleanup/src/service.test.ts | 13 +- .../archivematica_cleanup/vitest.config.ts | 1 + packages/event_send/Dockerfile | 2 +- packages/event_send/jest.config.js | 7 - packages/event_send/package.json | 2 +- packages/event_send/src/service.test.ts | 40 +- packages/event_send/vitest.config.ts | 1 + packages/event_utils/jest.config.js | 7 - packages/file-utils/jest.config.js | 7 - packages/file-utils/package.json | 2 +- packages/file-utils/vitest.config.ts | 1 + packages/file_copier/Dockerfile | 2 +- packages/file_copier/jest.config.js | 7 - packages/file_copier/package.json | 2 +- packages/file_copier/src/index.test.ts | 72 +- packages/file_copier/vitest.config.ts | 1 + packages/file_url_refresh/Dockerfile | 2 +- packages/file_url_refresh/jest.config.js | 7 - packages/file_url_refresh/package.json | 2 +- packages/file_url_refresh/src/service.test.ts | 26 +- packages/file_url_refresh/vitest.config.ts | 1 + packages/logger/src/__mocks__/index.ts | 12 + packages/metadata_attacher/Dockerfile | 2 +- packages/metadata_attacher/jest.config.js | 7 - packages/metadata_attacher/package.json | 2 +- packages/metadata_attacher/src/index.test.ts | 87 +- packages/metadata_attacher/vitest.config.ts | 1 + packages/publisher-utils/jest.config.js | 7 - packages/publisher-utils/package.json | 2 +- packages/publisher-utils/src/index.test.ts | 88 +- packages/publisher-utils/vitest.config.ts | 1 + packages/record_thumbnail_attacher/Dockerfile | 2 +- .../record_thumbnail_attacher/jest.config.js | 7 - .../record_thumbnail_attacher/package.json | 2 +- .../src/index.test.ts | 44 +- .../vitest.config.ts | 1 + packages/s3-utils/jest.config.js | 7 - packages/s3-utils/package.json | 2 +- packages/s3-utils/src/index.test.ts | 3 +- packages/s3-utils/vitest.config.ts | 1 + packages/thumbnail_refresh/Dockerfile | 2 +- packages/thumbnail_refresh/jest.config.js | 7 - packages/thumbnail_refresh/package.json | 2 +- .../thumbnail_refresh/src/service.test.ts | 20 +- packages/thumbnail_refresh/vitest.config.ts | 1 + packages/trigger_archivematica/Dockerfile | 2 +- packages/trigger_archivematica/jest.config.js | 8 - packages/trigger_archivematica/package.json | 2 +- .../trigger_archivematica/src/index.test.ts | 49 +- .../trigger_archivematica/vitest.config.ts | 11 + ...{jest.env.setup.js => vitest.env.setup.js} | 0 vitest.shared.ts | 16 + 144 files changed, 6697 insertions(+), 8854 deletions(-) delete mode 100644 jest.config.js delete mode 100644 packages/access_copy_attacher/jest.config.js create mode 100644 packages/access_copy_attacher/vitest.config.ts delete mode 100644 packages/account_space_updater/jest.config.js create mode 100644 packages/account_space_updater/vitest.config.ts delete mode 100644 packages/api/jest.config.js delete mode 100644 packages/api/jest.db.teardown.ts create mode 100644 packages/api/test/mock_sql.ts create mode 100644 packages/api/vitest.config.ts rename packages/api/{jest.db.setup.ts => vitest.db.setup.ts} (51%) rename packages/api/{jest.env.setup.js => vitest.env.setup.js} (100%) delete mode 100644 packages/archivematica-utils/jest.config.js create mode 100644 packages/archivematica-utils/vitest.config.ts delete mode 100644 packages/archivematica_cleanup/jest.config.js create mode 100644 packages/archivematica_cleanup/vitest.config.ts delete mode 100644 packages/event_send/jest.config.js create mode 100644 packages/event_send/vitest.config.ts delete mode 100644 packages/event_utils/jest.config.js delete mode 100644 packages/file-utils/jest.config.js create mode 100644 packages/file-utils/vitest.config.ts delete mode 100644 packages/file_copier/jest.config.js create mode 100644 packages/file_copier/vitest.config.ts delete mode 100644 packages/file_url_refresh/jest.config.js create mode 100644 packages/file_url_refresh/vitest.config.ts create mode 100644 packages/logger/src/__mocks__/index.ts delete mode 100644 packages/metadata_attacher/jest.config.js create mode 100644 packages/metadata_attacher/vitest.config.ts delete mode 100644 packages/publisher-utils/jest.config.js create mode 100644 packages/publisher-utils/vitest.config.ts delete mode 100644 packages/record_thumbnail_attacher/jest.config.js create mode 100644 packages/record_thumbnail_attacher/vitest.config.ts delete mode 100644 packages/s3-utils/jest.config.js create mode 100644 packages/s3-utils/vitest.config.ts delete mode 100644 packages/thumbnail_refresh/jest.config.js create mode 100644 packages/thumbnail_refresh/vitest.config.ts delete mode 100644 packages/trigger_archivematica/jest.config.js create mode 100644 packages/trigger_archivematica/vitest.config.ts rename packages/trigger_archivematica/{jest.env.setup.js => vitest.env.setup.js} (100%) create mode 100644 vitest.shared.ts diff --git a/AGENTS.md b/AGENTS.md index 235ec36b..2bf01fc3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -14,29 +14,29 @@ This is an npm workspace monorepo (workspaces defined in the root `package.json` ### Core Packages -| Package | Description | -|---------|-------------| -| `@stela/api` | Main Express API server — the primary package where most development happens | -| `@stela/logger` | Centralized logging via Winston | -| `@stela/permanent_models` | Shared TypeScript models and data types | -| `@stela/event_utils` | Event validation utilities | -| `@stela/file-utils` | File manipulation utilities | -| `@stela/s3-utils` | AWS S3 integration utilities | -| `@stela/archivematica-utils` | Archivematica integration utilities | +| Package | Description | +| ---------------------------- | ---------------------------------------------------------------------------- | +| `@stela/api` | Main Express API server — the primary package where most development happens | +| `@stela/logger` | Centralized logging via Winston | +| `@stela/permanent_models` | Shared TypeScript models and data types | +| `@stela/event_utils` | Event validation utilities | +| `@stela/file-utils` | File manipulation utilities | +| `@stela/s3-utils` | AWS S3 integration utilities | +| `@stela/archivematica-utils` | Archivematica integration utilities | ### Lambda / Cron Packages -| Package | Type | Description | -|---------|------|-------------| -| `@stela/record_thumbnail_attacher` | Lambda | Attaches thumbnails to records via CloudFront signed URLs | -| `@stela/account_space_updater` | Lambda | Updates account storage ledger | -| `@stela/access_copy_attacher` | Lambda | Attaches access copies generated by Archivematica to records | -| `@stela/metadata_attacher` | Lambda | Processes and attaches metadata to records | -| `@stela/trigger_archivematica` | Lambda | Triggers archivematica preservation workflows | -| `@stela/thumbnail_refresh` | Cron | Refreshes expired CDN thumbnail URLs | -| `@stela/file_url_refresh` | Cron | Refreshes expired file URLs | -| `@stela/archivematica_cleanup` | Cron | Cleans up archivematica processes | -| `@stela/event_send` | Cron | Sends unsent events from the event table to SNS | +| Package | Type | Description | +| ---------------------------------- | ------ | ------------------------------------------------------------ | +| `@stela/record_thumbnail_attacher` | Lambda | Attaches thumbnails to records via CloudFront signed URLs | +| `@stela/account_space_updater` | Lambda | Updates account storage ledger | +| `@stela/access_copy_attacher` | Lambda | Attaches access copies generated by Archivematica to records | +| `@stela/metadata_attacher` | Lambda | Processes and attaches metadata to records | +| `@stela/trigger_archivematica` | Lambda | Triggers archivematica preservation workflows | +| `@stela/thumbnail_refresh` | Cron | Refreshes expired CDN thumbnail URLs | +| `@stela/file_url_refresh` | Cron | Refreshes expired file URLs | +| `@stela/archivematica_cleanup` | Cron | Cleans up archivematica processes | +| `@stela/event_send` | Cron | Sends unsent events from the event table to SNS | ## Technology Stack @@ -45,7 +45,7 @@ This is an npm workspace monorepo (workspaces defined in the root `package.json` - **Framework:** Express - **Database:** PostgreSQL, accessed via TinyPg (SQL file-based query library) - **Authentication:** FusionAuth (external identity provider) -- **Testing:** Jest with ts-jest, Supertest, jest-when, nock, jest-mock-extended +- **Testing:** Vitest, Supertest, vitest-when, nock, vitest-mock-extended - **Linting:** ESLint (eslint-config-love + prettier), SQLFluff (PostgreSQL dialect) - **API Docs:** OpenAPI, linted with Redocly CLI - **Error Tracking:** Sentry @@ -89,9 +89,10 @@ The `@stela/api` lint script runs these checks sequentially: ### Testing Tests for `@stela/api` require a running PostgreSQL instance. The test setup: + 1. Starts Docker containers (`docker compose up`) 2. Creates a fresh `test_permanent` database from the main database schema -3. Runs Jest inside the Docker container +3. Runs Vitest inside the Docker container Other workspace tests can generally run independently. @@ -153,6 +154,7 @@ exampleController.get( ``` Key conventions: + - Authentication middleware injects `emailFromAuthToken` and `userSubjectFromAuthToken` into `req.body` - Validation uses Joi with TypeScript `asserts` type guards - Validation errors produce 400 responses; other errors are passed to `next()` @@ -165,17 +167,18 @@ Services contain business logic and database access: ```typescript export const getThingById = async (id: string): Promise => { - const result = await db - .sql("domain.queries.query_name", { id }) - .catch((err: unknown) => { - logger.error(err); - throw new createError.InternalServerError("Failed to get thing"); - }); - return result.rows[0]; + const result = await db + .sql("domain.queries.query_name", { id }) + .catch((err: unknown) => { + logger.error(err); + throw new createError.InternalServerError("Failed to get thing"); + }); + return result.rows[0]; }; ``` Key conventions: + - Use `db.sql("domain.queries.file_name", params)` for parameterized queries - The SQL file path is dot-notation: `domain.queries.file_name` maps to `packages/api/src/domain/queries/file_name.sql` - Errors are logged then re-thrown as HTTP errors @@ -186,21 +189,22 @@ Key conventions: Validators use Joi with TypeScript assertion functions: ```typescript -export const validateSomething: ( - data: unknown, -) => asserts data is SomeType = ( - data: unknown, +export const validateSomething: (data: unknown) => asserts data is SomeType = ( + data: unknown, ): asserts data is SomeType => { - const validation = Joi.object() - .keys({ /* schema */ }) - .validate(data); - if (validation.error !== undefined) { - throw validation.error; - } + const validation = Joi.object() + .keys({ + /* schema */ + }) + .validate(data); + if (validation.error !== undefined) { + throw validation.error; + } }; ``` Shared authentication validation fields are in `packages/api/src/validators/shared.ts`: + - `fieldsFromUserAuthentication` — requires `emailFromAuthToken` + `userSubjectFromAuthToken` - `fieldsFromAdminAuthentication` — requires `emailFromAuthToken` + `adminSubjectFromAuthToken` @@ -240,6 +244,7 @@ SQL files are linted with SQLFluff (PostgreSQL dialect, colon-style placeholder ### Schema The base database schema lives in `database/base.sql` (dumped from production). Key tables include: + - `account`, `account_archive` — user accounts and archive memberships - `archive` — archives (collections) - `folder`, `folder_link` — folder hierarchy @@ -263,48 +268,49 @@ Test files are co-located with source: `controller.test.ts` next to `controller. ### Integration Test Pattern (API) ```typescript -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { - await db.sql("domain.fixtures.create_test_accounts"); - await db.sql("domain.fixtures.create_test_data"); - // ... load all required fixtures + await db.sql("domain.fixtures.create_test_accounts"); + await db.sql("domain.fixtures.create_test_data"); + // ... load all required fixtures }; const clearDatabase = async (): Promise => { - await db.query(`TRUNCATE account, archive, ... CASCADE`); + await db.query(`TRUNCATE account, archive, ... CASCADE`); }; describe("GET /endpoint", () => { - beforeEach(async () => { - mockVerifyUserAuthentication("test@permanent.org", "uuid-here"); - await clearDatabase(); - await setupDatabase(); - }); - - afterEach(async () => { - await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); - }); - - const agent = request(app); - - test("description", async () => { - const response = await agent.get("/api/v2/endpoint").expect(200); - expect(response.body).toEqual(/* ... */); - }); + beforeEach(async () => { + mockVerifyUserAuthentication("test@permanent.org", "uuid-here"); + await clearDatabase(); + await setupDatabase(); + }); + + afterEach(async () => { + await clearDatabase(); + vi.restoreAllMocks(); + vi.clearAllMocks(); + }); + + const agent = request(app); + + test("description", async () => { + const response = await agent.get("/api/v2/endpoint").expect(200); + expect(response.body).toEqual(/* ... */); + }); }); ``` Key patterns: + - The database module, middleware, and logger are always mocked at the module level - `setupDatabase` loads SQL fixtures; `clearDatabase` truncates tables - Middleware mocks are in `packages/api/test/middleware_mocks.ts` - Each test block clears and rebuilds the database in `beforeEach`/`afterEach` -- Use `jest-when` for conditional mock behavior based on arguments +- Use `vitest-when` for conditional mock behavior based on arguments - Supertest `agent` is created from the Express `app` ## Authentication & Authorization @@ -369,25 +375,25 @@ API docs are at `packages/api/docs/src/api.yaml` using modular YAML references. GitHub Actions workflows in `.github/workflows/`: -| Workflow | Trigger | Purpose | -|----------|---------|---------| -| `lint.yml` | Every push | Builds and lints all workspaces | -| `test.yml` | Push to non-main branches | Runs all workspace tests with Codecov | -| `build.yml` | Called by deploy workflows | Builds Docker images, pushes to AWS ECR | -| `dev_deploy.yml` | Merge to main | Auto-deploys to dev environment | -| `staging_deploy.yml` | Manual | Deploys to staging | -| `prod_deploy.yml` | Manual (requires approval) | Deploys to production | -| `deploy_docs.yml` | Docs changes | Publishes API docs to GitHub Pages | +| Workflow | Trigger | Purpose | +| -------------------- | -------------------------- | --------------------------------------- | +| `lint.yml` | Every push | Builds and lints all workspaces | +| `test.yml` | Push to non-main branches | Runs all workspace tests with Codecov | +| `build.yml` | Called by deploy workflows | Builds Docker images, pushes to AWS ECR | +| `dev_deploy.yml` | Merge to main | Auto-deploys to dev environment | +| `staging_deploy.yml` | Manual | Deploys to staging | +| `prod_deploy.yml` | Manual (requires approval) | Deploys to production | +| `deploy_docs.yml` | Docs changes | Publishes API docs to GitHub Pages | ## Lambda Handler Pattern ```typescript export const handler: SQSHandler = async (event: SQSEvent) => { - for (const record of event.Records) { - // Validate and parse SQS message - // Execute business logic - // Handle errors with Sentry + logger - } + for (const record of event.Records) { + // Validate and parse SQS message + // Execute business logic + // Handle errors with Sentry + logger + } }; ``` diff --git a/README.md b/README.md index f4db2355..5a49358e 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Note that the database tests run against is dropped and recreated at the beginni For running tests on a single file in `stela`, you can make an adjustment to the existing `test` command in **packages/api/package.json** on your machine. See the example below (replace **src/middleware/authentication.test.ts** with a pattern to match your file): ```json - "test:file": "npm run start-containers && npm run clear-database && npm run create-database && npm run set-up-database && (cd ../..; docker compose run stela node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false -- src/middleware/authentication.test.ts)", + "test:file": "npm run start-containers && npm run clear-database && npm run create-database && npm run set-up-database && (cd ../..; docker compose run vitest run -- src/middleware/authentication.test.ts)", ``` ## Running the API Server Locally diff --git a/eslint.config.mjs b/eslint.config.mjs index 579f5b86..54221965 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -3,7 +3,7 @@ import typescriptEslint from "typescript-eslint"; import prettier from "eslint-config-prettier"; import love from "eslint-config-love"; import globals from "globals"; -import jest from "eslint-plugin-jest"; +import vitest from "@vitest/eslint-plugin"; import js from "@eslint/js"; export default defineConfig([ @@ -17,7 +17,7 @@ export default defineConfig([ languageOptions: { globals: { ...globals.node, - ...globals.jest, + ...vitest.environments.env.globals, }, }, @@ -48,13 +48,13 @@ export default defineConfig([ files: ["**/*.test.ts"], plugins: { - jest, + vitest, }, rules: { "@typescript-eslint/unbound-method": "off", - "jest/unbound-method": "error", - "jest/no-focused-tests": "error", + "vitest/unbound-method": "error", + "vitest/no-focused-tests": "error", // Test files are allowed to be long because they need to be able to comprehensively test // the relevant code, however many tests that takes. Their natural structure also makes // them more navigable than other lengthy files might be. @@ -65,5 +65,10 @@ export default defineConfig([ // This interferes with some mocking patterns that we use widely "@typescript-eslint/strict-void-return": "off", }, + languageOptions: { + globals: { + ...vitest.environments.env.globals, + }, + }, }, ]); diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 27aae3ba..00000000 --- a/jest.config.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - silent: true, - preset: "ts-jest", - testEnvironment: "node", -}; diff --git a/package-lock.json b/package-lock.json index 67b4eacc..b4533b1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,48 +39,31 @@ "@types/cors": "^2.8.17", "@types/express": "^5.0.3", "@types/http-errors": "^2.0.1", - "@types/jest": "30.0.0", - "@types/jest-when": "^3.5.5", "@types/mailchimp__mailchimp_transactional": "1.0.11", "@types/node": "^24.10.1", "@types/pg": "^8.20.0", "@types/supertest": "^6.0.3", + "@vitest/coverage-v8": "^4.1.10", + "@vitest/eslint-plugin": "^1.6.21", "eslint": "^9.39.4", "eslint-config-love": "^154.0.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.2", - "jest": "30.3.0", - "jest-mock-extended": "^4.0.0", - "jest-when": "^3.7.0", "node-mocks-http": "^1.17.2", "prettier": "^3.7.4", - "ts-jest": "29.4.6", "tsc-watch": "^7.2.0", "tslint-tinypg": "^2.0.2", "typescript": "^5.9.3", "typescript-cp": "^0.1.9", - "typescript-eslint": "^8.62.0" + "typescript-eslint": "^8.62.0", + "vitest": "^4.1.10", + "vitest-mock-extended": "^4.0.0" }, "engines": { "node": ">=24.0" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@apm-js-collab/code-transformer": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.14.0.tgz", - "integrity": "sha512-6G+FETQ/VyRBsIkDDZ5sc9fb7O6d6W9rm8bZPHumISZw/6nwxvnS+VTyxd3sKM04aZwHG5hJIHb7VPdPCLieSQ==", "license": "Apache-2.0", "dependencies": { "@types/estree": "^1.0.8", @@ -93,8 +76,6 @@ }, "node_modules/@apm-js-collab/code-transformer-bundler-plugins": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.5.0.tgz", - "integrity": "sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==", "license": "MIT", "dependencies": { "@apm-js-collab/code-transformer": "^0.15.0", @@ -108,8 +89,6 @@ }, "node_modules/@apm-js-collab/code-transformer-bundler-plugins/node_modules/@apm-js-collab/code-transformer": { "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.15.0.tgz", - "integrity": "sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==", "license": "Apache-2.0", "dependencies": { "@types/estree": "^1.0.8", @@ -125,8 +104,6 @@ }, "node_modules/@apm-js-collab/tracing-hooks": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.9.1.tgz", - "integrity": "sha512-9uzuUftJ+xF90g5u411OgU+TpdZqqGB4igq2c8swiS7BfDGe16bnDRfQSCU6jxk+hjiospSG/t9FI4Ja9iw3+g==", "license": "Apache-2.0", "dependencies": { "@apm-js-collab/code-transformer": "^0.14.0", @@ -285,8 +262,6 @@ }, "node_modules/@aws-sdk/checksums": { "version": "3.1000.11", - "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.11.tgz", - "integrity": "sha512-nW5kNBJBwVxkvBqygBYksS8WUFDO8Ad8OSfsVa+f5KFRRTrHL1rnWZNsWBwc5fC9YvZbET/57+X4hym/jKfV+g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -301,8 +276,6 @@ }, "node_modules/@aws-sdk/client-s3": { "version": "3.1075.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1075.0.tgz", - "integrity": "sha512-h1A6nIl1YX6Y45enGsTK7ef3ZrOnBiQJ1qF5R2K/nMWfsu6A9mc2Y5T66nxerABzyjjyyvign3MrzafnFoQKmA==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha1-browser": "5.2.0", @@ -326,8 +299,6 @@ }, "node_modules/@aws-sdk/client-sns": { "version": "3.1075.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sns/-/client-sns-3.1075.0.tgz", - "integrity": "sha512-z+GHXov9fkyAkBDZontInAPWGoUnBhMrPFuSX4FGZaCxhVo9UIStcYjpSBy1+aZN1yB7NRaGQYI0WfEAPv399w==", "license": "Apache-2.0", "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", @@ -347,8 +318,6 @@ }, "node_modules/@aws-sdk/core": { "version": "3.974.26", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.26.tgz", - "integrity": "sha512-wRj7Pthvjk3anees97pUWlxlTa0DUjeGrEQU5fKDZVdWZV0ekaprbof0df2uaE9g8u67t035v2j+ne2AW2UMkA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.15", @@ -366,8 +335,6 @@ }, "node_modules/@aws-sdk/credential-provider-env": { "version": "3.972.52", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.52.tgz", - "integrity": "sha512-sxuaHZGHqOgKB8OdL3doXa1NJjqmO60FPfyTnYVKGjX9taRsIEGS9pd+2yALmo06hijZ8L94uSK0kfXZsRmVyA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -382,8 +349,6 @@ }, "node_modules/@aws-sdk/credential-provider-http": { "version": "3.972.54", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.54.tgz", - "integrity": "sha512-e6yz52nq3SpR1oPLcvfsDM7H7k2gIYk/NSn/rwsFqzGXEwr3g0mRMlPbLaKCPCGNZJMU/gZg6/64B3eSam+gBw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -400,8 +365,6 @@ }, "node_modules/@aws-sdk/credential-provider-ini": { "version": "3.972.59", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.59.tgz", - "integrity": "sha512-9Um/UpruN76AdpiLnvwChVkJJwJ9Vx9ykk/2AeLxxSCM/YYRD8Kkq2towUk9fZQLV7dd9ATlsi87U7hKs0z/iQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -424,8 +387,6 @@ }, "node_modules/@aws-sdk/credential-provider-login": { "version": "3.972.58", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.58.tgz", - "integrity": "sha512-H3q96qF8/DJsPsXMVtMRqSWOc85K5O4zos32untdw+vE5vw0f3a6qJo1YqbND4BsEIKd4iZmzzVUq9kV4LjbHg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -441,8 +402,6 @@ }, "node_modules/@aws-sdk/credential-provider-node": { "version": "3.972.61", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.61.tgz", - "integrity": "sha512-2U2KHMRCt1dlZoLU3KZR5g5EL4b0h2HHw96SkaUBK7qvEXPZj5rGRO/3ZTeJmh37dIYQuCnA2273rZOQvmsiHw==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/credential-provider-env": "^3.972.52", @@ -463,8 +422,6 @@ }, "node_modules/@aws-sdk/credential-provider-process": { "version": "3.972.52", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.52.tgz", - "integrity": "sha512-Aff9Ebs42lz+Ep1wkS+Nlwh5S0eahakpyskPsuKGjiBJ6ExOjNtxbfKJTKovQtQNgJ7oG1BH6esJwGrbs7qgSA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -479,8 +436,6 @@ }, "node_modules/@aws-sdk/credential-provider-sso": { "version": "3.972.58", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.58.tgz", - "integrity": "sha512-syloC58mXOacUqM2toPNfwd7X3jT+tWj0F/cN7qdW1FQyI0q41J0tPf6DIZ56BF0x82iS9j3ALP45MoBz79YuQ==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -497,8 +452,6 @@ }, "node_modules/@aws-sdk/credential-provider-web-identity": { "version": "3.972.58", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.58.tgz", - "integrity": "sha512-pTBImKzcGK+pcMKjL0fAJbnYzzYd1c0UDc7BSIOGNQhF9Nuk66vWlIXfYTYyzNSs+w8Q/vfbbNDDU8zdrouwLg==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -514,8 +467,6 @@ }, "node_modules/@aws-sdk/middleware-flexible-checksums": { "version": "3.974.36", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.974.36.tgz", - "integrity": "sha512-dnbzbDuw+OHOVf67O9EaxtX9GM6R7MH7SZsCR9CkE2ogxuPPMs4NyhaJK1pjJaEP3uMNJIajcY0OezePG7Bgew==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/checksums": "^3.1000.11", @@ -527,8 +478,6 @@ }, "node_modules/@aws-sdk/middleware-sdk-s3": { "version": "3.972.57", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.57.tgz", - "integrity": "sha512-E7tRmmUb64LlsoI6pZZRTov21K74Fr/MVgYBeNFfBkFzpF8e2tuJkKd4YGmcNwz0UjDs8fMoS0v/MGgHASIx+Q==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -544,8 +493,6 @@ }, "node_modules/@aws-sdk/nested-clients": { "version": "3.997.26", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.26.tgz", - "integrity": "sha512-Lwe3F6K7bs+jEubp1LbrvzeMBYb5fMazJ1IxV9TtKWPF8CSh67Fmwyq9fLz3NL/k55Dfpuph5Dimw76JFgr+SA==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -563,8 +510,6 @@ }, "node_modules/@aws-sdk/signature-v4-multi-region": { "version": "3.996.38", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.38.tgz", - "integrity": "sha512-C379Sk+MiFZCfWZphKlMyLHKxV22OjoGM5KJjj5IJNJcOCWL4IGIpnEGzv1FQiRwhYXfq55SJMfxlqPE08JJ9g==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/types": "^3.973.15", @@ -578,8 +523,6 @@ }, "node_modules/@aws-sdk/token-providers": { "version": "3.1078.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1078.0.tgz", - "integrity": "sha512-/uyXLBGu3Lw1GbBA2X66hcOMnKtMcqAIF+3/eHfxBQmUeXF2sdqozDPrTfEr/TnSd0D6deZar+eVyhEqqWu29w==", "license": "Apache-2.0", "dependencies": { "@aws-sdk/core": "^3.974.26", @@ -595,8 +538,6 @@ }, "node_modules/@aws-sdk/types": { "version": "3.973.15", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.15.tgz", - "integrity": "sha512-IULn8uBV/SMtmOIANsm4WHXIOtVPBWfOWs3WGL0j/sI+KhaYehvOw0ET+9urnn8MBpiijuU/0JOpuwKOE451PQ==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.15.1", @@ -618,8 +559,6 @@ }, "node_modules/@aws-sdk/xml-builder": { "version": "3.972.33", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.33.tgz", - "integrity": "sha512-ezbwz9WpuLctm6o7P2t2naDhVVPI5jFGrVefVybhcKGjU57VIyT46pQVO0RI2RYkUdhdj2Z9uSIlAzGZE9NW9A==", "license": "Apache-2.0", "dependencies": { "@smithy/types": "^4.15.1", @@ -649,3496 +588,1610 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.28.0", + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/core": { - "version": "7.28.0", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", "dev": true, "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.27.3", - "@babel/helpers": "^7.27.6", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.0", - "@babel/types": "^7.28.0", - "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", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" } }, - "node_modules/@babel/generator": { - "version": "7.28.0", + "node_modules/@babel/parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", + "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" + "@babel/types": "^7.29.7" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "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" + "bin": { + "parser": "bin/babel-parser.js" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", + "node_modules/@babel/runtime": { + "version": "7.29.7", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", + "node_modules/@babel/types": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", + "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.27.3", - "dev": true, + "node_modules/@borewit/text-codec": { + "version": "0.2.2", "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.27.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "dev": true, + "node_modules/@colors/colors": { + "version": "1.6.0", "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=0.1.90" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "dev": true, + "node_modules/@dabh/diagnostics": { + "version": "2.0.8", "license": "MIT", - "engines": { - "node": ">=6.9.0" + "dependencies": { + "@so-ric/colorspace": "^1.1.6", + "enabled": "2.0.x", + "kuler": "^2.0.0" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "dev": true, - "license": "MIT", + "node_modules/@datadog/pprof": { + "version": "5.15.0", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.8.4", + "pprof-format": "^2.2.1", + "source-map": "^0.7.4" + }, "engines": { - "node": ">=6.9.0" + "node": ">=16" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "dev": true, - "license": "MIT", + "node_modules/@datadog/pprof/node_modules/source-map": { + "version": "0.7.6", + "license": "BSD-3-Clause", + "optional": true, "engines": { - "node": ">=6.9.0" + "node": ">= 12" } }, - "node_modules/@babel/helpers": { - "version": "7.28.2", + "node_modules/@edtf-ts/core": { + "version": "0.5.0", + "license": "MIT" + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.2" - }, - "engines": { - "node": ">=6.9.0" + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" } }, - "node_modules/@babel/parser": { - "version": "7.28.0", + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/types": "^7.28.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "tslib": "^2.4.0" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", + "node_modules/@emotion/is-prop-valid": { + "version": "1.4.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@emotion/memoize": "^0.9.0" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", + "node_modules/@emotion/memoize": { + "version": "0.9.0", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } + "license": "MIT" }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", + "node_modules/@eslint-community/eslint-plugin-eslint-comments": { + "version": "4.7.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "escape-string-regexp": "^4.0.0", + "ignore": "^7.0.5" }, "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", + "node_modules/@eslint-community/eslint-plugin-eslint-comments/node_modules/ignore": { + "version": "7.0.5", "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": ">= 4" } }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "eslint-visitor-keys": "^3.4.3" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", "dev": true, "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", + "node_modules/@eslint/config-array": { + "version": "0.21.2", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.5" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.13", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.5", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "brace-expansion": "^1.1.7" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "*" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@eslint/core": "^0.17.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", + "node_modules/@eslint/core": { + "version": "0.17.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@types/json-schema": "^7.0.15" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", + "node_modules/@eslint/eslintrc": { + "version": "3.3.5", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, + "ajv": "^6.14.0", + "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.1", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.14.0", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.13", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@babel/runtime": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", - "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } + "license": "MIT" }, - "node_modules/@babel/template": { - "version": "7.27.2", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.5", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=6.9.0" + "node": "*" } }, - "node_modules/@babel/traverse": { - "version": "7.28.0", + "node_modules/@eslint/js": { + "version": "9.39.4", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", - "debug": "^4.3.1" + "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", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@babel/types": { - "version": "7.28.2", + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, "engines": { - "node": ">=6.9.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", + "node_modules/@exodus/schemasafe": { + "version": "1.3.0", "dev": true, "license": "MIT" }, - "node_modules/@borewit/text-codec": { - "version": "0.2.2", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/@colors/colors": { - "version": "1.6.0", + "node_modules/@faker-js/faker": { + "version": "7.6.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=0.1.90" + "node": ">=14.0.0", + "npm": ">=6.0.0" } }, - "node_modules/@dabh/diagnostics": { - "version": "2.0.8", - "license": "MIT", + "node_modules/@fusionauth/typescript-client": { + "version": "1.60.0", + "license": "Apache-2.0", "dependencies": { - "@so-ric/colorspace": "^1.1.6", - "enabled": "2.0.x", - "kuler": "^2.0.0" + "node-fetch": "^2.6.1" } }, - "node_modules/@datadog/pprof": { - "version": "5.15.0", - "resolved": "https://registry.npmjs.org/@datadog/pprof/-/pprof-5.15.0.tgz", - "integrity": "sha512-ODGC3pE+NHo+rz74bWyOyFeC5GgvqA6Xzk0wIBGs8W3v+A14I5Q+Pmc7EC8etk5gE8t0hGYYwA5ymSGCljov+Q==", - "hasInstallScript": true, + "node_modules/@grpc/grpc-js": { + "version": "1.13.4", "license": "Apache-2.0", - "optional": true, "dependencies": { - "node-gyp-build": "^4.8.4", - "pprof-format": "^2.2.1", - "source-map": "^0.7.4" + "@grpc/proto-loader": "^0.7.13", + "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { - "node": ">=16" + "node": ">=12.10.0" } }, - "node_modules/@datadog/pprof/node_modules/source-map": { - "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", - "license": "BSD-3-Clause", - "optional": true, + "node_modules/@grpc/proto-loader": { + "version": "0.7.15", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.2.5", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, "engines": { - "node": ">= 12" + "node": ">=6" } }, - "node_modules/@edtf-ts/core": { - "version": "0.5.0", - "license": "MIT" - }, - "node_modules/@emnapi/core": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", - "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/@grpc/proto-loader/node_modules/cliui": { + "version": "8.0.1", + "license": "ISC", "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@emnapi/runtime": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", - "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", - "dev": true, + "node_modules/@grpc/proto-loader/node_modules/yargs": { + "version": "17.7.2", "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "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/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", - "dev": true, - "license": "MIT", - "optional": true, + "node_modules/@hapi/address": { + "version": "5.1.1", + "license": "BSD-3-Clause", "dependencies": { - "tslib": "^2.4.0" + "@hapi/hoek": "^11.0.2" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz", - "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==", - "dev": true, - "license": "MIT", + "node_modules/@hapi/formula": { + "version": "3.0.2", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/hoek": { + "version": "11.0.7", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/pinpoint": { + "version": "2.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/@hapi/tlds": { + "version": "1.1.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@hapi/topo": { + "version": "6.0.2", + "license": "BSD-3-Clause", "dependencies": { - "@emotion/memoize": "^0.9.0" + "@hapi/hoek": "^11.0.2" } }, - "node_modules/@emotion/memoize": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz", - "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==", + "node_modules/@humanfs/core": { + "version": "0.19.1", "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } }, - "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.7.1", + "node_modules/@humanfs/node": { + "version": "0.16.6", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "escape-string-regexp": "^4.0.0", - "ignore": "^7.0.5" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" }, "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 || ^9.0.0 || ^10.0.0" + "node": ">=18.18.0" } }, - "node_modules/@eslint-community/eslint-plugin-eslint-comments/node_modules/ignore": { - "version": "7.0.5", + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">= 4" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=12.22" }, "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", + "node_modules/@humanwhocodes/momoa": { + "version": "2.0.4", "dev": true, "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=10.10.0" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.2", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, - "license": "Apache-2.0", + "license": "ISC", "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.5" + "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": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.13", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.5", + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.5", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.14.0", - "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.1", - "minimatch": "^3.1.5", - "strip-json-comments": "^3.1.1" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.14.0", + "node_modules/@jest/schemas": { + "version": "30.0.5", "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" + "@sinclair/typebox": "^0.34.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.13", + "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", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=6.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", "license": "MIT" }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.5", + "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": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@eslint/js": { - "version": "9.39.4", - "dev": true, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", "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", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "dev": true, - "license": "Apache-2.0", + "node_modules/@mailchimp/mailchimp_marketing": { + "version": "3.0.80", + "license": "Apache 2.0", "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" + "dotenv": "^8.2.0", + "superagent": "3.8.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=10.0.0" } }, - "node_modules/@exodus/schemasafe": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@faker-js/faker": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz", - "integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==", - "dev": true, - "license": "MIT", + "node_modules/@mailchimp/mailchimp_marketing/node_modules/dotenv": { + "version": "8.6.0", + "license": "BSD-2-Clause", "engines": { - "node": ">=14.0.0", - "npm": ">=6.0.0" + "node": ">=10" } }, - "node_modules/@fusionauth/typescript-client": { - "version": "1.60.0", - "license": "Apache-2.0", + "node_modules/@mailchimp/mailchimp_transactional": { + "version": "1.1.2", "dependencies": { - "node-fetch": "^2.6.1" + "axios": "^1.7.7" + }, + "engines": { + "node": ">=10.0.0" } }, - "node_modules/@grpc/grpc-js": { - "version": "1.13.4", - "license": "Apache-2.0", + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "dev": true, + "license": "MIT", "dependencies": { - "@grpc/proto-loader": "^0.7.13", - "@js-sdsl/ordered-map": "^4.4.2" + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" }, "engines": { - "node": ">=12.10.0" + "node": ">=4" } }, - "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.2.5", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@grpc/proto-loader/node_modules/cliui": { - "version": "8.0.1", - "license": "ISC", + "node_modules/@mswjs/interceptors": { + "version": "0.39.5", + "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "@open-draft/deferred-promise": "^2.2.0", + "@open-draft/logger": "^0.3.0", + "@open-draft/until": "^2.0.0", + "is-node-process": "^1.2.0", + "outvariant": "^1.4.3", + "strict-event-emitter": "^0.5.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, - "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "17.7.2", + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, "license": "MIT", + "optional": true, "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" + "@tybys/wasm-util": "^0.10.3" }, - "engines": { - "node": ">=12" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, - "node_modules/@hapi/address": { - "version": "5.1.1", - "license": "BSD-3-Clause", + "node_modules/@newrelic/fn-inspect": { + "version": "5.0.0", + "hasInstallScript": true, + "license": "MIT", + "optional": true, "dependencies": { - "@hapi/hoek": "^11.0.2" + "nan": "^2.22.2", + "node-gyp-build": "^4.8.1", + "prebuildify": "^6.0.1" }, "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@hapi/formula": { - "version": "3.0.2", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/hoek": { - "version": "11.0.7", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/pinpoint": { - "version": "2.0.1", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/tlds": { - "version": "1.1.2", - "license": "BSD-3-Clause", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@hapi/topo": { - "version": "6.0.2", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^11.0.2" + "node": ">=22" } }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "dev": true, + "node_modules/@newrelic/native-metrics": { + "version": "13.0.0", + "hasInstallScript": true, "license": "Apache-2.0", + "optional": true, + "dependencies": { + "nan": "^2.22.2", + "node-gyp-build": "^4.8.1", + "prebuildify": "^6.0.1" + }, "engines": { - "node": ">=18.18.0" + "node": ">=22", + "npm": ">=6" } }, - "node_modules/@humanfs/node": { - "version": "0.16.6", - "dev": true, - "license": "Apache-2.0", + "node_modules/@newrelic/security-agent": { + "version": "3.0.4", + "license": "New Relic Software License v1.0", "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" + "check-disk-space": "^3.4.0", + "content-type": "^1.0.5", + "fast-safe-stringify": "^2.1.1", + "find-package-json": "^1.2.0", + "hash.js": "^1.1.7", + "html-entities": "^2.3.6", + "https-proxy-agent": "^7.0.4", + "is-invalid-path": "^1.0.2", + "log4js": "^6.9.1", + "node-cron": "^4.2.1", + "request-ip": "^3.3.0", + "ringbufferjs": "^2.0.0", + "semver": "^7.5.4", + "undici": "^7.19.0", + "unescape": "^1.0.1", + "unescape-js": "^1.1.4", + "ws": "^8.17.1" }, "engines": { - "node": ">=18.18.0" + "node": ">=20", + "npm": ">=6.0.0" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "dev": true, - "license": "Apache-2.0", + "node_modules/@newrelic/security-agent/node_modules/undici": { + "version": "7.28.0", + "license": "MIT", "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=20.18.1" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "dev": true, - "license": "Apache-2.0", + "node_modules/@newrelic/security-agent/node_modules/ws": { + "version": "8.21.0", + "license": "MIT", "engines": { - "node": ">=12.22" + "node": ">=10.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/momoa": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", - "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.10.0" + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", + "node_modules/@noble/hashes": { + "version": "1.8.0", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=18.18" + "node": "^14.21.3 || >=16" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/@nodable/entities": { + "version": "2.1.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", "dev": true, - "license": "ISC", + "license": "MIT", "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" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=12" + "node": ">= 8" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", "dev": true, "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">= 8" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">= 8" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", + "node_modules/@open-draft/deferred-promise": { + "version": "2.2.0", "dev": true, "license": "MIT" }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@open-draft/logger": { + "version": "0.3.0", "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" + "is-node-process": "^1.2.0", + "outvariant": "^1.4.0" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "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/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", + "node_modules/@open-draft/until": { + "version": "2.1.0", "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, + "license": "MIT" + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "license": "Apache-2.0", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=8.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "dev": true, - "license": "ISC", + "node_modules/@opentelemetry/api-logs": { + "version": "0.214.0", + "license": "Apache-2.0", "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" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.8.0", "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/core": { + "version": "2.8.0", + "license": "Apache-2.0", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=8" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.2", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.218.0", + "license": "Apache-2.0", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@opentelemetry/core": "2.7.1", + "@opentelemetry/otlp-exporter-base": "0.218.0", + "@opentelemetry/otlp-transformer": "0.218.0", + "@opentelemetry/resources": "2.7.1", + "@opentelemetry/sdk-metrics": "2.7.1" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/api-logs": { + "version": "0.218.0", + "license": "Apache-2.0", "dependencies": { - "p-locate": "^4.1.0" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": ">=8" + "node": ">=8.0.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.7.1", + "license": "Apache-2.0", "dependencies": { - "p-try": "^2.0.0" + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": ">=6" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.218.0", + "license": "Apache-2.0", "dependencies": { - "p-limit": "^2.2.0" + "@opentelemetry/core": "2.7.1", + "@opentelemetry/otlp-transformer": "0.218.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/otlp-transformer": { + "version": "0.218.0", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.218.0", + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1", + "@opentelemetry/sdk-logs": "0.218.0", + "@opentelemetry/sdk-metrics": "2.7.1", + "@opentelemetry/sdk-trace-base": "2.7.1" + }, "engines": { - "node": ">=8" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@jest/console": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.7.1", + "license": "Apache-2.0", "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "slash": "^3.0.0" + "@opentelemetry/core": "2.7.1", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@jest/core": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-logs": { + "version": "0.218.0", + "license": "Apache-2.0", "dependencies": { - "@jest/console": "30.3.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.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.3.0", - "jest-config": "30.3.0", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-resolve-dependencies": "30.3.0", - "jest-runner": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "jest-watcher": "30.3.0", - "pretty-format": "30.3.0", - "slash": "^3.0.0" + "@opentelemetry/api-logs": "0.218.0", + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, - "node_modules/@jest/diff-sequences": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-metrics": { + "version": "2.7.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1" + }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, - "node_modules/@jest/environment": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.7.1", + "license": "Apache-2.0", "dependencies": { - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-mock": "30.3.0" + "@opentelemetry/core": "2.7.1", + "@opentelemetry/resources": "2.7.1", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@jest/expect": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "expect": "30.3.0", - "jest-snapshot": "30.3.0" + "@opentelemetry/core": "2.8.0", + "@opentelemetry/otlp-exporter-base": "0.219.0", + "@opentelemetry/otlp-transformer": "0.219.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/sdk-trace-base": "2.8.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@jest/expect-utils": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/instrumentation": { + "version": "0.214.0", + "license": "Apache-2.0", "dependencies": { - "@jest/get-type": "30.1.0" + "@opentelemetry/api-logs": "0.214.0", + "import-in-the-middle": "^3.0.0", + "require-in-the-middle": "^8.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@jest/fake-timers": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "@jest/types": "30.3.0", - "@sinonjs/fake-timers": "^15.0.0", - "@types/node": "*", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "@opentelemetry/core": "2.8.0", + "@opentelemetry/otlp-transformer": "0.219.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/types": "30.3.0", - "jest-mock": "30.3.0" + "@opentelemetry/api-logs": "0.219.0", + "@opentelemetry/core": "2.8.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/sdk-logs": "0.219.0", + "@opentelemetry/sdk-metrics": "2.8.0", + "@opentelemetry/sdk-trace-base": "2.8.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-logs": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" + "@opentelemetry/api": "^1.3.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=8.0.0" } }, - "node_modules/@jest/reporters": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/resources": { + "version": "2.8.0", + "license": "Apache-2.0", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.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.5.0", - "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.3.0", - "jest-util": "30.3.0", - "jest-worker": "30.3.0", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" + "@opentelemetry/core": "2.8.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.5.0", - "dev": true, - "license": "ISC", + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "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" + "@opentelemetry/api-logs": "0.219.0", + "@opentelemetry/core": "2.8.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.9", - "dev": true, - "license": "ISC", + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/api-logs": { + "version": "0.219.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "@opentelemetry/api": "^1.3.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/reporters/node_modules/minipass": { - "version": "7.1.3", - "dev": true, - "license": "BlueOak-1.0.0", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=8.0.0" } }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.8.0", + "devOptional": true, + "license": "Apache-2.0", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@opentelemetry/core": "2.8.0", + "@opentelemetry/resources": "2.8.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, - "node_modules/@jest/snapshot-utils": { - "version": "30.3.0", - "dev": true, - "license": "MIT", + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.8.0", + "license": "Apache-2.0", "dependencies": { - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" + "@opentelemetry/core": "2.8.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/semantic-conventions": "^1.29.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, - "node_modules/@jest/source-map": { - "version": "30.0.1", + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.8.0", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" + "@opentelemetry/context-async-hooks": "2.8.0", + "@opentelemetry/core": "2.8.0", + "@opentelemetry/sdk-trace-base": "2.8.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@jest/test-result": { - "version": "30.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "30.3.0", - "@jest/types": "30.3.0", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" - }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.41.1", + "license": "Apache-2.0", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=14" } }, - "node_modules/@jest/test-sequencer": { - "version": "30.3.0", + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/test-result": "30.3.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "funding": { + "url": "https://github.com/sponsors/Boshen" } }, - "node_modules/@jest/transform": { - "version": "30.3.0", + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.3.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.3.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.3.0", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, + "@noble/hashes": "^1.1.5" + } + }, + "node_modules/@pdc/http-status-codes": { + "version": "1.0.1", + "license": "AGPL-3.0", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=16" } }, - "node_modules/@jest/types": { - "version": "30.3.0", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", "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" - }, + "optional": true, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=14" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.12", - "dev": true, - "license": "MIT", + "node_modules/@prisma/prisma-fmt-wasm": { + "version": "4.17.0-16.27eb2449f178cd9fe1a4b892d732cc4795f75085", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.5", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "license": "BSD-3-Clause", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "license": "BSD-3-Clause" }, - "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/@protobufjs/inquire": { + "version": "1.1.1", + "license": "BSD-3-Clause" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.29", + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.1", + "license": "BSD-3-Clause" + }, + "node_modules/@redocly/ajv": { + "version": "8.18.3", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@js-sdsl/ordered-map": { - "version": "4.4.2", - "license": "MIT", + "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": "opencollective", - "url": "https://opencollective.com/js-sdsl" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@mailchimp/mailchimp_marketing": { - "version": "3.0.80", - "license": "Apache 2.0", + "node_modules/@redocly/cli": { + "version": "2.33.2", + "dev": true, + "license": "MIT", "dependencies": { - "dotenv": "^8.2.0", - "superagent": "3.8.1" + "@opentelemetry/exporter-trace-otlp-http": "0.219.0", + "@opentelemetry/resources": "2.8.0", + "@opentelemetry/sdk-trace-node": "2.8.0", + "@opentelemetry/semantic-conventions": "1.41.1", + "@redocly/cli-otel": "0.3.1", + "@redocly/openapi-core": "2.33.2", + "@redocly/respect-core": "2.33.2", + "ajv": "npm:@redocly/ajv@8.18.1", + "ajv-formats": "^3.0.1", + "colorette": "^1.2.0", + "cookie": "^0.7.2", + "dotenv": "16.4.7", + "glob": "^13.0.5", + "handlebars": "^4.7.9", + "https-proxy-agent": "^7.0.5", + "mobx": "^6.0.4", + "picomatch": "^4.0.4", + "pluralize": "^8.0.0", + "react": "^17.0.0 || ^18.2.0 || ^19.2.7", + "react-dom": "^17.0.0 || ^18.2.0 || ^19.2.7", + "redoc": "2.5.3", + "semver": "^7.5.2", + "set-cookie-parser": "^2.3.5", + "simple-websocket": "^9.0.0", + "styled-components": "6.4.2", + "ulid": "^3.0.1", + "undici": "6.24.0", + "yargs": "17.0.1" }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@mailchimp/mailchimp_marketing/node_modules/dotenv": { - "version": "8.6.0", - "license": "BSD-2-Clause", - "engines": { - "node": ">=10" - } - }, - "node_modules/@mailchimp/mailchimp_transactional": { - "version": "1.1.2", - "dependencies": { - "axios": "^1.7.7" + "bin": { + "openapi": "bin/cli.js", + "redocly": "bin/cli.js" }, "engines": { - "node": ">=10.0.0" + "node": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" } }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", + "node_modules/@redocly/cli-otel": { + "version": "0.3.1", "dev": true, "license": "MIT", "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" + "ulid": "^2.3.0" } }, - "node_modules/@mswjs/interceptors": { - "version": "0.39.5", + "node_modules/@redocly/cli-otel/node_modules/ulid": { + "version": "2.4.0", "dev": true, "license": "MIT", - "dependencies": { - "@open-draft/deferred-promise": "^2.2.0", - "@open-draft/logger": "^0.3.0", - "@open-draft/until": "^2.0.0", - "is-node-process": "^1.2.0", - "outvariant": "^1.4.3", - "strict-event-emitter": "^0.5.1" - }, - "engines": { - "node": ">=18" + "bin": { + "ulid": "bin/cli.js" } }, - "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==", + "node_modules/@redocly/cli/node_modules/ajv": { + "name": "@redocly/ajv", + "version": "8.18.1", "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" + "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/@newrelic/fn-inspect": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@newrelic/fn-inspect/-/fn-inspect-5.0.0.tgz", - "integrity": "sha512-X/NciddM5AQ17JggcrmN230wlM/P+5j2fLos+m7pj0u1fiQK8F4Kru4qkNq7YRT/RhjYDSvy79KR80EYNhzVaw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "dependencies": { - "nan": "^2.22.2", - "node-gyp-build": "^4.8.1", - "prebuildify": "^6.0.1" - }, + "node_modules/@redocly/cli/node_modules/dotenv": { + "version": "16.4.7", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=22" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, - "node_modules/@newrelic/native-metrics": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@newrelic/native-metrics/-/native-metrics-13.0.0.tgz", - "integrity": "sha512-xtCzhiY6rLFseV5GfEEra0rGe8jyBzFl0DoqfYbjgIfmI/6h3O3z0KMKfuk2Xb2KINiXWRtKHYpfxwD4AWXoWA==", - "hasInstallScript": true, - "license": "Apache-2.0", - "optional": true, + "node_modules/@redocly/cli/node_modules/glob": { + "version": "13.0.6", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "nan": "^2.22.2", - "node-gyp-build": "^4.8.1", - "prebuildify": "^6.0.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, "engines": { - "node": ">=22", - "npm": ">=6" + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@newrelic/security-agent": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@newrelic/security-agent/-/security-agent-3.0.4.tgz", - "integrity": "sha512-em1kkd08yWh4i7qi7QMzLU3aAb9yg0KbbUwFiGlhgoDPNvEfGCJFGifnERDZzZGJJSfGVegEPQCu7zaZs/hx1g==", - "license": "New Relic Software License v1.0", - "dependencies": { - "check-disk-space": "^3.4.0", - "content-type": "^1.0.5", - "fast-safe-stringify": "^2.1.1", - "find-package-json": "^1.2.0", - "hash.js": "^1.1.7", - "html-entities": "^2.3.6", - "https-proxy-agent": "^7.0.4", - "is-invalid-path": "^1.0.2", - "log4js": "^6.9.1", - "node-cron": "^4.2.1", - "request-ip": "^3.3.0", - "ringbufferjs": "^2.0.0", - "semver": "^7.5.4", - "undici": "^7.19.0", - "unescape": "^1.0.1", - "unescape-js": "^1.1.4", - "ws": "^8.17.1" - }, + "node_modules/@redocly/cli/node_modules/lru-cache": { + "version": "11.5.1", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=20", - "npm": ">=6.0.0" + "node": "20 || >=22" } }, - "node_modules/@newrelic/security-agent/node_modules/undici": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.28.0.tgz", - "integrity": "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==", - "license": "MIT", + "node_modules/@redocly/cli/node_modules/minipass": { + "version": "7.1.3", + "dev": true, + "license": "BlueOak-1.0.0", "engines": { - "node": ">=20.18.1" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/@newrelic/security-agent/node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" + "node_modules/@redocly/cli/node_modules/path-scurry": { + "version": "2.0.2", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" + "engines": { + "node": "18 || 20 || >=22" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@noble/hashes": { - "version": "1.8.0", + "node_modules/@redocly/cli/node_modules/picomatch": { + "version": "4.0.4", "dev": true, "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">=12" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@nodable/entities": { - "version": "2.1.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/nodable" - } - ], - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", + "node_modules/@redocly/config": { + "version": "0.49.0", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" + "json-schema-to-ts": "2.7.2" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", + "node_modules/@redocly/openapi-core": { + "version": "2.33.2", "dev": true, "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.18.1", + "@redocly/config": "^0.49.0", + "ajv": "npm:@redocly/ajv@8.18.1", + "ajv-formats": "^3.0.1", + "colorette": "^1.2.0", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.2.0", + "picomatch": "^4.0.4", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, "engines": { - "node": ">= 8" + "node": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", + "node_modules/@redocly/openapi-core/node_modules/ajv": { + "name": "@redocly/ajv", + "version": "8.18.1", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@open-draft/deferred-promise": { - "version": "2.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@open-draft/logger": { - "version": "0.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "is-node-process": "^1.2.0", - "outvariant": "^1.4.0" - } - }, - "node_modules/@open-draft/until": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@opentelemetry/api": { - "version": "1.9.1", - "license": "Apache-2.0", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/api-logs": { - "version": "0.214.0", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/context-async-hooks": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.8.0.tgz", - "integrity": "sha512-/3FIraneMcng67SUJCxvyInk/oxzwsxyadufk0wwfOBLf5wqtAGX4MoQASwSbndBPeARzBryUM9Azr5kHIdWLw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.8.0.tgz", - "integrity": "sha512-hd1Lfh8p545nNz+jq1Ejfz+Mn1hyLuxYn1YzTfFNrxr8urEWMNQLPf1Th8kjOH+HxwawCrtgBp8JpBUR4ZSgww==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http": { - "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.218.0.tgz", - "integrity": "sha512-bV7d2OuMpZu2+gAaxUAhzfZ0h3WVZk8ETQUEE3DNSntbTaMpuITjtm8I0rNyHFdm7Ax57K6ty7SgFXlBmOLIvQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/otlp-exporter-base": "0.218.0", - "@opentelemetry/otlp-transformer": "0.218.0", - "@opentelemetry/resources": "2.7.1", - "@opentelemetry/sdk-metrics": "2.7.1" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/api-logs": { - "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.218.0.tgz", - "integrity": "sha512-fmEWp5kXlGEc3i/lR698Hz41DfGyN4Tbe4g7L1AxSc7fF8Xeh/FQ9Quqpa9dVA413Q1Ad43QOLzU4JoXgbFPWw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/core": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", - "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/otlp-exporter-base": { - "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.218.0.tgz", - "integrity": "sha512-ZwqpkNL5W7RyGJPDZ9g06DvKp8KFTWPJPN12anpMQYSKpTSU0z3EIZuPq9vPGpS8siFyOqDYDAuCwlNO9FqgbA==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/otlp-transformer": "0.218.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/otlp-transformer": { - "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.218.0.tgz", - "integrity": "sha512-CFaKH87WAzjuJ4awowTTLzUvMfaRfiOFG5+qm5S5ncyalRtN4ecQ+YmuANJSCrVPuvZFEkUgKhBPBndxi3rHsQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.218.0", - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1", - "@opentelemetry/sdk-logs": "0.218.0", - "@opentelemetry/sdk-metrics": "2.7.1", - "@opentelemetry/sdk-trace-base": "2.7.1" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/resources": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", - "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-logs": { - "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.218.0.tgz", - "integrity": "sha512-QvnNdugatFTVCJXH0Mcu7GOOJSylA9j127kIezOE4YwTI4YbowRons2K4WZTv5FMS8T4q9P0NdaRHdkSmeAIag==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.218.0", - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.4.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-metrics": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.7.1.tgz", - "integrity": "sha512-MpDJdkiFDs3Pm1RHO3KByuZbuBdJEXEAkiC0+yJdsZGVCdf1RpHR6n+LHDcS7ffmfrt5kVCzJSCfm4z2C7v0uQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.9.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", - "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.7.1", - "@opentelemetry/resources": "2.7.1", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/exporter-trace-otlp-http": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.219.0.tgz", - "integrity": "sha512-9t6SvBXXBEjOBcIzgozvBbd3jWrv3Gt3ngGhl1fhdZ/zRc7oZDVOFEqbi2zlBpW9BXhgDMKv422J0DL/3iQWfw==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/otlp-exporter-base": "0.219.0", - "@opentelemetry/otlp-transformer": "0.219.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/instrumentation": { - "version": "0.214.0", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.214.0", - "import-in-the-middle": "^3.0.0", - "require-in-the-middle": "^8.0.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/otlp-exporter-base": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.219.0.tgz", - "integrity": "sha512-zvIxQX/AZUVKDU+hCuYx+7UkiP7GRdnk1ZbFQRYzHvYp47cAWR4j3IhoPhV9KaeXEv2xdGq3IA6PnpzDmLcmSA==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/otlp-transformer": "0.219.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/otlp-transformer": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.219.0.tgz", - "integrity": "sha512-aaYKAyXhw9VchKZVGOopD3Gw/kPsyrX2c6IQ0AW32mTjqmZOh5Y6Gf5OYqTNqVktAeBjmFinhyFaCwW6GYK9YQ==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.219.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-logs": "0.219.0", - "@opentelemetry/sdk-metrics": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.3.0" - } - }, - "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-logs": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.219.0.tgz", - "integrity": "sha512-FFx7YnaYJlIjqWW/AG/yAZ0L/NEY724PipXXXQLdtZPbLwBGbUMTGL1i/esI56TWfTUXxhLfpgrnWJCG8aUJyg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/resources": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.8.0.tgz", - "integrity": "sha512-qmXQ27ilDbUK/vGMqwL8D4/rhn76C+sherM4wTbjlfknR8Nvfc/hCxjRJPhkzZzUsPiNg16SA31NxMabwttRjg==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/sdk-logs": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.219.0.tgz", - "integrity": "sha512-s6lTKRakaPClvKoWHRChxnXjDMkM/TQ30ff78jN6EBGf7MI7VzANE5PU3f4z9qDUudWjvZjOLHG0rBnBKYvoXA==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api-logs": "0.219.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.4.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/api-logs": { - "version": "0.219.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.219.0.tgz", - "integrity": "sha512-FFx7YnaYJlIjqWW/AG/yAZ0L/NEY724PipXXXQLdtZPbLwBGbUMTGL1i/esI56TWfTUXxhLfpgrnWJCG8aUJyg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/api": "^1.3.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@opentelemetry/sdk-metrics": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.8.0.tgz", - "integrity": "sha512-UDBGaj6W0Rgy5rTTaoxs8gVGF/aGkAKyjurJv7se6wjRxJu7FoquTLT/vt54DZfo4crbprYfhX/SOK9+BPw1qg==", - "devOptional": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.9.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/sdk-trace-base": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.8.0.tgz", - "integrity": "sha512-mhU4jp+vW0mGbFRd+GeXHvmfA4aDqWjBjLC3pE5XMpLs0IE2ryYb019Ts2AQrOq67gaTF25D91+fgvEHDZEnuQ==", - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/core": "2.8.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/semantic-conventions": "^1.29.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.3.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/sdk-trace-node": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.8.0.tgz", - "integrity": "sha512-nZt9OGufioAc3AfoLTqA9bsAeaMJAictYDdI2VcNQ+PmT+3rfKjAZDZvgPfd8VPX0O5Bw1hdQF6kDK8VSpZiWg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@opentelemetry/context-async-hooks": "2.8.0", - "@opentelemetry/core": "2.8.0", - "@opentelemetry/sdk-trace-base": "2.8.0" - }, - "engines": { - "node": "^18.19.0 || >=20.6.0" - }, - "peerDependencies": { - "@opentelemetry/api": ">=1.0.0 <1.10.0" - } - }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.41.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz", - "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==", - "license": "Apache-2.0", - "engines": { - "node": ">=14" - } - }, - "node_modules/@paralleldrive/cuid2": { - "version": "2.2.2", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "^1.1.5" - } - }, - "node_modules/@pdc/http-status-codes": { - "version": "1.0.1", - "license": "AGPL-3.0", - "engines": { - "node": ">=16" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@prisma/prisma-fmt-wasm": { - "version": "4.17.0-16.27eb2449f178cd9fe1a4b892d732cc4795f75085", - "license": "Apache-2.0", - "optional": true - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.5", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.1", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "license": "BSD-3-Clause" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.1", - "license": "BSD-3-Clause" - }, - "node_modules/@redocly/ajv": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.3.tgz", - "integrity": "sha512-l42u0of3hY98sN2A+M4qTX1O/KrpgGH32Hu9kP2GtHyD5Dfqq86PKFLe5dwaD8DEnNmlOlll2BAmeEtf0DaySg==", - "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/@redocly/cli": { - "version": "2.33.2", - "resolved": "https://registry.npmjs.org/@redocly/cli/-/cli-2.33.2.tgz", - "integrity": "sha512-D9ZLu89mmuOA/fNKNzCQXccE6BbCxucAT+ty++1DX/bih6Tf4fo8xVhQxQAbtmmCUFKjQ0MEF3TivPUFlIdHTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@opentelemetry/exporter-trace-otlp-http": "0.219.0", - "@opentelemetry/resources": "2.8.0", - "@opentelemetry/sdk-trace-node": "2.8.0", - "@opentelemetry/semantic-conventions": "1.41.1", - "@redocly/cli-otel": "0.3.1", - "@redocly/openapi-core": "2.33.2", - "@redocly/respect-core": "2.33.2", - "ajv": "npm:@redocly/ajv@8.18.1", - "ajv-formats": "^3.0.1", - "colorette": "^1.2.0", - "cookie": "^0.7.2", - "dotenv": "16.4.7", - "glob": "^13.0.5", - "handlebars": "^4.7.9", - "https-proxy-agent": "^7.0.5", - "mobx": "^6.0.4", - "picomatch": "^4.0.4", - "pluralize": "^8.0.0", - "react": "^17.0.0 || ^18.2.0 || ^19.2.7", - "react-dom": "^17.0.0 || ^18.2.0 || ^19.2.7", - "redoc": "2.5.3", - "semver": "^7.5.2", - "set-cookie-parser": "^2.3.5", - "simple-websocket": "^9.0.0", - "styled-components": "6.4.2", - "ulid": "^3.0.1", - "undici": "6.24.0", - "yargs": "17.0.1" - }, - "bin": { - "openapi": "bin/cli.js", - "redocly": "bin/cli.js" - }, - "engines": { - "node": ">=22.12.0 || >=20.19.0 <21.0.0", - "npm": ">=10" - } - }, - "node_modules/@redocly/cli-otel": { - "version": "0.3.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ulid": "^2.3.0" - } - }, - "node_modules/@redocly/cli-otel/node_modules/ulid": { - "version": "2.4.0", - "dev": true, - "license": "MIT", - "bin": { - "ulid": "bin/cli.js" - } - }, - "node_modules/@redocly/cli/node_modules/ajv": { - "name": "@redocly/ajv", - "version": "8.18.1", - "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/@redocly/cli/node_modules/dotenv": { - "version": "16.4.7", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/@redocly/cli/node_modules/glob": { - "version": "13.0.6", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.2.2", - "minipass": "^7.1.3", - "path-scurry": "^2.0.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@redocly/cli/node_modules/lru-cache": { - "version": "11.5.1", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@redocly/cli/node_modules/minipass": { - "version": "7.1.3", - "dev": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/@redocly/cli/node_modules/path-scurry": { - "version": "2.0.2", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@redocly/cli/node_modules/picomatch": { - "version": "4.0.4", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@redocly/config": { - "version": "0.49.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.49.0.tgz", - "integrity": "sha512-OI/rpEffX3fKUuy+OuBHPRspRI/S30b9aiqxfZLMpSWZzDncEGPxSEP1O2LrBVshnDX4hLjVjLvCZ4YT85+1rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-schema-to-ts": "2.7.2" - } - }, - "node_modules/@redocly/openapi-core": { - "version": "2.33.2", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-2.33.2.tgz", - "integrity": "sha512-gAxXAbvDxHyDJNQr7U11AUdBTPV4C9I4sDBdvKWpM3b7wctBUMvmEMwp9e1wiTxWpbmACA2V6P5nvtZryvIQsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@redocly/ajv": "^8.18.1", - "@redocly/config": "^0.49.0", - "ajv": "npm:@redocly/ajv@8.18.1", - "ajv-formats": "^3.0.1", - "colorette": "^1.2.0", - "js-levenshtein": "^1.1.6", - "js-yaml": "^4.2.0", - "picomatch": "^4.0.4", - "pluralize": "^8.0.0", - "yaml-ast-parser": "0.0.43" - }, - "engines": { - "node": ">=22.12.0 || >=20.19.0 <21.0.0", - "npm": ">=10" - } - }, - "node_modules/@redocly/openapi-core/node_modules/ajv": { - "name": "@redocly/ajv", - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.1.tgz", - "integrity": "sha512-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA==", - "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/@redocly/openapi-core/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@redocly/respect-core": { - "version": "2.33.2", - "resolved": "https://registry.npmjs.org/@redocly/respect-core/-/respect-core-2.33.2.tgz", - "integrity": "sha512-EAbV06GbjMrOPhADoXB56Gh1n63GibteYtWxp40lQeYnf1Bv7CMwH5nSHpbBhFkMXQ28tIbdzeL/GBeeGxU3mQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@faker-js/faker": "^7.6.0", - "@noble/hashes": "^1.8.0", - "@redocly/ajv": "^8.18.1", - "@redocly/openapi-core": "2.33.2", - "ajv": "npm:@redocly/ajv@8.18.1", - "better-ajv-errors": "^2.0.3", - "colorette": "^2.0.20", - "json-pointer": "^0.6.2", - "jsonpath-rfc9535": "1.3.0", - "openapi-sampler": "^1.7.1", - "outdent": "^0.8.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=22.12.0 || >=20.19.0 <21.0.0", - "npm": ">=10" - } - }, - "node_modules/@redocly/respect-core/node_modules/ajv": { - "name": "@redocly/ajv", - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.18.1.tgz", - "integrity": "sha512-Ifm/pP/tul1qmAecpbVxCBluVE32rKfjf8gYXH4xI2gCv9mRWFhJMHzkPDM4TXlxwPQYIFegymlsy8lXz7optA==", - "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/@redocly/respect-core/node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@redocly/respect-core/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@scaleleap/pg-format": { - "version": "1.0.0", - "license": "MIT" - }, - "node_modules/@sentry/aws-serverless": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/aws-serverless/-/aws-serverless-10.60.0.tgz", - "integrity": "sha512-4huDKc6dgvNeY2og4G395/Rdnpz0CuU8J0MrrHikOHyNmIUDmS4OmIRoY4I+d83VAvM+0zRs5F6P7OkNXTgmDQ==", - "license": "MIT", - "dependencies": { - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/instrumentation": "^0.214.0", - "@sentry/conventions": "^0.12.0", - "@sentry/core": "10.60.0", - "@sentry/node": "10.60.0", - "@sentry/node-core": "10.60.0", - "@types/aws-lambda": "^8.10.161" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/conventions": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.12.0.tgz", - "integrity": "sha512-z1JQrl/1SLY+8wpzvork6vl+fpsg/oCCxM7HWWhUnI/R+OGNyoIzieQuggX3uUMY7NBtp8UWCQx6FeFazzOF9g==", - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@sentry/core": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.60.0.tgz", - "integrity": "sha512-szN7ccOJAEaLb1BBQzCQhABGMTJmKNUk0G2sc7rWhajeXoZoMKIbNkI9RvJrFuV69cbad/d/BKGBjbpJhySAzw==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/node": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.60.0.tgz", - "integrity": "sha512-u//paUrkKaCr0oNn7r7UulGydkYMSkU1wQOIpG/P/jf7psZWnyXhgeszHzUfZXo6pCdxXG9z9viPvzGjqPQN7A==", - "license": "MIT", - "dependencies": { - "@opentelemetry/api": "^1.9.1", - "@opentelemetry/instrumentation": "^0.214.0", - "@opentelemetry/sdk-trace-base": "^2.6.1", - "@opentelemetry/semantic-conventions": "^1.40.0", - "@sentry/core": "10.60.0", - "@sentry/node-core": "10.60.0", - "@sentry/opentelemetry": "10.60.0", - "@sentry/server-utils": "10.60.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/node-core": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.60.0.tgz", - "integrity": "sha512-aXi9ixvP+hgUZPPZCRwMNHgY2I0gkSeoAKAUuysDJhWDmrygwfGdlkbGmmtW6PQjtMYFx69Igt5btvhjEBoJTw==", - "license": "MIT", - "dependencies": { - "@sentry/conventions": "^0.12.0", - "@sentry/core": "10.60.0", - "@sentry/opentelemetry": "10.60.0", - "import-in-the-middle": "^3.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", - "@opentelemetry/instrumentation": ">=0.57.1 <1", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" - }, - "peerDependenciesMeta": { - "@opentelemetry/api": { - "optional": true - }, - "@opentelemetry/core": { - "optional": true - }, - "@opentelemetry/exporter-trace-otlp-http": { - "optional": true - }, - "@opentelemetry/instrumentation": { - "optional": true - }, - "@opentelemetry/sdk-trace-base": { - "optional": true - } - } - }, - "node_modules/@sentry/node-cpu-profiler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/@sentry/node-cpu-profiler/-/node-cpu-profiler-2.4.2.tgz", - "integrity": "sha512-E6q+eE/sTpiofzW9jFKAx6ZQaDAoZDnsaLA/nRlkiK+K2X4k+hSyKhhLfw8PJlejB8edk7uxJF57r5JoRnyaPA==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "detect-libc": "^2.0.3", - "node-abi": "^3.73.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/opentelemetry": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.60.0.tgz", - "integrity": "sha512-gl+2NVH+9RmTu7pd9kV1tKif+Th+p9tmnXR1l3Sb3Wqo1ir5FaNMKrloWEKMXjnepii9EJUrEHdSC+i8NoexxQ==", - "license": "MIT", - "dependencies": { - "@sentry/conventions": "^0.12.0", - "@sentry/core": "10.60.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@opentelemetry/api": "^1.9.0", - "@opentelemetry/core": "^1.30.1 || ^2.1.0", - "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" - } - }, - "node_modules/@sentry/profiling-node": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/profiling-node/-/profiling-node-10.60.0.tgz", - "integrity": "sha512-6sEBQNdP8N20KjS12X0wr3+omxg4gMGNgyCUQ4z8JrywN8nC2DaIujZC0ps8oC6ncIoB7J8om5+mjRITZMwP6A==", - "license": "MIT", - "dependencies": { - "@sentry/core": "10.60.0", - "@sentry/node": "10.60.0", - "@sentry/node-cpu-profiler": "^2.4.2" - }, - "bin": { - "sentry-prune-profiler-binaries": "scripts/prune-profiler-binaries.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/server-utils": { - "version": "10.60.0", - "resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.60.0.tgz", - "integrity": "sha512-SX+MzWM3nz5ttKT48rlfktm0ERyIpDLma+b6pYeWgW2oFHKcpIu0g0qMGJrZs4lKM3MlgV7IqLa4texMqTp9kQ==", - "license": "MIT", - "dependencies": { - "@apm-js-collab/code-transformer": "^0.15.0", - "@apm-js-collab/code-transformer-bundler-plugins": "^0.5.0", - "@apm-js-collab/tracing-hooks": "^0.10.0", - "@sentry/conventions": "^0.12.0", - "@sentry/core": "10.60.0", - "magic-string": "~0.30.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sentry/server-utils/node_modules/@apm-js-collab/code-transformer": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.15.0.tgz", - "integrity": "sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==", - "license": "Apache-2.0", - "dependencies": { - "@types/estree": "^1.0.8", - "astring": "^1.9.0", - "esquery": "^1.7.0", - "meriyah": "^6.1.4", - "semifies": "^1.0.0", - "source-map": "^0.6.0" - }, - "bin": { - "code-transformer": "cli.js" - } - }, - "node_modules/@sentry/server-utils/node_modules/@apm-js-collab/tracing-hooks": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.10.1.tgz", - "integrity": "sha512-w2OWXR7FWrKqSziuE9+QclaZrStxO/8+OwbXM635s/zs0Eez1Qo3ivSPdB2WsaPY/iznKTytONPx/PitD7IXcA==", - "license": "Apache-2.0", - "dependencies": { - "@apm-js-collab/code-transformer": "^0.15.0", - "debug": "^4.4.1", - "module-details-from-path": "^1.0.4" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.38", - "dev": true, - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "15.3.0", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@smithy/core": { - "version": "3.29.0", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.29.0.tgz", - "integrity": "sha512-sEvpvkBVoMxjoek35XyJFn2ZD3EJ1RpiZrT47WaZodxzAIWS44zkdvbqGE/ZlugtjiQp62cffYZ9ldyRkjAGnA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.15.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.5.tgz", - "integrity": "sha512-LnjUTNG0GgQlKIq7IioeOrPaEmC5xOd1WtAz24TLSiYQnWX2uHr53GrFuQhkrJBktPYCMga/NbUOW7hFbSA2Cg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.0", - "@smithy/types": "^4.15.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.2.tgz", - "integrity": "sha512-q96PSDOAGw+X+nuELd7Cjebps0SYr+YlPbviEX9sLVw+VM4M7VV8hn1nL1mGS6urDu33eQ5A7WhlphaDO6kUyQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.0", - "@smithy/types": "^4.15.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.2.tgz", - "integrity": "sha512-s0yAIRj6TVfHgl+QzVyqal1KMGZ9B5512IrxKc6+dOpw8fUmFL3CvuAhjv0J+aNjUPfVZ2IhqPEDvkB5Ncx9oA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.0", - "@smithy/types": "^4.15.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.1.tgz", - "integrity": "sha512-SqvuP75p/DmgWWI7jv4kf/UW+V4LFmlUn19s604SgAcRuJRB1vDnWwzZMYCLUcmKxko9wDn6iLgGEIpTNgZbIQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.29.0", - "@smithy/types": "^4.15.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "4.15.1", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.15.1.tgz", - "integrity": "sha512-x3L0XSACF6UYzKpa9biqiRMgvH5+wnFFew9Tm/grFYqgaupPwx/+ojDPpPJM8dZON3S9tjz5U+PQYsCBd1Mw5Q==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@so-ric/colorspace": { - "version": "1.1.6", - "license": "MIT", - "dependencies": { - "color": "^5.0.2", - "text-hex": "1.0.x" - } - }, - "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "license": "MIT" - }, - "node_modules/@stela/access_copy_attacher": { - "resolved": "packages/access_copy_attacher", - "link": true - }, - "node_modules/@stela/account_space_updater": { - "resolved": "packages/account_space_updater", - "link": true - }, - "node_modules/@stela/api": { - "resolved": "packages/api", - "link": true - }, - "node_modules/@stela/archivematica_cleanup": { - "resolved": "packages/archivematica_cleanup", - "link": true - }, - "node_modules/@stela/archivematica-utils": { - "resolved": "packages/archivematica-utils", - "link": true - }, - "node_modules/@stela/event_send": { - "resolved": "packages/event_send", - "link": true - }, - "node_modules/@stela/event_utils": { - "resolved": "packages/event_utils", - "link": true - }, - "node_modules/@stela/file_copier": { - "resolved": "packages/file_copier", - "link": true - }, - "node_modules/@stela/file_url_refresh": { - "resolved": "packages/file_url_refresh", - "link": true - }, - "node_modules/@stela/file-utils": { - "resolved": "packages/file-utils", - "link": true - }, - "node_modules/@stela/logger": { - "resolved": "packages/logger", - "link": true - }, - "node_modules/@stela/metadata_attacher": { - "resolved": "packages/metadata_attacher", - "link": true - }, - "node_modules/@stela/permanent_models": { - "resolved": "packages/permanent_models", - "link": true - }, - "node_modules/@stela/publisher-utils": { - "resolved": "packages/publisher-utils", - "link": true - }, - "node_modules/@stela/record_thumbnail_attacher": { - "resolved": "packages/record_thumbnail_attacher", - "link": true - }, - "node_modules/@stela/s3-utils": { - "resolved": "packages/s3-utils", - "link": true - }, - "node_modules/@stela/thumbnail_refresh": { - "resolved": "packages/thumbnail_refresh", - "link": true - }, - "node_modules/@stela/trigger_archivematica": { - "resolved": "packages/trigger_archivematica", - "link": true - }, - "node_modules/@tokenizer/inflate": { - "version": "0.4.1", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "token-types": "^6.1.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "license": "MIT" - }, - "node_modules/@tsconfig/node24": { - "version": "24.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/strictest": { - "version": "2.0.7", - "dev": true, - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/aws-lambda": { - "version": "8.10.162", - "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.162.tgz", - "integrity": "sha512-Fn658grtLOci1oxi1391vvDWJRKNGWRSqfxRkmN/Iy3c0tQH1USMKEXcPYHLvope+ZgTFocx9FRQJx1muBL6qw==", - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "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", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cookiejar": { - "version": "2.1.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/cors": { - "version": "2.8.19", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "5.0.3", - "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.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "30.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^30.0.0", - "pretty-format": "^30.0.0" - } - }, - "node_modules/@types/jest-when": { - "version": "3.5.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mailchimp__mailchimp_transactional": { - "version": "1.0.11", - "dev": true, - "license": "MIT", - "dependencies": { - "axios": "^1.8.2" - } - }, - "node_modules/@types/memoizee": { - "version": "0.4.12", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/methods": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime-types": { - "version": "3.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/newrelic": { - "version": "9.14.8", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.10.1", - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/pg": { - "version": "8.20.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^2.2.0" - } - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "0.17.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/superagent": { - "version": "8.1.9", - "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", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/methods": "^1.1.4", - "@types/superagent": "^8.1.0" - } - }, - "node_modules/@types/triple-beam": { - "version": "1.3.5", - "license": "MIT" - }, - "node_modules/@types/trusted-types": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", - "dev": true, - "license": "MIT", - "optional": true - }, - "node_modules/@types/yargs": { - "version": "17.0.33", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.0.tgz", - "integrity": "sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/type-utils": "8.62.0", - "@typescript-eslint/utils": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.5.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.62.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.62.0.tgz", - "integrity": "sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", - "debug": "^4.4.3" - }, - "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 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.62.0.tgz", - "integrity": "sha512-wexnCqiTg7BOGtbLDftYpRWlmLq4xfoMd7BKFR6Y75sZS3QmRKLdN3yWLhmIYgqMmP/OXWpj3H8odkb5nGURCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.62.0", - "@typescript-eslint/types": "^8.62.0", - "debug": "^4.4.3" - }, - "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.1.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.62.0.tgz", - "integrity": "sha512-1lX38kNxXIRb8mEc3lbq5mdHq1Pf2+U0nFU65KfT18mtPxxl0fvjuEE92mHuXPuCtElJhOrddOpyMlM3Z0umEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "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": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.0.tgz", - "integrity": "sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==", + "node_modules/@redocly/openapi-core/node_modules/picomatch": { + "version": "4.0.4", "dev": true, "license": "MIT", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.62.0.tgz", - "integrity": "sha512-+g5O3j0w2ldzC86Pv6fvbO/xhAonbJFIdf/MKQ1d30gndlsVzUOE83ldfSE15Qrl9fhFjK6AovHs5Wpp6vx86w==", + "node_modules/@redocly/respect-core": { + "version": "2.33.2", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.0", - "@typescript-eslint/utils": "8.62.0", - "debug": "^4.4.3", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "@faker-js/faker": "^7.6.0", + "@noble/hashes": "^1.8.0", + "@redocly/ajv": "^8.18.1", + "@redocly/openapi-core": "2.33.2", + "ajv": "npm:@redocly/ajv@8.18.1", + "better-ajv-errors": "^2.0.3", + "colorette": "^2.0.20", + "json-pointer": "^0.6.2", + "jsonpath-rfc9535": "1.3.0", + "openapi-sampler": "^1.7.1", + "outdent": "^0.8.0", + "picomatch": "^4.0.4" }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.62.0.tgz", - "integrity": "sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==", - "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": ">=22.12.0 || >=20.19.0 <21.0.0", + "npm": ">=10" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.0.tgz", - "integrity": "sha512-+hVbNxtW64pIcZWDPGbyaKF7vp2IBTVY5ma1blwwksrjdsbdqqEKvJWMGbBofei4F6Dovx1M0RJgoFeNu2279A==", + "node_modules/@redocly/respect-core/node_modules/ajv": { + "name": "@redocly/ajv", + "version": "8.18.1", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.62.0", - "@typescript-eslint/tsconfig-utils": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/visitor-keys": "8.62.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "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": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@typescript-eslint/utils": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.62.0.tgz", - "integrity": "sha512-82r66fi9zYwZ+mTq3vKgwjbZ1PVk/DJzrXFLpG6RnBbdvH8TEGVHIs9H4d2drhkOzf0syZuD/OZvvlu6GDbP4g==", + "node_modules/@redocly/respect-core/node_modules/colorette": { + "version": "2.0.20", "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.62.0", - "@typescript-eslint/types": "8.62.0", - "@typescript-eslint/typescript-estree": "8.62.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 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } + "license": "MIT" }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.62.0.tgz", - "integrity": "sha512-CY3uyFSRbcQv3nnSv8S0+lDftMVz6P963PoRlxrV7ew/Md564g9ut60PYzdLM5qW4jFn93GBF+Soi90ISAN+GQ==", + "node_modules/@redocly/respect-core/node_modules/picomatch": { + "version": "4.0.4", "dev": true, "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.62.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">=12" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@tyriar/fibonacci-heap": { - "version": "2.0.9", - "license": "MIT" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "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==", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", "cpu": [ "arm64" ], @@ -4147,12 +2200,15 @@ "optional": true, "os": [ "android" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", "cpu": [ "arm64" ], @@ -4161,12 +2217,15 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", "cpu": [ "x64" ], @@ -4175,12 +2234,15 @@ "optional": true, "os": [ "darwin" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", "cpu": [ "x64" ], @@ -4189,26 +2251,15 @@ "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" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", "cpu": [ "arm" ], @@ -4217,12 +2268,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", "cpu": [ "arm64" ], @@ -4234,12 +2288,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", "cpu": [ "arm64" ], @@ -4251,31 +2308,17 @@ "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, - "libc": [ - "glibc" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", "cpu": [ - "riscv64" + "ppc64" ], "dev": true, "libc": [ @@ -4285,29 +2328,15 @@ "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, - "libc": [ - "musl" ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", "cpu": [ "s390x" ], @@ -4319,10 +2348,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", "cpu": [ "x64" ], @@ -4334,12 +2368,15 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", "cpu": [ "x64" ], @@ -4351,57 +2388,68 @@ "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", "cpu": [ - "wasm32" + "arm64" ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, + "os": [ + "openharmony" + ], "engines": { - "node": ">=14.0.0" + "node": "^20.19.0 || >=22.12.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==", + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", "cpu": [ - "arm64" + "wasm32" ], "dev": true, "license": "MIT", "optional": true, - "os": [ - "win32" - ] + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", "cpu": [ - "ia32" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "win32" - ] + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } }, - "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==", + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", "cpu": [ "x64" ], @@ -4410,1326 +2458,1240 @@ "optional": true, "os": [ "win32" - ] - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "license": "BSD-2-Clause" - }, - "node_modules/accepts": { - "version": "1.3.8", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, + ], "engines": { - "node": ">= 0.6" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/accepts/node_modules/mime-db": { - "version": "1.52.0", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } + "license": "MIT" }, - "node_modules/accepts/node_modules/mime-types": { - "version": "2.1.35", + "node_modules/@rtsao/scc": { + "version": "1.1.0", "dev": true, + "license": "MIT" + }, + "node_modules/@scaleleap/pg-format": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/@sentry/aws-serverless": { + "version": "10.60.0", "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/instrumentation": "^0.214.0", + "@sentry/conventions": "^0.12.0", + "@sentry/core": "10.60.0", + "@sentry/node": "10.60.0", + "@sentry/node-core": "10.60.0", + "@types/aws-lambda": "^8.10.161" }, "engines": { - "node": ">= 0.6" + "node": ">=18" } }, - "node_modules/acorn": { - "version": "8.15.0", + "node_modules/@sentry/conventions": { + "version": "0.12.0", "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-attributes": { - "version": "1.9.5", - "license": "MIT", - "peerDependencies": { - "acorn": "^8" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": ">=14" } }, - "node_modules/agent-base": { - "version": "7.1.4", + "node_modules/@sentry/core": { + "version": "10.60.0", "license": "MIT", "engines": { - "node": ">= 14" + "node": ">=18" } }, - "node_modules/ajv": { - "version": "8.18.0", + "node_modules/@sentry/node": { + "version": "10.60.0", "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" + "@opentelemetry/api": "^1.9.1", + "@opentelemetry/instrumentation": "^0.214.0", + "@opentelemetry/sdk-trace-base": "^2.6.1", + "@opentelemetry/semantic-conventions": "^1.40.0", + "@sentry/core": "10.60.0", + "@sentry/node-core": "10.60.0", + "@sentry/opentelemetry": "10.60.0", + "@sentry/server-utils": "10.60.0", + "import-in-the-middle": "^3.0.0" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=18" } }, - "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, + "node_modules/@sentry/node-core": { + "version": "10.60.0", "license": "MIT", "dependencies": { - "ajv": "^8.0.0" + "@sentry/conventions": "^0.12.0", + "@sentry/core": "10.60.0", + "@sentry/opentelemetry": "10.60.0", + "import-in-the-middle": "^3.0.0" + }, + "engines": { + "node": ">=18" }, "peerDependencies": { - "ajv": "^8.0.0" + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1", + "@opentelemetry/instrumentation": ">=0.57.1 <1", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" }, "peerDependenciesMeta": { - "ajv": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/core": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-http": { + "optional": true + }, + "@opentelemetry/instrumentation": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { "optional": true } } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "dev": true, + "node_modules/@sentry/node-cpu-profiler": { + "version": "2.4.2", + "hasInstallScript": true, "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" + "detect-libc": "^2.0.3", + "node-abi": "^3.73.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", + "node_modules/@sentry/opentelemetry": { + "version": "10.60.0", "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@sentry/conventions": "^0.12.0", + "@sentry/core": "10.60.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "node": ">=18" }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "peerDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/core": "^1.30.1 || ^2.1.0", + "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0" } }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.2", - "dev": true, + "node_modules/@sentry/profiling-node": { + "version": "10.60.0", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" + "@sentry/core": "10.60.0", + "@sentry/node": "10.60.0", + "@sentry/node-cpu-profiler": "^2.4.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "sentry-prune-profiler-binaries": "scripts/prune-profiler-binaries.js" + }, + "engines": { + "node": ">=18" } }, - "node_modules/array-includes": { - "version": "3.1.9", - "dev": true, + "node_modules/@sentry/server-utils": { + "version": "10.60.0", "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.0", - "es-object-atoms": "^1.1.1", - "get-intrinsic": "^1.3.0", - "is-string": "^1.1.1", - "math-intrinsics": "^1.1.0" + "@apm-js-collab/code-transformer": "^0.15.0", + "@apm-js-collab/code-transformer-bundler-plugins": "^0.5.0", + "@apm-js-collab/tracing-hooks": "^0.10.0", + "@sentry/conventions": "^0.12.0", + "@sentry/core": "10.60.0", + "magic-string": "~0.30.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" } }, - "node_modules/array-union": { - "version": "1.0.2", - "dev": true, - "license": "MIT", + "node_modules/@sentry/server-utils/node_modules/@apm-js-collab/code-transformer": { + "version": "0.15.0", + "license": "Apache-2.0", "dependencies": { - "array-uniq": "^1.0.1" + "@types/estree": "^1.0.8", + "astring": "^1.9.0", + "esquery": "^1.7.0", + "meriyah": "^6.1.4", + "semifies": "^1.0.0", + "source-map": "^0.6.0" }, - "engines": { - "node": ">=0.10.0" + "bin": { + "code-transformer": "cli.js" } }, - "node_modules/array-uniq": { - "version": "1.0.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node_modules/@sentry/server-utils/node_modules/@apm-js-collab/tracing-hooks": { + "version": "0.10.1", + "license": "Apache-2.0", + "dependencies": { + "@apm-js-collab/code-transformer": "^0.15.0", + "debug": "^4.4.1", + "module-details-from-path": "^1.0.4" } }, - "node_modules/array-unique": { - "version": "0.3.2", + "node_modules/@sinclair/typebox": { + "version": "0.34.38", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/@smithy/core": { + "version": "3.29.0", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.15.1", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18.0.0" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.6", - "dev": true, - "license": "MIT", + "node_modules/@smithy/credential-provider-imds": { + "version": "4.4.5", + "license": "Apache-2.0", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-shim-unscopables": "^1.1.0" + "@smithy/core": "^3.29.0", + "@smithy/types": "^4.15.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.3", - "dev": true, - "license": "MIT", + "node_modules/@smithy/fetch-http-handler": { + "version": "5.6.2", + "license": "Apache-2.0", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "@smithy/core": "^3.29.0", + "@smithy/types": "^4.15.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "dev": true, - "license": "MIT", + "node_modules/@smithy/node-http-handler": { + "version": "4.9.2", + "license": "Apache-2.0", "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" + "@smithy/core": "^3.29.0", + "@smithy/types": "^4.15.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "dev": true, - "license": "MIT", + "node_modules/@smithy/signature-v4": { + "version": "5.6.1", + "license": "Apache-2.0", "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" + "@smithy/core": "^3.29.0", + "@smithy/types": "^4.15.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18.0.0" } }, - "node_modules/asap": { - "version": "2.0.6", - "dev": true, - "license": "MIT" - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "dev": true, - "license": "MIT", + "node_modules/@smithy/types": { + "version": "4.15.1", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=18.0.0" } }, - "node_modules/astring": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "node_modules/@so-ric/colorspace": { + "version": "1.1.6", "license": "MIT", - "bin": { - "astring": "bin/astring" + "dependencies": { + "color": "^5.0.2", + "text-hex": "1.0.x" } }, - "node_modules/async": { - "version": "3.2.6", + "node_modules/@standard-schema/spec": { + "version": "1.1.0", "license": "MIT" }, - "node_modules/async-function": { - "version": "1.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } + "node_modules/@stela/access_copy_attacher": { + "resolved": "packages/access_copy_attacher", + "link": true + }, + "node_modules/@stela/account_space_updater": { + "resolved": "packages/account_space_updater", + "link": true + }, + "node_modules/@stela/api": { + "resolved": "packages/api", + "link": true + }, + "node_modules/@stela/archivematica_cleanup": { + "resolved": "packages/archivematica_cleanup", + "link": true + }, + "node_modules/@stela/archivematica-utils": { + "resolved": "packages/archivematica-utils", + "link": true + }, + "node_modules/@stela/event_send": { + "resolved": "packages/event_send", + "link": true + }, + "node_modules/@stela/event_utils": { + "resolved": "packages/event_utils", + "link": true + }, + "node_modules/@stela/file_copier": { + "resolved": "packages/file_copier", + "link": true + }, + "node_modules/@stela/file_url_refresh": { + "resolved": "packages/file_url_refresh", + "link": true + }, + "node_modules/@stela/file-utils": { + "resolved": "packages/file-utils", + "link": true + }, + "node_modules/@stela/logger": { + "resolved": "packages/logger", + "link": true + }, + "node_modules/@stela/metadata_attacher": { + "resolved": "packages/metadata_attacher", + "link": true + }, + "node_modules/@stela/permanent_models": { + "resolved": "packages/permanent_models", + "link": true + }, + "node_modules/@stela/publisher-utils": { + "resolved": "packages/publisher-utils", + "link": true + }, + "node_modules/@stela/record_thumbnail_attacher": { + "resolved": "packages/record_thumbnail_attacher", + "link": true + }, + "node_modules/@stela/s3-utils": { + "resolved": "packages/s3-utils", + "link": true }, - "node_modules/asynckit": { - "version": "0.4.0", - "license": "MIT" + "node_modules/@stela/thumbnail_refresh": { + "resolved": "packages/thumbnail_refresh", + "link": true }, - "node_modules/atob": { - "version": "2.1.2", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } + "node_modules/@stela/trigger_archivematica": { + "resolved": "packages/trigger_archivematica", + "link": true }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "dev": true, + "node_modules/@tokenizer/inflate": { + "version": "0.4.1", "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "debug": "^4.4.3", + "token-types": "^6.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-cloudfront-sign": { - "version": "3.0.2", - "license": "MIT", "engines": { "node": ">=18" }, "funding": { - "url": "https://ko-fi.com/jzimz" + "type": "github", + "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/axios": { - "version": "1.16.1", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.16.0", - "form-data": "^4.0.5", - "https-proxy-agent": "^5.0.1", - "proxy-from-env": "^2.1.0" - } + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "license": "MIT" }, - "node_modules/axios/node_modules/agent-base": { - "version": "6.0.2", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } + "node_modules/@tsconfig/node24": { + "version": "24.0.3", + "dev": true, + "license": "MIT" }, - "node_modules/axios/node_modules/https-proxy-agent": { - "version": "5.0.1", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } + "node_modules/@tsconfig/strictest": { + "version": "2.0.7", + "dev": true, + "license": "MIT" }, - "node_modules/babel-jest": { - "version": "30.3.0", + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "@jest/transform": "30.3.0", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.3.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" + "tslib": "^2.4.0" } }, - "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "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/@types/aws-lambda": { + "version": "8.10.162", + "license": "MIT" }, - "node_modules/babel-plugin-jest-hoist": { - "version": "30.3.0", + "node_modules/@types/body-parser": { + "version": "1.19.6", "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" + "@types/connect": "*", + "@types/node": "*" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "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" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/babel-preset-jest": { - "version": "30.3.0", + "node_modules/@types/connect": { + "version": "3.4.38", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "30.3.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" + "@types/node": "*" } }, - "node_modules/balanced-match": { - "version": "1.0.2", + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "dev": true, "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", + "node_modules/@types/cors": { + "version": "2.8.19", "dev": true, "license": "MIT", "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/node": "*" } }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "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==", - "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", - "optional": true + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" }, - "node_modules/better-ajv-errors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-2.0.3.tgz", - "integrity": "sha512-t1vxUP+vYKsaYi/BbKo2K98nEAZmfi4sjwvmRT8aOPDzPJeAtLurfoIDazVkLILxO4K+Sw4YrLYnBQ46l6pePg==", + "node_modules/@types/express": { + "version": "5.0.3", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@humanwhocodes/momoa": "^2.0.4", - "chalk": "^4.1.2", - "jsonpointer": "^5.0.1", - "leven": "^3.1.0 < 4" - }, - "engines": { - "node": ">= 18.20.6" - }, - "peerDependencies": { - "ajv": "4.11.8 - 8" - } - }, - "node_modules/bignumber.js": { - "version": "9.3.1", "license": "MIT", - "engines": { - "node": "*" + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", + "node_modules/@types/express-serve-static-core": { + "version": "5.0.7", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "optional": true, "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" } }, - "node_modules/body-parser": { - "version": "2.2.1", + "node_modules/@types/glob": { + "version": "7.2.0", + "dev": true, "license": "MIT", "dependencies": { - "bytes": "^3.1.2", - "content-type": "^1.0.5", - "debug": "^4.4.3", - "http-errors": "^2.0.0", - "iconv-lite": "^0.7.0", - "on-finished": "^2.4.1", - "qs": "^6.14.0", - "raw-body": "^3.0.1", - "type-is": "^2.0.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/body-parser/node_modules/media-typer": { - "version": "1.1.0", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "node_modules/@types/http-errors": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" }, - "node_modules/body-parser/node_modules/type-is": { - "version": "2.0.1", + "node_modules/@types/mailchimp__mailchimp_transactional": { + "version": "1.0.11", + "dev": true, "license": "MIT", "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" - }, - "engines": { - "node": ">= 0.6" + "axios": "^1.8.2" } }, - "node_modules/bowser": { - "version": "2.14.1", + "node_modules/@types/memoizee": { + "version": "0.4.12", + "dev": true, "license": "MIT" }, - "node_modules/brace-expansion": { - "version": "2.0.3", + "node_modules/@types/methods": { + "version": "1.1.4", "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime-types": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/newrelic": { + "version": "9.14.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.10.1", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "undici-types": "~7.16.0" } }, - "node_modules/braces": { - "version": "3.0.3", + "node_modules/@types/pg": { + "version": "8.20.0", + "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" } }, - "node_modules/browserslist": { - "version": "4.25.2", + "node_modules/@types/qs": { + "version": "6.14.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", "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": { - "caniuse-lite": "^1.0.30001733", - "electron-to-chromium": "^1.5.199", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "@types/mime": "^1", + "@types/node": "*" } }, - "node_modules/bs-logger": { - "version": "0.2.6", + "node_modules/@types/serve-static": { + "version": "1.15.8", "dev": true, "license": "MIT", "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" } }, - "node_modules/bser": { - "version": "2.1.1", + "node_modules/@types/superagent": { + "version": "8.1.9", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "node-int64": "^0.4.0" + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], + "node_modules/@types/supertest": { + "version": "6.0.3", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", + "node_modules/@types/triple-beam": { + "version": "1.3.5", "license": "MIT" }, - "node_modules/bytes": { - "version": "3.1.2", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", + "node_modules/@types/trusted-types": { + "version": "2.0.7", "dev": true, "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } + "optional": true }, - "node_modules/call-bind": { - "version": "1.0.8", + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.62.0", + "dev": true, "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" + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/type-utils": "8.62.0", + "@typescript-eslint/utils": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.62.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, "engines": { - "node": ">= 0.4" + "node": ">= 4" } }, - "node_modules/call-bound": { - "version": "1.0.4", + "node_modules/@typescript-eslint/parser": { + "version": "8.62.0", + "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", + "debug": "^4.4.3" }, "engines": { - "node": ">= 0.4" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/call-me-maybe": { - "version": "1.0.2", - "dev": true, - "license": "MIT" - }, - "node_modules/callsites": { - "version": "3.1.0", + "node_modules/@typescript-eslint/project-service": { + "version": "8.62.0", "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.62.0", + "@typescript-eslint/types": "^8.62.0", + "debug": "^4.4.3" + }, "engines": { - "node": ">=6" + "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.1.0" } }, - "node_modules/camelcase": { - "version": "5.3.1", + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.62.0", "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0" + }, "engines": { - "node": ">=6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.62.0", "dev": true, "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001734", + "node_modules/@typescript-eslint/type-utils": { + "version": "8.62.0", "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", "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0", + "@typescript-eslint/utils": "8.62.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/char-regex": { - "version": "1.0.2", + "node_modules/@typescript-eslint/types": { + "version": "8.62.0", "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/check-disk-space": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/check-disk-space/-/check-disk-space-3.4.0.tgz", - "integrity": "sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.62.0", + "dev": true, "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.62.0", + "@typescript-eslint/tsconfig-utils": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/visitor-keys": "8.62.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, "engines": { - "node": ">=16" + "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.1.0" } }, - "node_modules/chokidar": { - "version": "3.6.0", + "node_modules/@typescript-eslint/utils": { + "version": "8.62.0", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.62.0", + "@typescript-eslint/types": "8.62.0", + "@typescript-eslint/typescript-estree": "8.62.0" }, "engines": { - "node": ">= 8.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://paulmillr.com/funding/" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, - "node_modules/chownr": { - "version": "2.0.0", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.62.0", "dev": true, - "license": "ISC", + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.62.0", + "eslint-visitor-keys": "^5.0.0" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/ci-info": { - "version": "4.3.0", + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=8" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/cjs-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "node_modules/@tyriar/fibonacci-heap": { + "version": "2.0.9", "license": "MIT" }, - "node_modules/class-utils": { - "version": "0.3.6", + "node_modules/@vitest/coverage-v8": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.10.tgz", + "integrity": "sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==", "dev": true, "license": "MIT", "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "@bcoe/v8-coverage": "^1.0.2", + "@vitest/utils": "4.1.10", + "ast-v8-to-istanbul": "^1.0.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.2.0", + "magicast": "^0.5.2", + "obug": "^2.1.1", + "std-env": "^4.0.0-rc.1", + "tinyrainbow": "^3.1.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@vitest/browser": "4.1.10", + "vitest": "4.1.10" + }, + "peerDependenciesMeta": { + "@vitest/browser": { + "optional": true + } } }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", + "node_modules/@vitest/coverage-v8/node_modules/@bcoe/v8-coverage": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz", + "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==", "dev": true, "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=18" } }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.7", + "node_modules/@vitest/eslint-plugin": { + "version": "1.6.21", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.6.21.tgz", + "integrity": "sha512-5nu7QuW5Dg9v4I9t9ZiU1Hh91BoG0x3lOzOWYTsr1bqpIqcHYzFSQ052LvZwGtEm7Trh+Mr2heYEmZ4LkDjfaA==", "dev": true, "license": "MIT", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" + "@typescript-eslint/scope-manager": "^8.58.0", + "@typescript-eslint/utils": "^8.58.0" }, "engines": { - "node": ">= 0.4" + "node": ">=18" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "*", + "eslint": ">=8.57.0", + "typescript": ">=5.0.0", + "vitest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "typescript": { + "optional": true + }, + "vitest": { + "optional": true + } } }, - "node_modules/classnames": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/clsx": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/co": { - "version": "4.6.0", + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", "dev": true, "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "dev": true, - "license": "MIT" - }, - "node_modules/collection-visit": { - "version": "1.0.0", + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", "dev": true, "license": "MIT", "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/color": { - "version": "5.0.3", + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, "license": "MIT", - "dependencies": { - "color-convert": "^3.1.3", - "color-string": "^2.1.3" - }, - "engines": { - "node": ">=18" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/color-convert": { - "version": "2.0.1", + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" }, - "engines": { - "node": ">=7.0.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, - "node_modules/color-name": { - "version": "1.1.4", - "license": "MIT" + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "license": "BSD-2-Clause" }, - "node_modules/color-string": { - "version": "2.1.4", + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "^2.0.0" + "mime-types": "~2.1.34", + "negotiator": "0.6.3" }, "engines": { - "node": ">=18" + "node": ">= 0.6" } }, - "node_modules/color-string/node_modules/color-name": { - "version": "2.1.0", + "node_modules/accepts/node_modules/mime-db": { + "version": "1.52.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">= 0.6" } }, - "node_modules/color/node_modules/color-convert": { - "version": "3.1.3", + "node_modules/accepts/node_modules/mime-types": { + "version": "2.1.35", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "^2.0.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=14.6" + "node": ">= 0.6" } }, - "node_modules/color/node_modules/color-name": { - "version": "2.1.0", + "node_modules/acorn": { + "version": "8.15.0", "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=12.20" + "node": ">=0.4.0" } }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" + "peerDependencies": { + "acorn": "^8" } }, - "node_modules/commander": { - "version": "10.0.1", + "node_modules/acorn-jsx": { + "version": "5.3.2", "dev": true, "license": "MIT", - "engines": { - "node": ">=14" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/component-emitter": { - "version": "1.3.1", + "node_modules/agent-base": { + "version": "7.1.4", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 14" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "engines": [ - "node >= 6.0" - ], + "node_modules/ajv": { + "version": "8.18.0", "license": "MIT", "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" + "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/content-disposition": { - "version": "0.5.4", + "node_modules/ajv-formats": { + "version": "3.0.1", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "ajv": "^8.0.0" }, - "engines": { - "node": ">= 0.6" + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, - "node_modules/content-type": { - "version": "1.0.5", + "node_modules/ansi-regex": { + "version": "5.0.1", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.2", + "node_modules/ansi-styles": { + "version": "4.3.0", "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/cookie-signature": { - "version": "1.2.2", - "license": "MIT", + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, "engines": { - "node": ">=6.6.0" + "node": ">= 8" } }, - "node_modules/cookiejar": { - "version": "2.1.4", - "license": "MIT" + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" }, - "node_modules/copy-descriptor": { - "version": "0.1.1", + "node_modules/arr-diff": { + "version": "4.0.0", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/core-js": { - "version": "3.49.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.49.0.tgz", - "integrity": "sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==", + "node_modules/arr-flatten": { + "version": "1.1.0", "dev": true, - "hasInstallScript": true, "license": "MIT", - "peer": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "license": "MIT" - }, - "node_modules/cors": { - "version": "2.8.5", + "node_modules/arr-union": { + "version": "3.1.0", + "dev": true, "license": "MIT", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, "engines": { - "node": ">= 0.10" + "node": ">=0.10.0" } }, - "node_modules/cosmiconfig": { - "version": "8.3.6", + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", "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" + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" }, "engines": { - "node": ">=14" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cosmiconfig/node_modules/path-type": { - "version": "4.0.0", + "node_modules/array-includes": { + "version": "3.1.9", "dev": true, "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", + "node_modules/array-union": { + "version": "1.0.2", + "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "array-uniq": "^1.0.1" }, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "node_modules/array-uniq": { + "version": "1.0.3", "dev": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/css-to-react-native": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", + "node_modules/array-unique": { + "version": "0.3.2", "dev": true, "license": "MIT", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", "dev": true, - "license": "MIT" - }, - "node_modules/d": { - "version": "1.0.2", - "license": "ISC", + "license": "MIT", "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" }, "engines": { - "node": ">=0.12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-view-buffer": { - "version": "1.0.2", + "node_modules/array.prototype.flat": { + "version": "1.3.3", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -5738,30 +3700,35 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" }, "engines": { "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/inspect-js" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" }, "engines": { "node": ">= 0.4" @@ -5770,77 +3737,88 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "node_modules/asap": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4.0" + "node": ">=12" } }, - "node_modules/debug": { - "version": "4.4.3", + "node_modules/assign-symbols": { + "version": "1.0.0", + "dev": true, "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": ">=0.10.0" } }, - "node_modules/decko": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", - "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==", - "dev": true - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", + "node_modules/ast-v8-to-istanbul": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.4.tgz", + "integrity": "sha512-0bC0/4bTSrnwdhU3IsZDwEdojvuPrSg59OYZfKsLRtJZ0u8VBx9DebfqqG8bRdCC0I7vjgxmPi41P0lpkhJHtA==", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.10" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.31", + "estree-walker": "^3.0.3", + "js-tokens": "^10.0.0" } }, - "node_modules/dedent": { - "version": "1.7.2", + "node_modules/ast-v8-to-istanbul/node_modules/js-tokens": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz", + "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==", "dev": true, + "license": "MIT" + }, + "node_modules/astring": { + "version": "1.9.0", "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } + "bin": { + "astring": "bin/astring" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "dev": true, + "node_modules/async": { + "version": "3.2.6", "license": "MIT" }, - "node_modules/deepmerge": { - "version": "4.3.1", + "node_modules/async-function": { + "version": "1.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, - "node_modules/define-data-property": { - "version": "1.1.4", + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/atob": { + "version": "2.1.2", + "dev": true, + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5849,281 +3827,293 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-properties": { - "version": "1.2.1", - "dev": true, + "node_modules/aws-cloudfront-sign": { + "version": "3.0.2", "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://ko-fi.com/jzimz" } }, - "node_modules/define-property": { - "version": "2.0.2", - "dev": true, + "node_modules/axios": { + "version": "1.16.1", "license": "MIT", "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "https-proxy-agent": "^5.0.1", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/axios/node_modules/agent-base": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "debug": "4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6.0.0" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", + "node_modules/axios/node_modules/https-proxy-agent": { + "version": "5.0.1", "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, "engines": { - "node": ">=0.4.0" + "node": ">= 6" } }, - "node_modules/depd": { - "version": "1.1.2", + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/base": { + "version": "0.11.2", "dev": true, "license": "MIT", + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.10.0" } }, - "node_modules/detect-europe-js": { - "version": "0.1.2", + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/faisalman" + "url": "https://github.com/sponsors/feross" }, { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" + "type": "patreon", + "url": "https://www.patreon.com/feross" }, { - "type": "paypal", - "url": "https://paypal.me/faisalman" + "type": "consulting", + "url": "https://feross.org/support" } ], - "license": "MIT" + "license": "MIT", + "optional": true }, - "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==", + "node_modules/better-ajv-errors": { + "version": "2.0.3", + "dev": true, "license": "Apache-2.0", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@humanwhocodes/momoa": "^2.0.4", + "chalk": "^4.1.2", + "jsonpointer": "^5.0.1", + "leven": "^3.1.0 < 4" + }, "engines": { - "node": ">=8" + "node": ">= 18.20.6" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "dev": true, + "node_modules/bignumber.js": { + "version": "9.3.1", "license": "MIT", "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/dezalgo": { - "version": "1.0.4", + "node_modules/binary-extensions": { + "version": "2.3.0", "dev": true, - "license": "ISC", - "dependencies": { - "asap": "^2.0.0", - "wrappy": "1" + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/dir-glob": { - "version": "2.2.2", - "dev": true, + "node_modules/bl": { + "version": "4.1.0", "license": "MIT", + "optional": true, "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" } }, - "node_modules/doctrine": { - "version": "2.1.0", - "dev": true, - "license": "Apache-2.0", + "node_modules/body-parser": { + "version": "2.2.1", + "license": "MIT", "dependencies": { - "esutils": "^2.0.2" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dompurify": { - "version": "3.4.11", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.4.11.tgz", - "integrity": "sha512-zhlUV12GsaRzMsf9q5M254YhA4+VuF0fG+QFqu6aYpoGlKtz+w8//jBcGVYBgQkR5GHjUomejY84AV+/uPbWdw==", - "dev": true, - "license": "(MPL-2.0 OR Apache-2.0)", - "optionalDependencies": { - "@types/trusted-types": "^2.0.7" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/dotenv": { - "version": "17.4.2", - "license": "BSD-2-Clause", + "node_modules/body-parser/node_modules/media-typer": { + "version": "1.1.0", + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" + "node": ">= 0.8" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", + "node_modules/body-parser/node_modules/type-is": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/duplexer": { - "version": "0.1.2", - "dev": true, - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", + "node_modules/bowser": { + "version": "2.14.1", "license": "MIT" }, - "node_modules/electron-to-chromium": { - "version": "1.5.200", + "node_modules/brace-expansion": { + "version": "2.0.3", "dev": true, - "license": "ISC" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } }, - "node_modules/emittery": { - "version": "0.13.1", - "dev": true, + "node_modules/braces": { + "version": "3.0.3", "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "fill-range": "^7.1.1" }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "engines": { + "node": ">=8" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" + "node_modules/buffer": { + "version": "5.7.1", + "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", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } }, - "node_modules/enabled": { - "version": "2.0.0", + "node_modules/buffer-from": { + "version": "1.1.2", "license": "MIT" }, - "node_modules/encodeurl": { - "version": "2.0.0", + "node_modules/bytes": { + "version": "3.1.2", "license": "MIT", "engines": { "node": ">= 0.8" } }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "node_modules/cache-base": { + "version": "1.0.1", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "once": "^1.4.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/enhanced-resolve": { - "version": "5.22.1", - "dev": true, + "node_modules/call-bind": { + "version": "1.0.8", "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.3" + "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": ">=10.13.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "dev": true, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", "license": "MIT", "dependencies": { - "is-arrayish": "^0.2.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/es-abstract": { - "version": "1.24.0", - "dev": true, + "node_modules/call-bound": { + "version": "1.0.4", "license": "MIT", "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -6132,1963 +4122,1962 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-define-property": { - "version": "1.0.1", + "node_modules/call-me-maybe": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/camelize": { + "version": "1.0.1", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-module-lexer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.2.0.tgz", - "integrity": "sha512-3lGxdTXCLfe1MYfTz1y2ksAAUM4NAOP6rPEjxGJVKO7TZ5+tvHCaQWGpC4Y3IXvW3ece0Cz1cIP4FWBxOnGCTQ==", - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", + "node_modules/chalk": { + "version": "4.1.2", "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/es-shim-unscopables": { - "version": "1.1.0", - "dev": true, + "node_modules/check-disk-space": { + "version": "3.4.0", "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=16" } }, - "node_modules/es-to-primitive": { - "version": "1.3.0", + "node_modules/chokidar": { + "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { - "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 0.4" + "node": ">= 8.10.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" } }, - "node_modules/es5-ext": { - "version": "0.10.64", - "hasInstallScript": true, + "node_modules/chownr": { + "version": "2.0.0", + "dev": true, "license": "ISC", - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" + "node": ">=10" } }, - "node_modules/es6-promise": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", - "dev": true, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", "license": "MIT" }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "license": "ISC", + "node_modules/class-utils": { + "version": "0.3.6", + "dev": true, + "license": "MIT", "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "engines": { - "node": ">=0.12" + "node": ">=0.10.0" } }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "license": "ISC", + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "dev": true, + "license": "MIT", "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/escalade": { - "version": "3.2.0", + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.7", + "dev": true, "license": "MIT", + "dependencies": { + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" + }, "engines": { - "node": ">=6" + "node": ">= 0.4" } }, - "node_modules/escape-html": { - "version": "1.0.3", + "node_modules/classnames": { + "version": "2.5.1", + "dev": true, "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", + "node_modules/cliui": { + "version": "7.0.4", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/eslint": { - "version": "9.39.4", + "node_modules/clsx": { + "version": "2.1.1", "dev": true, "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.2", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.5", - "@eslint/js": "9.39.4", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "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.5", - "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": ">=6" } }, - "node_modules/eslint-compat-utils": { - "version": "0.5.1", + "node_modules/collection-visit": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.5.4" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" }, "engines": { - "node": ">=12" - }, - "peerDependencies": { - "eslint": ">=6.0.0" + "node": ">=0.10.0" } }, - "node_modules/eslint-config-love": { - "version": "154.0.0", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mightyiam" - }, - "https://wise.com/pay/me/shaharo" - ], + "node_modules/color": { + "version": "5.0.3", "license": "MIT", "dependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "^4.0.0", - "@typescript-eslint/utils": "^8.58.1", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-n": "^18.0.1", - "eslint-plugin-promise": "^7.2.0", - "typescript-eslint": "^8.58.1" + "color-convert": "^3.1.3", + "color-string": "^2.1.3" }, "engines": { - "npm": "*" - }, - "peerDependencies": { - "eslint": "^9.35.0", - "typescript": "*" + "node": ">=18" } }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" }, - "peerDependencies": { - "eslint": ">=7.0.0" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "dev": true, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "2.1.4", "license": "MIT", "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "color-name": "^2.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "dev": true, + "node_modules/color-string/node_modules/color-name": { + "version": "2.1.0", "license": "MIT", - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">=12.20" } }, - "node_modules/eslint-module-utils": { - "version": "2.12.1", - "dev": true, + "node_modules/color/node_modules/color-convert": { + "version": "3.1.3", "license": "MIT", "dependencies": { - "debug": "^3.2.7" + "color-name": "^2.0.0" }, "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "node": ">=14.6" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "dev": true, + "node_modules/color/node_modules/color-name": { + "version": "2.1.0", "license": "MIT", - "dependencies": { - "ms": "^2.1.1" + "engines": { + "node": ">=12.20" } }, - "node_modules/eslint-plugin-es-x": { - "version": "7.8.0", + "node_modules/colorette": { + "version": "1.4.0", "dev": true, - "funding": [ - "https://github.com/sponsors/ota-meshi", - "https://opencollective.com/eslint" - ], + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.1.2", - "@eslint-community/regexpp": "^4.11.0", - "eslint-compat-utils": "^0.5.1" + "delayed-stream": "~1.0.0" }, "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": ">=8" + "node": ">= 0.8" } }, - "node_modules/eslint-plugin-import": { - "version": "2.32.0", + "node_modules/commander": { + "version": "10.0.1", "dev": true, "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.9", - "array.prototype.findlastindex": "^1.2.6", - "array.prototype.flat": "^1.3.3", - "array.prototype.flatmap": "^1.3.3", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.1", - "hasown": "^2.0.2", - "is-core-module": "^2.16.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.1", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.9", - "tsconfig-paths": "^3.15.0" - }, "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + "node": ">=14" } }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.13", - "dev": true, + "node_modules/component-emitter": { + "version": "1.3.1", "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "dev": true, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "engines": [ + "node >= 6.0" + ], "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" } }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.5", + "node_modules/content-disposition": { + "version": "0.5.4", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "safe-buffer": "5.2.1" }, "engines": { - "node": "*" + "node": ">= 0.6" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/eslint-plugin-jest": { - "version": "29.15.2", + "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", "license": "MIT", - "dependencies": { - "@typescript-eslint/utils": "^8.0.0" - }, "engines": { - "node": "^20.12.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "jest": "*", - "typescript": ">=4.8.4 <7.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - }, - "typescript": { - "optional": true - } + "node": ">= 0.6" } }, - "node_modules/eslint-plugin-n": { - "version": "18.0.1", - "dev": true, + "node_modules/cookie-signature": { + "version": "1.2.2", "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.5.0", - "enhanced-resolve": "^5.17.1", - "eslint-plugin-es-x": "^7.8.0", - "get-tsconfig": "^4.8.1", - "globals": "^15.11.0", - "globrex": "^0.1.2", - "ignore": "^5.3.2", - "semver": "^7.6.3" - }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": ">=8.57.1", - "ts-declaration-location": "^1.0.6", - "typescript": ">=5.0.0" - }, - "peerDependenciesMeta": { - "ts-declaration-location": { - "optional": true - }, - "typescript": { - "optional": true - } + "node": ">=6.6.0" } }, - "node_modules/eslint-plugin-n/node_modules/globals": { - "version": "15.15.0", + "node_modules/cookiejar": { + "version": "2.1.4", + "license": "MIT" + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", "dev": true, "license": "MIT", "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-promise": { - "version": "7.2.1", + "node_modules/core-js": { + "version": "3.49.0", "dev": true, - "license": "ISC", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, + "hasInstallScript": true, + "license": "MIT", + "peer": true, "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + "type": "opencollective", + "url": "https://opencollective.com/core-js" } }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "dev": true, - "license": "BSD-2-Clause", + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "object-assign": "^4", + "vary": "^1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">= 0.10" } }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", + "node_modules/cosmiconfig": { + "version": "8.3.6", "dev": true, - "license": "Apache-2.0", + "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": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=14" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.14.0", + "node_modules/cosmiconfig/node_modules/path-type": { + "version": "4.0.0", "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" + "engines": { + "node": ">=8" } }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.13", - "dev": true, + "node_modules/cross-spawn": { + "version": "7.0.6", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", + "node_modules/css-color-keywords": { + "version": "1.0.0", "dev": true, "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, "engines": { - "node": ">=10.13.0" + "node": ">=4" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.5", + "node_modules/css-to-react-native": { + "version": "3.2.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" } }, - "node_modules/esniff": { - "version": "2.0.1", + "node_modules/csstype": { + "version": "3.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/d": { + "version": "1.0.2", "license": "ISC", "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", + "es5-ext": "^0.10.64", "type": "^2.7.2" }, "engines": { - "node": ">=0.10" + "node": ">=0.12" } }, - "node_modules/espree": { - "version": "10.4.0", + "node_modules/data-view-buffer": { + "version": "1.0.2", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", + "node_modules/data-view-byte-length": { + "version": "1.0.2", "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "estraverse": "^5.1.0" + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" }, "engines": { - "node": ">=0.10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" } }, - "node_modules/esrecurse": { - "version": "4.3.0", + "node_modules/data-view-byte-offset": { + "version": "1.0.1", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "estraverse": "^5.2.0" + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "license": "BSD-2-Clause", + "node_modules/date-format": { + "version": "4.0.14", + "license": "MIT", "engines": { "node": ">=4.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", + "node_modules/debug": { + "version": "4.4.3", "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": ">= 0.6" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/event-emitter": { - "version": "0.3.5", - "license": "MIT", - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } + "node_modules/decko": { + "version": "1.2.0", + "dev": true }, - "node_modules/event-stream": { - "version": "3.3.4", + "node_modules/decode-uri-component": { + "version": "0.2.2", "dev": true, "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" + "engines": { + "node": ">=0.10" } }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "node_modules/deep-is": { + "version": "0.1.4", "dev": true, "license": "MIT" }, - "node_modules/execa": { - "version": "5.1.1", - "dev": true, + "node_modules/define-data-property": { + "version": "1.1.4", "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" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit-x": { - "version": "0.2.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", + "node_modules/define-properties": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", + "node_modules/define-property": { + "version": "2.0.2", "dev": true, "license": "MIT", "dependencies": { - "is-descriptor": "^0.1.0" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, + "node_modules/delayed-stream": { + "version": "1.0.0", "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.7", + "node_modules/depd": { + "version": "1.1.2", "dev": true, "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "dev": true, - "license": "MIT", + "node_modules/detect-europe-js": { + "version": "0.1.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "license": "Apache-2.0", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", + "node_modules/dezalgo": { + "version": "1.0.4", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } }, - "node_modules/expect": { - "version": "30.3.0", + "node_modules/dir-glob": { + "version": "2.2.2", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.3.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-util": "30.3.0" + "path-type": "^3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=4" } }, - "node_modules/express": { - "version": "5.2.0", - "license": "MIT", + "node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "accepts": "^2.0.0", - "body-parser": "^2.2.1", - "content-disposition": "^1.0.0", - "content-type": "^1.0.5", - "cookie": "^0.7.1", - "cookie-signature": "^1.2.1", - "debug": "^4.4.0", - "depd": "^2.0.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" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 18" + "node": ">=0.10.0" + } + }, + "node_modules/dompurify": { + "version": "3.4.11", + "dev": true, + "license": "(MPL-2.0 OR Apache-2.0)", + "optionalDependencies": { + "@types/trusted-types": "^2.0.7" + } + }, + "node_modules/dotenv": { + "version": "17.4.2", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "url": "https://dotenvx.com" } }, - "node_modules/express-winston": { - "version": "4.2.0", + "node_modules/dunder-proto": { + "version": "1.0.1", "license": "MIT", "dependencies": { - "chalk": "^2.4.2", - "lodash": "^4.17.21" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "winston": ">=3.x <4" + "node": ">= 0.4" } }, - "node_modules/express-winston/node_modules/ansi-styles": { - "version": "3.2.1", + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, "engines": { - "node": ">=4" + "node": ">= 0.8" } }, - "node_modules/express-winston/node_modules/chalk": { - "version": "2.4.2", + "node_modules/end-of-stream": { + "version": "1.4.5", + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.22.1", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" }, "engines": { - "node": ">=4" + "node": ">=10.13.0" } }, - "node_modules/express-winston/node_modules/color-convert": { - "version": "1.9.3", + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "is-arrayish": "^0.2.1" } }, - "node_modules/express-winston/node_modules/color-name": { - "version": "1.1.3", - "license": "MIT" - }, - "node_modules/express-winston/node_modules/escape-string-regexp": { - "version": "1.0.5", + "node_modules/es-abstract": { + "version": "1.24.0", + "dev": true, "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, "engines": { - "node": ">=0.8.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express-winston/node_modules/has-flag": { - "version": "3.0.0", + "node_modules/es-define-property": { + "version": "1.0.1", "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/express-winston/node_modules/supports-color": { - "version": "5.5.0", + "node_modules/es-errors": { + "version": "1.3.0", "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/express/node_modules/accepts": { - "version": "2.0.0", + "node_modules/es-module-lexer": { + "version": "2.2.0", + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", "license": "MIT", "dependencies": { - "mime-types": "^3.0.0", - "negotiator": "^1.0.0" + "es-errors": "^1.3.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.4" } }, - "node_modules/express/node_modules/content-disposition": { - "version": "1.0.0", + "node_modules/es-set-tostringtag": { + "version": "2.1.0", "license": "MIT", "dependencies": { - "safe-buffer": "5.2.1" + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/express/node_modules/depd": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/fresh": { - "version": "2.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.8" + "node": ">= 0.4" } }, - "node_modules/express/node_modules/media-typer": { + "node_modules/es-shim-unscopables": { "version": "1.1.0", + "dev": true, "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, "engines": { - "node": ">= 0.8" + "node": ">= 0.4" } }, - "node_modules/express/node_modules/merge-descriptors": { - "version": "2.0.0", + "node_modules/es-to-primitive": { + "version": "1.3.0", + "dev": true, "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, "engines": { - "node": ">=18" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/express/node_modules/negotiator": { - "version": "1.0.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/express/node_modules/type-is": { - "version": "2.0.1", - "license": "MIT", + "node_modules/es5-ext": { + "version": "0.10.64", + "hasInstallScript": true, + "license": "ISC", "dependencies": { - "content-type": "^1.0.5", - "media-typer": "^1.1.0", - "mime-types": "^3.0.0" + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" }, "engines": { - "node": ">= 0.6" + "node": ">=0.10" } }, - "node_modules/ext": { - "version": "1.7.0", - "license": "ISC", + "node_modules/es6-iterator": { + "version": "2.0.3", + "license": "MIT", "dependencies": { - "type": "^2.7.2" + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" } }, - "node_modules/extend": { - "version": "3.0.2", + "node_modules/es6-promise": { + "version": "3.3.1", + "dev": true, "license": "MIT" }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "dev": true, - "license": "MIT", + "node_modules/es6-symbol": { + "version": "3.1.4", + "license": "ISC", "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "d": "^1.0.2", + "ext": "^1.7.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12" } }, - "node_modules/extglob": { - "version": "2.0.4", - "dev": true, - "license": "MIT", + "node_modules/es6-weak-map": { + "version": "2.0.3", + "license": "ISC", "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "dev": true, + "node_modules/escalade": { + "version": "3.2.0", "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", + "node_modules/eslint": { + "version": "9.39.4", "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "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.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", + "node_modules/eslint-compat-utils": { + "version": "0.5.1", "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" + "semver": "^7.5.4" }, "engines": { - "node": ">=8.6.0" + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", + "node_modules/eslint-config-love": { + "version": "154.0.0", "dev": true, - "license": "MIT" - }, - "node_modules/fast-safe-stringify": { - "version": "2.1.1", - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.1.2", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/fastify" + "url": "https://github.com/sponsors/mightyiam" }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fast-xml-builder": { - "version": "1.2.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } + "https://wise.com/pay/me/shaharo" ], "license": "MIT", "dependencies": { - "path-expression-matcher": "^1.5.0", - "xml-naming": "^0.1.0" + "@eslint-community/eslint-plugin-eslint-comments": "^4.0.0", + "@typescript-eslint/utils": "^8.58.1", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-n": "^18.0.1", + "eslint-plugin-promise": "^7.2.0", + "typescript-eslint": "^8.58.1" + }, + "engines": { + "npm": "*" + }, + "peerDependencies": { + "eslint": "^9.35.0", + "typescript": "*" } }, - "node_modules/fast-xml-parser": { - "version": "5.7.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "dev": true, "license": "MIT", - "dependencies": { - "@nodable/entities": "^2.1.0", - "fast-xml-builder": "^1.1.7", - "path-expression-matcher": "^1.5.0", - "strnum": "^2.2.3" - }, "bin": { - "fxparser": "src/cli/cli.js" + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/fastq": { - "version": "1.19.1", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "reusify": "^1.0.4" + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "bser": "2.1.1" + "ms": "^2.1.1" } }, - "node_modules/fecha": { - "version": "4.2.3", - "license": "MIT" - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", + "node_modules/eslint-module-utils": { + "version": "2.12.1", "dev": true, "license": "MIT", "dependencies": { - "flat-cache": "^4.0.0" + "debug": "^3.2.7" }, "engines": { - "node": ">=16.0.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/file-type": { - "version": "22.0.1", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, "license": "MIT", "dependencies": { - "@tokenizer/inflate": "^0.4.1", - "strtok3": "^10.3.5", - "token-types": "^6.1.2", - "uint8array-extras": "^1.5.0" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" + "ms": "^2.1.1" } }, - "node_modules/fill-range": { - "version": "7.1.1", + "node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" }, "engines": { - "node": ">=8" + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" } }, - "node_modules/finalhandler": { - "version": "2.1.0", + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "dev": true, "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" + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": ">= 0.8" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, - "node_modules/find-package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-package-json/-/find-package-json-1.2.0.tgz", - "integrity": "sha512-+SOGcLGYDJHtyqHd87ysBhmaeQ95oWspDKnMXBrnQ9Eq4OkLNqejgoaD8xVWu6GPa0B6roa6KinCMEMcVeqONw==", - "license": "MIT" - }, - "node_modules/find-up": { - "version": "5.0.0", + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.13", "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" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/find-yarn-workspace-root": { - "version": "2.0.0", - "license": "Apache-2.0", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", "dependencies": { - "micromatch": "^4.0.2" + "ms": "^2.1.1" } }, - "node_modules/flat-cache": { - "version": "4.0.1", + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.5", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=16" + "node": "*" } }, - "node_modules/flatted": { - "version": "3.4.1", - "license": "ISC" - }, - "node_modules/fn.name": { - "version": "1.1.0", - "license": "MIT" + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } }, - "node_modules/follow-redirects": { - "version": "1.16.0", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], + "node_modules/eslint-plugin-n": { + "version": "18.0.1", + "dev": true, "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3" + }, "engines": { - "node": ">=4.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.57.1", + "ts-declaration-location": "^1.0.6", + "typescript": ">=5.0.0" }, "peerDependenciesMeta": { - "debug": { + "ts-declaration-location": { + "optional": true + }, + "typescript": { "optional": true } } }, - "node_modules/for-each": { - "version": "0.3.5", + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", "dev": true, "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, "engines": { - "node": ">= 0.4" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/for-in": { - "version": "1.0.2", + "node_modules/eslint-plugin-promise": { + "version": "7.2.1", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, "engines": { - "node": ">=0.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/foreach": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", - "dev": true, - "license": "MIT" - }, - "node_modules/foreground-child": { - "version": "3.3.1", + "node_modules/eslint-scope": { + "version": "8.4.0", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=14" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", "dev": true, - "license": "ISC", + "license": "Apache-2.0", "engines": { - "node": ">=14" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint" } }, - "node_modules/form-data": { - "version": "4.0.5", + "node_modules/eslint/node_modules/ajv": { + "version": "6.14.0", + "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" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/form-data/node_modules/mime-db": { - "version": "1.52.0", + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.13", + "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.6" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/form-data/node_modules/mime-types": { - "version": "2.1.35", - "license": "MIT", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", "dependencies": { - "mime-db": "1.52.0" + "is-glob": "^4.0.3" }, "engines": { - "node": ">= 0.6" - } - }, - "node_modules/formidable": { - "version": "1.2.6", - "license": "MIT", - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" + "node": ">=10.13.0" } }, - "node_modules/forwarded": { - "version": "0.2.0", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" }, - "node_modules/fragment-cache": { - "version": "0.2.1", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.5", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "map-cache": "^0.2.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10.0" + "node": "*" } }, - "node_modules/fresh": { - "version": "0.5.2", - "dev": true, - "license": "MIT", + "node_modules/esniff": { + "version": "2.0.1", + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, "engines": { - "node": ">= 0.6" + "node": ">=0.10" } }, - "node_modules/from": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT", - "optional": true - }, - "node_modules/fs-extra": { - "version": "11.3.1", + "node_modules/espree": { + "version": "10.4.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=14.14" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "dev": true, - "license": "ISC", + "node_modules/esquery": { + "version": "1.7.0", + "license": "BSD-3-Clause", "dependencies": { - "minipass": "^3.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">= 8" + "node": ">=0.10" } }, - "node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", + "node_modules/esrecurse": { + "version": "4.3.0", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "yallist": "^4.0.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/fs-minipass/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "license": "ISC" - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "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" - ], + "node_modules/estraverse": { + "version": "5.3.0", + "license": "BSD-2-Clause", "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=4.0" } }, - "node_modules/function-bind": { - "version": "1.1.2", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "@types/estree": "^1.0.0" } }, - "node_modules/function.prototype.name": { - "version": "1.1.8", + "node_modules/esutils": { + "version": "2.0.3", "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" - }, + "license": "BSD-2-Clause", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "dev": true, + "node_modules/event-emitter": { + "version": "0.3.5", "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", + "node_modules/event-stream": { + "version": "3.3.4", "dev": true, "license": "MIT", - "engines": { - "node": ">=6.9.0" + "dependencies": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } + "node_modules/eventemitter3": { + "version": "5.0.4", + "dev": true, + "license": "MIT" }, - "node_modules/get-intrinsic": { - "version": "1.3.0", + "node_modules/expand-brackets": { + "version": "2.1.4", + "dev": true, "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" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/get-package-type": { - "version": "0.1.0", + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", "dev": true, "license": "MIT", - "engines": { - "node": ">=8.0.0" + "dependencies": { + "ms": "2.0.0" } }, - "node_modules/get-proto": { - "version": "1.0.1", + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "is-descriptor": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/get-stream": { - "version": "6.0.1", + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=10" + "dependencies": { + "is-extendable": "^0.1.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/get-symbol-description": { - "version": "1.1.0", + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.7", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-tsconfig": { - "version": "4.14.0", + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", "dev": true, "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/get-value": { - "version": "2.0.6", + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=0.10.0" + "node": ">=12.0.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "license": "ISC", + "node_modules/express": { + "version": "5.2.0", + "license": "MIT", "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" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.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": "*" + "node": ">= 18" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "dev": true, - "license": "ISC", + "node_modules/express-winston": { + "version": "4.2.0", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "chalk": "^2.4.2", + "lodash": "^4.17.21" }, "engines": { "node": ">= 6" + }, + "peerDependencies": { + "winston": ">=3.x <4" } }, - "node_modules/glob-to-regexp": { - "version": "0.3.0", - "dev": true, - "license": "BSD" - }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.13", + "node_modules/express-winston/node_modules/ansi-styles": { + "version": "3.2.1", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.5", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" + "color-convert": "^1.9.0" }, "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/globals": { - "version": "14.0.0", - "dev": true, + "node_modules/express-winston/node_modules/chalk": { + "version": "2.4.2", "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=4" } }, - "node_modules/globalthis": { - "version": "1.0.4", - "dev": true, + "node_modules/express-winston/node_modules/color-convert": { + "version": "1.9.3", "license": "MIT", "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "color-name": "1.1.3" } }, - "node_modules/globby": { - "version": "9.2.0", - "dev": true, + "node_modules/express-winston/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/express-winston/node_modules/escape-string-regexp": { + "version": "1.0.5", "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, "engines": { - "node": ">=6" + "node": ">=0.8.0" } }, - "node_modules/globby/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "dev": true, + "node_modules/express-winston/node_modules/has-flag": { + "version": "3.0.0", "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=4" } }, - "node_modules/globby/node_modules/braces": { - "version": "2.3.2", - "dev": true, + "node_modules/express-winston/node_modules/supports-color": { + "version": "5.5.0", "license": "MIT", "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/globby/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, + "node_modules/express/node_modules/accepts": { + "version": "2.0.0", "license": "MIT", "dependencies": { - "is-extendable": "^0.1.0" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/globby/node_modules/fast-glob": { - "version": "2.2.7", - "dev": true, + "node_modules/express/node_modules/content-disposition": { + "version": "1.0.0", "license": "MIT", "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" + "safe-buffer": "5.2.1" }, "engines": { - "node": ">=4.0.0" + "node": ">= 0.6" } }, - "node_modules/globby/node_modules/fill-range": { - "version": "4.0.0", - "dev": true, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/globby/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "dev": true, + "node_modules/express/node_modules/fresh": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "is-extendable": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/globby/node_modules/glob-parent": { - "version": "3.1.0", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "node_modules/express/node_modules/media-typer": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "node_modules/globby/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "dev": true, + "node_modules/express/node_modules/merge-descriptors": { + "version": "2.0.0", "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.0" + "engines": { + "node": ">=18" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/express/node_modules/negotiator": { + "version": "1.0.0", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/globby/node_modules/ignore": { - "version": "4.0.6", - "dev": true, + "node_modules/express/node_modules/type-is": { + "version": "2.0.1", "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, "engines": { - "node": ">= 4" + "node": ">= 0.6" } }, - "node_modules/globby/node_modules/is-extendable": { - "version": "0.1.1", + "node_modules/ext": { + "version": "1.7.0", + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", "dev": true, "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/globby/node_modules/is-number": { - "version": "3.0.0", + "node_modules/extglob": { + "version": "2.0.4", "dev": true, "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/globby/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "is-descriptor": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/globby/node_modules/micromatch": { - "version": "3.1.10", + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "is-extendable": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/globby/node_modules/slash": { - "version": "2.0.0", + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/globby/node_modules/to-regex-range": { - "version": "2.1.1", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", "dev": true, "license": "MIT", "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "@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": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/globrex": { - "version": "0.1.2", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", "dev": true, "license": "MIT" }, - "node_modules/gopd": { + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-builder": { "version": "1.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.7.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.7", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "license": "ISC" + "node_modules/fecha": { + "version": "4.2.3", + "license": "MIT" }, - "node_modules/handlebars": { - "version": "4.7.9", + "node_modules/file-entry-cache": { + "version": "8.0.0", "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" + "flat-cache": "^4.0.0" }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": ">=16.0.0" } }, - "node_modules/has-bigints": { - "version": "1.1.0", - "dev": true, + "node_modules/file-type": { + "version": "22.0.1", "license": "MIT", + "dependencies": { + "@tokenizer/inflate": "^0.4.1", + "strtok3": "^10.3.5", + "token-types": "^6.1.2", + "uint8array-extras": "^1.5.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=22" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/has-flag": { - "version": "4.0.0", + "node_modules/fill-range": { + "version": "7.1.1", "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, "engines": { "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", + "node_modules/finalhandler": { + "version": "2.1.0", "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "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" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 0.8" } }, - "node_modules/has-proto": { + "node_modules/find-package-json": { "version": "1.2.0", + "license": "MIT" + }, + "node_modules/find-up": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "license": "Apache-2.0", + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.1", + "license": "ISC" + }, + "node_modules/fn.name": { "version": "1.1.0", + "license": "MIT" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">=4.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "debug": { + "optional": true + } } }, - "node_modules/has-tostringtag": { - "version": "1.0.2", + "node_modules/for-each": { + "version": "0.3.5", + "dev": true, "license": "MIT", "dependencies": { - "has-symbols": "^1.0.3" + "is-callable": "^1.2.7" }, "engines": { "node": ">= 0.4" @@ -8097,302 +6086,259 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", + "node_modules/for-in": { + "version": "1.0.2", "dev": true, "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/has-values": { - "version": "1.0.0", + "node_modules/foreach": { + "version": "2.0.6", "dev": true, - "license": "MIT", + "license": "MIT" + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "dev": true, + "license": "ISC", "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.5", "license": "MIT", "dependencies": { - "kind-of": "^3.0.2" + "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": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "dev": true, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "dev": true, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", "license": "MIT", "dependencies": { - "is-buffer": "^1.1.5" + "mime-db": "1.52.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.6" } }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/formidable": { + "version": "1.2.6", "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" } }, - "node_modules/hasown": { - "version": "2.0.2", + "node_modules/forwarded": { + "version": "0.2.0", "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/html-entities": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.6.0.tgz", - "integrity": "sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/mdevils" - }, - { - "type": "patreon", - "url": "https://patreon.com/mdevils" - } - ], - "license": "MIT" - }, - "node_modules/html-escaper": { - "version": "2.0.2", + "node_modules/fragment-cache": { + "version": "0.2.1", "dev": true, - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.1", "license": "MIT", "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" + "map-cache": "^0.2.2" }, "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=0.10.0" } }, - "node_modules/http-errors/node_modules/depd": { - "version": "2.0.0", + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">= 0.6" } }, - "node_modules/http2-client": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", + "node_modules/from": { + "version": "0.1.7", "dev": true, "license": "MIT" }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", + "node_modules/fs-constants": { + "version": "1.0.0", + "license": "MIT", + "optional": true + }, + "node_modules/fs-extra": { + "version": "11.3.1", + "dev": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": ">= 14" + "node": ">=14.14" } }, - "node_modules/human-signals": { + "node_modules/fs-minipass": { "version": "2.1.0", "dev": true, - "license": "Apache-2.0", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, "engines": { - "node": ">=10.17.0" + "node": ">= 8" } }, - "node_modules/iconv-lite": { - "version": "0.7.0", - "license": "MIT", + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" + "node": ">=8" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "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/fs-minipass/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" }, - "node_modules/ignore": { - "version": "5.3.2", + "node_modules/fs.realpath": { + "version": "1.0.0", + "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": ">= 4" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.1", - "dev": true, + "node_modules/function-bind": { + "version": "1.1.2", "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-in-the-middle": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.0.2.tgz", - "integrity": "sha512-LGLYRl0A2gtyUJb2WDliBHmk6TtlHwdDjxonacZ8QrEs/ZW+YDgNv2QAfjRQWpS8HqvNcq6GGnN6jrOa5FysDQ==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^8.15.0", - "acorn-import-attributes": "^1.9.5", - "cjs-module-lexer": "^2.2.0", - "module-details-from-path": "^1.0.4" - }, - "engines": { - "node": ">=18" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/import-local": { - "version": "3.2.0", + "node_modules/function.prototype.name": { + "version": "1.1.8", "dev": true, "license": "MIT", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", + "node_modules/functions-have-names": { + "version": "1.2.3", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.8.19" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/inflight": { - "version": "1.0.6", + "node_modules/get-caller-file": { + "version": "2.0.5", "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/inherits": { - "version": "2.0.4", - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.1.0", - "dev": true, + "node_modules/get-intrinsic": { + "version": "1.3.0", "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", - "side-channel": "^1.1.0" + "math-intrinsics": "^1.1.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-accessor-descriptor": { + "node_modules/get-proto": { "version": "1.0.1", - "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 0.4" } }, - "node_modules/is-array-buffer": { - "version": "3.0.5", + "node_modules/get-symbol-description": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", "call-bound": "^1.0.3", + "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6" }, "engines": { @@ -8402,35 +6348,95 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", + "node_modules/get-tsconfig": { + "version": "4.14.0", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } }, - "node_modules/is-async-function": { - "version": "2.1.1", + "node_modules/get-value": { + "version": "2.0.6", "dev": true, "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "license": "ISC", "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" + "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/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "dev": true, + "license": "BSD" + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.5", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">= 0.4" + "node": "*" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-bigint": { - "version": "1.1.0", + "node_modules/globalthis": { + "version": "1.0.4", "dev": true, "license": "MIT", "dependencies": { - "has-bigints": "^1.0.2" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -8439,227 +6445,246 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-binary-path": { - "version": "2.1.0", + "node_modules/globby": { + "version": "9.2.0", "dev": true, "license": "MIT", "dependencies": { - "binary-extensions": "^2.0.0" + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/is-boolean-object": { - "version": "1.2.2", + "node_modules/globby/node_modules/@nodelib/fs.stat": { + "version": "1.1.3", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 6" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "dev": true, - "license": "MIT" - }, - "node_modules/is-callable": { - "version": "1.2.7", + "node_modules/globby/node_modules/braces": { + "version": "2.3.2", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-core-module": { - "version": "2.16.1", + "node_modules/globby/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "is-extendable": "^0.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", + "node_modules/globby/node_modules/fast-glob": { + "version": "2.2.7", "dev": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.0" + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" }, "engines": { - "node": ">= 0.4" + "node": ">=4.0.0" } }, - "node_modules/is-data-view": { - "version": "1.0.2", + "node_modules/globby/node_modules/fill-range": { + "version": "4.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-date-object": { - "version": "1.1.0", + "node_modules/globby/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" + "is-extendable": "^0.1.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-descriptor": { - "version": "1.0.3", + "node_modules/globby/node_modules/glob-parent": { + "version": "3.1.0", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" } }, - "node_modules/is-docker": { - "version": "2.2.1", + "node_modules/globby/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "dev": true, "license": "MIT", - "bin": { - "is-docker": "cli.js" + "dependencies": { + "is-extglob": "^2.1.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/is-extendable": { - "version": "1.0.1", + "node_modules/globby/node_modules/ignore": { + "version": "4.0.6", "dev": true, "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 4" } }, - "node_modules/is-extglob": { - "version": "2.1.1", + "node_modules/globby/node_modules/is-extendable": { + "version": "0.1.1", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", + "node_modules/globby/node_modules/is-number": { + "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "kind-of": "^3.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", + "node_modules/globby/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "dev": true, "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", + "node_modules/globby/node_modules/micromatch": { + "version": "3.1.10", "dev": true, "license": "MIT", + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/is-generator-function": { - "version": "1.1.0", + "node_modules/globby/node_modules/slash": { + "version": "2.0.0", "dev": true, "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/is-glob": { - "version": "4.0.3", + "node_modules/globby/node_modules/to-regex-range": { + "version": "2.1.1", "dev": true, "license": "MIT", "dependencies": { - "is-extglob": "^2.1.1" + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/is-invalid-path": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-invalid-path/-/is-invalid-path-1.0.2.tgz", - "integrity": "sha512-6KLcFrPCEP3AFXMfnWrIFkZpYNBVzZAoBJJDEZKtI3LXkaDjM3uFMJQjxiizUuZTZ9Oh9FNv/soXbx5TcpaDmA==", + "node_modules/globrex": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", "license": "MIT", "engines": { - "node": ">=6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-map": { - "version": "2.0.3", + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", "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" + "node": ">=0.4.7" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", + "node_modules/has-bigints": { + "version": "1.1.0", "dev": true, "license": "MIT", "engines": { @@ -8669,57 +6694,29 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-node-process": { - "version": "1.2.0", - "dev": true, - "license": "MIT" - }, - "node_modules/is-number": { - "version": "7.0.0", + "node_modules/has-flag": { + "version": "4.0.0", "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">=8" } }, - "node_modules/is-number-object": { - "version": "1.1.1", - "dev": true, + "node_modules/has-property-descriptors": { + "version": "1.0.2", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "license": "MIT" - }, - "node_modules/is-regex": { - "version": "1.2.1", + "node_modules/has-proto": { + "version": "1.2.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "dunder-proto": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -8728,9 +6725,8 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-set": { - "version": "2.0.3", - "dev": true, + "node_modules/has-symbols": { + "version": "1.1.0", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8739,12 +6735,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "dev": true, + "node_modules/has-tostringtag": { + "version": "1.0.2", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -8753,917 +6748,810 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-standalone-pwa": { - "version": "0.1.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/faisalman" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" - }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" - } - ], - "license": "MIT" - }, - "node_modules/is-stream": { - "version": "2.0.1", + "node_modules/has-value": { + "version": "1.0.0", + "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-string": { - "version": "1.1.1", + "node_modules/has-values": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-symbol": { - "version": "1.1.1", + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" + "kind-of": "^3.0.2" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.15", + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", "dev": true, "license": "MIT", "dependencies": { - "which-typed-array": "^1.1.16" + "is-buffer": "^1.1.5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, - "node_modules/is-weakmap": { - "version": "2.0.2", + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "is-buffer": "^1.1.5" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/is-weakref": { - "version": "1.1.1", - "dev": true, + "node_modules/hash.js": { + "version": "1.1.7", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-weakset": { - "version": "2.0.4", + "node_modules/html-entities": { + "version": "2.6.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/mdevils" + }, + { + "type": "patreon", + "url": "https://patreon.com/mdevils" + } + ], + "license": "MIT" + }, + "node_modules/html-escaper": { + "version": "2.0.2", "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/is-windows": { - "version": "1.0.2", - "dev": true, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/is-wsl": { - "version": "2.2.0", + "node_modules/http2-client": { + "version": "1.3.5", + "dev": true, + "license": "MIT" + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", "license": "MIT", "dependencies": { - "is-docker": "^2.0.0" + "agent-base": "^7.1.2", + "debug": "4" }, "engines": { - "node": ">=8" + "node": ">= 14" } }, - "node_modules/isarray": { - "version": "2.0.5", - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "dev": true, + "node_modules/iconv-lite": { + "version": "0.7.0", "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/istanbul-lib-coverage": { - "version": "3.2.2", + "node_modules/ieee754": { + "version": "1.2.1", + "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", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", + "node_modules/import-fresh": { + "version": "3.3.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "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" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" + "node": ">=6" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "dev": true, - "license": "BSD-3-Clause", + "node_modules/import-in-the-middle": { + "version": "3.0.2", + "license": "Apache-2.0", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" }, "engines": { - "node": ">=10" + "node": ">=18" } }, - "node_modules/istanbul-reports": { - "version": "3.2.0", + "node_modules/imurmurhash": { + "version": "0.1.4", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.8.19" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "dev": true, - "license": "BlueOak-1.0.0", + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/jest": { - "version": "30.3.0", + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/types": "30.3.0", - "import-local": "^3.2.0", - "jest-cli": "30.3.0" - }, - "bin": { - "jest": "bin/jest.js" + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.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": ">= 0.4" } }, - "node_modules/jest-changed-files": { - "version": "30.3.0", - "dev": true, + "node_modules/ipaddr.js": { + "version": "1.9.1", "license": "MIT", - "dependencies": { - "execa": "^5.1.1", - "jest-util": "30.3.0", - "p-limit": "^3.1.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.10" } }, - "node_modules/jest-circus": { - "version": "30.3.0", + "node_modules/is-accessor-descriptor": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/expect": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "co": "^4.6.0", - "dedent": "^1.6.0", - "is-generator-fn": "^2.1.0", - "jest-each": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-runtime": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.0", - "p-limit": "^3.1.0", - "pretty-format": "30.3.0", - "pure-rand": "^7.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" + "hasown": "^2.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.10" } }, - "node_modules/jest-cli": { - "version": "30.3.0", + "node_modules/is-array-buffer": { + "version": "3.0.5", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "exit-x": "^0.2.2", - "import-local": "^3.2.0", - "jest-config": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "yargs": "^17.7.2" - }, - "bin": { - "jest": "bin/jest.js" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" }, "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" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-cli/node_modules/cliui": { - "version": "8.0.1", + "node_modules/is-arrayish": { + "version": "0.2.1", "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } + "license": "MIT" }, - "node_modules/jest-cli/node_modules/yargs": { - "version": "17.7.2", + "node_modules/is-async-function": { + "version": "2.1.1", "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" + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": ">=12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config": { - "version": "30.3.0", + "node_modules/is-bigint": { + "version": "1.1.0", "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.3.0", - "@jest/types": "30.3.0", - "babel-jest": "30.3.0", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "deepmerge": "^4.3.1", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-circus": "30.3.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-runner": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "parse-json": "^5.2.0", - "pretty-format": "30.3.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" + "has-bigints": "^1.0.2" }, "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" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "esbuild-register": { - "optional": true - }, - "ts-node": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/glob": { - "version": "10.5.0", + "node_modules/is-binary-path": { + "version": "2.1.0", "dev": true, - "license": "ISC", + "license": "MIT", "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" + "binary-extensions": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=8" } }, - "node_modules/jest-config/node_modules/minimatch": { - "version": "9.0.9", + "node_modules/is-boolean-object": { + "version": "1.2.2", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.2" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/minipass": { - "version": "7.1.3", + "node_modules/is-buffer": { + "version": "1.1.6", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-diff": { - "version": "30.3.0", + "node_modules/is-core-module": { + "version": "2.16.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.3.0", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.3.0" + "hasown": "^2.0.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-docblock": { - "version": "30.2.0", + "node_modules/is-data-descriptor": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "detect-newline": "^3.1.0" + "hasown": "^2.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" } }, - "node_modules/jest-each": { - "version": "30.3.0", + "node_modules/is-data-view": { + "version": "1.0.2", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", - "chalk": "^4.1.2", - "jest-util": "30.3.0", - "pretty-format": "30.3.0" + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-environment-node": { - "version": "30.3.0", + "node_modules/is-date-object": { + "version": "1.1.0", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-mock": "30.3.0", - "jest-util": "30.3.0", - "jest-validate": "30.3.0" + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-haste-map": { - "version": "30.3.0", + "node_modules/is-descriptor": { + "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.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.3.0", - "jest-worker": "30.3.0", - "picomatch": "^4.0.3", - "walker": "^1.0.8" + "is-accessor-descriptor": "^1.0.1", + "is-data-descriptor": "^1.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" + "node": ">= 0.4" } }, - "node_modules/jest-haste-map/node_modules/picomatch": { - "version": "4.0.4", - "dev": true, + "node_modules/is-docker": { + "version": "2.2.1", "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, "engines": { - "node": ">=12" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-leak-detector": { - "version": "30.3.0", + "node_modules/is-extendable": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.3.0" + "is-plain-object": "^2.0.4" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-matcher-utils": { - "version": "30.3.0", + "node_modules/is-extglob": { + "version": "2.1.1", "dev": true, "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.3.0", - "pretty-format": "30.3.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-message-util": { - "version": "30.3.0", + "node_modules/is-finalizationregistry": { + "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.3.0", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3", - "pretty-format": "30.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" + "call-bound": "^1.0.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-message-util/node_modules/picomatch": { - "version": "4.0.4", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-mock": { - "version": "30.3.0", + "node_modules/is-glob": { + "version": "4.0.3", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "jest-util": "30.3.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-mock-extended": { - "version": "4.0.0", + "node_modules/is-invalid-path": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", "dev": true, "license": "MIT", - "dependencies": { - "ts-essentials": "^10.0.2" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "@jest/globals": "^28.0.0 || ^29.0.0 || ^30.0.0", - "jest": "^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 || ^30.0.0", - "typescript": "^3.0.0 || ^4.0.0 || ^5.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", + "node_modules/is-negative-zero": { + "version": "2.0.3", "dev": true, "license": "MIT", "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-regex-util": { - "version": "30.0.1", + "node_modules/is-node-process": { + "version": "1.2.0", "dev": true, + "license": "MIT" + }, + "node_modules/is-number": { + "version": "7.0.0", "license": "MIT", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.12.0" } }, - "node_modules/jest-resolve": { - "version": "30.3.0", + "node_modules/is-number-object": { + "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.3.0", - "jest-validate": "30.3.0", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-resolve-dependencies": { - "version": "30.3.0", + "node_modules/is-plain-object": { + "version": "2.0.4", "dev": true, "license": "MIT", "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.3.0" + "isobject": "^3.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-runner": { - "version": "30.3.0", + "node_modules/is-promise": { + "version": "2.2.2", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.3.0", - "@jest/environment": "30.3.0", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.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.3.0", - "jest-haste-map": "30.3.0", - "jest-leak-detector": "30.3.0", - "jest-message-util": "30.3.0", - "jest-resolve": "30.3.0", - "jest-runtime": "30.3.0", - "jest-util": "30.3.0", - "jest-watcher": "30.3.0", - "jest-worker": "30.3.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-runtime": { - "version": "30.3.0", + "node_modules/is-set": { + "version": "2.0.3", "dev": true, "license": "MIT", - "dependencies": { - "@jest/environment": "30.3.0", - "@jest/fake-timers": "30.3.0", - "@jest/globals": "30.3.0", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.5.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.3.0", - "jest-message-util": "30.3.0", - "jest-mock": "30.3.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.3.0", - "jest-snapshot": "30.3.0", - "jest-util": "30.3.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": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "10.5.0", + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", "dev": true, - "license": "ISC", + "license": "MIT", "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" + "call-bound": "^1.0.3" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-runtime/node_modules/minimatch": { - "version": "9.0.9", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, + "node_modules/is-standalone-pwa": { + "version": "0.1.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + } + ], + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-runtime/node_modules/minipass": { - "version": "7.1.3", + "node_modules/is-string": { + "version": "1.1.1", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-snapshot": { - "version": "30.3.0", + "node_modules/is-symbol": { + "version": "1.1.1", "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.3.0", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.3.0", - "@jest/transform": "30.3.0", - "@jest/types": "30.3.0", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.3.0", - "graceful-fs": "^4.2.11", - "jest-diff": "30.3.0", - "jest-matcher-utils": "30.3.0", - "jest-message-util": "30.3.0", - "jest-util": "30.3.0", - "pretty-format": "30.3.0", - "semver": "^7.7.2", - "synckit": "^0.11.8" + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-util": { - "version": "30.3.0", + "node_modules/is-typed-array": { + "version": "1.1.15", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.3.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.3" + "which-typed-array": "^1.1.16" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.3", + "node_modules/is-weakmap": { + "version": "2.0.2", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-validate": { - "version": "30.3.0", + "node_modules/is-weakref": { + "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.3.0", - "camelcase": "^6.3.0", - "chalk": "^4.1.2", - "leven": "^3.1.0", - "pretty-format": "30.3.0" + "call-bound": "^1.0.3" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", + "node_modules/is-weakset": { + "version": "2.0.4", "dev": true, "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-watcher": { - "version": "30.3.0", + "node_modules/is-windows": { + "version": "1.0.2", "dev": true, "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "license": "MIT", "dependencies": { - "@jest/test-result": "30.3.0", - "@jest/types": "30.3.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "jest-util": "30.3.0", - "string-length": "^4.0.2" + "is-docker": "^2.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=8" } }, - "node_modules/jest-when": { - "version": "3.7.0", + "node_modules/isarray": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", "dev": true, "license": "MIT", - "peerDependencies": { - "jest": ">= 25" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/jest-worker": { - "version": "30.3.0", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.3.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=10" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", + "node_modules/istanbul-reports": { + "version": "3.2.0", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "has-flag": "^4.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" }, "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/joi": { @@ -9684,8 +7572,6 @@ }, "node_modules/js-levenshtein": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", "dev": true, "license": "MIT", "engines": { @@ -9699,8 +7585,6 @@ }, "node_modules/js-yaml": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.2.0.tgz", - "integrity": "sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==", "dev": true, "funding": [ { @@ -9720,17 +7604,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/json-bigint": { "version": "1.0.0", "license": "MIT", @@ -9754,8 +7627,6 @@ }, "node_modules/json-pointer": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", - "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", "dev": true, "license": "MIT", "dependencies": { @@ -9764,8 +7635,6 @@ }, "node_modules/json-schema-to-ts": { "version": "2.7.2", - "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-2.7.2.tgz", - "integrity": "sha512-R1JfqKqbBR4qE8UyBR56Ms30LL62/nlhoz+1UkfI/VE7p54Awu919FZ6ZUPG8zIa3XB65usPJgr1ONVncUGSaQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9792,114 +7661,372 @@ "object-keys": "^1.1.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonify": { + "version": "0.0.1", + "license": "Public Domain", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jsonpath-rfc9535": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=20" + } + }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "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.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "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.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" + "node": ">= 12.0.0" }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonify": { - "version": "0.0.1", - "license": "Public Domain", "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/jsonpath-rfc9535": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsonpath-rfc9535/-/jsonpath-rfc9535-1.3.0.tgz", - "integrity": "sha512-3jFHya7oZ45aDxIIdx+/zQARahHXxFSMWBkcBUldfXpLS9VCXDJyTKt35kQfEXLqh0K3Ixw/9xFnvcDStaxh7Q==", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=20" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/keyv": { - "version": "4.5.4", + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/kind-of": { - "version": "6.0.3", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/klaw-sync": { - "version": "6.0.0", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/kuler": { - "version": "2.0.0", - "license": "MIT" - }, - "node_modules/leven": { - "version": "3.1.0", + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/levn": { - "version": "0.4.1", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.8.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, "node_modules/lines-and-columns": { @@ -9929,11 +8056,6 @@ "version": "4.3.0", "license": "MIT" }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "dev": true, @@ -9941,8 +8063,6 @@ }, "node_modules/log4js": { "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", "license": "Apache-2.0", "dependencies": { "date-format": "^4.0.14", @@ -9976,8 +8096,6 @@ }, "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==", "dev": true, "license": "MIT", "dependencies": { @@ -9987,14 +8105,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "5.1.1", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, "node_modules/lru-queue": { "version": "0.1.0", "license": "MIT", @@ -10004,20 +8114,28 @@ }, "node_modules/lunr": { "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "dev": true, "license": "MIT" }, "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/magicast": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.3.tgz", + "integrity": "sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.3", + "@babel/types": "^7.29.0", + "source-map-js": "^1.2.1" + } + }, "node_modules/make-dir": { "version": "4.0.0", "dev": true, @@ -10032,19 +8150,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/map-cache": { "version": "0.2.2", "dev": true, @@ -10070,15 +8175,11 @@ }, "node_modules/mark.js": { "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", "dev": true, "license": "MIT" }, "node_modules/marked": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "dev": true, "license": "MIT", "bin": { @@ -10128,11 +8229,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "dev": true, @@ -10143,8 +8239,6 @@ }, "node_modules/meriyah": { "version": "6.1.4", - "resolved": "https://registry.npmjs.org/meriyah/-/meriyah-6.1.4.tgz", - "integrity": "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==", "license": "ISC", "engines": { "node": ">=18.0.0" @@ -10199,18 +8293,8 @@ "url": "https://opencollective.com/express" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC" }, "node_modules/minimatch": { @@ -10325,15 +8409,11 @@ }, "node_modules/mkdirp-classic": { "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", "license": "MIT", "optional": true }, "node_modules/mobx": { "version": "6.16.1", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.16.1.tgz", - "integrity": "sha512-syNcDdX3KT+Jq3je6eGjBhuc24Z68td2VG0zNFqRswaE433D9SNH5VRy/xrGbJsUixfppLLccXhAW9JSf6n+SQ==", "dev": true, "license": "MIT", "funding": { @@ -10343,8 +8423,6 @@ }, "node_modules/mobx-react": { "version": "9.2.0", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.2.0.tgz", - "integrity": "sha512-dkGWCx+S0/1mfiuFfHRH8D9cplmwhxOV5CkXMp38u6rQGG2Pv3FWYztS0M7ncR6TyPRQKaTG/pnitInoYE9Vrw==", "dev": true, "license": "MIT", "dependencies": { @@ -10369,8 +8447,6 @@ }, "node_modules/mobx-react-lite": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.1.1.tgz", - "integrity": "sha512-iUxiMpsvNraCKXU+yPotsOncNNmyeS2B5DKL+TL6Tar/xm+wwNJAubJmtRSeAoYawdZqwv8Z/+5nPRHeQxTiXg==", "dev": true, "license": "MIT", "dependencies": { @@ -10403,11 +8479,28 @@ }, "node_modules/nan": { "version": "2.27.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.27.0.tgz", - "integrity": "sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==", "license": "MIT", "optional": true }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "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/nanomatch": { "version": "1.2.13", "dev": true, @@ -10429,20 +8522,6 @@ "node": ">=0.10.0" } }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "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", "dev": true, @@ -10463,8 +8542,6 @@ }, "node_modules/newrelic": { "version": "14.1.0", - "resolved": "https://registry.npmjs.org/newrelic/-/newrelic-14.1.0.tgz", - "integrity": "sha512-PEysakyHV3CNR7LyHBp4V2Ob44CminUEMcvak74dKpAuw9s562qGBeQjpo/u4LYXMpUwSAd/QoUVFtikCaZClw==", "license": "Apache-2.0", "dependencies": { "@apm-js-collab/tracing-hooks": "^0.9.1", @@ -10508,8 +8585,6 @@ }, "node_modules/newrelic/node_modules/@grpc/proto-loader": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", - "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", @@ -10526,8 +8601,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/api-logs": { "version": "0.217.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.217.0.tgz", - "integrity": "sha512-Cdq0jW2lknrNfrAm92MyEAvpe2cRsKjdnQLHUL6xRA4IVUnsWx6P65E7NcUO0Y+L4w1Aee5iV8FvjSwd+lrs9A==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -10538,8 +8611,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/core": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.7.1.tgz", - "integrity": "sha512-QAqIj32AtK6+pEVNG7EOVxHdE06RP+FM5qpiEJ4RtDcFIqKUZHYhl7/7UY5efhwmwNAg7j8QbJVBLxMerc0+gw==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" @@ -10553,8 +8624,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/otlp-exporter-base": { "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.218.0.tgz", - "integrity": "sha512-ZwqpkNL5W7RyGJPDZ9g06DvKp8KFTWPJPN12anpMQYSKpTSU0z3EIZuPq9vPGpS8siFyOqDYDAuCwlNO9FqgbA==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.7.1", @@ -10569,8 +8638,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/otlp-transformer": { "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.218.0.tgz", - "integrity": "sha512-CFaKH87WAzjuJ4awowTTLzUvMfaRfiOFG5+qm5S5ncyalRtN4ecQ+YmuANJSCrVPuvZFEkUgKhBPBndxi3rHsQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.218.0", @@ -10589,8 +8656,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-logs": { "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.218.0.tgz", - "integrity": "sha512-fmEWp5kXlGEc3i/lR698Hz41DfGyN4Tbe4g7L1AxSc7fF8Xeh/FQ9Quqpa9dVA413Q1Ad43QOLzU4JoXgbFPWw==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api": "^1.3.0" @@ -10601,8 +8666,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/sdk-logs": { "version": "0.218.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.218.0.tgz", - "integrity": "sha512-QvnNdugatFTVCJXH0Mcu7GOOJSylA9j127kIezOE4YwTI4YbowRons2K4WZTv5FMS8T4q9P0NdaRHdkSmeAIag==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.218.0", @@ -10619,8 +8682,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/resources": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.7.1.tgz", - "integrity": "sha512-DeT6KKolmC4e/dRQvMQ/RwlnzhaqeiFOXY5ngoOPJ07GgVVKxZOg9EcrNZb5aTzUn+iCrJldAgOfQm1O/QfPAQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.7.1", @@ -10635,8 +8696,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/sdk-logs": { "version": "0.217.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.217.0.tgz", - "integrity": "sha512-BB+PcHItcZDL63dPMW+mJvwN9rk37wuIDjRxbVlg6pPDvDR/7GL7UJHbGsllgoggOoTimsKgENaWPoGch/oE1A==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/api-logs": "0.217.0", @@ -10653,8 +8712,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/sdk-metrics": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.7.1.tgz", - "integrity": "sha512-MpDJdkiFDs3Pm1RHO3KByuZbuBdJEXEAkiC0+yJdsZGVCdf1RpHR6n+LHDcS7ffmfrt5kVCzJSCfm4z2C7v0uQ==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.7.1", @@ -10669,8 +8726,6 @@ }, "node_modules/newrelic/node_modules/@opentelemetry/sdk-trace-base": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.7.1.tgz", - "integrity": "sha512-NAYIlsF8MPUsKqJMiDQJTMPOmlbawC1Iz/omMLygZ1C9am8fTKYjTaI+OZM+WTY3t3Glo0wnOg/6/pac6RGPPw==", "license": "Apache-2.0", "dependencies": { "@opentelemetry/core": "2.7.1", @@ -10686,8 +8741,6 @@ }, "node_modules/newrelic/node_modules/agent-base": { "version": "9.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-9.0.0.tgz", - "integrity": "sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==", "license": "MIT", "engines": { "node": ">= 20" @@ -10695,8 +8748,6 @@ }, "node_modules/newrelic/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==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -10709,8 +8760,6 @@ }, "node_modules/newrelic/node_modules/https-proxy-agent": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-9.1.0.tgz", - "integrity": "sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==", "license": "MIT", "dependencies": { "agent-base": "9.0.0", @@ -10723,8 +8772,6 @@ }, "node_modules/newrelic/node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -10758,8 +8805,6 @@ }, "node_modules/node-abi": { "version": "3.92.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.92.0.tgz", - "integrity": "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==", "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -10775,8 +8820,6 @@ }, "node_modules/node-cron": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-4.2.1.tgz", - "integrity": "sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==", "license": "ISC", "engines": { "node": ">=6.0.0" @@ -10802,8 +8845,6 @@ }, "node_modules/node-fetch-h2": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", - "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", "dev": true, "license": "MIT", "dependencies": { @@ -10815,8 +8856,6 @@ }, "node_modules/node-gyp-build": { "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "license": "MIT", "optional": true, "bin": { @@ -10825,11 +8864,6 @@ "node-gyp-build-test": "build-test.js" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "dev": true, - "license": "MIT" - }, "node_modules/node-mocks-http": { "version": "1.17.2", "dev": true, @@ -10864,19 +8898,12 @@ }, "node_modules/node-readfiles": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", - "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", "dev": true, "license": "MIT", "dependencies": { "es6-promise": "^3.2.1" } }, - "node_modules/node-releases": { - "version": "2.0.19", - "dev": true, - "license": "MIT" - }, "node_modules/normalize-path": { "version": "3.0.0", "dev": true, @@ -10885,21 +8912,8 @@ "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/oas-kit-common": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", - "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10908,8 +8922,6 @@ }, "node_modules/oas-linter": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", - "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10923,8 +8935,6 @@ }, "node_modules/oas-resolver": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10943,8 +8953,6 @@ }, "node_modules/oas-schema-walker": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", - "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", "dev": true, "license": "BSD-3-Clause", "funding": { @@ -10953,8 +8961,6 @@ }, "node_modules/oas-validator": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -11130,6 +9136,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/on-finished": { "version": "2.4.1", "license": "MIT", @@ -11147,25 +9167,11 @@ "wrappy": "1" } }, - "node_modules/one-time": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "fn.name": "1.x.x" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "dev": true, + "node_modules/one-time": { + "version": "1.0.0", "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "fn.name": "1.x.x" } }, "node_modules/open": { @@ -11184,8 +9190,6 @@ }, "node_modules/openapi-sampler": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.7.4.tgz", - "integrity": "sha512-CKS/rd5ucPCuEDbJnjGDXZTsuGWcmv53aCmQx7soZlPEONUGN4af0/dY5+THRFZraSEjeA78nlfzdFswC/N5SA==", "dev": true, "license": "MIT", "dependencies": { @@ -11212,8 +9216,6 @@ }, "node_modules/outdent": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.8.0.tgz", - "integrity": "sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==", "dev": true, "license": "MIT" }, @@ -11266,14 +9268,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.1", "dev": true, @@ -11396,8 +9390,6 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "dev": true, "license": "MIT" }, @@ -11492,6 +9484,13 @@ "node": ">=4" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/pause-stream": { "version": "0.0.11", "dev": true, @@ -11505,8 +9504,6 @@ }, "node_modules/perfect-scrollbar": { "version": "1.5.6", - "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.6.tgz", - "integrity": "sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==", "dev": true, "license": "MIT" }, @@ -11606,77 +9603,8 @@ "node": ">=6" } }, - "node_modules/pirates": { - "version": "4.0.7", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "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", - "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", - "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", - "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", - "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": { @@ -11685,8 +9613,6 @@ }, "node_modules/polished": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", "dev": true, "license": "MIT", "dependencies": { @@ -11712,10 +9638,37 @@ "node": ">= 0.4" } }, + "node_modules/postcss": { + "version": "8.5.19", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.19.tgz", + "integrity": "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==", + "dev": true, + "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.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true, "license": "MIT" }, @@ -11752,15 +9705,11 @@ }, "node_modules/pprof-format": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/pprof-format/-/pprof-format-2.2.2.tgz", - "integrity": "sha512-hd90rHVDhNOhgHTmazVzDSVwTLOBjpZQ26AO/0j46sAFZ9uSWY0DcK2zJcwnuo2R6EzufBbOoWlPazA5nSyHcg==", "license": "MIT", "optional": true }, "node_modules/prebuildify": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/prebuildify/-/prebuildify-6.0.1.tgz", - "integrity": "sha512-8Y2oOOateom/s8dNBsGIcnm6AxPmLH4/nanQzL5lQMU+sC0CMhzARZHizwr36pUPLdvBnOkCNQzxg4djuFSgIw==", "license": "MIT", "optional": true, "dependencies": { @@ -11777,8 +9726,6 @@ }, "node_modules/prebuildify/node_modules/npm-run-path": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", - "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", "license": "MIT", "optional": true, "dependencies": { @@ -11836,8 +9783,6 @@ }, "node_modules/prismjs": { "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "dev": true, "license": "MIT", "engines": { @@ -11850,8 +9795,6 @@ }, "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==", "dev": true, "license": "MIT", "dependencies": { @@ -11862,8 +9805,6 @@ }, "node_modules/prop-types/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==", "dev": true, "license": "MIT" }, @@ -11910,8 +9851,6 @@ }, "node_modules/proxy-agent-negotiate": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-agent-negotiate/-/proxy-agent-negotiate-1.1.0.tgz", - "integrity": "sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==", "license": "MIT", "engines": { "node": ">= 20" @@ -11948,8 +9887,6 @@ }, "node_modules/pump": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "license": "MIT", "optional": true, "dependencies": { @@ -11965,21 +9902,6 @@ "node": ">=6" } }, - "node_modules/pure-rand": { - "version": "7.0.1", - "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.15.2", "license": "BSD-3-Clause", @@ -12042,8 +9964,6 @@ }, "node_modules/react": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", - "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", "dev": true, "license": "MIT", "engines": { @@ -12052,8 +9972,6 @@ }, "node_modules/react-dom": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", - "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12070,8 +9988,6 @@ }, "node_modules/react-tabs": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.1.1.tgz", - "integrity": "sha512-CPiuKoMFf89B7QlbFfdBD9XmUWiE3qudQputMVZB8GQvPJZRX/gqjDaDWOPDwGinEfpJKEuBCkGt83Tt4efeyA==", "dev": true, "license": "MIT", "dependencies": { @@ -12107,8 +10023,6 @@ }, "node_modules/redoc": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.5.3.tgz", - "integrity": "sha512-bBbat+Sx6xKWdyoCGTtA0BWeTEW9Vs4VnEja7q7ZLOk4IM7cHQLrf+kDxWF6dKeKxT8kOBnoy/OsNXCeLttpyQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12148,8 +10062,6 @@ }, "node_modules/redoc/node_modules/@redocly/ajv": { "version": "8.11.2", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", - "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==", "dev": true, "license": "MIT", "dependencies": { @@ -12165,15 +10077,11 @@ }, "node_modules/redoc/node_modules/@redocly/config": { "version": "0.22.0", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.22.0.tgz", - "integrity": "sha512-gAy93Ddo01Z3bHuVdPWfCwzgfaYgMdaZPcfL7JZ7hWJoK9V0lXDbigTWkhiPFAaLWzbOJ+kbUQG1+XwIm0KRGQ==", "dev": true, "license": "MIT" }, "node_modules/redoc/node_modules/@redocly/openapi-core": { "version": "1.34.15", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.34.15.tgz", - "integrity": "sha512-HAwCnNyKcs5XGQqms+9t7OdAPM/5TDstmhF+0i7tdCFato2QKuYIlyWETwkXd8c5zbltr1oB+6y9NTeQLr2d6Q==", "dev": true, "license": "MIT", "dependencies": { @@ -12194,8 +10102,6 @@ }, "node_modules/redoc/node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -12207,8 +10113,6 @@ }, "node_modules/redoc/node_modules/minimatch": { "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "license": "ISC", "dependencies": { @@ -12241,8 +10145,6 @@ }, "node_modules/reftools": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", - "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", "dev": true, "license": "BSD-3-Clause", "funding": { @@ -12298,8 +10200,6 @@ }, "node_modules/request-ip": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/request-ip/-/request-ip-3.3.0.tgz", - "integrity": "sha512-cA6Xh6e0fDBBBwH77SLJaJPBmD3nWVAcF9/XAcsrIHdjhFzFiB5aNQFytdjCGPezU3ROwrR11IddKAM08vohxA==", "license": "MIT" }, "node_modules/require-directory": { @@ -12322,8 +10222,6 @@ }, "node_modules/require-in-the-middle": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", - "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", "license": "MIT", "dependencies": { "debug": "^4.3.5", @@ -12352,25 +10250,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "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", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "dev": true, @@ -12411,8 +10290,6 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "license": "MIT" }, "node_modules/rimraf": { @@ -12472,10 +10349,42 @@ }, "node_modules/ringbufferjs": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ringbufferjs/-/ringbufferjs-2.0.0.tgz", - "integrity": "sha512-GCOqTzUsTHF7nrqcgtNGAFotXztLgiePpIDpyWZ7R5I02tmfJWV+/yuJc//Hlsd8G+WzI1t/dc2y/w2imDZdog==", "license": "MIT" }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, "node_modules/router": { "version": "2.2.0", "license": "MIT", @@ -12611,15 +10520,11 @@ }, "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==", "dev": true, "license": "MIT" }, "node_modules/semifies": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz", - "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==", "license": "Apache-2.0" }, "node_modules/semver": { @@ -12775,8 +10680,6 @@ }, "node_modules/should": { "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12789,8 +10692,6 @@ }, "node_modules/should-equal": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", "dev": true, "license": "MIT", "dependencies": { @@ -12799,8 +10700,6 @@ }, "node_modules/should-format": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, "license": "MIT", "dependencies": { @@ -12810,15 +10709,11 @@ }, "node_modules/should-type": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true, "license": "MIT" }, "node_modules/should-type-adaptors": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "dev": true, "license": "MIT", "dependencies": { @@ -12828,8 +10723,6 @@ }, "node_modules/should-util": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", "dev": true, "license": "MIT" }, @@ -12897,8 +10790,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/signal-exit": { - "version": "3.0.7", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, @@ -12938,8 +10833,6 @@ }, "node_modules/slugify": { "version": "1.4.7", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", - "integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg==", "dev": true, "license": "MIT", "engines": { @@ -13080,6 +10973,16 @@ "node": ">=0.10.0" } }, + "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==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-resolve": { "version": "0.5.3", "dev": true, @@ -13092,15 +10995,6 @@ "urix": "^0.1.0" } }, - "node_modules/source-map-support": { - "version": "0.5.13", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, "node_modules/source-map-url": { "version": "0.4.1", "dev": true, @@ -13135,11 +11029,6 @@ "node": ">= 10.x" } }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/stack-trace": { "version": "0.0.10", "license": "MIT", @@ -13147,24 +11036,12 @@ "node": "*" } }, - "node_modules/stack-utils": { - "version": "2.0.6", - "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", + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } + "license": "MIT" }, "node_modules/static-extend": { "version": "0.1.2", @@ -13208,10 +11085,15 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, "node_modules/stickyfill": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz", - "integrity": "sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==", "dev": true }, "node_modules/stop-iteration-iterator": { @@ -13236,8 +11118,6 @@ }, "node_modules/streamroller": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", "license": "MIT", "dependencies": { "date-format": "^4.0.14", @@ -13250,8 +11130,6 @@ }, "node_modules/streamroller/node_modules/fs-extra": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -13264,8 +11142,6 @@ }, "node_modules/streamroller/node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -13273,8 +11149,6 @@ }, "node_modules/streamroller/node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "license": "MIT", "engines": { "node": ">= 4.0.0" @@ -13300,18 +11174,6 @@ "node": ">=0.6.19" } }, - "node_modules/string-length": { - "version": "4.0.2", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/string-width": { "version": "4.2.3", "license": "MIT", @@ -13339,9 +11201,7 @@ } }, "node_modules/string.fromcodepoint": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string.fromcodepoint/-/string.fromcodepoint-0.2.1.tgz", - "integrity": "sha512-n69H31OnxSGSZyZbgBlvYIXlrMhJQ0dQAX1js1QDhpaUH6zmU3QYlj07bCwCNlPOu3oRXIubGPl2gDGnHsiCqg==" + "version": "0.2.1" }, "node_modules/string.prototype.trim": { "version": "1.2.10", @@ -13418,22 +11278,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "dev": true, @@ -13486,8 +11330,6 @@ }, "node_modules/styled-components": { "version": "6.4.2", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.4.2.tgz", - "integrity": "sha512-xZBhBJsMtGqb+aKcwKgaT+BtuFums9VynX2JRvXJGTx5UfZzN12rk5r4nVdhXYvRw+hE7yiYxVrOqJZaK2+Txg==", "dev": true, "license": "MIT", "dependencies": { @@ -13523,8 +11365,6 @@ }, "node_modules/stylis": { "version": "4.3.6", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", - "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", "dev": true, "license": "MIT" }, @@ -13699,8 +11539,6 @@ }, "node_modules/swagger2openapi": { "version": "7.0.8", - "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", - "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -13725,20 +11563,6 @@ "url": "https://github.com/Mermade/oas-kit?sponsor=1" } }, - "node_modules/synckit": { - "version": "0.11.11", - "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.3", "dev": true, @@ -13769,8 +11593,6 @@ }, "node_modules/tar-fs": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", - "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "license": "MIT", "optional": true, "dependencies": { @@ -13782,15 +11604,11 @@ }, "node_modules/tar-fs/node_modules/chownr": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "license": "ISC", "optional": true }, "node_modules/tar-stream": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", "license": "MIT", "optional": true, "dependencies": { @@ -13809,39 +11627,6 @@ "dev": true, "license": "ISC" }, - "node_modules/test-exclude": { - "version": "6.0.0", - "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/brace-expansion": { - "version": "1.1.13", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/test-exclude/node_modules/minimatch": { - "version": "3.1.5", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/text-hex": { "version": "1.0.0", "license": "MIT" @@ -13862,13 +11647,32 @@ "node": ">=0.12" } }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/tinyglobby": { - "version": "0.2.15", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -13894,7 +11698,9 @@ } }, "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -13936,6 +11742,16 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.2.7", "license": "MIT", @@ -13943,11 +11759,6 @@ "node": ">=14.14" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "dev": true, - "license": "BSD-3-Clause" - }, "node_modules/to-object-path": { "version": "0.3.0", "dev": true, @@ -14030,8 +11841,6 @@ }, "node_modules/ts-algebra": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-1.2.2.tgz", - "integrity": "sha512-kloPhf1hq3JbCPOTYoOWDKxebWjNb2o/LKnNfkWhxVVisFFmMJPPdJeGoGmM+iRLyoXAR61e08Pb+vUXINg8aA==", "dev": true, "license": "MIT" }, @@ -14059,68 +11868,6 @@ } } }, - "node_modules/ts-jest": { - "version": "29.4.6", - "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", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ts-md5": { "version": "1.3.1", "license": "MIT", @@ -14207,25 +11954,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "1.6.18", "dev": true, @@ -14412,8 +12140,6 @@ }, "node_modules/typescript-eslint": { "version": "8.62.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.62.0.tgz", - "integrity": "sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -14542,8 +12268,6 @@ }, "node_modules/unescape": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unescape/-/unescape-1.0.1.tgz", - "integrity": "sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==", "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1" @@ -14554,8 +12278,6 @@ }, "node_modules/unescape-js": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unescape-js/-/unescape-js-1.1.4.tgz", - "integrity": "sha512-42SD8NOQEhdYntEiUQdYq/1V/YHwr1HLwlHuTJB5InVVdOSbgI6xu8jK5q65yIzuFCfczzyDF/7hbGzVbyCw0g==", "license": "MIT", "dependencies": { "string.fromcodepoint": "^0.2.1" @@ -14563,8 +12285,6 @@ }, "node_modules/unescape/node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" @@ -14575,8 +12295,6 @@ }, "node_modules/unescape/node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14618,39 +12336,6 @@ "node": ">= 0.8" } }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "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/unset-value": { "version": "1.0.0", "dev": true, @@ -14700,35 +12385,6 @@ "dev": true, "license": "MIT" }, - "node_modules/update-browserslist-db": { - "version": "1.1.3", - "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", "dev": true, @@ -14739,8 +12395,6 @@ }, "node_modules/uri-js-replace": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", - "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", "dev": true, "license": "MIT" }, @@ -14751,8 +12405,6 @@ }, "node_modules/url-template": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", "dev": true, "license": "BSD" }, @@ -14766,8 +12418,6 @@ }, "node_modules/use-sync-external-store": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "dev": true, "license": "MIT", "peerDependencies": { @@ -14780,8 +12430,6 @@ }, "node_modules/uuid": { "version": "11.1.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", - "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -14791,32 +12439,252 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", + "node_modules/vary": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" }, "engines": { - "node": ">=10.12.0" + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } } }, - "node_modules/vary": { - "version": "1.1.2", + "node_modules/vitest-mock-extended": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vitest-mock-extended/-/vitest-mock-extended-4.0.0.tgz", + "integrity": "sha512-m2FmH8JYfxzZoLsHuhXRY+Pv++a3zd91HYpSz81tpRLEHbtFkEL2QcWvJowucWuNTirzQURKfWbJJSXbYqkTsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ts-essentials": ">=10.0.0" + }, + "peerDependencies": { + "typescript": "3.x || 4.x || 5.x || 6.x", + "vitest": ">=4.0.0" + } + }, + "node_modules/vitest-when": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/vitest-when/-/vitest-when-0.10.0.tgz", + "integrity": "sha512-tZiZ3+HR3X+pN1h4484an6/kuPezs/0b7frOikEnHfsPbOLGoiC+8NHRP/CRTAnG9Ccevq5/oGfCNRm/sp2EAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pretty-format": "^30.2.0" + }, + "peerDependencies": { + "@vitest/expect": ">=0.31.0 <5", + "vitest": ">=0.31.0 <5" + }, + "peerDependenciesMeta": { + "@vitest/expect": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/walker": { - "version": "1.0.8", + "node_modules/vitest/node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "makeerror": "1.0.12" + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "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", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.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 + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "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/webidl-conversions": { @@ -14925,6 +12793,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/winston": { "version": "3.19.0", "license": "MIT", @@ -15006,29 +12891,6 @@ "version": "1.0.2", "license": "ISC" }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "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/write-file-atomic/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/ws": { "version": "7.5.10", "dev": true, @@ -15076,15 +12938,8 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "3.1.1", - "dev": true, - "license": "ISC" - }, "node_modules/yaml": { "version": "1.10.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", - "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", "dev": true, "license": "ISC", "engines": { @@ -15093,15 +12948,11 @@ }, "node_modules/yaml-ast-parser": { "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", "dev": true, "license": "Apache-2.0" }, "node_modules/yargs": { "version": "17.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.0.1.tgz", - "integrity": "sha512-xBBulfCc8Y6gLFcrPvtqKz9hz8SO0l1Ni8GgDekvBX2ro0HRQImDGnikfc33cgzcYUSncapnNcZDjVFIH3f6KQ==", "dev": true, "license": "MIT", "dependencies": { @@ -15126,8 +12977,6 @@ }, "node_modules/yargs/node_modules/yargs-parser": { "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "license": "ISC", "engines": { @@ -15227,12 +13076,12 @@ }, "devDependencies": { "@types/http-errors": "^2.0.1", - "@types/jest-when": "^3.5.5", "@types/memoizee": "^0.4.12", "@types/newrelic": "^9.14.4", - "jest-when": "^3.7.0", + "@vitest/expect": "^4.1.10", "nock": "^14.0.10", - "supertest": "^7.1.0" + "supertest": "^7.1.0", + "vitest-when": "^0.10.0" }, "engines": { "node": ">=24.0" diff --git a/package.json b/package.json index 78fe4fd0..b3925a72 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,6 @@ "@types/cors": "^2.8.17", "@types/express": "^5.0.3", "@types/http-errors": "^2.0.1", - "@types/jest": "30.0.0", - "@types/jest-when": "^3.5.5", "@types/mailchimp__mailchimp_transactional": "1.0.11", "@types/node": "^24.10.1", "@types/pg": "^8.20.0", @@ -62,17 +60,16 @@ "eslint": "^9.39.4", "eslint-config-love": "^154.0.0", "eslint-config-prettier": "^10.1.8", - "eslint-plugin-jest": "^29.15.2", - "jest": "30.3.0", - "jest-mock-extended": "^4.0.0", - "jest-when": "^3.7.0", + "@vitest/eslint-plugin": "^1.6.21", "node-mocks-http": "^1.17.2", "prettier": "^3.7.4", - "ts-jest": "29.4.6", "tsc-watch": "^7.2.0", + "vitest": "^4.1.10", + "@vitest/coverage-v8": "^4.1.10", "tslint-tinypg": "^2.0.2", "typescript": "^5.9.3", "typescript-cp": "^0.1.9", - "typescript-eslint": "^8.62.0" + "typescript-eslint": "^8.62.0", + "vitest-mock-extended": "^4.0.0" } } diff --git a/packages/access_copy_attacher/Dockerfile b/packages/access_copy_attacher/Dockerfile index ba363a12..17fb5886 100644 --- a/packages/access_copy_attacher/Dockerfile +++ b/packages/access_copy_attacher/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/access_copy_attacher/jest.config.js b/packages/access_copy_attacher/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/access_copy_attacher/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/access_copy_attacher/package.json b/packages/access_copy_attacher/package.json index 28b52115..5578855f 100644 --- a/packages/access_copy_attacher/package.json +++ b/packages/access_copy_attacher/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@aws-sdk/client-s3": "^3.1075.0", diff --git a/packages/access_copy_attacher/src/index.test.ts b/packages/access_copy_attacher/src/index.test.ts index 9305a923..b35b4fed 100644 --- a/packages/access_copy_attacher/src/index.test.ts +++ b/packages/access_copy_attacher/src/index.test.ts @@ -1,5 +1,6 @@ import type { Context, SQSEvent } from "aws-lambda"; -import { mock } from "jest-mock-extended"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { Readable } from "node:stream"; import { S3Client } from "@aws-sdk/client-s3"; import { detectFileType } from "./file-type-utils"; @@ -8,16 +9,19 @@ import { constructSignedCdnUrl } from "@stela/s3-utils"; import { db } from "./database"; import { handler } from "./index"; -jest.mock("./database"); -jest.mock("@stela/logger"); -jest.mock("@aws-sdk/client-s3"); -jest.mock("./file-type-utils", () => ({ - detectFileType: jest.fn(), -})); -jest.mock("@stela/s3-utils", (): unknown => ({ - ...jest.requireActual("@stela/s3-utils"), - constructSignedCdnUrl: jest.fn(), +vi.mock("./database"); +vi.mock("@stela/logger"); +vi.mock("@aws-sdk/client-s3"); +vi.mock("./file-type-utils", () => ({ + detectFileType: vi.fn(), })); +vi.mock(import("@stela/s3-utils"), async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + constructSignedCdnUrl: vi.fn(), + }; +}); describe("handler", () => { const loadFixtures = async (): Promise => { @@ -46,8 +50,8 @@ describe("handler", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); - jest.restoreAllMocks(); + vi.clearAllMocks(); + vi.restoreAllMocks(); }); test("should take no action if the file is a thumbnail", async () => { @@ -86,7 +90,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordThumbnail256Result = await db.query<{ fileId: string; @@ -110,7 +114,7 @@ describe("handler", () => { const testSize = 102400; const testVersionId = "test-s3-version-id"; - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); const event = { Records: [ @@ -149,7 +153,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const fileResult = await db.query<{ size: number; @@ -252,7 +256,7 @@ describe("handler", () => { let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } finally { @@ -307,11 +311,11 @@ describe("handler", () => { }; const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValue(testError); + vi.spyOn(db, "sql").mockRejectedValue(testError); let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } finally { @@ -364,8 +368,7 @@ describe("handler", () => { }; const testError = new Error("out of cheese - redo from start"); - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockResolvedValueOnce({ command: "", row_count: 1, @@ -377,7 +380,7 @@ describe("handler", () => { let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } finally { @@ -390,7 +393,7 @@ describe("handler", () => { const noExtKey = "_Liam/access_copies/e38e/8582/b417/430c/953d/5c7e/8040/1ae2/100_upload-cb45fa84-f0ea-4a9e-b1da-309e485a4f4a/objects/710a1def-caf8-48f2-8eee-0848b4cfda10"; const testUrl = "https://localcdn.permanent.org/test"; - const mockS3Send = jest.fn(); + const mockS3Send = vi.fn(); const buildEvent = (key: string): SQSEvent => ({ Records: [ @@ -425,21 +428,20 @@ describe("handler", () => { }); beforeEach(() => { - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); - jest - .mocked(S3Client) - .mockImplementation(jest.fn().mockReturnValue({ send: mockS3Send })); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.spyOn(S3Client.prototype, "send").mockImplementation(mockS3Send); mockS3Send.mockResolvedValue({ Body: Readable.from(["test data"]), }); }); test("should identify a recognized file type via content sniffing", async () => { - jest - .mocked(detectFileType) - .mockResolvedValue({ ext: "jpg", mime: "image/jpeg" }); + vi.mocked(detectFileType).mockResolvedValue({ + ext: "jpg", + mime: "image/jpeg", + }); - await handler(buildEvent(noExtKey), mock(), jest.fn()); + await handler(buildEvent(noExtKey), mock(), vi.fn()); const result = await db.query<{ type: string }>( `SELECT type FROM file WHERE parentFileId = 100`, @@ -448,11 +450,12 @@ describe("handler", () => { }); test("should not write a file row if the file extension is unrecognized", async () => { - jest - .mocked(detectFileType) - .mockResolvedValue({ ext: "xyz", mime: "application/xyz" }); + vi.mocked(detectFileType).mockResolvedValue({ + ext: "xyz", + mime: "application/xyz", + }); - await handler(buildEvent(noExtKey), mock(), jest.fn()); + await handler(buildEvent(noExtKey), mock(), vi.fn()); const result = await db.query<{ type: string }>( `SELECT type FROM file WHERE parentFileId = 100`, @@ -461,9 +464,9 @@ describe("handler", () => { }); test("should not write a file row when content sniffing cannot identify the file", async () => { - jest.mocked(detectFileType).mockResolvedValue(undefined); + vi.mocked(detectFileType).mockResolvedValue(undefined); - await handler(buildEvent(noExtKey), mock(), jest.fn()); + await handler(buildEvent(noExtKey), mock(), vi.fn()); const result = await db.query<{ type: string }>( `SELECT type FROM file WHERE parentFileId = 100`, @@ -474,7 +477,7 @@ describe("handler", () => { test("should not write a file row when the S3 response body is not a stream", async () => { mockS3Send.mockResolvedValue({ Body: undefined }); - await handler(buildEvent(noExtKey), mock(), jest.fn()); + await handler(buildEvent(noExtKey), mock(), vi.fn()); const result = await db.query<{ type: string }>( `SELECT type FROM file WHERE parentFileId = 100`, @@ -491,7 +494,7 @@ describe("handler", () => { const testSize = 102400; const testVersionId = "test-s3-version-id"; - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); const event = { Records: [ @@ -530,7 +533,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const fileResult = await db.query<{ size: number; @@ -564,7 +567,7 @@ describe("handler", () => { expect(fileResult.rows.length).toEqual(1); - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const fileResultAfterSecondRun = await db.query<{ size: number; diff --git a/packages/access_copy_attacher/vitest.config.ts b/packages/access_copy_attacher/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/access_copy_attacher/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/account_space_updater/Dockerfile b/packages/account_space_updater/Dockerfile index 61cf6145..4c411960 100644 --- a/packages/account_space_updater/Dockerfile +++ b/packages/account_space_updater/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/account_space_updater/jest.config.js b/packages/account_space_updater/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/account_space_updater/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/account_space_updater/package.json b/packages/account_space_updater/package.json index c8b7219c..0a497f58 100644 --- a/packages/account_space_updater/package.json +++ b/packages/account_space_updater/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/node": "^10.60.0", diff --git a/packages/account_space_updater/src/index.test.ts b/packages/account_space_updater/src/index.test.ts index 23b133c0..1922be21 100644 --- a/packages/account_space_updater/src/index.test.ts +++ b/packages/account_space_updater/src/index.test.ts @@ -1,9 +1,10 @@ import type { Context } from "aws-lambda"; -import { mock } from "jest-mock-extended"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { db } from "./database"; import { handler } from "./index"; -jest.mock("./database"); +vi.mock("./database"); describe("handler", () => { const loadFixtures = async (): Promise => { @@ -155,7 +156,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); const updatedAccountSpace = await getUpdatedAccountSpace(); const ledgerEntry = await getLedgerEntry(); @@ -221,7 +222,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); const updatedAccountSpace = await getUpdatedAccountSpace(); const ledgerEntry = await getLedgerEntry(); @@ -286,7 +287,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); const ledgerEntry = await getLedgerEntry(); expect(ledgerEntry).toBeFalsy(); @@ -317,7 +318,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -352,7 +353,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -391,7 +392,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -434,7 +435,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -526,7 +527,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; diff --git a/packages/account_space_updater/vitest.config.ts b/packages/account_space_updater/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/account_space_updater/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/api/Dockerfile b/packages/api/Dockerfile index e3f6ff45..8105c649 100644 --- a/packages/api/Dockerfile +++ b/packages/api/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/api/Dockerfile.test b/packages/api/Dockerfile.test index 958f44f1..143e821a 100644 --- a/packages/api/Dockerfile.test +++ b/packages/api/Dockerfile.test @@ -8,7 +8,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY patches ./patches COPY packages/api/package.json ./packages/api/package.json COPY packages/logger ./packages/logger diff --git a/packages/api/jest.config.js b/packages/api/jest.config.js deleted file mode 100644 index 2d8c6cfc..00000000 --- a/packages/api/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, - setupFiles: ["/jest.env.setup.js"], - globalSetup: "/jest.db.setup.ts", - globalTeardown: "/jest.db.teardown.ts", - modulePathIgnorePatterns: ["/dist/"], - maxWorkers: "50%", -}; diff --git a/packages/api/jest.db.teardown.ts b/packages/api/jest.db.teardown.ts deleted file mode 100644 index a8a88cb0..00000000 --- a/packages/api/jest.db.teardown.ts +++ /dev/null @@ -1,43 +0,0 @@ -import pg from "pg"; -import os from "node:os"; - -const { Client } = pg; - -const TEMPLATE_DATABASE_NAME = "test_permanent_template"; - -export default async function globalTeardown(): Promise { - const client = new Client({ - connectionString: "postgres://postgres:permanent@database/postgres", - }); - await client.connect(); - - try { - const numWorkers = os.cpus().length / 2; - - // Terminate connections and drop worker databases - for (let i = 1; i <= numWorkers; i++) { - const workerDbName = `test_permanent_worker_${i}`; - - // Terminate any remaining connections - await client.query(` - SELECT pg_terminate_backend(pg_stat_activity.pid) - FROM pg_stat_activity - WHERE pg_stat_activity.datname = '${workerDbName}' - AND pid <> pg_backend_pid() - `); - - await client.query(`DROP DATABASE IF EXISTS ${workerDbName}`); - } - - // Drop the template database - await client.query(` - SELECT pg_terminate_backend(pg_stat_activity.pid) - FROM pg_stat_activity - WHERE pg_stat_activity.datname = '${TEMPLATE_DATABASE_NAME}' - AND pid <> pg_backend_pid() - `); - await client.query(`DROP DATABASE IF EXISTS ${TEMPLATE_DATABASE_NAME}`); - } finally { - await client.end(); - } -} diff --git a/packages/api/package.json b/packages/api/package.json index edd4c10a..ac5d68c0 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -31,11 +31,10 @@ "start:watch": "tsc-watch --onSuccess \"npm run start\"", "start": "tsc -p tsconfig.build.json && tscp -p tsconfig.tscp.json && node dist/index.js", "start-containers": "(cd ../..; docker compose up -d --build stela)", - "test": "npm run start-containers && (cd ../..; docker compose run stela node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --silent=false)", - "test:ci": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js --coverage" + "test": "npm run start-containers && (cd ../..; docker compose run stela npm run test:ci)", + "test:ci": "vitest run --coverage" }, "dependencies": { - "@stela/publisher-utils": "^1.0.0", "@edtf-ts/core": "^0.5.0", "@fusionauth/typescript-client": "^1.60.0", "@mailchimp/mailchimp_marketing": "^3.0.80", @@ -44,6 +43,7 @@ "@sentry/node": "^10.60.0", "@stela/logger": "^1.0.0", "@stela/permanent_models": "^1.0.0", + "@stela/publisher-utils": "^1.0.0", "cors": "^2.8.5", "dotenv": "^17.4.2", "express": "^5.2.0", @@ -61,11 +61,11 @@ }, "devDependencies": { "@types/http-errors": "^2.0.1", - "@types/jest-when": "^3.5.5", "@types/memoizee": "^0.4.12", "@types/newrelic": "^9.14.4", - "jest-when": "^3.7.0", + "@vitest/expect": "^4.1.10", "nock": "^14.0.10", - "supertest": "^7.1.0" + "supertest": "^7.1.0", + "vitest-when": "^0.10.0" } } diff --git a/packages/api/src/__mocks__/database.ts b/packages/api/src/__mocks__/database.ts index aacfa80f..1046f645 100644 --- a/packages/api/src/__mocks__/database.ts +++ b/packages/api/src/__mocks__/database.ts @@ -1,9 +1,10 @@ import * as path from "node:path"; import { TinyPg } from "tinypg"; -// Use worker-specific databases to enable parallel test execution -// Each Jest worker gets its own isolated database -const workerId = process.env["JEST_WORKER_ID"] ?? "1"; +// Use pool-slot-specific databases to enable parallel test execution. +// VITEST_POOL_ID is the pool-slot index (1…maxThreads), reused across files. +// VITEST_WORKER_ID is a globally unique per-file ID and must NOT be used here. +const workerId = process.env["VITEST_POOL_ID"] ?? "1"; const dbName = `test_permanent_worker_${workerId}`; const db = new TinyPg({ diff --git a/packages/api/src/access/permission.test.ts b/packages/api/src/access/permission.test.ts index 8d4515ec..3307c892 100644 --- a/packages/api/src/access/permission.test.ts +++ b/packages/api/src/access/permission.test.ts @@ -1,4 +1,5 @@ import createError from "http-errors"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { getArchiveAccessRole, getRecordAccessRole, @@ -8,7 +9,7 @@ import { import { AccessRole } from "./models"; import { db } from "../database"; -jest.mock("../database"); +vi.mock("../database"); const loadFixtures = async (): Promise => { await db.sql("access.fixtures.create_test_accounts"); @@ -33,7 +34,7 @@ describe("getArchiveAccessRole", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); }); @@ -76,7 +77,7 @@ describe("getArchiveAccessRole", () => { }); test("should throw internal server error if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); let error = null; try { await getArchiveAccessRole("1", "test@permanent.org"); @@ -97,7 +98,7 @@ describe("getRecordAccessRole", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); }); @@ -183,7 +184,7 @@ describe("getRecordAccessRole", () => { }); test("should throw internal server error if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); let error = null; try { await getRecordAccessRole("1", "test@permanent.org"); @@ -197,8 +198,8 @@ describe("getRecordAccessRole", () => { }); test("should throw not found error if the all access roles returned are null", async () => { - jest.spyOn(db, "sql").mockImplementation( - jest.fn().mockResolvedValue({ + vi.spyOn(db, "sql").mockImplementation( + vi.fn().mockResolvedValue({ rows: [ { archiveAccessRole: null, shareAccessRole: null }, { archiveAccessRole: null, shareAccessRole: null }, @@ -315,7 +316,7 @@ describe("isItemPublic", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); }); test("should return true for a public record", async () => { @@ -335,7 +336,7 @@ describe("isItemPublic", () => { expect(isPublic).toEqual(false); }); test("should throw a 500 error if database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); let error = null; try { await isItemPublic("1", "folder"); diff --git a/packages/api/src/account/controller/create_storage_adjustments.test.ts b/packages/api/src/account/controller/create_storage_adjustments.test.ts index bf14910c..cf24e371 100644 --- a/packages/api/src/account/controller/create_storage_adjustments.test.ts +++ b/packages/api/src/account/controller/create_storage_adjustments.test.ts @@ -1,5 +1,6 @@ import request from "supertest"; -import { when } from "jest-when"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { when } from "vitest-when"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; @@ -8,9 +9,9 @@ import { verifyAdminAuthentication } from "../../middleware"; import type { StorageAdjustment } from "../models"; import { mockVerifyAdminAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); interface AccountSpace { spaceLeft: string; @@ -55,7 +56,7 @@ describe("/account/storage-adjustments", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.resetAllMocks(); }); test("should call verifyAdminAuthentication", async () => { @@ -275,13 +276,13 @@ describe("/account/storage-adjustments", () => { test("should log error and return 500 if storage adjustment fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); when(spy) .calledWith("account.queries.adjust_account_storage", { accountId: testAccountId, storageAmountInBytes: 5 * GB, }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .post(`/api/v2/accounts/${testAccountId}/storage-adjustments`) diff --git a/packages/api/src/account/controller/get_accounts.test.ts b/packages/api/src/account/controller/get_accounts.test.ts index 4b66c826..8d3e0e00 100644 --- a/packages/api/src/account/controller/get_accounts.test.ts +++ b/packages/api/src/account/controller/get_accounts.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; @@ -6,9 +7,9 @@ import { verifyAdminAuthentication } from "../../middleware"; import { mockVerifyAdminAuthentication } from "../../../test/middleware_mocks"; import type { Account } from "../models"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("account.fixtures.create_test_accounts"); @@ -32,7 +33,7 @@ describe("GET /account", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should call verifyAdminAuthentication", async () => { @@ -245,7 +246,7 @@ describe("GET /account", () => { test("should log error and return 500 if database query fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/account?accountIds[]=2&pageSize=10").expect(500); diff --git a/packages/api/src/account/controller/get_signup_details.test.ts b/packages/api/src/account/controller/get_signup_details.test.ts index 6411d4d7..e9964526 100644 --- a/packages/api/src/account/controller/get_signup_details.test.ts +++ b/packages/api/src/account/controller/get_signup_details.test.ts @@ -1,13 +1,14 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import type { SignupDetails } from "../models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("account.fixtures.create_test_accounts"); @@ -28,7 +29,7 @@ describe("getSignupDetails", () => { await loadFixtures(); }); afterEach(async () => { - jest.clearAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -55,13 +56,11 @@ describe("getSignupDetails", () => { }); test("should throw an error if database call fails unexpectedly", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce( - jest - .fn() - .mockRejectedValueOnce(new Error("out of cheese - redo from start")), - ); + vi.spyOn(db, "sql").mockImplementationOnce( + vi + .fn() + .mockRejectedValueOnce(new Error("out of cheese - redo from start")), + ); await agent.get("/api/v2/accounts/signup").expect(500); expect(logger.error).toHaveBeenCalled(); }); diff --git a/packages/api/src/account/controller/leave_archive.test.ts b/packages/api/src/account/controller/leave_archive.test.ts index 89457ff8..40fabed7 100644 --- a/packages/api/src/account/controller/leave_archive.test.ts +++ b/packages/api/src/account/controller/leave_archive.test.ts @@ -1,5 +1,6 @@ import request from "supertest"; -import { when } from "jest-when"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { when } from "vitest-when"; import { db } from "../../database"; import { EVENT_ACTION, EVENT_ACTOR, EVENT_ENTITY } from "../../constants"; @@ -10,9 +11,9 @@ import { mockExtractIp, } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("../../event/service"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("../../event/service"); const loadFixtures = async (): Promise => { await db.sql("account.fixtures.create_test_accounts"); @@ -42,13 +43,13 @@ describe("leaveArchive", () => { accountid = 3 AND archiveid = 1`; beforeEach(async () => { + vi.resetAllMocks(); mockVerifyUserAuthentication( "test+1@permanent.org", "b5461dc2-1eb0-450e-b710-fef7b2cafe1e", ); mockExtractIp(ip); await loadFixtures(); - jest.clearAllMocks(); }); afterEach(async () => { @@ -94,17 +95,13 @@ describe("leaveArchive", () => { }); test("should return a 500 error if the deletion database call fails", async () => { - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); when(spy) .calledWith("account.queries.delete_account_archive", { archiveId: "1", email: "test+1@permanent.org", }) - .mockImplementation( - jest.fn().mockResolvedValue({ - rows: [], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent.delete("/api/v2/accounts/archive/1").expect(500); }); }); diff --git a/packages/api/src/account/controller/update_tags.test.ts b/packages/api/src/account/controller/update_tags.test.ts index 07049e80..671ca1dc 100644 --- a/packages/api/src/account/controller/update_tags.test.ts +++ b/packages/api/src/account/controller/update_tags.test.ts @@ -1,28 +1,29 @@ import request from "supertest"; +import { beforeEach, describe, expect, test, vi } from "vitest"; import { Md5 } from "ts-md5"; import { app } from "../../app"; import { MailchimpMarketing } from "../../mailchimp"; import type { UpdateTagsRequest } from "../models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../mailchimp", () => ({ +vi.mock("../../mailchimp", () => ({ MailchimpMarketing: { lists: { - updateListMemberTags: jest.fn(), + updateListMemberTags: vi.fn(), }, }, })); -jest.mock("../../middleware"); +vi.mock("../../middleware"); describe("updateTags", () => { const agent = request.agent(app); beforeEach(() => { + vi.clearAllMocks(); mockVerifyUserAuthentication( "test@permanent.org", "b5461dc2-1eb0-450e-b710-fef7b2cafe1e", ); - jest.clearAllMocks(); }); test("should call updateListMemberTags with the correct arguments", async () => { @@ -42,9 +43,9 @@ describe("updateTags", () => { const expectedListId = process.env["MAILCHIMP_COMMUNITY_LIST_ID"] ?? ""; const expectedSubscriberHash = Md5.hashStr(requestBody.emailFromAuthToken); - jest - .mocked(MailchimpMarketing.lists.updateListMemberTags) - .mockResolvedValue(null); + vi.mocked(MailchimpMarketing.lists.updateListMemberTags).mockResolvedValue( + null, + ); await agent.put("/api/v2/accounts/tags").send(requestBody).expect(200); @@ -56,15 +57,13 @@ describe("updateTags", () => { }); test("should throw an error if MailChimp call fails", async () => { - jest - .mocked(MailchimpMarketing.lists.updateListMemberTags) - .mockResolvedValue({ - detail: "Out of Cheese - Redo from Start", - status: 500, - type: "", - title: "", - instance: "", - }); + vi.mocked(MailchimpMarketing.lists.updateListMemberTags).mockResolvedValue({ + detail: "Out of Cheese - Redo from Start", + status: 500, + type: "", + title: "", + instance: "", + }); await agent .put("/api/v2/accounts/tags") .send({ diff --git a/packages/api/src/account/service.test.ts b/packages/api/src/account/service.test.ts index 7ec682b7..c81396c4 100644 --- a/packages/api/src/account/service.test.ts +++ b/packages/api/src/account/service.test.ts @@ -1,8 +1,9 @@ import { InternalServerError } from "http-errors"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { db } from "../database"; import { accountService } from "./service"; -jest.mock("../database"); +vi.mock("../database"); const loadFixtures = async (): Promise => { await db.sql("account.fixtures.create_test_accounts"); @@ -40,9 +41,9 @@ describe("getAccountArchive", () => { }); test("should throw an internal server error if the database call fails", async () => { - jest - .spyOn(db, "sql") - .mockRejectedValue(new Error("Out of Cheese - Redo from Start")); + vi.spyOn(db, "sql").mockRejectedValue( + new Error("Out of Cheese - Redo from Start"), + ); let error = null; try { await accountService.getAccountArchive("1", "test@permanent.org"); diff --git a/packages/api/src/account/validators.test.ts b/packages/api/src/account/validators.test.ts index 6499e76e..77f3ad74 100644 --- a/packages/api/src/account/validators.test.ts +++ b/packages/api/src/account/validators.test.ts @@ -4,6 +4,7 @@ import { validateLeaveArchiveRequest, validateUpdateTagsRequest, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateUpdateTagsRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/admin/controller.test.ts b/packages/api/src/admin/controller.test.ts index 733091fb..a2973d7d 100644 --- a/packages/api/src/admin/controller.test.ts +++ b/packages/api/src/admin/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import createError from "http-errors"; import { logger } from "@stela/logger"; @@ -8,10 +9,10 @@ import { lowPriorityTopicArn, publisherClient } from "@stela/publisher-utils"; import { verifyAdminAuthentication } from "../middleware"; import { mockVerifyAdminAuthentication } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("@stela/logger"); -jest.mock("../middleware"); -jest.mock("@stela/publisher-utils"); +vi.mock("../database"); +vi.mock("@stela/logger"); +vi.mock("../middleware"); +vi.mock("@stela/publisher-utils"); describe("recalculateFolderThumbnails", () => { const loadFixtures = async (): Promise => { @@ -28,7 +29,7 @@ describe("recalculateFolderThumbnails", () => { "test@permanent.org", "5c3473b6-cf2e-4c55-a80e-8db51d1bc5fd", ); - jest.clearAllMocks(); + vi.clearAllMocks(); await clearDatabase(); await loadFixtures(); }); @@ -38,9 +39,10 @@ describe("recalculateFolderThumbnails", () => { }); test("should send messages for folders created before the cutoff", async () => { - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockResolvedValueOnce({ failedMessages: [], messagesSent: 6 }); + vi.spyOn(publisherClient, "batchPublishMessages").mockResolvedValueOnce({ + failedMessages: [], + messagesSent: 6, + }); const result = await agent .post("/api/v2/admin/folder/recalculate_thumbnails") .send({ @@ -52,7 +54,7 @@ describe("recalculateFolderThumbnails", () => { mock: { calls: [callsToBatchPublish], }, - } = jest.mocked(publisherClient.batchPublishMessages); + } = vi.mocked(publisherClient.batchPublishMessages); expect(callsToBatchPublish).toBeDefined(); if (callsToBatchPublish !== undefined) { expect(callsToBatchPublish[1].length).toBe(6); @@ -61,9 +63,10 @@ describe("recalculateFolderThumbnails", () => { }); test("should respond with 500 error if messages fail to send", async () => { - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockResolvedValueOnce({ failedMessages: ["1", "2"], messagesSent: 2 }); + vi.spyOn(publisherClient, "batchPublishMessages").mockResolvedValueOnce({ + failedMessages: ["1", "2"], + messagesSent: 2, + }); const result = await agent .post("/api/v2/admin/folder/recalculate_thumbnails") .send({ @@ -76,7 +79,7 @@ describe("recalculateFolderThumbnails", () => { test("should respond with internal server error if database call fails", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .post("/api/v2/admin/folder/recalculate_thumbnails") .send({ @@ -89,9 +92,9 @@ describe("recalculateFolderThumbnails", () => { test("should respond with internal server error if message publishing fails", async () => { const testError = new Error("out of cheese - redo from start"); - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockRejectedValueOnce(testError); + vi.spyOn(publisherClient, "batchPublishMessages").mockRejectedValueOnce( + testError, + ); await agent .post("/api/v2/admin/folder/recalculate_thumbnails") .send({ @@ -126,7 +129,7 @@ describe("set_null_subjects", () => { "test@permanent.org", "5c3473b6-cf2e-4c55-a80e-8db51d1bc5fd", ); - jest.clearAllMocks(); + vi.clearAllMocks(); await clearDatabase(); await loadFixtures(); }); @@ -143,11 +146,11 @@ describe("set_null_subjects", () => { }); test("should respond with 401 if not authenticated", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent .post("/api/v2/admin/account/set_null_subjects") .send({}) @@ -318,7 +321,7 @@ describe("set_null_subjects", () => { test("should call logger.error if database call fails", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); const testEmailOne = "test@permanent.org"; await agent @@ -337,7 +340,7 @@ describe("set_null_subjects", () => { test("should return emails for which the update failed", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); const testEmailOne = "test@permanent.org"; const testEmailTwo = "test+2@permanent.org"; @@ -384,7 +387,7 @@ describe("/record/:recordId/recalculate_thumbnail", () => { "test@permanent.org", "5c3473b6-cf2e-4c55-a80e-8db51d1bc5fd", ); - jest.clearAllMocks(); + vi.clearAllMocks(); await clearDatabase(); await loadFixtures(); }); @@ -394,18 +397,18 @@ describe("/record/:recordId/recalculate_thumbnail", () => { }); test("should response with 401 if not authenticated as an admin", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent .post("/api/v2/admin/record/1/recalculate_thumbnail") .expect(401); }); test("should publish a message with correct parameters", async () => { - jest.mocked(publisherClient.batchPublishMessages).mockResolvedValueOnce({ + vi.mocked(publisherClient.batchPublishMessages).mockResolvedValueOnce({ failedMessages: [], messagesSent: 1, }); @@ -418,7 +421,7 @@ describe("/record/:recordId/recalculate_thumbnail", () => { mock: { calls: [firstCallToBatchPublish], }, - } = jest.mocked(publisherClient.batchPublishMessages); + } = vi.mocked(publisherClient.batchPublishMessages); expect(firstCallToBatchPublish).toBeDefined(); if (firstCallToBatchPublish !== undefined) { const [, [firstMessage]] = firstCallToBatchPublish; @@ -449,9 +452,10 @@ describe("/record/:recordId/recalculate_thumbnail", () => { }); test("should respond with 500 if the message fails to send", async () => { - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockResolvedValueOnce({ failedMessages: ["1"], messagesSent: 0 }); + vi.spyOn(publisherClient, "batchPublishMessages").mockResolvedValueOnce({ + failedMessages: ["1"], + messagesSent: 0, + }); await agent .post("/api/v2/admin/record/1/recalculate_thumbnail") .expect(500); @@ -459,7 +463,7 @@ describe("/record/:recordId/recalculate_thumbnail", () => { test("should respond with 500 and log the error if the database call fails", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .post("/api/v2/admin/record/1/recalculate_thumbnail") @@ -484,7 +488,7 @@ describe("/folder/delete-orphaned-folders", () => { "test@permanent.org", "5c3473b6-cf2e-4c55-a80e-8db51d1bc5fd", ); - jest.mocked(publisherClient.batchPublishMessages).mockResolvedValue({ + vi.mocked(publisherClient.batchPublishMessages).mockResolvedValue({ failedMessages: [], messagesSent: 2, }); @@ -496,15 +500,15 @@ describe("/folder/delete-orphaned-folders", () => { await db.query( "TRUNCATE account, archive, folder, record, folder_link CASCADE", ); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should respond with 401 if not authenticated as an admin", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent .post("/api/v2/admin/folder/delete-orphaned-folders") .expect(401); @@ -540,9 +544,9 @@ describe("/folder/delete-orphaned-folders", () => { test("should respond with a 500 error if publishing fails", async () => { const testError = new Error("Out of cheese - redo from start"); - jest - .mocked(publisherClient.batchPublishMessages) - .mockRejectedValue(testError); + vi.mocked(publisherClient.batchPublishMessages).mockRejectedValue( + testError, + ); await agent .post("/api/v2/admin/folder/delete-orphaned-folders") @@ -552,7 +556,7 @@ describe("/folder/delete-orphaned-folders", () => { test("should respond with a 500 error if database call fails", async () => { const testError = new Error("Out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValue(testError); + vi.spyOn(db, "sql").mockRejectedValue(testError); await agent .post("/api/v2/admin/folder/delete-orphaned-folders") diff --git a/packages/api/src/admin/validators.test.ts b/packages/api/src/admin/validators.test.ts index e9c4a5fd..365ec0ed 100644 --- a/packages/api/src/admin/validators.test.ts +++ b/packages/api/src/admin/validators.test.ts @@ -1,4 +1,5 @@ import { validateRecalculateFolderThumbnailsRequest } from "./validators"; +import { describe, expect, test } from "vitest"; const adminSubjectFromAuthToken = "fcb2b59b-df07-4e79-ad20-bf7f067a965e"; diff --git a/packages/api/src/archive/controller/backfill_ledger.test.ts b/packages/api/src/archive/controller/backfill_ledger.test.ts index f5602ba4..33d4634d 100644 --- a/packages/api/src/archive/controller/backfill_ledger.test.ts +++ b/packages/api/src/archive/controller/backfill_ledger.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import createError from "http-errors"; import { logger } from "@stela/logger"; @@ -8,10 +9,10 @@ import { db } from "../../database"; import { publisherClient } from "@stela/publisher-utils"; import { mockVerifyAdminAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/publisher-utils"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/publisher-utils"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -31,12 +32,12 @@ describe("POST /:archiveId/backfill-ledger", () => { "82bd483e-914b-4bfe-abf9-92ffe86d7803", ); await loadFixtures(); - jest.spyOn(publisherClient, "publishMessage").mockResolvedValue(); + vi.spyOn(publisherClient, "publishMessage").mockResolvedValue(); }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should backfill ledger records successfully", async () => { @@ -75,11 +76,11 @@ describe("POST /:archiveId/backfill-ledger", () => { }); test("should require admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError.Unauthorized("Invalid token")); - }); + }, + ); await agent.post("/api/v2/archive/1/backfill-ledger").expect(401); expect(publisherClient.publishMessage).not.toHaveBeenCalled(); @@ -92,7 +93,7 @@ describe("POST /:archiveId/backfill-ledger", () => { test("should handle database query errors", async () => { const testError = new Error("Database error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.post("/api/v2/archive/1/backfill-ledger").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); @@ -101,9 +102,7 @@ describe("POST /:archiveId/backfill-ledger", () => { test("should handle publisher client errors", async () => { const testError = new Error("Publisher error"); - jest - .mocked(publisherClient.publishMessage) - .mockRejectedValueOnce(testError); + vi.mocked(publisherClient.publishMessage).mockRejectedValueOnce(testError); await agent.post("/api/v2/archive/1/backfill-ledger").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); diff --git a/packages/api/src/archive/controller/get_featured.test.ts b/packages/api/src/archive/controller/get_featured.test.ts index 1fb7d00d..3cf23fd0 100644 --- a/packages/api/src/archive/controller/get_featured.test.ts +++ b/packages/api/src/archive/controller/get_featured.test.ts @@ -1,11 +1,12 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import type { FeaturedArchive } from "../models"; -jest.mock("../../database"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -47,7 +48,7 @@ describe("getFeatured", () => { test("should throw InternalServerError if database query fails", async () => { const testError = new Error("error: out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/archive/featured").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/get_payer_account_storage.test.ts b/packages/api/src/archive/controller/get_payer_account_storage.test.ts index fcd96322..fca32575 100644 --- a/packages/api/src/archive/controller/get_payer_account_storage.test.ts +++ b/packages/api/src/archive/controller/get_payer_account_storage.test.ts @@ -1,13 +1,14 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import { GB } from "../../constants"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -34,7 +35,7 @@ describe("getPayerAccountStorage", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should return payer account storage", async () => { @@ -74,7 +75,7 @@ describe("getPayerAccountStorage", () => { test("should throw an internal server error if database call fails", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/archive/2/payer-account-storage").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/get_public_tags.test.ts b/packages/api/src/archive/controller/get_public_tags.test.ts index c58182c8..a963393c 100644 --- a/packages/api/src/archive/controller/get_public_tags.test.ts +++ b/packages/api/src/archive/controller/get_public_tags.test.ts @@ -1,10 +1,11 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; -jest.mock("../../database"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -29,7 +30,7 @@ describe("getPublicTags", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should return public tags and not private or deleted tags", async () => { @@ -58,7 +59,7 @@ describe("getPublicTags", () => { test("should throw an internal server error if database query fails unexpectedly", async () => { const testError = new Error("out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/archive/1/tags/public").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/get_shared_folders.test.ts b/packages/api/src/archive/controller/get_shared_folders.test.ts index 67620d52..eb868e6f 100644 --- a/packages/api/src/archive/controller/get_shared_folders.test.ts +++ b/packages/api/src/archive/controller/get_shared_folders.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import createError from "http-errors"; import { logger } from "@stela/logger"; @@ -8,9 +9,9 @@ import { db } from "../../database"; import type { Folder } from "../../folder/models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -39,8 +40,8 @@ describe("getSharedFolders", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("should return shared folders for an archive", async () => { @@ -56,11 +57,11 @@ describe("getSharedFolders", () => { }); test("should return 401 when not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent.get(`/api/v2/archive/2/folders/shared`).expect(401); }); @@ -72,7 +73,7 @@ describe("getSharedFolders", () => { test("should return 500 if database query fails", async () => { const testError = new Error("error: database connection lost"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get(`/api/v2/archive/2/folders/shared`).expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/make_featured.test.ts b/packages/api/src/archive/controller/make_featured.test.ts index 0893a7b1..f1942598 100644 --- a/packages/api/src/archive/controller/make_featured.test.ts +++ b/packages/api/src/archive/controller/make_featured.test.ts @@ -1,12 +1,13 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import { mockVerifyAdminAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -63,7 +64,7 @@ describe("makeFeatured", () => { test("should throw an InternalServerError if database query fails", async () => { const archiveId = "3"; const testError = new Error("error: out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.post(`/api/v2/archive/${archiveId}/make-featured`).expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/search_archives.test.ts b/packages/api/src/archive/controller/search_archives.test.ts index 12d4fdb3..d91327a3 100644 --- a/packages/api/src/archive/controller/search_archives.test.ts +++ b/packages/api/src/archive/controller/search_archives.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; @@ -8,9 +9,9 @@ import { mockExtractUserEmailFromAuthToken, } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("@stela/logger"); -jest.mock("../../middleware"); +vi.mock("../../database"); +vi.mock("@stela/logger"); +vi.mock("../../middleware"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -36,7 +37,7 @@ describe("searchArchives", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should search archives without authentication and return only public archives", async () => { @@ -180,7 +181,7 @@ describe("searchArchives", () => { mockExtractUserIsAdminFromAuthToken(false); mockExtractUserEmailFromAuthToken(undefined); const testError = new Error("error: out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/archive?searchQuery=test&pageSize=10").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/unfeature.test.ts b/packages/api/src/archive/controller/unfeature.test.ts index 4668aede..88c374f3 100644 --- a/packages/api/src/archive/controller/unfeature.test.ts +++ b/packages/api/src/archive/controller/unfeature.test.ts @@ -1,13 +1,14 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import { archiveService } from "../service/index"; import { mockVerifyAdminAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -47,7 +48,7 @@ describe("getFeatured", () => { test("should throw InternalServerError if database query fails", async () => { const testError = new Error("error: out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.delete("/api/v2/archive/3/unfeature").expect(500); expect(logger.error).toHaveBeenCalledWith(testError); }); diff --git a/packages/api/src/archive/controller/update_archive.test.ts b/packages/api/src/archive/controller/update_archive.test.ts index e0b73caf..e7f8d368 100644 --- a/packages/api/src/archive/controller/update_archive.test.ts +++ b/packages/api/src/archive/controller/update_archive.test.ts @@ -1,13 +1,14 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../../app"; import { db } from "../../database"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; import type { Archive } from "../models"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("archive.fixtures.create_test_accounts"); @@ -110,7 +111,7 @@ describe("PATCH /archive/:archiveId", () => { test("should throw an InternalServerError if database query fails", async () => { const archiveId = "1"; const testError = new Error("error: out of cheese - redo from start"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .patch(`/api/v2/archive/${archiveId}`) diff --git a/packages/api/src/archive/validators.test.ts b/packages/api/src/archive/validators.test.ts index 298bdeca..b728834c 100644 --- a/packages/api/src/archive/validators.test.ts +++ b/packages/api/src/archive/validators.test.ts @@ -1,4 +1,5 @@ import { validateArchiveIdFromParams } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateArchiveIdFromParams", () => { test("should find no errors in valid parameters", () => { diff --git a/packages/api/src/database_util.test.ts b/packages/api/src/database_util.test.ts index 8dedd712..cb20ff90 100644 --- a/packages/api/src/database_util.test.ts +++ b/packages/api/src/database_util.test.ts @@ -3,6 +3,7 @@ import { isInvalidEnumError, getInvalidValueFromInvalidEnumMessage, } from "./database_util"; +import { describe, expect, test } from "vitest"; const testInvalidEnumError = "invalid input value for enum test_enum: not_a_test_enum"; diff --git a/packages/api/src/directive/controller.test.ts b/packages/api/src/directive/controller.test.ts index e890a447..5306ab77 100644 --- a/packages/api/src/directive/controller.test.ts +++ b/packages/api/src/directive/controller.test.ts @@ -1,5 +1,6 @@ import request from "supertest"; -import { when } from "jest-when"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { when } from "vitest-when"; import { logger } from "@stela/logger"; import { app } from "../app"; import { db } from "../database"; @@ -11,13 +12,13 @@ import { mockVerifyAdminAuthentication, } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("../email", () => ({ - sendArchiveStewardNotification: jest.fn(), +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("../email", () => ({ + sendArchiveStewardNotification: vi.fn(), })); -jest.mock("@stela/logger"); -jest.mock("../legacy_client"); +vi.mock("@stela/logger"); +vi.mock("../legacy_client"); describe("GET /directive/archive/:archiveId", () => { const agent = request(app); @@ -130,13 +131,11 @@ describe("POST /directive", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.resetAllMocks(); }); test("should successfully create a directive and trigger", async () => { - jest - .mocked(sendArchiveStewardNotification) - .mockResolvedValueOnce(undefined); + vi.mocked(sendArchiveStewardNotification).mockResolvedValueOnce(undefined); await agent .post("/api/v2/directive/") .send({ @@ -188,9 +187,7 @@ describe("POST /directive", () => { test("should log error if notification email fails", async () => { const testError = new Error("out of cheese error - redo from start"); - jest - .mocked(sendArchiveStewardNotification) - .mockRejectedValueOnce(testError); + vi.mocked(sendArchiveStewardNotification).mockRejectedValueOnce(testError); await agent .post("/api/v2/directive/") .send({ @@ -252,8 +249,8 @@ describe("POST /directive", () => { }); test("should error if steward account not found", async () => { - jest.spyOn(db, "sql").mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ rows: [{ hasAccess: true }], }), ); @@ -271,25 +268,21 @@ describe("POST /directive", () => { }); test("should error if directive can't be created", async () => { - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) - .expectCalledWith("directive.queries.check_archive_ownership", { + .calledWith("directive.queries.check_archive_ownership", { archiveId: "1", email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [{ hasAccess: true }], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ hasAccess: true }] })); when(dbSpy) - .expectCalledWith("directive.queries.create_directive", { + .calledWith("directive.queries.create_directive", { archiveId: "1", type: "transfer", stewardEmail, note: null, }) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .post("/api/v2/directive/") .send({ @@ -304,34 +297,27 @@ describe("POST /directive", () => { }); test("should error if trigger can't be created", async () => { - jest.spyOn(db, "sql"); - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) - .expectCalledWith("directive.queries.check_archive_ownership", { + .calledWith("directive.queries.check_archive_ownership", { archiveId: "1", email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [{ hasAccess: true }], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ hasAccess: true }] })); when(dbSpy) - .expectCalledWith("directive.queries.create_directive", { + .calledWith("directive.queries.create_directive", { archiveId: "1", type: "transfer", stewardEmail, note: null, }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ rows: [{ directiveId: "1" }] }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ directiveId: "1" }] })); when(dbSpy) - .expectCalledWith("directive.queries.create_directive_trigger", { + .calledWith("directive.queries.create_directive_trigger", { directiveId: "1", type: "admin", }) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .post("/api/v2/directive/") .send({ @@ -380,13 +366,11 @@ describe("PUT /directive/:directiveId", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.resetAllMocks(); }); test("should successfully update steward account and note", async () => { - jest - .mocked(sendArchiveStewardNotification) - .mockResolvedValueOnce(undefined); + vi.mocked(sendArchiveStewardNotification).mockResolvedValueOnce(undefined); await agent .put(`/api/v2/directive/${testDirectiveId}`) .send({ @@ -498,9 +482,7 @@ describe("PUT /directive/:directiveId", () => { test("should log error if notification email fails", async () => { const testError = new Error("out of cheese error - redo from start"); - jest - .mocked(sendArchiveStewardNotification) - .mockRejectedValueOnce(testError); + vi.mocked(sendArchiveStewardNotification).mockRejectedValueOnce(testError); await agent .put(`/api/v2/directive/${testDirectiveId}`) .send({ @@ -575,39 +557,29 @@ describe("PUT /directive/:directiveId", () => { }); test("should error if trigger update fails unexpectedly", async () => { - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) - .expectCalledWith("directive.queries.check_directive_ownership", { + .calledWith("directive.queries.check_directive_ownership", { directiveId: testDirectiveId, email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [{ hasAccess: true }], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ hasAccess: true }] })); when(dbSpy) - .expectCalledWith("directives.queries.update_directive", { + .calledWith("directive.queries.update_directive", { directiveId: testDirectiveId, type: undefined, stewardEmail: "test+2@permanent.org", note: testNote, }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [ - { - directiveId: testDirectiveId, - }, - ], - }), + .thenDo( + vi.fn().mockResolvedValue({ rows: [{ directiveId: testDirectiveId }] }), ); when(dbSpy) - .expectCalledWith("directives.queries.update_directive_trigger", { + .calledWith("directive.queries.update_directive_trigger", { directiveId: testDirectiveId, type: "admin", }) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .put(`/api/v2/directive/${testDirectiveId}`) @@ -622,29 +594,21 @@ describe("PUT /directive/:directiveId", () => { }); test("should error if directive update fails unexpectedly", async () => { - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) - .expectCalledWith("directive.queries.check_directive_ownership", { + .calledWith("directive.queries.check_directive_ownership", { directiveId: testDirectiveId, email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [{ hasAccess: true }], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ hasAccess: true }] })); when(dbSpy) - .expectCalledWith("directives.queries.update_directive", { + .calledWith("directive.queries.update_directive", { directiveId: testDirectiveId, type: undefined, - stewardEmail: "test+2@permanent.org", + stewardEmail: undefined, note: testNote, }) - .mockImplementationOnce( - jest - .fn() - .mockRejectedValueOnce(new Error("Out of cheese - redo from start")), - ); + .thenReject(new Error("Out of cheese - redo from start")); await agent .put(`/api/v2/directive/${testDirectiveId}`) @@ -688,8 +652,8 @@ describe("POST /trigger/account/:accountId", () => { }; beforeEach(async () => { - jest.clearAllMocks(); - jest.restoreAllMocks(); + vi.resetAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); await loadFixtures(); @@ -703,9 +667,9 @@ describe("POST /trigger/account/:accountId", () => { }); test("should respond with success when transfer directive succesfully executed", async () => { - jest - .spyOn(legacyClient, "transferArchiveOwnership") - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ status: 200 })); + vi.spyOn(legacyClient, "transferArchiveOwnership").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ status: 200 }), + ); const response = await agent .post("/api/v2/directive/trigger/account/2") .expect(200); @@ -724,9 +688,9 @@ describe("POST /trigger/account/:accountId", () => { }); test("should respond with error when transfer directive fails to execute", async () => { - jest - .spyOn(legacyClient, "transferArchiveOwnership") - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ status: 500 })); + vi.spyOn(legacyClient, "transferArchiveOwnership").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ status: 500 }), + ); const response = await agent .post("/api/v2/directive/trigger/account/2") .expect(200); @@ -753,7 +717,7 @@ describe("POST /trigger/account/:accountId", () => { }); test("should respond with error when transfer directive has unsupported type", async () => { - jest.spyOn(db, "sql").mockResolvedValue({ + vi.spyOn(db, "sql").mockResolvedValue({ command: "", row_count: 1, rows: [{ type: "not_a_type" }], @@ -775,13 +739,11 @@ describe("POST /trigger/account/:accountId", () => { }); test("should respond with a 500 error if the database call fails", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce( - jest - .fn() - .mockRejectedValueOnce(new Error("Out of cheese - redo from start")), - ); + vi.spyOn(db, "sql").mockImplementationOnce( + vi + .fn() + .mockRejectedValueOnce(new Error("Out of cheese - redo from start")), + ); await agent.post("/api/v2/directive/trigger/account/2").expect(500); }); }); diff --git a/packages/api/src/directive/service/utils.test.ts b/packages/api/src/directive/service/utils.test.ts index 86759334..7f53a17c 100644 --- a/packages/api/src/directive/service/utils.test.ts +++ b/packages/api/src/directive/service/utils.test.ts @@ -1,8 +1,9 @@ import { NotFound } from "http-errors"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { db } from "../../database"; import { confirmArchiveOwnership } from "./utils"; -jest.mock("../../database"); +vi.mock("../../database"); const testArchiveId = "1"; const testEmail = "test@permanent.org"; diff --git a/packages/api/src/directive/validators.test.ts b/packages/api/src/directive/validators.test.ts index 8c30e8ad..d34708c6 100644 --- a/packages/api/src/directive/validators.test.ts +++ b/packages/api/src/directive/validators.test.ts @@ -5,6 +5,7 @@ import { validateUpdateDirectiveParams, validateUpdateDirectiveRequest, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateCreateDirectiveRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/email/service.test.ts b/packages/api/src/email/service.test.ts index bc1362e6..8fb62184 100644 --- a/packages/api/src/email/service.test.ts +++ b/packages/api/src/email/service.test.ts @@ -1,4 +1,5 @@ import type { MessagesSendSuccessResponse } from "@mailchimp/mailchimp_transactional"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { sendLegacyContactNotification, sendArchiveStewardNotification, @@ -9,11 +10,11 @@ import { import { MailchimpTransactional } from "../mailchimp"; import { db } from "../database"; -jest.mock("../database"); -jest.mock("../mailchimp", () => ({ +vi.mock("../database"); +vi.mock("../mailchimp", () => ({ MailchimpTransactional: { messages: { - sendTemplate: jest.fn(), + sendTemplate: vi.fn(), }, }, })); @@ -44,7 +45,7 @@ describe("sendLegacyContactNotification", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should send legacy contact notification successfully", async () => { @@ -56,9 +57,9 @@ describe("sendLegacyContactNotification", () => { reject_reason: null, }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await sendLegacyContactNotification(testLegacyContactId); @@ -105,7 +106,7 @@ describe("sendArchiveNotification", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should send archive steward notification successfully", async () => { @@ -117,9 +118,9 @@ describe("sendArchiveNotification", () => { reject_reason: null, }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await sendArchiveStewardNotification(testDirectiveId); @@ -161,7 +162,7 @@ describe("sendArchiveNotification", () => { describe("sendEmail", () => { afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should successfully call Mailchimp", async () => { @@ -173,9 +174,9 @@ describe("sendEmail", () => { reject_reason: null, }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await sendEmail("legacy-contact-added", { fromName: "Jack Rando", @@ -210,9 +211,9 @@ describe("sendEmail", () => { test("should throw an error if no email is sent", async () => { const mockResponse: MessagesSendSuccessResponse[] = []; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await expect( sendEmail("legacy-contact-added", { @@ -236,9 +237,9 @@ describe("sendEmail", () => { _id: "test", }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await expect( sendEmail("legacy-contact-added", { @@ -257,14 +258,14 @@ describe("sendEmail", () => { const mockResponse = { config: {}, isAxiosError: true, - toJSON: jest.fn(), + toJSON: vi.fn(), response: { status: 500, }, }; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce(mockResponse)); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockImplementationOnce(vi.fn().mockResolvedValueOnce(mockResponse)); await expect( sendEmail("legacy-contact-added", { @@ -293,7 +294,7 @@ describe("sendInvitationNotification", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("send invite email should call mailchimp successfully", async () => { @@ -305,9 +306,9 @@ describe("sendInvitationNotification", () => { reject_reason: null, }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await sendInvitationNotification({ fromEmail: senderEmail, @@ -376,7 +377,7 @@ describe("sendGiftNotification", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("send gift email should call mailchimp successfully", async () => { @@ -388,9 +389,9 @@ describe("sendGiftNotification", () => { reject_reason: null, }, ]; - jest - .mocked(MailchimpTransactional.messages.sendTemplate) - .mockResolvedValueOnce(mockResponse); + vi.mocked( + MailchimpTransactional.messages.sendTemplate, + ).mockResolvedValueOnce(mockResponse); await sendGiftNotification( senderEmail, diff --git a/packages/api/src/event/controller.test.ts b/packages/api/src/event/controller.test.ts index 0b42d490..47315bd7 100644 --- a/packages/api/src/event/controller.test.ts +++ b/packages/api/src/event/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import createError from "http-errors"; import { db } from "../database"; @@ -14,9 +15,9 @@ import { mockExtractIp, } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("@stela/publisher-utils"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("@stela/publisher-utils"); const testSubject = "fcb2b59b-df07-4e79-ad20-bf7f067a965e"; const testEmail = "test+1@permanent.org"; @@ -42,16 +43,16 @@ describe("POST /event", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("should return 401 if unauthenticated", async () => { - jest - .mocked(verifyUserOrAdminOrDelegatedCallAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { - next(new createError.Unauthorized("You aren't logged in")); - }); + vi.mocked( + verifyUserOrAdminOrDelegatedCallAuthentication, + ).mockImplementation(async (_, __, next: NextFunction) => { + next(new createError.Unauthorized("You aren't logged in")); + }); await agent.post("/api/v2/event").expect(401); }); @@ -108,11 +109,11 @@ describe("POST /event", () => { }); test("should return 400 if fields from auth token fail validation", async () => { - jest - .mocked(verifyUserOrAdminOrDelegatedCallAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { - next(); - }); + vi.mocked( + verifyUserOrAdminOrDelegatedCallAuthentication, + ).mockImplementation(async (_, __, next: NextFunction) => { + next(); + }); await agent.post("/api/v2/event").expect(400); }); @@ -380,7 +381,7 @@ describe("POST /event", () => { }); test("should return 500 error if database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent @@ -396,8 +397,8 @@ describe("POST /event", () => { }); test("should return 500 error if database call returns an empty result", async () => { - jest.spyOn(db, "sql").mockImplementation( - jest.fn().mockResolvedValue({ + vi.spyOn(db, "sql").mockImplementation( + vi.fn().mockResolvedValue({ rows: [], }), ); @@ -495,8 +496,8 @@ describe("GET /event/checklist", () => { }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -505,11 +506,11 @@ describe("GET /event/checklist", () => { }); test("should return 401 if unauthenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent.get("/api/v2/event/checklist").expect(401); }); @@ -651,15 +652,15 @@ describe("GET /event/checklist", () => { }); test("should return 500 error if database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent.get("/api/v2/event/checklist").expect(500); }); test("should return 500 error if database response is empty", async () => { - jest.spyOn(db, "sql").mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ rows: [], }), ); diff --git a/packages/api/src/feature_flag/controller.test.ts b/packages/api/src/feature_flag/controller.test.ts index e9f46946..8d8e4a3c 100644 --- a/packages/api/src/feature_flag/controller.test.ts +++ b/packages/api/src/feature_flag/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import { logger } from "@stela/logger"; import createError from "http-errors"; @@ -13,9 +14,9 @@ import { mockExtractUserIsAdminFromAuthToken, } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("feature_flag.fixtures.create_test_feature_flags"); @@ -40,13 +41,13 @@ describe("GET /feature-flags", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); }); test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/feature-flags").expect(500); expect(logger.error).toHaveBeenCalled(); @@ -55,21 +56,20 @@ describe("GET /feature-flags", () => { test("should log the error if the database call fails when calling user is admin", async () => { mockExtractUserIsAdminFromAuthToken(true); const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/feature-flags").expect(500); expect(logger.error).toHaveBeenCalled(); }); - test("should log the error if the request is invalid", async () => { - jest - .mocked(extractUserIsAdminFromAuthToken) - .mockImplementation(async (_, __, next: NextFunction) => { + test("should return 400 if the request is invalid", async () => { + vi.mocked(extractUserIsAdminFromAuthToken).mockImplementation( + async (_, __, next: NextFunction) => { next(); - }); + }, + ); await agent.get("/api/v2/feature-flags").expect(400); - expect(logger.error).toHaveBeenCalled(); }); test("should return list of globally enabled feature flags if user is not logged in", async () => { @@ -111,16 +111,16 @@ describe("GET /feature-flags", () => { describe("POST /feature-flag", () => { const agent = request(app); beforeEach(async () => { + vi.restoreAllMocks(); + vi.clearAllMocks(); mockVerifyAdminAuthentication(testEmail, testSubject); - jest.restoreAllMocks(); - jest.clearAllMocks(); await loadFixtures(); await clearDatabase(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -154,11 +154,11 @@ describe("POST /feature-flag", () => { }); test("should respond with 401 status code if lacking admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent.post("/api/v2/feature-flags").expect(401); }); @@ -219,7 +219,7 @@ describe("POST /feature-flag", () => { }); test("should respond with 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent @@ -233,7 +233,7 @@ describe("POST /feature-flag", () => { test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .post("/api/v2/feature-flags") .send({ @@ -248,16 +248,16 @@ describe("POST /feature-flag", () => { describe("PUT /feature-flag/:featureFlagId", () => { const agent = request(app); beforeEach(async () => { + vi.restoreAllMocks(); + vi.clearAllMocks(); mockVerifyAdminAuthentication(testEmail, testSubject); - jest.restoreAllMocks(); - jest.clearAllMocks(); await clearDatabase(); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -272,11 +272,11 @@ describe("PUT /feature-flag/:featureFlagId", () => { }); test("should respond with 401 status code if lacking admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent .put("/api/v2/feature-flags/1bdf2da6-026b-4e8e-9b57-a86b1817be5d") .expect(401); @@ -347,7 +347,7 @@ describe("PUT /feature-flag/:featureFlagId", () => { }); test("should respond with 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent @@ -361,7 +361,7 @@ describe("PUT /feature-flag/:featureFlagId", () => { test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .put("/api/v2/feature-flags/1bdf2da6-026b-4e8e-9b57-a86b1817be5d") .send({ @@ -386,16 +386,16 @@ describe("PUT /feature-flag/:featureFlagId", () => { describe("DELETE /feature-flag/:featureFlagId", () => { const agent = request(app); beforeEach(async () => { + vi.restoreAllMocks(); + vi.clearAllMocks(); mockVerifyAdminAuthentication(testEmail, testSubject); - jest.restoreAllMocks(); - jest.clearAllMocks(); await clearDatabase(); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -407,11 +407,11 @@ describe("DELETE /feature-flag/:featureFlagId", () => { }); test("should respond with 401 status code if lacking admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent .delete("/api/v2/feature-flags/1bdf2da6-026b-4e8e-9b57-a86b1817be5d") .expect(401); @@ -434,7 +434,7 @@ describe("DELETE /feature-flag/:featureFlagId", () => { }); test("should respond with 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent @@ -445,7 +445,7 @@ describe("DELETE /feature-flag/:featureFlagId", () => { test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .delete("/api/v2/feature-flags/1bdf2da6-026b-4e8e-9b57-a86b1817be5d") .send({}) diff --git a/packages/api/src/feature_flag/validators.test.ts b/packages/api/src/feature_flag/validators.test.ts index 6bed8299..ce987198 100644 --- a/packages/api/src/feature_flag/validators.test.ts +++ b/packages/api/src/feature_flag/validators.test.ts @@ -3,6 +3,7 @@ import { validateUpdateFeatureFlagRequest, validateFeatureFlagParams, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateCreateFeatureFlagRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/folder/controller/get_folder.test.ts b/packages/api/src/folder/controller/get_folder.test.ts index 3092f6b0..62f1080b 100644 --- a/packages/api/src/folder/controller/get_folder.test.ts +++ b/packages/api/src/folder/controller/get_folder.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { app } from "../../app"; import { db } from "../../database"; import { @@ -12,9 +13,9 @@ import { } from "../../../test/middleware_mocks"; import { loadFixtures, clearDatabase } from "./utils_test"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const testEmail = "test@permanent.org"; describe("GET /folder", () => { @@ -29,8 +30,8 @@ describe("GET /folder", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("should return 200 code for successful call", async () => { @@ -376,7 +377,7 @@ describe("GET /folder", () => { }); test("should throw a 500 error if database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("test error")); await agent.get("/api/v2/folders?folderIds[]=2").expect(500); }); }); diff --git a/packages/api/src/folder/controller/get_folder_children.test.ts b/packages/api/src/folder/controller/get_folder_children.test.ts index 1b12b0d6..47e8dbdb 100644 --- a/packages/api/src/folder/controller/get_folder_children.test.ts +++ b/packages/api/src/folder/controller/get_folder_children.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { FolderChildItem, Folder } from "../models"; import type { ArchiveFile } from "../../record/models"; import type { Tag } from "../../tag/models"; @@ -15,8 +16,8 @@ import { import { loadFixtures, clearDatabase } from "./utils_test"; import { db } from "../../database"; -jest.mock("../../database"); -jest.mock("../../middleware"); +vi.mock("../../database"); +vi.mock("../../middleware"); describe("GET /folder/{id}/children", () => { const agent = request(app); @@ -444,7 +445,7 @@ describe("GET /folder/{id}/children", () => { }); test("should return 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("test error")); await agent.get("/api/v2/folders/10/children?pageSize=1").expect(500); }); }); diff --git a/packages/api/src/folder/controller/get_folder_share_links.test.ts b/packages/api/src/folder/controller/get_folder_share_links.test.ts index 978e042f..94b6f35e 100644 --- a/packages/api/src/folder/controller/get_folder_share_links.test.ts +++ b/packages/api/src/folder/controller/get_folder_share_links.test.ts @@ -1,4 +1,5 @@ import type { NextFunction } from "express"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import request from "supertest"; import { logger } from "@stela/logger"; import createError from "http-errors"; @@ -9,9 +10,9 @@ import type { ShareLink } from "../../share_link/models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; import { loadFixtures, clearDatabase } from "./utils_test"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); describe("GET /folder/{id}/share_links", () => { const agent = request(app); @@ -27,8 +28,8 @@ describe("GET /folder/{id}/share_links", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("expect to return share links for a folder", async () => { @@ -81,7 +82,7 @@ describe("GET /folder/{id}/share_links", () => { test("expect to log error and return 500 if database lookup fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -90,11 +91,11 @@ describe("GET /folder/{id}/share_links", () => { }); test("expect 401 if not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError.Unauthorized("Invalid auth token")); - }); + }, + ); await agent.get("/api/v2/folders/1/share_links").expect(401); }); diff --git a/packages/api/src/folder/controller/patch_folder.test.ts b/packages/api/src/folder/controller/patch_folder.test.ts index ce0fb97e..f6d474a6 100644 --- a/packages/api/src/folder/controller/patch_folder.test.ts +++ b/packages/api/src/folder/controller/patch_folder.test.ts @@ -1,14 +1,15 @@ import { logger } from "@stela/logger"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import request from "supertest"; -import { when } from "jest-when"; import { app } from "../../app"; import { db } from "../../database"; import { loadFixtures, clearDatabase } from "./utils_test"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; +import { mockSqlCall } from "../../../test/mock_sql"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); describe("patch folder", () => { const agent = request(app); @@ -24,8 +25,8 @@ describe("patch folder", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); }); test("expect an empty query to cause a 400 error", async () => { @@ -137,7 +138,7 @@ describe("patch folder", () => { test("expect to log error and return 500 if database update fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql").mockImplementation(async () => { + const spy = vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -152,9 +153,10 @@ describe("patch folder", () => { test("expect to log error and return 500 if database update fails", async () => { const testError = new Error("test error"); - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.update_folder", { + mockSqlCall( + db, + "folder.queries.update_folder", + { folderId: "1", displayDate: "2024-09-26T15:09:52.000Z", setDisplayDateToNull: false, @@ -163,10 +165,9 @@ describe("patch folder", () => { displayTime: undefined, setDisplayTimeToNull: false, locationId: null, - }) - .mockImplementation(async () => { - throw testError; - }); + }, + { reject: testError }, + ); await agent .patch("/api/v2/folders/1") @@ -178,16 +179,16 @@ describe("patch folder", () => { test("expect to log error and return 500 if database update is ok but the database select fails", async () => { const testError = new Error("test error"); - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.get_folders", { + mockSqlCall( + db, + "folder.queries.get_folders", + { folderIds: ["1"], email: "test@permanent.org", shareToken: undefined, - }) - .mockImplementation(async () => { - throw testError; - }); + }, + { reject: testError }, + ); await agent .patch("/api/v2/folders/1") @@ -198,9 +199,10 @@ describe("patch folder", () => { }); test("expect 404 if update_folder returns no rows", async () => { - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.update_folder", { + mockSqlCall( + db, + "folder.queries.update_folder", + { folderId: "1", displayDate: "2024-09-26T15:09:52.000Z", setDisplayDateToNull: false, @@ -209,12 +211,9 @@ describe("patch folder", () => { displayTime: undefined, setDisplayTimeToNull: false, locationId: null, - }) - .mockImplementationOnce( - jest.fn().mockResolvedValue({ - rows: [], - }), - ); + }, + { resolve: { rows: [] } }, + ); await agent .patch("/api/v2/folders/1") @@ -223,18 +222,16 @@ describe("patch folder", () => { }); test("expect to log error and return 404 if database update is ok but the database select has empty result", async () => { - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.get_folders", { + mockSqlCall( + db, + "folder.queries.get_folders", + { folderIds: ["1"], email: "test@permanent.org", shareToken: undefined, - }) - .mockImplementationOnce( - jest.fn().mockResolvedValue({ - rows: [], - }), - ); + }, + { resolve: { rows: [] } }, + ); await agent .patch("/api/v2/folders/1") @@ -355,14 +352,12 @@ describe("patch folder", () => { }); test("expect 404 if folder disappears between access check and location lookup", async () => { - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.get_folder_location_id", { folderId: "1" }) - .mockImplementationOnce( - jest.fn().mockResolvedValue({ - rows: [], - }), - ); + mockSqlCall( + db, + "folder.queries.get_folder_location_id", + { folderId: "1" }, + { resolve: { rows: [] } }, + ); await agent .patch("/api/v2/folders/1") @@ -372,10 +367,12 @@ describe("patch folder", () => { test("expect 500 if the folder location lookup query fails", async () => { const testError = new Error("test error"); - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("folder.queries.get_folder_location_id", { folderId: "1" }) - .mockImplementationOnce(jest.fn().mockRejectedValue(testError)); + mockSqlCall( + db, + "folder.queries.get_folder_location_id", + { folderId: "1" }, + { reject: testError }, + ); await agent .patch("/api/v2/folders/1") diff --git a/packages/api/src/folder/service.test.ts b/packages/api/src/folder/service.test.ts index 213c4fbe..351efb2c 100644 --- a/packages/api/src/folder/service.test.ts +++ b/packages/api/src/folder/service.test.ts @@ -14,6 +14,7 @@ import { FolderView, PrettyFolderView, } from "./models"; +import { describe, expect, test } from "vitest"; describe("prettifyFolderType", () => { test("should convert sort.display_date_desc to date-descending", () => { diff --git a/packages/api/src/folder/validators.test.ts b/packages/api/src/folder/validators.test.ts index 1413083d..e1b58892 100644 --- a/packages/api/src/folder/validators.test.ts +++ b/packages/api/src/folder/validators.test.ts @@ -2,6 +2,7 @@ import { validatePatchFolderRequest, validateGetFoldersQuery, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validatePatchFolderRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/fusionauth.test.ts b/packages/api/src/fusionauth.test.ts index 60313d12..20f6aa76 100644 --- a/packages/api/src/fusionauth.test.ts +++ b/packages/api/src/fusionauth.test.ts @@ -1,5 +1,6 @@ import nock from "nock"; import { fusionAuthClient } from "./fusionauth"; +import { afterEach, describe, expect, test } from "vitest"; const mockFusionAuthHost = process.env["FUSIONAUTH_HOST"] ?? ""; diff --git a/packages/api/src/health/controller.test.ts b/packages/api/src/health/controller.test.ts index 2b15c8ee..7c177480 100644 --- a/packages/api/src/health/controller.test.ts +++ b/packages/api/src/health/controller.test.ts @@ -1,8 +1,9 @@ import request from "supertest"; +import { describe, expect, test, vi } from "vitest"; import { app } from "../app"; import { db } from "../database"; -jest.mock("../database"); +vi.mock("../database"); describe("/health", () => { const agent = request(app); @@ -18,7 +19,7 @@ describe("/health", () => { }); test("should be unavailable when DB connection fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error(); }); diff --git a/packages/api/src/idpuser/controller.test.ts b/packages/api/src/idpuser/controller.test.ts index 7443914e..4e3b188f 100644 --- a/packages/api/src/idpuser/controller.test.ts +++ b/packages/api/src/idpuser/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import createError from "http-errors"; import type { NextFunction } from "express"; import { app } from "../app"; @@ -8,15 +9,15 @@ import { fusionAuthClient } from "../fusionauth"; import type { TwoFactorRequestResponse } from "./models"; import { mockVerifyUserAuthentication } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../middleware"); -global.fetch = jest.fn(); -jest.mock("../fusionauth", () => ({ +vi.mock("../database"); +vi.mock("../middleware"); +global.fetch = vi.fn(); +vi.mock("../fusionauth", () => ({ fusionAuthClient: { - retrieveUserByEmail: jest.fn(), - sendTwoFactorCodeForEnableDisable: jest.fn(), - enableTwoFactor: jest.fn(), - disableTwoFactor: jest.fn(), + retrieveUserByEmail: vi.fn(), + sendTwoFactorCodeForEnableDisable: vi.fn(), + enableTwoFactor: vi.fn(), + disableTwoFactor: vi.fn(), }, })); @@ -30,8 +31,8 @@ const mockRetrieveUserByEmail = ( successful: boolean, exception?: { code: string; message: string }, ): void => { - jest.mocked(fusionAuthClient.retrieveUserByEmail).mockImplementation( - jest.fn().mockResolvedValue({ + vi.mocked(fusionAuthClient.retrieveUserByEmail).mockImplementation( + vi.fn().mockResolvedValue({ response: { user: { twoFactor: { @@ -49,22 +50,22 @@ const mockSendTwoFactorCodeForEnableDisable = ( successful: boolean, exception?: { code: string; message: string }, ): void => { - jest - .mocked(fusionAuthClient.sendTwoFactorCodeForEnableDisable) - .mockImplementation( - jest.fn().mockResolvedValue({ - wasSuccessful: () => successful, - exception, - }), - ); + vi.mocked( + fusionAuthClient.sendTwoFactorCodeForEnableDisable, + ).mockImplementation( + vi.fn().mockResolvedValue({ + wasSuccessful: () => successful, + exception, + }), + ); }; const mockEnableTwoFactor = ( successful: boolean, exception?: { code: string; message: string }, ): void => { - jest.mocked(fusionAuthClient.enableTwoFactor).mockImplementation( - jest.fn().mockResolvedValue({ + vi.mocked(fusionAuthClient.enableTwoFactor).mockImplementation( + vi.fn().mockResolvedValue({ wasSuccessful: () => successful, exception, }), @@ -75,8 +76,8 @@ const mockDisableTwoFactor = ( successful: boolean, exception?: { code: string; message: string }, ): void => { - jest.mocked(fusionAuthClient.disableTwoFactor).mockImplementation( - jest.fn().mockResolvedValue({ + vi.mocked(fusionAuthClient.disableTwoFactor).mockImplementation( + vi.fn().mockResolvedValue({ wasSuccessful: () => successful, exception, }), @@ -94,7 +95,7 @@ describe("/idpuser", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); test("expect a non-404 response", async () => { @@ -219,7 +220,7 @@ describe("idpuser/send-enable-code", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); test("should return a 200 status if the request is successful", async () => { @@ -230,11 +231,11 @@ describe("idpuser/send-enable-code", () => { }); test("should return a 401 status if the request is not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError(401, "Unauthorized")); - }); + }, + ); await agent.post("/api/v2/idpuser/send-enable-code").expect(401); }); @@ -313,7 +314,7 @@ describe("idpuser/send-enable-code", () => { }); test("should return a 500 status if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("test_error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("test_error")); await agent .post("/api/v2/idpuser/send-enable-code") .send({ method: "email", value: "test@permanent.org" }) @@ -334,8 +335,8 @@ describe("POST /idpuser/enable-two-factor", () => { beforeEach(async () => { await clearDatabase(); - jest.clearAllMocks(); - jest.resetAllMocks(); + vi.clearAllMocks(); + vi.resetAllMocks(); await loadFixtures(); mockVerifyUserAuthentication( "test@permanent.org", @@ -345,15 +346,15 @@ describe("POST /idpuser/enable-two-factor", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); test("should return a 401 status if the caller is not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation((_req, _res, _next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + (_req, _res, _next: NextFunction) => { throw new createError.Unauthorized("Invalid token"); - }); + }, + ); await agent .post("/api/v2/idpuser/enable-two-factor") .send({ code: "test_code", method: "sms", value: "000-000-0000" }) @@ -455,7 +456,7 @@ describe("POST /idpuser/enable-two-factor", () => { }); test("should return status 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValueOnce(new Error("Database error")); + vi.spyOn(db, "sql").mockRejectedValueOnce(new Error("Database error")); await agent .post("/api/v2/idpuser/enable-two-factor") .send({ @@ -489,7 +490,7 @@ describe("idpuser/send-disable-code", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); test("should return a 200 status if the request is successful", async () => { @@ -500,11 +501,11 @@ describe("idpuser/send-disable-code", () => { }); test("should return a 401 status if the request not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError(401, "Unauthorized")); - }); + }, + ); await agent .post("/api/v2/idpuser/send-disable-code") .send({ methodId: "test_method_id" }) @@ -571,7 +572,7 @@ describe("idpuser/send-disable-code", () => { }); test("should return a 500 status if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("test_error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("test_error")); await agent .post("/api/v2/idpuser/send-disable-code") .send({ methodId: "test_method_id" }) @@ -601,7 +602,7 @@ describe("/idpuser/disable-two-factor", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); test("should return 200 status if the request is successful", async () => { @@ -612,11 +613,11 @@ describe("/idpuser/disable-two-factor", () => { }); test("should return 401 status if the request is not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError.Unauthorized("Invalid token")); - }); + }, + ); await agent .post("/api/v2/idpuser/disable-two-factor") .send({ methodId: "test_method_id", code: "test_code" }) @@ -688,7 +689,7 @@ describe("/idpuser/disable-two-factor", () => { }); test("should return status 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValueOnce(new Error("Database error")); + vi.spyOn(db, "sql").mockRejectedValueOnce(new Error("Database error")); await agent .post("/api/v2/idpuser/disable-two-factor") .send({ methodId: "test_method_id", code: "test_code" }) diff --git a/packages/api/src/legacy_client.test.ts b/packages/api/src/legacy_client.test.ts index 4dcebee2..66b67130 100644 --- a/packages/api/src/legacy_client.test.ts +++ b/packages/api/src/legacy_client.test.ts @@ -1,6 +1,7 @@ +import { describe, expect, test, vi } from "vitest"; import { legacyClient } from "./legacy_client"; -global.fetch = jest.fn(); +global.fetch = vi.fn(); describe("creditStorage", () => { test("should submit the correct request", async () => { diff --git a/packages/api/src/legacy_contact/controller.test.ts b/packages/api/src/legacy_contact/controller.test.ts index f36949cd..18f24d8f 100644 --- a/packages/api/src/legacy_contact/controller.test.ts +++ b/packages/api/src/legacy_contact/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { app } from "../app"; import { db } from "../database"; @@ -6,11 +7,11 @@ import { sendLegacyContactNotification } from "../email"; import type { LegacyContact } from "./model"; import { mockVerifyUserAuthentication } from "../../test/middleware_mocks"; -jest.mock("@stela/logger"); -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("../email", () => ({ - sendLegacyContactNotification: jest.fn(), +vi.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("../email", () => ({ + sendLegacyContactNotification: vi.fn(), })); describe("GET /legacy-contact", () => { @@ -49,7 +50,7 @@ describe("GET /legacy-contact", () => { test("should throw an InternalServerError when retrieval of legacy contacts fails", async () => { const testError = new Error("Out of cheese error - redo from start"); - jest.spyOn(db, "sql").mockImplementationOnce(async () => { + vi.spyOn(db, "sql").mockImplementationOnce(async () => { throw testError; }); await agent.get("/api/v2/legacy-contact/").expect(500); @@ -86,11 +87,11 @@ describe("POST /legacy-contact", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should successfully create a legacy contact", async () => { - jest.mocked(sendLegacyContactNotification).mockResolvedValueOnce(undefined); + vi.mocked(sendLegacyContactNotification).mockResolvedValueOnce(undefined); await agent .post("/api/v2/legacy-contact/") .send({ @@ -121,7 +122,7 @@ describe("POST /legacy-contact", () => { test("should log errors sending email", async () => { const testError = new Error("out of cheese error - redo from start"); - jest.mocked(sendLegacyContactNotification).mockRejectedValueOnce(testError); + vi.mocked(sendLegacyContactNotification).mockRejectedValueOnce(testError); await agent .post("/api/v2/legacy-contact") .send({ @@ -148,9 +149,9 @@ describe("POST /legacy-contact", () => { }); test("should error if legacy contact can't be created", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce(jest.fn().mockResolvedValue({ rows: [] })); + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockResolvedValue({ rows: [] }), + ); await agent .post("/api/v2/legacy-contact") .send({ @@ -189,11 +190,11 @@ describe("PUT /legacy-contact/:legacyContactId", () => { }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should update a legacy contact's name and email", async () => { - jest.mocked(sendLegacyContactNotification).mockResolvedValueOnce(undefined); + vi.mocked(sendLegacyContactNotification).mockResolvedValueOnce(undefined); const result = await agent .put(`/api/v2/legacy-contact/${testLegacyContactId}`) .send({ @@ -271,7 +272,7 @@ describe("PUT /legacy-contact/:legacyContactId", () => { }); test("should throw an InternalServerError when update fails unexpectedly", async () => { - jest.spyOn(db, "sql").mockImplementationOnce(async () => { + vi.spyOn(db, "sql").mockImplementationOnce(async () => { throw new Error("Out of cheese error - redo from start"); }); await agent @@ -284,7 +285,7 @@ describe("PUT /legacy-contact/:legacyContactId", () => { test("should log errors sending email", async () => { const testError = new Error("out of cheese error - redo from start"); - jest.mocked(sendLegacyContactNotification).mockRejectedValueOnce(testError); + vi.mocked(sendLegacyContactNotification).mockRejectedValueOnce(testError); await agent .put(`/api/v2/legacy-contact/${testLegacyContactId}`) .send({ diff --git a/packages/api/src/legacy_contact/validators.test.ts b/packages/api/src/legacy_contact/validators.test.ts index 107aac59..48802763 100644 --- a/packages/api/src/legacy_contact/validators.test.ts +++ b/packages/api/src/legacy_contact/validators.test.ts @@ -3,6 +3,7 @@ import { validateUpdateLegacyContactParams, validateUpdateLegacyContactRequest, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateCreateLegacyContactRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/location/service.test.ts b/packages/api/src/location/service.test.ts index 01ecbe9a..842ddf77 100644 --- a/packages/api/src/location/service.test.ts +++ b/packages/api/src/location/service.test.ts @@ -1,22 +1,23 @@ +import { afterEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { db } from "../database"; import { insertLocation, updateLocation } from "./service"; import type { LocationInput } from "./models"; -jest.mock("../database"); -jest.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("@stela/logger"); const baseLocation: LocationInput = { name: "Test" }; describe("insertLocation", () => { afterEach(() => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("expect 500 if the insert query fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -27,9 +28,9 @@ describe("insertLocation", () => { }); test("expect 500 if the insert returns no row", async () => { - jest - .spyOn(db, "sql") - .mockImplementation(jest.fn().mockResolvedValue({ rows: [] })); + vi.spyOn(db, "sql").mockImplementation( + vi.fn().mockResolvedValue({ rows: [] }), + ); await expect(insertLocation(baseLocation)).rejects.toMatchObject({ statusCode: 500, @@ -37,10 +38,10 @@ describe("insertLocation", () => { }); test("expect a sublocation without a leading number to be stored entirely as streetName", async () => { - const sqlSpy = jest + const sqlSpy = vi .spyOn(db, "sql") .mockImplementation( - jest.fn().mockResolvedValue({ rows: [{ locationId: "1" }] }), + vi.fn().mockResolvedValue({ rows: [{ locationId: "1" }] }), ); await insertLocation({ name: "Test", sublocation: "Main Street" }); @@ -57,13 +58,13 @@ describe("insertLocation", () => { describe("updateLocation", () => { afterEach(() => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("expect 500 if the update query fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -74,9 +75,9 @@ describe("updateLocation", () => { }); test("expect 404 if the update returns no row", async () => { - jest - .spyOn(db, "sql") - .mockImplementation(jest.fn().mockResolvedValue({ rows: [] })); + vi.spyOn(db, "sql").mockImplementation( + vi.fn().mockResolvedValue({ rows: [] }), + ); await expect(updateLocation("1", baseLocation)).rejects.toMatchObject({ statusCode: 404, diff --git a/packages/api/src/middleware/authentication.test.ts b/packages/api/src/middleware/authentication.test.ts index 0e319016..0e661f18 100644 --- a/packages/api/src/middleware/authentication.test.ts +++ b/packages/api/src/middleware/authentication.test.ts @@ -1,4 +1,5 @@ import { createRequest, createResponse } from "node-mocks-http"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { extractUserEmailFromAuthToken, verifyUserAuthentication, @@ -14,7 +15,7 @@ import { fieldsFromUserOrAdminAuthentication, } from "../validators"; -jest.mock("../fusionauth"); +vi.mock("../fusionauth"); const testEmail = "test@permanent.org"; const testSubject = "b2a6787c-f255-465a-8eb0-1583004d4a4f"; @@ -90,10 +91,10 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await verifyUserAuthentication(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await verifyUserAuthentication(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, @@ -105,10 +106,10 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await verifyUserAuthentication(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await verifyUserAuthentication(request, createResponse(), vi.fn()); const { body: { userSubjectFromAuthToken }, @@ -120,10 +121,10 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await verifyUserAuthentication(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await verifyUserAuthentication(request, createResponse(), vi.fn()); expect(() => { validateBodyFromAuthentication(request.body); @@ -132,9 +133,9 @@ describe("verifyUserAuthentication", () => { test("should throw unauthorized if authorization header is missing", async () => { const request = createRequest(); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -153,9 +154,9 @@ describe("verifyUserAuthentication", () => { test("should throw unauthorized if authorization header has the wrong number of words", async () => { const request = createRequest({ headers: { Authorization: "test" } }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -174,9 +175,9 @@ describe("verifyUserAuthentication", () => { test("should throw unauthorized if authorization header doesn't start with Bearer", async () => { const request = createRequest({ headers: { Authorization: "test test" } }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -197,9 +198,9 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => failedIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => failedIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -220,9 +221,9 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => expiredTokenIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => expiredTokenIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -243,9 +244,9 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => missingEmailIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => missingEmailIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -266,11 +267,10 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") + vi.spyOn(fusionAuthClient, "introspectAccessToken") .mockImplementationOnce(async () => failedIntrospectionResponse) .mockImplementationOnce(async () => successfulIntrospectionResponse); - await verifyUserAuthentication(request, createResponse(), jest.fn()); + await verifyUserAuthentication(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken, userSubjectFromAuthToken }, @@ -285,9 +285,9 @@ describe("verifyUserAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => failedIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => failedIntrospectionResponse, + ); await verifyUserAuthentication( request, createResponse(), @@ -311,11 +311,11 @@ describe("verifyUserAuthentication", () => { const testError = Object.assign(new Error("Rate Limit Exceeded"), { statusCode: 429, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => { + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => { throw testError; - }); + }, + ); await verifyUserAuthentication( request, createResponse(), @@ -338,10 +338,10 @@ describe("verifyAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await verifyAdminAuthentication(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await verifyAdminAuthentication(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, @@ -353,10 +353,10 @@ describe("verifyAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await verifyAdminAuthentication(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await verifyAdminAuthentication(request, createResponse(), vi.fn()); const { body: { adminSubjectFromAuthToken }, @@ -366,9 +366,9 @@ describe("verifyAdminAuthentication", () => { test("should throw unauthorized if authorization header is missing", async () => { const request = createRequest(); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyAdminAuthentication( request, createResponse(), @@ -388,18 +388,18 @@ describe("verifyAdminAuthentication", () => { describe("verifyUserOrAdminAuthentication", () => { beforeEach(() => { - jest.clearAllMocks(); - jest.resetAllMocks(); + vi.clearAllMocks(); + vi.resetAllMocks(); }); test("should add subject and email to the request body if user token is valid", async () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); - await verifyUserOrAdminAuthentication(request, createResponse(), jest.fn()); + await verifyUserOrAdminAuthentication(request, createResponse(), vi.fn()); const { body: { userSubjectFromAuthToken, userEmailFromAuthToken }, } = request as { @@ -419,13 +419,12 @@ describe("verifyUserOrAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") + vi.spyOn(fusionAuthClient, "introspectAccessToken") .mockImplementationOnce(async () => expiredTokenIntrospectionResponse) .mockImplementationOnce(async () => expiredTokenIntrospectionResponse) .mockImplementationOnce(async () => successfulIntrospectionResponse); - await verifyUserOrAdminAuthentication(request, createResponse(), jest.fn()); + await verifyUserOrAdminAuthentication(request, createResponse(), vi.fn()); const { body: { adminSubjectFromAuthToken, adminEmailFromAuthToken }, } = request as { @@ -445,9 +444,9 @@ describe("verifyUserOrAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => failedIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => failedIntrospectionResponse, + ); await verifyUserOrAdminAuthentication( request, @@ -469,13 +468,12 @@ describe("verifyUserOrAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") + vi.spyOn(fusionAuthClient, "introspectAccessToken") .mockImplementationOnce(async () => expiredTokenIntrospectionResponse) .mockImplementationOnce(async () => successfulIntrospectionResponse) .mockImplementationOnce(async () => successfulIntrospectionResponse); - await verifyUserOrAdminAuthentication(request, createResponse(), jest.fn()); + await verifyUserOrAdminAuthentication(request, createResponse(), vi.fn()); const { body: { userSubjectFromAuthToken, userEmailFromAuthToken }, } = request as { @@ -495,9 +493,9 @@ describe("verifyUserOrAdminAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => expiredTokenIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => expiredTokenIntrospectionResponse, + ); await verifyUserOrAdminAuthentication( request, @@ -517,9 +515,9 @@ describe("verifyUserOrAdminAuthentication", () => { test("should throw unauthorized if the authentication header is formatted incorrectly", async () => { const request = createRequest({ headers: { Authorization: "test" } }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => expiredTokenIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => expiredTokenIntrospectionResponse, + ); await verifyUserOrAdminAuthentication( request, @@ -543,10 +541,10 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -555,7 +553,7 @@ describe("extractUserEmailFromAuthToken", () => { test("Request body has undefined emailFromAuthToken if there was no auth token", async () => { const request = createRequest({ headers: { Authorization: "" } }); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -566,10 +564,10 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => failedIntrospectionResponse); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => failedIntrospectionResponse, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -580,10 +578,10 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => expiredTokenIntrospectionResponse); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => expiredTokenIntrospectionResponse, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -594,12 +592,12 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => { + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => { throw new Error("unauthenticated"); - }); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + }, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -610,13 +608,13 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => failedIntrospectionResponse); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => successfulIntrospectionResponse); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => failedIntrospectionResponse, + ); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => successfulIntrospectionResponse, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -627,15 +625,15 @@ describe("extractUserEmailFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => { + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => { throw new Error("unauthenticated"); - }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => successfulIntrospectionResponse); - await extractUserEmailFromAuthToken(request, createResponse(), jest.fn()); + }, + ); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => successfulIntrospectionResponse, + ); + await extractUserEmailFromAuthToken(request, createResponse(), vi.fn()); const { body: { emailFromAuthToken }, } = request as { body: { emailFromAuthToken: string } }; @@ -649,15 +647,15 @@ describe("extractUserEmailFromAuthToken", () => { const testError = Object.assign(new Error("Rate Limit Exceeded"), { statusCode: 429, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => { + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => { throw testError; - }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => successfulIntrospectionResponse); - const next = jest.fn(); + }, + ); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => successfulIntrospectionResponse, + ); + const next = vi.fn(); await extractUserEmailFromAuthToken(request, createResponse(), next); expect(next).toHaveBeenCalledWith(testError); }); @@ -668,10 +666,10 @@ describe("extractUserIsAdminFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => successfulIntrospectionResponse); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => successfulIntrospectionResponse, + ); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -680,7 +678,7 @@ describe("extractUserIsAdminFromAuthToken", () => { test("is admin will be false if there is no auth token", async () => { const request = createRequest({ headers: { Authorization: "" } }); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -691,10 +689,10 @@ describe("extractUserIsAdminFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => failedIntrospectionResponse); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => failedIntrospectionResponse, + ); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -707,10 +705,10 @@ describe("extractUserIsAdminFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => successfulIntrospectionResponse); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => successfulIntrospectionResponse, + ); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -719,7 +717,7 @@ describe("extractUserIsAdminFromAuthToken", () => { test("is admin will be false if there is no auth token", async () => { const request = createRequest({ headers: { Authorization: "" } }); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -730,10 +728,10 @@ describe("extractUserIsAdminFromAuthToken", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementationOnce(async () => failedIntrospectionResponse); - await extractUserIsAdminFromAuthToken(request, createResponse(), jest.fn()); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementationOnce( + async () => failedIntrospectionResponse, + ); + await extractUserIsAdminFromAuthToken(request, createResponse(), vi.fn()); const { body: { admin }, } = request as { body: { admin: boolean } }; @@ -747,7 +745,7 @@ describe("extractShareTokenFromHeaders", () => { const request = createRequest({ headers: { "X-Permanent-Share-Token": testShareToken }, }); - extractShareTokenFromHeaders(request, createResponse(), jest.fn()); + extractShareTokenFromHeaders(request, createResponse(), vi.fn()); const { body: { shareToken }, } = request as { body: { shareToken: string } }; @@ -775,7 +773,7 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { await verifyUserOrAdminOrDelegatedCallAuthentication( request, createResponse(), - jest.fn(), + vi.fn(), ); const { body: { userEmailFromAuthToken, userSubjectFromAuthToken }, @@ -800,7 +798,7 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { await verifyUserOrAdminOrDelegatedCallAuthentication( request, createResponse(), - jest.fn(), + vi.fn(), ); expect( fieldsFromUserOrAdminAuthentication.validate(request.body).error, @@ -860,14 +858,14 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyUserOrAdminOrDelegatedCallAuthentication( request, createResponse(), - jest.fn(), + vi.fn(), ); const { body: { userSubjectFromAuthToken, userEmailFromAuthToken }, @@ -885,8 +883,7 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") + vi.spyOn(fusionAuthClient, "introspectAccessToken") .mockImplementationOnce(async () => expiredTokenIntrospectionResponse) .mockImplementationOnce(async () => expiredTokenIntrospectionResponse) .mockImplementationOnce(async () => successfulIntrospectionResponse); @@ -894,7 +891,7 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { await verifyUserOrAdminOrDelegatedCallAuthentication( request, createResponse(), - jest.fn(), + vi.fn(), ); const { body: { adminSubjectFromAuthToken, adminEmailFromAuthToken }, @@ -912,9 +909,9 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { const request = createRequest({ headers: { Authorization: "Bearer test" }, }); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => failedIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => failedIntrospectionResponse, + ); await verifyUserOrAdminOrDelegatedCallAuthentication( request, @@ -934,9 +931,9 @@ describe("verifyUserOrAdminOrDelegatedCallAuthentication", () => { test("should throw unauthorized if the authorization header is missing", async () => { const request = createRequest(); - jest - .spyOn(fusionAuthClient, "introspectAccessToken") - .mockImplementation(async () => successfulIntrospectionResponse); + vi.spyOn(fusionAuthClient, "introspectAccessToken").mockImplementation( + async () => successfulIntrospectionResponse, + ); await verifyUserOrAdminOrDelegatedCallAuthentication( request, createResponse(), diff --git a/packages/api/src/middleware/extract_ip.test.ts b/packages/api/src/middleware/extract_ip.test.ts index 57d3a063..3398f7da 100644 --- a/packages/api/src/middleware/extract_ip.test.ts +++ b/packages/api/src/middleware/extract_ip.test.ts @@ -1,11 +1,12 @@ import { createRequest, createResponse } from "node-mocks-http"; +import { describe, expect, test, vi } from "vitest"; import { extractIp } from "./extract_ip"; describe("extractIp", () => { test("should extract the IP from X-Forwarded-For header", () => { const testIp = "192.168.0.1"; const request = createRequest({ headers: { "X-Forwarded-For": testIp } }); - extractIp(request, createResponse(), jest.fn()); + extractIp(request, createResponse(), vi.fn()); const { body: { ip }, @@ -19,7 +20,7 @@ describe("extractIp", () => { remoteAddress: testIp, }, }); - extractIp(request, createResponse(), jest.fn()); + extractIp(request, createResponse(), vi.fn()); const { body: { ip }, @@ -34,7 +35,7 @@ describe("extractIp", () => { remoteAddress: testIp, }, }); - extractIp(request, createResponse(), jest.fn()); + extractIp(request, createResponse(), vi.fn()); const { body: { ip }, @@ -44,7 +45,7 @@ describe("extractIp", () => { test("should extract the client IP from X-Forwarded-For header with multiple proxies", () => { const testIp = "192.168.0.1"; const request = createRequest({ headers: { "X-Forwarded-For": testIp } }); - extractIp(request, createResponse(), jest.fn()); + extractIp(request, createResponse(), vi.fn()); const { body: { ip }, diff --git a/packages/api/src/middleware/handleError.test.ts b/packages/api/src/middleware/handleError.test.ts index 9a0adb11..3849bfab 100644 --- a/packages/api/src/middleware/handleError.test.ts +++ b/packages/api/src/middleware/handleError.test.ts @@ -1,20 +1,21 @@ import type { NextFunction } from "express"; +import { beforeEach, describe, expect, test, vi } from "vitest"; import { createRequest, createResponse } from "node-mocks-http"; import * as Sentry from "@sentry/node"; import { handleError } from "./handleError"; -jest.mock("@sentry/node", () => ({ - captureException: jest.fn(), +vi.mock("@sentry/node", () => ({ + captureException: vi.fn(), })); describe("handleError", () => { const request = createRequest(); const response = createResponse(); - response.status = jest.fn().mockReturnThis(); - response.json = jest.fn(); - const nextFunction = jest.fn() as NextFunction; + response.status = vi.fn().mockReturnThis(); + response.json = vi.fn(); + const nextFunction = vi.fn() as NextFunction; beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should respond with the status and error object if the error has 'status' property", async () => { diff --git a/packages/api/src/middleware/handleValidationError.test.ts b/packages/api/src/middleware/handleValidationError.test.ts index 991092e5..33f75890 100644 --- a/packages/api/src/middleware/handleValidationError.test.ts +++ b/packages/api/src/middleware/handleValidationError.test.ts @@ -1,16 +1,17 @@ import type { NextFunction } from "express"; +import { beforeEach, describe, expect, test, vi } from "vitest"; import { createRequest, createResponse } from "node-mocks-http"; import { handleValidationError } from "./handleValidationError"; describe("handleValidationError", () => { const request = createRequest(); const response = createResponse(); - response.status = jest.fn().mockReturnThis(); - response.json = jest.fn(); - const nextFunction = jest.fn() as NextFunction; + response.status = vi.fn().mockReturnThis(); + response.json = vi.fn(); + const nextFunction = vi.fn() as NextFunction; beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should respond with 400 and error message if error is a Joi ValidationError", () => { diff --git a/packages/api/src/promo/controller.test.ts b/packages/api/src/promo/controller.test.ts index e7358480..3cf56b59 100644 --- a/packages/api/src/promo/controller.test.ts +++ b/packages/api/src/promo/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; import createError from "http-errors"; import { logger } from "@stela/logger"; @@ -8,9 +9,9 @@ import type { Promo } from "./models"; import { db } from "../database"; import { mockVerifyAdminAuthentication } from "../../test/middleware_mocks"; -jest.mock("../middleware/authentication"); -jest.mock("../database"); -jest.mock("@stela/logger"); +vi.mock("../middleware/authentication"); +vi.mock("../database"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("promo.fixtures.create_test_promos"); @@ -22,18 +23,18 @@ const clearDatabase = async (): Promise => { describe("POST /promo", () => { const agent = request(app); beforeEach(async () => { + vi.restoreAllMocks(); + vi.clearAllMocks(); mockVerifyAdminAuthentication( "test@permanent.org", "6b640c73-4963-47de-a096-4a05ff8dc5f5", ); - jest.restoreAllMocks(); - jest.clearAllMocks(); await clearDatabase(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -50,11 +51,11 @@ describe("POST /promo", () => { }); test("should respond with 401 status code if lacking admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent.post("/api/v2/promo").expect(401); }); @@ -311,7 +312,7 @@ describe("POST /promo", () => { }); test("should respond with 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockImplementation(() => { + vi.spyOn(db, "sql").mockImplementation(() => { throw new Error("SQL error"); }); await agent @@ -327,7 +328,7 @@ describe("POST /promo", () => { test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent .post("/api/v2/promo") .send({ @@ -345,15 +346,15 @@ describe("GET /promo", () => { const agent = request(app); beforeEach(async () => { + vi.restoreAllMocks(); + vi.clearAllMocks(); mockVerifyAdminAuthentication("test@permanent.org"); - jest.restoreAllMocks(); - jest.clearAllMocks(); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -362,11 +363,11 @@ describe("GET /promo", () => { }); test("should respond with 401 status code if lacking admin authentication", async () => { - jest - .mocked(verifyAdminAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyAdminAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("You aren't logged in")); - }); + }, + ); await agent.get("/api/v2/promo").expect(401); }); @@ -415,14 +416,14 @@ describe("GET /promo", () => { test("should response with 500 status code if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/promo").expect(500); }); test("should log the error if the database call fails", async () => { const testError = new Error("SQL error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); await agent.get("/api/v2/promo").expect(500); expect(logger.error).toHaveBeenCalled(); diff --git a/packages/api/src/record/controller/copy_record.test.ts b/packages/api/src/record/controller/copy_record.test.ts index 067b8a9c..007765ef 100644 --- a/packages/api/src/record/controller/copy_record.test.ts +++ b/packages/api/src/record/controller/copy_record.test.ts @@ -1,6 +1,7 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { NextFunction } from "express"; -import { when } from "jest-when"; +import { when } from "vitest-when"; import createError from "http-errors"; import { logger } from "@stela/logger"; import { app } from "../../app"; @@ -11,10 +12,11 @@ import { mockVerifyUserAuthentication, mockExtractIp, } from "../../../test/middleware_mocks"; +import { mockSqlCall } from "../../../test/mock_sql"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("record.fixtures.create_test_accounts"); @@ -77,16 +79,16 @@ describe("POST /record/{recordId}/copies", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); }); test("expect 401 if not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError.Unauthorized("Invalid auth token")); - }); + }, + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -392,7 +394,7 @@ describe("POST /record/{recordId}/copies", () => { test("expect 500 if database lookup fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementationOnce(async () => { + vi.spyOn(db, "sql").mockImplementationOnce(async () => { throw testError; }); await agent @@ -403,9 +405,9 @@ describe("POST /record/{recordId}/copies", () => { }); test("expect 500 if transaction fails", async () => { - jest - .spyOn(db, "transaction") - .mockRejectedValueOnce(new Error("Transaction error")); + vi.spyOn(db, "transaction").mockRejectedValueOnce( + new Error("Transaction error"), + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -414,12 +416,12 @@ describe("POST /record/{recordId}/copies", () => { test("expect 500 if account space lookup fails", async () => { const testError = new Error("SQL error"); - const dbSpy = jest.spyOn(db, "sql"); - when(dbSpy) - .calledWith("storage.queries.get_account_space_for_update", { - email: "test@permanent.org", - }) - .mockRejectedValueOnce(testError); + mockSqlCall( + db, + "storage.queries.get_account_space_for_update", + { email: "test@permanent.org" }, + { reject: testError }, + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -428,16 +430,12 @@ describe("POST /record/{recordId}/copies", () => { }); test("expect 500 if account space lookup yields and empty response", async () => { - const dbSpy = jest.spyOn(db, "sql"); - when(dbSpy) - .calledWith("storage.queries.get_account_space_for_update", { - email: "test@permanent.org", - }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [], - }), - ); + mockSqlCall( + db, + "storage.queries.get_account_space_for_update", + { email: "test@permanent.org" }, + { resolve: { rows: [] } }, + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -449,9 +447,10 @@ describe("POST /record/{recordId}/copies", () => { test("expect 500 if copy query fails", async () => { const testError = new Error("SQL error"); - const dbSpy = jest.spyOn(db, "sql"); - when(dbSpy) - .calledWith("record.queries.copy_record", { + mockSqlCall( + db, + "record.queries.copy_record", + { destinationArchiveId: "1", destinationFolderId: "2", originalRecordId: "10008", @@ -459,8 +458,9 @@ describe("POST /record/{recordId}/copies", () => { destinationIsPublic: false, callerIp: "127.0.0.1", callerUserAgent: undefined, - }) - .mockRejectedValueOnce(testError); + }, + { reject: testError }, + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -469,9 +469,10 @@ describe("POST /record/{recordId}/copies", () => { }); test("expect 500 if copy query yields an empty response", async () => { - const dbSpy = jest.spyOn(db, "sql"); - when(dbSpy) - .calledWith("record.queries.copy_record", { + mockSqlCall( + db, + "record.queries.copy_record", + { destinationArchiveId: "1", destinationFolderId: "2", originalRecordId: "10008", @@ -479,12 +480,9 @@ describe("POST /record/{recordId}/copies", () => { destinationIsPublic: false, callerIp: "127.0.0.1", callerUserAgent: undefined, - }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [], - }), - ); + }, + { resolve: { rows: [] } }, + ); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) @@ -494,7 +492,7 @@ describe("POST /record/{recordId}/copies", () => { test("expect 500 if copy cannot be found after its creation", async () => { const fakeCopiedRecordId = "99999"; - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) .calledWith("record.queries.copy_record", { destinationArchiveId: "1", @@ -505,10 +503,8 @@ describe("POST /record/{recordId}/copies", () => { callerIp: "127.0.0.1", callerUserAgent: undefined, }) - .mockImplementationOnce( - jest - .fn() - .mockResolvedValueOnce({ rows: [{ recordId: fakeCopiedRecordId }] }), + .thenDo( + vi.fn().mockResolvedValue({ rows: [{ recordId: fakeCopiedRecordId }] }), ); when(dbSpy) .calledWith("record.queries.get_records", { @@ -517,7 +513,7 @@ describe("POST /record/{recordId}/copies", () => { accountEmail: "test@permanent.org", shareToken: undefined, }) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .post("/api/v2/records/10008/copies") .send({ destinationFolderId: "2" }) diff --git a/packages/api/src/record/controller/get_record_share_links.test.ts b/packages/api/src/record/controller/get_record_share_links.test.ts index c9d62e67..169c1ff9 100644 --- a/packages/api/src/record/controller/get_record_share_links.test.ts +++ b/packages/api/src/record/controller/get_record_share_links.test.ts @@ -1,4 +1,5 @@ import type { NextFunction } from "express"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import createError from "http-errors"; import { logger } from "@stela/logger"; import request from "supertest"; @@ -8,9 +9,9 @@ import { verifyUserAuthentication } from "../../middleware"; import type { ShareLink } from "../../share_link/models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("record.fixtures.create_test_accounts"); @@ -73,8 +74,8 @@ describe("GET /records/{id}/share-links", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("expect to return share links for a record", async () => { @@ -123,7 +124,7 @@ describe("GET /records/{id}/share-links", () => { test("expect to log error and return 500 if database lookup fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -132,11 +133,11 @@ describe("GET /records/{id}/share-links", () => { }); test("expect 401 if not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(createError.Unauthorized("Invalid auth token")); - }); + }, + ); await agent.get("/api/v2/records/10001/share-links").expect(401); }); diff --git a/packages/api/src/record/controller/get_records.test.ts b/packages/api/src/record/controller/get_records.test.ts index 07c17498..de42dd1f 100644 --- a/packages/api/src/record/controller/get_records.test.ts +++ b/packages/api/src/record/controller/get_records.test.ts @@ -1,3 +1,4 @@ +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import request from "supertest"; import { app } from "../../app"; @@ -9,9 +10,9 @@ import { mockExtractUserEmailFromAuthToken, } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("record.fixtures.create_test_accounts"); @@ -70,8 +71,8 @@ describe("GET /records", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); const agent = request(app); @@ -460,7 +461,7 @@ describe("GET /records", () => { }); test("expect to log error and return 500 if database lookup fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); diff --git a/packages/api/src/record/controller/get_single_record.test.ts b/packages/api/src/record/controller/get_single_record.test.ts index 8308b9b7..ee80148d 100644 --- a/packages/api/src/record/controller/get_single_record.test.ts +++ b/packages/api/src/record/controller/get_single_record.test.ts @@ -1,3 +1,4 @@ +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import request from "supertest"; import { app } from "../../app"; @@ -8,9 +9,9 @@ import { mockExtractUserEmailFromAuthToken, } from "../../../test/middleware_mocks"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("record.fixtures.create_test_accounts"); @@ -69,8 +70,8 @@ describe("GET /records/:recordId", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); const agent = request(app); @@ -217,7 +218,7 @@ describe("GET /records/:recordId", () => { }); test("expect to log error and return 500 if database lookup fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); diff --git a/packages/api/src/record/controller/update_record.test.ts b/packages/api/src/record/controller/update_record.test.ts index 72bfd1ff..ca0afe67 100644 --- a/packages/api/src/record/controller/update_record.test.ts +++ b/packages/api/src/record/controller/update_record.test.ts @@ -1,15 +1,17 @@ -import { when } from "jest-when"; +import { when } from "vitest-when"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import request from "supertest"; import { app } from "../../app"; import { db } from "../../database"; import { AccessRole } from "../../access/models"; import { mockVerifyUserAuthentication } from "../../../test/middleware_mocks"; +import { mockSqlCall } from "../../../test/mock_sql"; import type { ArchiveRecord } from "../models"; -jest.mock("../../database"); -jest.mock("../../middleware"); -jest.mock("@stela/logger"); +vi.mock("../../database"); +vi.mock("../../middleware"); +vi.mock("@stela/logger"); const setupDatabase = async (): Promise => { await db.sql("record.fixtures.create_test_accounts"); @@ -72,8 +74,8 @@ describe("PATCH /records", () => { afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); }); test("expect an empty query to cause a 400 error", async () => { @@ -218,7 +220,7 @@ describe("PATCH /records", () => { test("expect to log error and return 500 if database permissions query fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementation(async () => { + vi.spyOn(db, "sql").mockImplementation(async () => { throw testError; }); @@ -232,14 +234,14 @@ describe("PATCH /records", () => { test("expect to log error and return 500 if database update query fails", async () => { const testError = new Error("test error"); - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) .calledWith("access.queries.get_record_access_role", { itemId: "10001", email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ + .thenDo( + vi.fn().mockResolvedValue({ rows: [ { archiveAccessRole: AccessRole.Owner, @@ -247,7 +249,8 @@ describe("PATCH /records", () => { }, ], }), - ) + ); + when(dbSpy) .calledWith("record.queries.update_record", { recordId: "10001", displayName: undefined, @@ -258,7 +261,7 @@ describe("PATCH /records", () => { displayTime: undefined, setDisplayTimeToNull: false, }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .patch("/api/v2/records/10001") @@ -291,14 +294,14 @@ describe("PATCH /records", () => { }); test("expect to return 404 if database update updates nothing", async () => { - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) .calledWith("access.queries.get_record_access_role", { itemId: "10001", email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ + .thenDo( + vi.fn().mockResolvedValue({ rows: [ { archiveAccessRole: AccessRole.Owner, @@ -306,7 +309,8 @@ describe("PATCH /records", () => { }, ], }), - ) + ); + when(dbSpy) .calledWith("record.queries.update_record", { recordId: "10001", displayName: undefined, @@ -317,11 +321,7 @@ describe("PATCH /records", () => { displayTime: undefined, setDisplayTimeToNull: false, }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ - rows: [], - }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .patch("/api/v2/records/10001") @@ -516,16 +516,12 @@ describe("PATCH /records", () => { }); test("expect 404 if record disappears between access check and location lookup", async () => { - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("record.queries.get_record_location_id", { - recordId: "10001", - }) - .mockImplementationOnce( - jest.fn().mockResolvedValue({ - rows: [], - }), - ); + mockSqlCall( + db, + "record.queries.get_record_location_id", + { recordId: "10001" }, + { resolve: { rows: [] } }, + ); await agent .patch("/api/v2/records/10001") @@ -535,12 +531,12 @@ describe("PATCH /records", () => { test("expect 500 if the record location lookup query fails", async () => { const testError = new Error("test error"); - const sqlSpy = jest.spyOn(db, "sql"); - when(sqlSpy) - .calledWith("record.queries.get_record_location_id", { - recordId: "10001", - }) - .mockImplementationOnce(jest.fn().mockRejectedValue(testError)); + mockSqlCall( + db, + "record.queries.get_record_location_id", + { recordId: "10001" }, + { reject: testError }, + ); await agent .patch("/api/v2/records/10001") diff --git a/packages/api/src/record/validators.test.ts b/packages/api/src/record/validators.test.ts index bb4cbd0b..4e85ffcb 100644 --- a/packages/api/src/record/validators.test.ts +++ b/packages/api/src/record/validators.test.ts @@ -1,4 +1,5 @@ import { validatePatchRecordRequest } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validatePatchRecordRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/share_link/controller.test.ts b/packages/api/src/share_link/controller.test.ts index 23a0f4ef..73434fbc 100644 --- a/packages/api/src/share_link/controller.test.ts +++ b/packages/api/src/share_link/controller.test.ts @@ -1,8 +1,9 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import type { Request, Response, NextFunction } from "express"; import createError from "http-errors"; import { v4 as uuidv4 } from "uuid"; -import { when } from "jest-when"; +import { when } from "vitest-when"; import { app } from "../app"; import { extractUserEmailFromAuthToken, @@ -14,10 +15,11 @@ import { mockVerifyUserAuthentication, mockExtractUserEmailFromAuthToken, } from "../../test/middleware_mocks"; +import { mockSqlCall } from "../../test/mock_sql"; -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("uuid"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("uuid"); const loadFixtures = async (): Promise => { await db.sql("share_link.fixtures.create_test_accounts"); @@ -80,7 +82,7 @@ describe("POST /share-links", () => { const testUuid = "3afb2671-bc26-4928-9ea9-0ad4cb735f11"; beforeEach(async () => { - jest.mocked(uuidv4).mockImplementation(jest.fn().mockReturnValue(testUuid)); + vi.mocked(uuidv4).mockImplementation(vi.fn().mockReturnValue(testUuid)); mockVerifyUserAuthentication( "test@permanent.org", "315aedc2-67d5-4144-9f0d-ee547d98af9c", @@ -89,8 +91,8 @@ describe("POST /share-links", () => { }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); await clearDatabase(); }); @@ -115,11 +117,11 @@ describe("POST /share-links", () => { }); test("should return 401 if the caller is not authenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent.post("/api/v2/share-links").expect(401); }); @@ -262,7 +264,7 @@ describe("POST /share-links", () => { test("should return a 500 error if the database call fails", async () => { const testError = new Error("Test error"); - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) .calledWith("share_link.queries.create_share_link", { itemId: "2", @@ -276,7 +278,7 @@ describe("POST /share-links", () => { shareUrl: `https://${process.env["SITE_URL"] ?? ""}/share/${testUuid}`, email: "test@permanent.org", }) - .mockRejectedValue(testError); + .thenReject(testError); await agent .post("/api/v2/share-links") .send({ @@ -287,9 +289,10 @@ describe("POST /share-links", () => { }); test("should return a 404 error if the database returns an empty result", async () => { - const dbSpy = jest.spyOn(db, "sql"); - when(dbSpy) - .calledWith("share_link.queries.create_share_link", { + mockSqlCall( + db, + "share_link.queries.create_share_link", + { itemId: "2", itemType: "record", permissionsLevel: "access.role.viewer", @@ -300,8 +303,9 @@ describe("POST /share-links", () => { urlToken: testUuid, shareUrl: `https://${process.env["SITE_URL"] ?? ""}/share/${testUuid}`, email: "test@permanent.org", - }) - .mockImplementation(jest.fn().mockResolvedValue({ rows: [] })); + }, + { resolve: { rows: [] } }, + ); await agent .post("/api/v2/share-links") .send({ @@ -345,8 +349,8 @@ describe("PATCH /share-links/{id}", () => { }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.resetAllMocks(); await clearDatabase(); }); @@ -358,11 +362,11 @@ describe("PATCH /share-links/{id}", () => { }); test("should return 401 if the caller is unauthenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (_, __, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (_, __, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent.patch("/api/v2/share-links/1").send({}).expect(401); }); @@ -534,7 +538,7 @@ describe("PATCH /share-links/{id}", () => { }); test("should return 500 if the query to retrieve the share link fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); await agent .patch("/api/v2/share-links/1000") .send({ @@ -547,7 +551,7 @@ describe("PATCH /share-links/{id}", () => { }); test("should return 500 if the query to update the share link fails", async () => { - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); when(dbSpy) .calledWith("share_link.queries.update_share_link", { permissionsLevel: "access.role.editor", @@ -560,7 +564,7 @@ describe("PATCH /share-links/{id}", () => { shareLinkId: "1000", email: "test@permanent.org", }) - .mockRejectedValue(new Error("Test error")); + .thenReject(new Error("Test error")); await agent .patch("/api/v2/share-links/1000") .send({ @@ -581,7 +585,7 @@ describe("GET /share-links", () => { }); afterEach(async () => { - jest.restoreAllMocks(); + vi.restoreAllMocks(); await clearDatabase(); }); @@ -590,17 +594,15 @@ describe("GET /share-links", () => { }); test("should return 401 if the caller's auth token is invalid", async () => { - jest - .mocked(extractUserEmailFromAuthToken) - .mockImplementation( - async ( - _: Request, - __: Response, - next: NextFunction, - ) => { - next(new createError.Unauthorized("Invalid token")); - }, - ); + vi.mocked(extractUserEmailFromAuthToken).mockImplementation( + async ( + _: Request, + __: Response, + next: NextFunction, + ) => { + next(new createError.Unauthorized("Invalid token")); + }, + ); await agent.get("/api/v2/share-links?shareLinkIds[]=1").expect(401); }); @@ -699,9 +701,9 @@ describe("GET /share-links", () => { }); test("should return a 500 error if the database call fails", async () => { - jest - .spyOn(db, "sql") - .mockRejectedValue(new Error("out of cheese - redo from start")); + vi.spyOn(db, "sql").mockRejectedValue( + new Error("out of cheese - redo from start"), + ); await agent.get("/api/v2/share-links?shareLinkIds[]=1000").expect(500); }); }); @@ -726,11 +728,11 @@ describe("DELETE /share-links", () => { }); test("should return 401 if the caller is unauthenticated", async () => { - jest - .mocked(verifyUserAuthentication) - .mockImplementation(async (__, _, next: NextFunction) => { + vi.mocked(verifyUserAuthentication).mockImplementation( + async (__, _, next: NextFunction) => { next(new createError.Unauthorized("Invalid token")); - }); + }, + ); await agent.delete("/api/v2/share-links/1000").expect(401); }); @@ -740,6 +742,7 @@ describe("DELETE /share-links", () => { }); test("should delete the share link", async () => { + mockExtractUserEmailFromAuthToken("test@permanent.org"); await agent.delete("/api/v2/share-links/1000").expect(204); const response = await agent .get("/api/v2/share-links?shareLinkIds[]=1000") @@ -764,7 +767,7 @@ describe("DELETE /share-links", () => { }); test("should return 500 if the database call fails", async () => { - jest.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); + vi.spyOn(db, "sql").mockRejectedValue(new Error("Test error")); await agent.delete("/api/v2/share-links/1000").expect(500); }); }); diff --git a/packages/api/src/share_link/validators.test.ts b/packages/api/src/share_link/validators.test.ts index 571e579e..2d6ad989 100644 --- a/packages/api/src/share_link/validators.test.ts +++ b/packages/api/src/share_link/validators.test.ts @@ -4,6 +4,7 @@ import { validateGetShareLinksParameters, validateShareLinkParameters, } from "./validators"; +import { describe, expect, test } from "vitest"; describe("validateCreateShareLinkRequest", () => { test("should find no errors in a valid request", () => { diff --git a/packages/api/src/storage/controller.test.ts b/packages/api/src/storage/controller.test.ts index 63e4875d..9986318e 100644 --- a/packages/api/src/storage/controller.test.ts +++ b/packages/api/src/storage/controller.test.ts @@ -1,5 +1,6 @@ import request from "supertest"; -import { when } from "jest-when"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { when } from "vitest-when"; import { logger } from "@stela/logger"; import { app } from "../app"; import { verifyUserAuthentication } from "../middleware"; @@ -8,10 +9,10 @@ import { GB } from "../constants"; import { sendInvitationNotification, sendGiftNotification } from "../email"; import { mockVerifyUserAuthentication } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../middleware"); -jest.mock("../email"); -jest.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("../middleware"); +vi.mock("../email"); +vi.mock("@stela/logger"); interface AccountSpace { spaceLeft: string; @@ -132,7 +133,7 @@ describe("/storage/gift", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); + vi.resetAllMocks(); }); test("should call verifyUserAuthentication", async () => { @@ -549,7 +550,7 @@ describe("/storage/gift", () => { test("should log error and return 500 if check for existing emails fails", async () => { const testError = new Error("test error"); - jest.spyOn(db, "sql").mockImplementationOnce(async () => { + vi.spyOn(db, "sql").mockImplementationOnce(async () => { throw testError; }); @@ -563,12 +564,17 @@ describe("/storage/gift", () => { test("should log error and return 500 if check for invited emails fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); + when(spy) + .calledWith("storage.queries.get_existing_account_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.get_invited_emails", { emails: ["test+1@permanent.org"], }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .post("/api/v2/storage/gift") @@ -580,12 +586,22 @@ describe("/storage/gift", () => { test("should log error and return 500 if check for available space fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); + when(spy) + .calledWith("storage.queries.get_existing_account_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); + when(spy) + .calledWith("storage.queries.get_invited_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.get_account_space_for_update", { email: "test@permanent.org", }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .post("/api/v2/storage/gift") @@ -596,12 +612,22 @@ describe("/storage/gift", () => { }); test("should log error and return 500 if check for available space finds nothing", async () => { - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); + when(spy) + .calledWith("storage.queries.get_existing_account_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); + when(spy) + .calledWith("storage.queries.get_invited_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.get_account_space_for_update", { email: "test@permanent.org", }) - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); await agent .post("/api/v2/storage/gift") @@ -615,23 +641,24 @@ describe("/storage/gift", () => { test("should log error and return 500 if recording gifts for existing accounts fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); when(spy) .calledWith("storage.queries.get_existing_account_emails", { emails: ["test+1@permanent.org"], }) - .mockImplementationOnce( - jest + .thenDo( + vi .fn() - .mockResolvedValueOnce({ rows: [{ email: "test+1@permanent.org" }] }), + .mockResolvedValue({ rows: [{ email: "test+1@permanent.org" }] }), ); + when(spy) + .calledWith("storage.queries.get_invited_emails", { emails: [] }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.get_account_space_for_update", { email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ rows: [{ spaceLeft: 2 * GB }] }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ spaceLeft: 2 * GB }] })); when(spy) .calledWith("storage.queries.record_gift", { fromEmail: "test@permanent.org", @@ -639,7 +666,7 @@ describe("/storage/gift", () => { storageAmountInBytes: 1 * GB, recipientCount: 1, }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .post("/api/v2/storage/gift") @@ -651,14 +678,30 @@ describe("/storage/gift", () => { test("should log error and return 500 if creating invites fails", async () => { const testError = new Error("test error"); - const spy = jest.spyOn(db, "sql"); + const spy = vi.spyOn(db, "sql"); + when(spy) + .calledWith("storage.queries.get_existing_account_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); + when(spy) + .calledWith("storage.queries.get_invited_emails", { + emails: ["test+1@permanent.org"], + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.get_account_space_for_update", { email: "test@permanent.org", }) - .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ rows: [{ spaceLeft: 2 * GB }] }), - ); + .thenDo(vi.fn().mockResolvedValue({ rows: [{ spaceLeft: 2 * GB }] })); + when(spy) + .calledWith("storage.queries.record_gift", { + fromEmail: "test@permanent.org", + toEmails: [], + storageAmountInBytes: 1 * GB, + recipientCount: 0, + }) + .thenDo(vi.fn().mockResolvedValue({ rows: [] })); when(spy) .calledWith("storage.queries.create_invites", { emails: ["test+1@permanent.org"], @@ -667,7 +710,7 @@ describe("/storage/gift", () => { byAccountEmail: "test@permanent.org", recipientCount: 1, }) - .mockRejectedValueOnce(testError); + .thenReject(testError); await agent .post("/api/v2/storage/gift") diff --git a/packages/api/src/storage_purchase/controller.test.ts b/packages/api/src/storage_purchase/controller.test.ts index 92783661..0771c1c4 100644 --- a/packages/api/src/storage_purchase/controller.test.ts +++ b/packages/api/src/storage_purchase/controller.test.ts @@ -1,4 +1,5 @@ import request from "supertest"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import Stripe from "stripe"; import { logger } from "@stela/logger"; import { app } from "../app"; @@ -8,11 +9,11 @@ import { legacyClient } from "../legacy_client"; import { verifyUserAuthentication } from "../middleware"; import { mockVerifyUserAuthentication } from "../../test/middleware_mocks"; -jest.mock("../database"); -jest.mock("../stripe"); -jest.mock("../legacy_client"); -jest.mock("../middleware"); -jest.mock("@stela/logger"); +vi.mock("../database"); +vi.mock("../stripe"); +vi.mock("../legacy_client"); +vi.mock("../middleware"); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("storage_purchase.fixtures.create_test_accounts"); @@ -30,27 +31,23 @@ describe("POST /storage-purchases", () => { "test@permanent.org", "5a4b6d8c-2e1f-7a3b-9c0d-4e5f6a7b8c9d", ); - jest - .spyOn(stripeClient.customers, "list") - .mockImplementation( - jest.fn().mockResolvedValue({ data: [{ id: "cus_stripe123" }] }), - ); - jest - .spyOn(stripeClient.customers, "create") - .mockImplementation(jest.fn().mockResolvedValue({ id: "cus_new123" })); - jest - .spyOn(stripeClient.paymentIntents, "create") - .mockImplementation( - jest.fn().mockResolvedValue({ client_secret: "test_client_secret" }), - ); + vi.spyOn(stripeClient.customers, "list").mockImplementation( + vi.fn().mockResolvedValue({ data: [{ id: "cus_stripe123" }] }), + ); + vi.spyOn(stripeClient.customers, "create").mockImplementation( + vi.fn().mockResolvedValue({ id: "cus_new123" }), + ); + vi.spyOn(stripeClient.paymentIntents, "create").mockImplementation( + vi.fn().mockResolvedValue({ client_secret: "test_client_secret" }), + ); await clearDatabase(); await loadFixtures(); }); afterEach(async () => { await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("should call verifyUserAuthentication", async () => { @@ -98,9 +95,9 @@ describe("POST /storage-purchases", () => { }); test("should create a new Stripe customer if none exists", async () => { - jest - .spyOn(stripeClient.customers, "list") - .mockImplementation(jest.fn().mockResolvedValue({ data: [] })); + vi.spyOn(stripeClient.customers, "list").mockImplementation( + vi.fn().mockResolvedValue({ data: [] }), + ); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -133,7 +130,7 @@ describe("POST /storage-purchases", () => { "test+1@permanent.org", "5a4b6d8c-2e1f-7a3b-9c0d-4e5f6a7b8c9d", ); - const dbSpy = jest.spyOn(db, "sql"); + const dbSpy = vi.spyOn(db, "sql"); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -173,11 +170,9 @@ describe("POST /storage-purchases", () => { }); test("should return 500 if the account lookup fails", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("DB error")), - ); + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockRejectedValueOnce(new Error("DB error")), + ); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -185,11 +180,9 @@ describe("POST /storage-purchases", () => { }); test("should return 500 if the Stripe customer lookup fails", async () => { - jest - .spyOn(stripeClient.customers, "list") - .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("Stripe error")), - ); + vi.spyOn(stripeClient.customers, "list").mockImplementationOnce( + vi.fn().mockRejectedValueOnce(new Error("Stripe error")), + ); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -197,14 +190,12 @@ describe("POST /storage-purchases", () => { }); test("should return 500 if Stripe customer creation fails", async () => { - jest - .spyOn(stripeClient.customers, "list") - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ data: [] })); - jest - .spyOn(stripeClient.customers, "create") - .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("Stripe error")), - ); + vi.spyOn(stripeClient.customers, "list").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ data: [] }), + ); + vi.spyOn(stripeClient.customers, "create").mockImplementationOnce( + vi.fn().mockRejectedValueOnce(new Error("Stripe error")), + ); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -212,13 +203,12 @@ describe("POST /storage-purchases", () => { }); test("should return 500 if saving the customer ID fails", async () => { - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockImplementationOnce( - jest.fn().mockResolvedValueOnce({ rows: [{ stripeCustomerId: null }] }), + vi.fn().mockResolvedValueOnce({ rows: [{ stripeCustomerId: null }] }), ) .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("DB error")), + vi.fn().mockRejectedValueOnce(new Error("DB error")), ); await agent .post("/api/v2/storage-purchases") @@ -227,11 +217,9 @@ describe("POST /storage-purchases", () => { }); test("should return 500 if payment intent creation fails", async () => { - jest - .spyOn(stripeClient.paymentIntents, "create") - .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("Stripe error")), - ); + vi.spyOn(stripeClient.paymentIntents, "create").mockImplementationOnce( + vi.fn().mockRejectedValueOnce(new Error("Stripe error")), + ); await agent .post("/api/v2/storage-purchases") .send({ amountInUSD: 10 }) @@ -255,12 +243,12 @@ describe("POST /storage-purchases/stripe/webhook", () => { beforeEach(async () => { process.env["STRIPE_WEBHOOK_SECRET"] = "test_webhook_secret"; - jest - .spyOn(stripeClient.webhooks, "constructEvent") - .mockImplementation(jest.fn().mockReturnValue(mockSuccessEvent)); - jest - .spyOn(legacyClient, "creditStorage") - .mockImplementation(jest.fn().mockResolvedValue({ ok: true })); + vi.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( + vi.fn().mockReturnValue(mockSuccessEvent), + ); + vi.spyOn(legacyClient, "creditStorage").mockImplementation( + vi.fn().mockResolvedValue({ ok: true }), + ); await clearDatabase(); await loadFixtures(); }); @@ -269,8 +257,8 @@ describe("POST /storage-purchases/stripe/webhook", () => { delete process.env["STRIPE_WEBHOOK_SECRET"]; delete process.env["SLACK_WEBHOOK_URL"]; await clearDatabase(); - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); }); test("should return 400 if no stripe-signature header", async () => { @@ -294,8 +282,8 @@ describe("POST /storage-purchases/stripe/webhook", () => { const signatureError = new Stripe.errors.StripeSignatureVerificationError({ type: "api_error", }); - jest.spyOn(stripeClient.webhooks, "constructEvent").mockImplementationOnce( - jest.fn().mockImplementation(() => { + vi.spyOn(stripeClient.webhooks, "constructEvent").mockImplementationOnce( + vi.fn().mockImplementation(() => { throw signatureError; }), ); @@ -330,8 +318,8 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 200 on payment_intent.payment_failed and log the failure", async () => { - jest.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( - jest.fn().mockReturnValueOnce({ + vi.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( + vi.fn().mockReturnValueOnce({ type: "payment_intent.payment_failed", data: { object: mockPaymentIntent }, }), @@ -348,8 +336,8 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 200 on unhandled event types", async () => { - jest.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( - jest.fn().mockReturnValueOnce({ + vi.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( + vi.fn().mockReturnValueOnce({ type: "customer.created", data: { object: {} }, }), @@ -373,8 +361,8 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 400 if the payment intent customer is not a string", async () => { - jest.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( - jest.fn().mockReturnValue({ + vi.spyOn(stripeClient.webhooks, "constructEvent").mockImplementation( + vi.fn().mockReturnValue({ ...mockSuccessEvent, data: { object: { ...mockPaymentIntent, customer: null } }, }), @@ -388,11 +376,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 500 if the account lookup fails", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce( - jest.fn().mockRejectedValueOnce(new Error("DB error")), - ); + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockRejectedValueOnce(new Error("DB error")), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -402,9 +388,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 500 if no account is found for the Stripe customer", async () => { - jest - .spyOn(db, "sql") - .mockImplementationOnce(jest.fn().mockResolvedValueOnce({ rows: [] })); + vi.spyOn(db, "sql").mockImplementationOnce( + vi.fn().mockResolvedValueOnce({ rows: [] }), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -414,9 +400,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 500 if creditStorage throws", async () => { - jest - .spyOn(legacyClient, "creditStorage") - .mockRejectedValueOnce(new Error("Network error")); + vi.spyOn(legacyClient, "creditStorage").mockRejectedValueOnce( + new Error("Network error"), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -426,11 +412,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should return 500 if the legacy API returns an error", async () => { - jest - .spyOn(legacyClient, "creditStorage") - .mockImplementation( - jest.fn().mockResolvedValueOnce({ ok: false, status: 500 }), - ); + vi.spyOn(legacyClient, "creditStorage").mockImplementation( + vi.fn().mockResolvedValueOnce({ ok: false, status: 500 }), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -441,9 +425,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { test("should send a Slack notification on payment_intent.succeeded", async () => { process.env["SLACK_WEBHOOK_URL"] = "https://hooks.slack.com/test"; - jest - .spyOn(global, "fetch") - .mockImplementation(jest.fn().mockResolvedValue({ ok: true })); + vi.spyOn(global, "fetch").mockImplementation( + vi.fn().mockResolvedValue({ ok: true }), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -463,9 +447,9 @@ describe("POST /storage-purchases/stripe/webhook", () => { }); test("should not send a Slack notification if SLACK_WEBHOOK_URL is not set", async () => { - jest - .spyOn(global, "fetch") - .mockImplementation(jest.fn().mockResolvedValue({ ok: true })); + vi.spyOn(global, "fetch").mockImplementation( + vi.fn().mockResolvedValue({ ok: true }), + ); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") @@ -476,7 +460,7 @@ describe("POST /storage-purchases/stripe/webhook", () => { test("should return 200 if the Slack notification fails", async () => { process.env["SLACK_WEBHOOK_URL"] = "https://hooks.slack.com/test"; - jest.spyOn(global, "fetch").mockRejectedValue(new Error("Slack error")); + vi.spyOn(global, "fetch").mockRejectedValue(new Error("Slack error")); await agent .post("/api/v2/storage-purchases/stripe/webhook") .set("stripe-signature", "test_sig") diff --git a/packages/api/src/validators/shared.test.ts b/packages/api/src/validators/shared.test.ts index 83b14602..c9e2e643 100644 --- a/packages/api/src/validators/shared.test.ts +++ b/packages/api/src/validators/shared.test.ts @@ -6,6 +6,7 @@ import { validateOptionalAuthenticationValues, validatePaginationParameters, } from "./shared"; +import { describe, expect, test } from "vitest"; describe("validateBodyFromAuthentication", () => { test("should find no errors in valid parameter set", () => { diff --git a/packages/api/src/validators/validator_util.test.ts b/packages/api/src/validators/validator_util.test.ts index cc7bd2ab..8f9d3e7e 100644 --- a/packages/api/src/validators/validator_util.test.ts +++ b/packages/api/src/validators/validator_util.test.ts @@ -1,4 +1,5 @@ import { isValidationError } from "./validator_util"; +import { describe, expect, test } from "vitest"; describe("isValidationError", () => { test("should recognize a ValidationError", () => { diff --git a/packages/api/test/middleware_mocks.ts b/packages/api/test/middleware_mocks.ts index 6a056cb5..fe281b58 100644 --- a/packages/api/test/middleware_mocks.ts +++ b/packages/api/test/middleware_mocks.ts @@ -1,4 +1,5 @@ import type { NextFunction, Request } from "express"; +import { vi } from "vitest"; import { extractShareTokenFromHeaders, extractUserEmailFromAuthToken, @@ -10,68 +11,62 @@ import { } from "../src/middleware"; export const mockExtractUserEmailFromAuthToken = (mockEmail?: string): void => { - jest - .mocked(extractUserEmailFromAuthToken) - .mockImplementation( - async ( - req: Request, - __, - next: NextFunction, - ) => { - if (mockEmail !== undefined) { - req.body.emailFromAuthToken = mockEmail; - } - next(); - }, - ); + vi.mocked(extractUserEmailFromAuthToken).mockImplementation( + async ( + req: Request, + __, + next: NextFunction, + ) => { + if (mockEmail !== undefined) { + req.body.emailFromAuthToken = mockEmail; + } + next(); + }, + ); }; export const mockExtractShareTokenFromHeaders = ( mockShareToken?: string, ): void => { - jest - .mocked(extractShareTokenFromHeaders) - .mockImplementation( - ( - req: Request< - unknown, - unknown, - { emailFromAuthToken?: string; shareToken: string | undefined } - >, - __, - next: NextFunction, - ) => { - if (mockShareToken !== undefined) { - req.body.shareToken = mockShareToken; - } - next(); - }, - ); + vi.mocked(extractShareTokenFromHeaders).mockImplementation( + ( + req: Request< + unknown, + unknown, + { emailFromAuthToken?: string; shareToken: string | undefined } + >, + __, + next: NextFunction, + ) => { + if (mockShareToken !== undefined) { + req.body.shareToken = mockShareToken; + } + next(); + }, + ); }; export const mockExtractIp = (ip?: string): void => { - jest - .mocked(extractIp) - .mockImplementation( - ( - req: Request, - __, - next: NextFunction, - ) => { - if (ip !== undefined) { - req.body.ip = ip; - } + vi.mocked(extractIp).mockImplementation( + ( + req: Request, + __, + next: NextFunction, + ) => { + if (ip !== undefined) { + req.body.ip = ip; + } - next(); - }, - ); + next(); + }, + ); }; export const mockVerifyUserAuthentication = ( mockUserEmail?: string, mockUserSubject?: string, ): void => { - jest.mocked(verifyUserAuthentication).mockImplementation( + vi.mocked(verifyUserAuthentication).mockImplementation( async ( req: Request< unknown, @@ -99,7 +94,7 @@ export const mockVerifyAdminAuthentication = ( mockAdminEmail?: string, mockAdminSubject?: string, ): void => { - jest.mocked(verifyAdminAuthentication).mockImplementation( + vi.mocked(verifyAdminAuthentication).mockImplementation( async ( req: Request< unknown, @@ -124,18 +119,16 @@ export const mockVerifyAdminAuthentication = ( }; export const mockExtractUserIsAdminFromAuthToken = (isAdmin: boolean): void => { - jest - .mocked(extractUserIsAdminFromAuthToken) - .mockImplementation( - async ( - req: Request, - __, - next: NextFunction, - ) => { - req.body.admin = isAdmin; - next(); - }, - ); + vi.mocked(extractUserIsAdminFromAuthToken).mockImplementation( + async ( + req: Request, + __, + next: NextFunction, + ) => { + req.body.admin = isAdmin; + next(); + }, + ); }; export const mockVerifyUserOrAdminOrDelegatedCallAuthentication = ( @@ -144,28 +137,26 @@ export const mockVerifyUserOrAdminOrDelegatedCallAuthentication = ( mockAdminEmail: string | undefined, mockAdminSubject: string | undefined, ): void => { - jest - .mocked(verifyUserOrAdminOrDelegatedCallAuthentication) - .mockImplementation( - async ( - req: Request< - unknown, - unknown, - { - userEmailFromAuthToken?: string | undefined; - userSubjectFromAuthToken?: string | undefined; - adminEmailFromAuthToken?: string | undefined; - adminSubjectFromAuthToken?: string | undefined; - } - >, - __, - next: NextFunction, - ) => { - req.body.userEmailFromAuthToken = mockUserEmail; - req.body.userSubjectFromAuthToken = mockUserSubject; - req.body.adminEmailFromAuthToken = mockAdminEmail; - req.body.adminSubjectFromAuthToken = mockAdminSubject; - next(); - }, - ); + vi.mocked(verifyUserOrAdminOrDelegatedCallAuthentication).mockImplementation( + async ( + req: Request< + unknown, + unknown, + { + userEmailFromAuthToken?: string | undefined; + userSubjectFromAuthToken?: string | undefined; + adminEmailFromAuthToken?: string | undefined; + adminSubjectFromAuthToken?: string | undefined; + } + >, + __, + next: NextFunction, + ) => { + req.body.userEmailFromAuthToken = mockUserEmail; + req.body.userSubjectFromAuthToken = mockUserSubject; + req.body.adminEmailFromAuthToken = mockAdminEmail; + req.body.adminSubjectFromAuthToken = mockAdminSubject; + next(); + }, + ); }; diff --git a/packages/api/test/mock_sql.ts b/packages/api/test/mock_sql.ts new file mode 100644 index 00000000..e466487b --- /dev/null +++ b/packages/api/test/mock_sql.ts @@ -0,0 +1,38 @@ +import { vi } from "vitest"; +import { equals } from "@vitest/expect"; +import type { Result, TinyPg, TinyPgParams } from "tinypg"; + +type MockSqlBehavior = + | { reject: unknown } + | { resolve: Partial> & { rows: unknown[] } }; + +/** + * Stubs a single named `db.sql` query while leaving every other query to hit + * the real database. `vitest-when`'s `calledWith(...).thenReject/thenDo(...)` + * can't be used for this: its fallback for non-matching calls relies on + * Vitest internals that no longer exist as of Vitest 4, so any unmatched + * call silently returns `undefined` instead of running for real. + */ +export const mockSqlCall = ( + db: TinyPg, + queryName: string, + params: unknown, + behavior: MockSqlBehavior, +): void => { + const originalSql = db.sql.bind(db); + vi.spyOn(db, "sql").mockImplementation( + async (name: string, actualParams?: TinyPgParams) => { + if (name === queryName && equals(actualParams, params)) { + if ("reject" in behavior) { + throw behavior.reject; + } + return { + command: "", + row_count: behavior.resolve.rows.length, + ...behavior.resolve, + }; + } + return originalSql(name, actualParams); + }, + ); +}; diff --git a/packages/api/vitest.config.ts b/packages/api/vitest.config.ts new file mode 100644 index 00000000..f9e4c9d1 --- /dev/null +++ b/packages/api/vitest.config.ts @@ -0,0 +1,28 @@ +import { + mergeConfig, + defineConfig, + coverageConfigDefaults, +} from "vitest/config"; +import os from "node:os"; +import shared from "../../vitest.shared"; + +export default mergeConfig( + shared, + defineConfig({ + test: { + setupFiles: ["./vitest.env.setup.js"], + globalSetup: ["./vitest.db.setup.ts"], + exclude: ["**/dist/**", "**/node_modules/**"], + coverage: { + clean: false, + exclude: [ + ...coverageConfigDefaults.exclude, + "vitest.env.setup.js", + "vitest.db.setup.ts", + ], + }, + pool: "threads", + maxWorkers: Math.max(1, Math.floor(os.availableParallelism() / 2)), + }, + }), +); diff --git a/packages/api/jest.db.setup.ts b/packages/api/vitest.db.setup.ts similarity index 51% rename from packages/api/jest.db.setup.ts rename to packages/api/vitest.db.setup.ts index 80fa17fc..32aa6a41 100644 --- a/packages/api/jest.db.setup.ts +++ b/packages/api/vitest.db.setup.ts @@ -9,7 +9,7 @@ const { Client } = pg; const TEMPLATE_DATABASE_NAME = "test_permanent_template"; const GOLDEN_DATABASE_NAME = "permanent"; -export default async function globalSetup(): Promise { +export async function setup(): Promise { const client = new Client({ connectionString: "postgres://postgres:permanent@database/postgres", }); @@ -25,8 +25,8 @@ export default async function globalSetup(): Promise { ); // Create worker-specific databases from the template - // We've configured jest to use a number of workers equal to half the number of CPUs - const numWorkers = os.cpus().length / 2; + // We've configured vitest to use a number of workers equal to half the number of CPUs + const numWorkers = Math.max(1, Math.floor(os.availableParallelism() / 2)); const adminClient = new Client({ connectionString: "postgres://postgres:permanent@database/postgres", @@ -49,3 +49,40 @@ export default async function globalSetup(): Promise { throw error; } } + +export async function teardown(): Promise { + const client = new Client({ + connectionString: "postgres://postgres:permanent@database/postgres", + }); + await client.connect(); + + try { + const numWorkers = Math.max(1, Math.floor(os.availableParallelism() / 2)); + + // Terminate connections and drop worker databases + for (let i = 1; i <= numWorkers; i++) { + const workerDbName = `test_permanent_worker_${i}`; + + // Terminate any remaining connections + await client.query(` + SELECT pg_terminate_backend(pg_stat_activity.pid) + FROM pg_stat_activity + WHERE pg_stat_activity.datname = '${workerDbName}' + AND pid <> pg_backend_pid() + `); + + await client.query(`DROP DATABASE IF EXISTS ${workerDbName}`); + } + + // Drop the template database + await client.query(` + SELECT pg_terminate_backend(pg_stat_activity.pid) + FROM pg_stat_activity + WHERE pg_stat_activity.datname = '${TEMPLATE_DATABASE_NAME}' + AND pid <> pg_backend_pid() + `); + await client.query(`DROP DATABASE IF EXISTS ${TEMPLATE_DATABASE_NAME}`); + } finally { + await client.end(); + } +} diff --git a/packages/api/jest.env.setup.js b/packages/api/vitest.env.setup.js similarity index 100% rename from packages/api/jest.env.setup.js rename to packages/api/vitest.env.setup.js diff --git a/packages/archivematica-utils/jest.config.js b/packages/archivematica-utils/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/archivematica-utils/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/archivematica-utils/package.json b/packages/archivematica-utils/package.json index ef9c3a87..6e539ace 100644 --- a/packages/archivematica-utils/package.json +++ b/packages/archivematica-utils/package.json @@ -22,7 +22,7 @@ "eslint": "eslint --max-warnings 0 ./src --ext .ts", "lint": "npm run check-format && npm run check-types && npm run eslint", "build": "rm -rf dist/* && tsc -p tsconfig.build.json && tscp -p tsconfig.tscp.json", - "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "vitest run" }, "dependencies": { "@stela/logger": "^1.0.0" diff --git a/packages/archivematica-utils/src/index.test.ts b/packages/archivematica-utils/src/index.test.ts index 055721eb..7a3579b4 100644 --- a/packages/archivematica-utils/src/index.test.ts +++ b/packages/archivematica-utils/src/index.test.ts @@ -1,9 +1,10 @@ +import { describe, expect, test, vi } from "vitest"; import { getOriginalFileIdFromInformationPackagePath, triggerArchivematicaProcessing, } from "./index"; -global.fetch = jest.fn(); +global.fetch = vi.fn(); describe("getFileIdFromInformationPackagePath", () => { test("should return the file ID if the file ID is a number", () => { diff --git a/packages/archivematica-utils/vitest.config.ts b/packages/archivematica-utils/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/archivematica-utils/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/archivematica_cleanup/Dockerfile b/packages/archivematica_cleanup/Dockerfile index 040f13ae..b904d2c0 100644 --- a/packages/archivematica_cleanup/Dockerfile +++ b/packages/archivematica_cleanup/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/archivematica_cleanup/jest.config.js b/packages/archivematica_cleanup/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/archivematica_cleanup/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/archivematica_cleanup/package.json b/packages/archivematica_cleanup/package.json index 3109b3a9..31bfbd09 100644 --- a/packages/archivematica_cleanup/package.json +++ b/packages/archivematica_cleanup/package.json @@ -23,7 +23,7 @@ "lint": "npm run check-format && npm run check-types && npm run eslint", "build": "rm -rf dist/* && tsc -p tsconfig.build.json && tscp -p tsconfig.tscp.json", "start": "node dist/index.js", - "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "vitest run" }, "dependencies": { "@sentry/node": "^10.60.0", diff --git a/packages/archivematica_cleanup/src/service.test.ts b/packages/archivematica_cleanup/src/service.test.ts index 5f313639..9a559833 100644 --- a/packages/archivematica_cleanup/src/service.test.ts +++ b/packages/archivematica_cleanup/src/service.test.ts @@ -1,15 +1,16 @@ import * as Sentry from "@sentry/node"; +import { afterEach, describe, expect, test, vi } from "vitest"; import { cleanupDashboard } from "./service"; -jest.mock("@sentry/node"); +vi.mock("@sentry/node"); describe("cleanupDashboard", () => { afterEach(() => { - jest.clearAllMocks(); - jest.resetAllMocks(); + vi.clearAllMocks(); + vi.resetAllMocks(); }); test("should call fetch with the correct arguments", async () => { - global.fetch = jest.fn().mockResolvedValue({ + global.fetch = vi.fn().mockResolvedValue({ ok: true, }); await cleanupDashboard(); @@ -37,7 +38,7 @@ describe("cleanupDashboard", () => { test("should log an error to sentry if the transfer deletion fails", async () => { const errorText = "500 Internal Server Error"; - global.fetch = jest.fn().mockResolvedValue({ + global.fetch = vi.fn().mockResolvedValue({ ok: false, text: async () => await Promise.resolve(errorText), }); @@ -48,7 +49,7 @@ describe("cleanupDashboard", () => { test("should log an error to sentry if the ingest deletion fails", async () => { const errorText = "500 Internal Server Error"; - global.fetch = jest + global.fetch = vi .fn() .mockResolvedValueOnce({ ok: true, diff --git a/packages/archivematica_cleanup/vitest.config.ts b/packages/archivematica_cleanup/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/archivematica_cleanup/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/event_send/Dockerfile b/packages/event_send/Dockerfile index 07a4dbd2..5aa2cd9e 100644 --- a/packages/event_send/Dockerfile +++ b/packages/event_send/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/event_send/jest.config.js b/packages/event_send/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/event_send/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/event_send/package.json b/packages/event_send/package.json index 23a93c18..4b010fac 100644 --- a/packages/event_send/package.json +++ b/packages/event_send/package.json @@ -26,7 +26,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/node": "^10.60.0", diff --git a/packages/event_send/src/service.test.ts b/packages/event_send/src/service.test.ts index 6cab4a25..ef211545 100644 --- a/packages/event_send/src/service.test.ts +++ b/packages/event_send/src/service.test.ts @@ -1,12 +1,13 @@ import { logger } from "@stela/logger"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { publisherClient } from "@stela/publisher-utils"; import { mixpanelClient } from "./mixpanel"; import { sendEvents } from "./service"; import { db } from "./database"; -jest.mock("@stela/logger"); -jest.mock("./database"); -jest.mock("./mixpanel"); +vi.mock("@stela/logger"); +vi.mock("./database"); +vi.mock("./mixpanel"); const loadFixtures = async (): Promise => { await db.sql("fixtures.create_test_events"); @@ -30,15 +31,16 @@ const getEventSentStatus = async (entityId: string): Promise => { describe("sendEvents", () => { beforeEach(async () => { - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockResolvedValue({ messagesSent: 3, failedMessages: [] }); + vi.spyOn(publisherClient, "batchPublishMessages").mockResolvedValue({ + messagesSent: 3, + failedMessages: [], + }); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -65,7 +67,7 @@ describe("sendEvents", () => { mock: { calls: [call], }, - } = jest.mocked(publisherClient.batchPublishMessages); + } = vi.mocked(publisherClient.batchPublishMessages); const messages = call?.[1] ?? []; expect( messages.some( @@ -89,9 +91,10 @@ describe("sendEvents", () => { ); const archiveEventId = result.rows[0]?.id ?? ""; - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockResolvedValue({ messagesSent: 1, failedMessages: [archiveEventId] }); + vi.spyOn(publisherClient, "batchPublishMessages").mockResolvedValue({ + messagesSent: 1, + failedMessages: [archiveEventId], + }); await sendEvents(); @@ -127,7 +130,7 @@ describe("sendEvents", () => { }); test("should log an error and continue if Mixpanel tracking fails", async () => { - jest.mocked(mixpanelClient.track).mockImplementation(() => { + vi.mocked(mixpanelClient.track).mockImplementation(() => { throw new Error("Mixpanel error"); }); @@ -140,7 +143,7 @@ describe("sendEvents", () => { test("should log and rethrow an error if database fetch fails", async () => { expect.assertions(2); const errorMessage = "database connection failed"; - jest.spyOn(db, "sql").mockRejectedValue(errorMessage); + vi.spyOn(db, "sql").mockRejectedValue(errorMessage); await sendEvents().catch((err: unknown) => { expect(err).toEqual(errorMessage); @@ -152,9 +155,7 @@ describe("sendEvents", () => { test("should log and rethrow an error if SNS publish fails", async () => { expect.assertions(2); const error = new Error("SNS publish failed"); - jest - .spyOn(publisherClient, "batchPublishMessages") - .mockRejectedValue(error); + vi.spyOn(publisherClient, "batchPublishMessages").mockRejectedValue(error); await sendEvents().catch((err: unknown) => { expect(err).toBe(error); @@ -166,10 +167,9 @@ describe("sendEvents", () => { test("should log and rethrow an error if database update fails", async () => { expect.assertions(2); const errorMessage = "database update failed"; - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockImplementationOnce( - jest.fn().mockResolvedValue({ + vi.fn().mockResolvedValue({ rows: [ { id: "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", diff --git a/packages/event_send/vitest.config.ts b/packages/event_send/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/event_send/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/event_utils/jest.config.js b/packages/event_utils/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/event_utils/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/file-utils/jest.config.js b/packages/file-utils/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/file-utils/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/file-utils/package.json b/packages/file-utils/package.json index cc36080e..1a447b3c 100644 --- a/packages/file-utils/package.json +++ b/packages/file-utils/package.json @@ -22,7 +22,7 @@ "eslint": "eslint --max-warnings 0 ./src --ext .ts", "lint": "npm run check-format && npm run check-types && npm run eslint", "build": "rm -rf dist/* && tsc -p tsconfig.json", - "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "vitest run" }, "dependencies": {}, "devDependencies": {} diff --git a/packages/file-utils/vitest.config.ts b/packages/file-utils/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/file-utils/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/file_copier/Dockerfile b/packages/file_copier/Dockerfile index e935ed9e..8b213953 100644 --- a/packages/file_copier/Dockerfile +++ b/packages/file_copier/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/file_copier/jest.config.js b/packages/file_copier/jest.config.js deleted file mode 100644 index e6d7a3a8..00000000 --- a/packages/file_copier/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/file_copier/package.json b/packages/file_copier/package.json index f7b41556..eb1f0532 100644 --- a/packages/file_copier/package.json +++ b/packages/file_copier/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@aws-sdk/client-s3": "^3.1075.0", diff --git a/packages/file_copier/src/index.test.ts b/packages/file_copier/src/index.test.ts index 1a75db25..8a6d3349 100644 --- a/packages/file_copier/src/index.test.ts +++ b/packages/file_copier/src/index.test.ts @@ -1,20 +1,24 @@ import type { Context, SQSRecord } from "aws-lambda"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { S3Client, CopyObjectCommand } from "@aws-sdk/client-s3"; -import { mock } from "jest-mock-extended"; +import { mock } from "vitest-mock-extended"; import { constructSignedCdnUrl } from "@stela/s3-utils"; import { logger } from "@stela/logger"; import { db } from "./database"; import { handler, extractFileDataFromFileCopyMessage } from "./index"; -jest.mock("./database"); -jest.mock("@stela/logger"); -jest.mock("@aws-sdk/client-s3"); -jest.mock("@stela/s3-utils", (): unknown => ({ - ...jest.requireActual("@stela/s3-utils"), - constructSignedCdnUrl: jest.fn(), -})); +vi.mock("./database"); +vi.mock("@stela/logger"); +vi.mock("@aws-sdk/client-s3"); +vi.mock(import("@stela/s3-utils"), async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + constructSignedCdnUrl: vi.fn(), + }; +}); -const mockS3Send = jest.fn(); +const mockS3Send = vi.fn(); const originalCloudPath = "originals/100/100"; const newCloudPath = "originals/101/101"; @@ -130,13 +134,9 @@ describe("handler", () => { }; beforeEach(async () => { - jest.mocked(S3Client).mockImplementation( - jest.fn().mockReturnValue({ - send: mockS3Send.mockResolvedValue({}), - }), - ); - jest - .mocked(constructSignedCdnUrl) + vi.spyOn(S3Client.prototype, "send").mockImplementation(mockS3Send); + mockS3Send.mockResolvedValue({}); + vi.mocked(constructSignedCdnUrl) .mockReturnValueOnce(testFileUrl) .mockReturnValueOnce(testDownloadUrl); await loadFixtures(); @@ -144,18 +144,18 @@ describe("handler", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); - jest.restoreAllMocks(); + vi.clearAllMocks(); + vi.restoreAllMocks(); }); test("should copy the S3 object and update the file record", async () => { await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); - const commandInput = jest.mocked(CopyObjectCommand).mock.calls.at(0)?.[0]; + const commandInput = vi.mocked(CopyObjectCommand).mock.calls.at(0)?.[0]; expect(commandInput?.CopySource).toEqual(`/${originalCloudPath}`); expect(commandInput?.Key).toEqual(newCloudPath); @@ -186,11 +186,7 @@ describe("handler", () => { }, }); - await handler( - { Records: [messageWithOldFile] }, - mock(), - jest.fn(), - ); + await handler({ Records: [messageWithOldFile] }, mock(), vi.fn()); const { rows: [updatedFile], @@ -216,11 +212,7 @@ describe("handler", () => { }, }); - await handler( - { Records: [messageWithOldFile] }, - mock(), - jest.fn(), - ); + await handler({ Records: [messageWithOldFile] }, mock(), vi.fn()); const { rows: [updatedFile], @@ -244,7 +236,7 @@ describe("handler", () => { await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -270,7 +262,7 @@ describe("handler", () => { await handler( { Records: [messageWithMissingFile] }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -283,14 +275,14 @@ describe("handler", () => { test("should throw if the get_file_upload_name query fails", async () => { const testError = new Error("database error"); - jest.spyOn(db, "sql").mockRejectedValueOnce(testError); + vi.spyOn(db, "sql").mockRejectedValueOnce(testError); let error = null; try { await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; @@ -304,18 +296,17 @@ describe("handler", () => { await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); - jest - .mocked(constructSignedCdnUrl) + vi.mocked(constructSignedCdnUrl) .mockReturnValueOnce(testFileUrl) .mockReturnValueOnce(testDownloadUrl); await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); const { rows } = await db.query<{ count: string }>( @@ -327,8 +318,7 @@ describe("handler", () => { test("should throw if the update_file_and_send_event query fails", async () => { const testError = new Error("database error"); - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockResolvedValueOnce({ command: "", row_count: 1, @@ -341,7 +331,7 @@ describe("handler", () => { await handler( { Records: [buildFileCopyRecord()] }, mock(), - jest.fn(), + vi.fn(), ); } catch (err) { error = err; diff --git a/packages/file_copier/vitest.config.ts b/packages/file_copier/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/file_copier/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/file_url_refresh/Dockerfile b/packages/file_url_refresh/Dockerfile index 07352f8c..99de308a 100644 --- a/packages/file_url_refresh/Dockerfile +++ b/packages/file_url_refresh/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/file_url_refresh/jest.config.js b/packages/file_url_refresh/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/file_url_refresh/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/file_url_refresh/package.json b/packages/file_url_refresh/package.json index b9060aea..370670ae 100644 --- a/packages/file_url_refresh/package.json +++ b/packages/file_url_refresh/package.json @@ -26,7 +26,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/node": "^10.60.0", diff --git a/packages/file_url_refresh/src/service.test.ts b/packages/file_url_refresh/src/service.test.ts index b65a6ce9..35ca16c8 100644 --- a/packages/file_url_refresh/src/service.test.ts +++ b/packages/file_url_refresh/src/service.test.ts @@ -1,11 +1,12 @@ import { logger } from "@stela/logger"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { constructSignedCdnUrl } from "@stela/s3-utils"; import { refreshFileUrls } from "./service"; import { db } from "./database"; -jest.mock("@stela/logger"); -jest.mock("@stela/s3-utils"); -jest.mock("./database"); +vi.mock("@stela/logger"); +vi.mock("@stela/s3-utils"); +vi.mock("./database"); interface FileData { accessUrl: string; @@ -77,20 +78,20 @@ describe("refreshThumbnails", () => { "https://testcdn.permanent.org/originals/1/1?Expires=2757200650&Policy=new-test-policy&Signature=new-test-signature&Key-Pair-Id=test-key-pair&response-content-disposition=attachment; filename=public_file.png"; beforeEach(async () => { - jest - .mocked(constructSignedCdnUrl) - .mockImplementation((_: string, fileName?: string) => { + vi.mocked(constructSignedCdnUrl).mockImplementation( + (_: string, fileName?: string) => { if (fileName === undefined) { return testDownloadUrl; } return testFileUrl; - }); + }, + ); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -184,7 +185,7 @@ describe("refreshThumbnails", () => { test("should log and rethrow an error if database call to find items fails", async () => { expect.assertions(2); const errorMessage = "out of cheese - redo from start"; - jest.spyOn(db, "sql").mockRejectedValue(errorMessage); + vi.spyOn(db, "sql").mockRejectedValue(errorMessage); await refreshFileUrls().catch((err: unknown) => { expect(err).toEqual(errorMessage); }); @@ -193,10 +194,9 @@ describe("refreshThumbnails", () => { test("should log error if an individual update fails", async () => { const errorMessage = "out of cheese - redo from start"; - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockImplementationOnce( - jest.fn().mockResolvedValue({ + vi.fn().mockResolvedValue({ rows: [ { id: "1", diff --git a/packages/file_url_refresh/vitest.config.ts b/packages/file_url_refresh/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/file_url_refresh/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/logger/src/__mocks__/index.ts b/packages/logger/src/__mocks__/index.ts new file mode 100644 index 00000000..84ac8c13 --- /dev/null +++ b/packages/logger/src/__mocks__/index.ts @@ -0,0 +1,12 @@ +import { vi } from "vitest"; + +export const logger = { + log: vi.fn(), + error: vi.fn(), + warn: vi.fn(), + info: vi.fn(), + http: vi.fn(), + verbose: vi.fn(), + debug: vi.fn(), + silly: vi.fn(), +}; diff --git a/packages/metadata_attacher/Dockerfile b/packages/metadata_attacher/Dockerfile index e1b4ecd0..686a098d 100644 --- a/packages/metadata_attacher/Dockerfile +++ b/packages/metadata_attacher/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/metadata_attacher/jest.config.js b/packages/metadata_attacher/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/metadata_attacher/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/metadata_attacher/package.json b/packages/metadata_attacher/package.json index 9cc20d28..ea8866d8 100644 --- a/packages/metadata_attacher/package.json +++ b/packages/metadata_attacher/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@aws-sdk/client-s3": "^3.1075.0", diff --git a/packages/metadata_attacher/src/index.test.ts b/packages/metadata_attacher/src/index.test.ts index e097a59d..0049b60c 100644 --- a/packages/metadata_attacher/src/index.test.ts +++ b/packages/metadata_attacher/src/index.test.ts @@ -1,14 +1,15 @@ import type { Context } from "aws-lambda"; -import { mock } from "jest-mock-extended"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { S3Client } from "@aws-sdk/client-s3"; import * as fs from "node:fs/promises"; import * as path from "node:path"; import { logger } from "@stela/logger"; import { db } from "./database"; import { handler } from "./index"; -jest.mock("./database"); -jest.mock("@stela/logger"); -jest.mock("@aws-sdk/client-s3"); +vi.mock("./database"); +vi.mock("@stela/logger"); +vi.mock("@aws-sdk/client-s3"); describe("handler", () => { const loadFixtures = async (): Promise => { @@ -83,22 +84,18 @@ describe("handler", () => { return metadata.rows[0]; }; - const mockS3Send = jest.fn(); + const mockS3Send = vi.fn(); beforeEach(async () => { await loadFixtures(); mockS3Send.mockClear(); - jest.mocked(S3Client).mockImplementation( - jest.fn().mockReturnValue({ - send: mockS3Send, - }), - ); + vi.spyOn(S3Client.prototype, "send").mockImplementation(mockS3Send); }); afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); - jest.restoreAllMocks(); + vi.clearAllMocks(); + vi.restoreAllMocks(); }); test("should skip non-METS files", async () => { @@ -138,7 +135,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); // Verify that S3 was not called expect(mockS3Send).not.toHaveBeenCalled(); @@ -148,7 +145,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("sample_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -188,7 +185,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -214,7 +211,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("sample_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -258,7 +255,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -271,7 +268,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("sample_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -315,7 +312,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -328,7 +325,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("minimal_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -368,7 +365,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordMetadata = await getRecordMetadata("1"); expect(recordMetadata).toBeDefined(); @@ -382,7 +379,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("sample_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -453,7 +450,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); }); @@ -499,7 +496,7 @@ describe("handler", () => { ], }; - await expect(handler(event, mock(), jest.fn())).rejects.toThrow( + await expect(handler(event, mock(), vi.fn())).rejects.toThrow( "metadata file is empty", ); }); @@ -509,7 +506,7 @@ describe("handler", () => { mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -549,7 +546,7 @@ describe("handler", () => { ], }; - await expect(handler(event, mock(), jest.fn())).rejects.toThrow( + await expect(handler(event, mock(), vi.fn())).rejects.toThrow( "Wrong number of administrative metadata sections for original file; expected 1, got 2", ); }); @@ -559,7 +556,7 @@ describe("handler", () => { mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -599,7 +596,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(logger.info).toHaveBeenCalledWith( "Invalid timestamp: not_a_timestamp", @@ -623,7 +620,7 @@ describe("handler", () => { mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -663,7 +660,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordMetadata = await getRecordMetadata("1"); expect(recordMetadata).toBeDefined(); @@ -675,7 +672,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("single_keyword_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -715,7 +712,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordMetadata = await getRecordMetadata("1"); expect(recordMetadata).toBeDefined(); @@ -726,12 +723,12 @@ describe("handler", () => { const metsContent = await loadMetsFile("sample_mets.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); const dbError = new Error("Database connection failed"); - jest.spyOn(db, "sql").mockRejectedValue(dbError); + vi.spyOn(db, "sql").mockRejectedValue(dbError); const event = { Records: [ @@ -769,7 +766,7 @@ describe("handler", () => { ], }; - await expect(handler(event, mock(), jest.fn())).rejects.toThrow( + await expect(handler(event, mock(), vi.fn())).rejects.toThrow( "Database connection failed", ); }); @@ -778,7 +775,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("video_mediainfo.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -818,7 +815,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -838,7 +835,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("video_quicktime.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -878,7 +875,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -898,7 +895,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("video_mediainfo_single_track.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -938,7 +935,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); @@ -958,7 +955,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("numeric_caption_abstract.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -998,7 +995,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordMetadata = await getRecordMetadata("1"); expect(recordMetadata).toBeDefined(); @@ -1009,7 +1006,7 @@ describe("handler", () => { const metsContent = await loadMetsFile("video_no_timestamp.xml"); mockS3Send.mockResolvedValue({ Body: { - transformToString: jest.fn().mockResolvedValue(metsContent), + transformToString: vi.fn().mockResolvedValue(metsContent), }, }); @@ -1049,7 +1046,7 @@ describe("handler", () => { ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); expect(mockS3Send).toHaveBeenCalledTimes(1); diff --git a/packages/metadata_attacher/vitest.config.ts b/packages/metadata_attacher/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/metadata_attacher/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/publisher-utils/jest.config.js b/packages/publisher-utils/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/publisher-utils/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/publisher-utils/package.json b/packages/publisher-utils/package.json index 7f0f1e53..71a0de04 100644 --- a/packages/publisher-utils/package.json +++ b/packages/publisher-utils/package.json @@ -22,7 +22,7 @@ "eslint": "eslint --max-warnings 0 ./src --ext .ts", "lint": "npm run check-format && npm run check-types && npm run eslint", "build": "rm -rf dist/* && tsc -p tsconfig.build.json && tscp -p tsconfig.tscp.json", - "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "vitest run" }, "dependencies": { "@aws-sdk/client-sns": "^3.1075.0" diff --git a/packages/publisher-utils/src/index.test.ts b/packages/publisher-utils/src/index.test.ts index a32a5892..34c86bb7 100644 --- a/packages/publisher-utils/src/index.test.ts +++ b/packages/publisher-utils/src/index.test.ts @@ -1,3 +1,4 @@ +import { beforeEach, describe, expect, test, vi } from "vitest"; import { PublishBatchCommand, SNSClient, @@ -5,23 +6,24 @@ import { } from "@aws-sdk/client-sns"; import { publisherClient } from "./index"; -const mockSend = jest.fn(); -jest.createMockFromModule("@aws-sdk/client-sns"); -jest.mock("@aws-sdk/client-sns"); +const mockSend = vi.fn(); +vi.mock("@aws-sdk/client-sns"); +vi.mock("@aws-sdk/client-sns"); describe("batchPublishMessages", () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should publish messages in batches", async () => { - jest.mocked(SNSClient).mockImplementation( - jest.fn().mockReturnValue({ - send: mockSend.mockResolvedValue({ Failed: [] }), + vi.mocked(SNSClient).mockImplementation( + vi.fn().mockReturnValue({ + send: mockSend, }), ); + mockSend.mockResolvedValue({ Failed: [] }); - jest.mocked(PublishBatchCommand).mockImplementation( - jest.fn().mockImplementation((input: PublishBatchInput) => ({ + vi.mocked(PublishBatchCommand).mockImplementation( + vi.fn().mockImplementation((input: PublishBatchInput) => ({ __input: input, })), ); @@ -134,8 +136,8 @@ describe("batchPublishMessages", () => { }); test("should report failures", async () => { - jest.mocked(SNSClient).mockImplementation( - jest.fn().mockReturnValue({ + vi.mocked(SNSClient).mockImplementation( + vi.fn().mockReturnValue({ send: mockSend.mockResolvedValue({ Failed: [{ Id: "1" }] }), }), ); @@ -169,10 +171,10 @@ describe("batchPublishMessages", () => { } = process; process.env["AWS_ENDPOINT_URL"] = "http://localhost:4566"; - const mockSNSClient = jest.fn().mockReturnValue({ + const mockSNSClient = vi.fn().mockReturnValue({ send: mockSend.mockResolvedValue({ Failed: [] }), }); - jest.mocked(SNSClient).mockImplementation(mockSNSClient); + vi.mocked(SNSClient).mockImplementation(mockSNSClient); const messages = [{ id: "1", body: "message 1" }]; @@ -193,12 +195,12 @@ describe("batchPublishMessages", () => { describe("publishMessage", () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test("should publish a message", async () => { - jest.mocked(SNSClient).mockImplementation( - jest.fn().mockReturnValue({ + vi.mocked(SNSClient).mockImplementation( + vi.fn().mockReturnValue({ send: mockSend.mockResolvedValue({ Failed: [] }), }), ); @@ -208,8 +210,8 @@ describe("publishMessage", () => { }); test("should include message attributes if provided", async () => { - jest.mocked(SNSClient).mockImplementation( - jest.fn().mockReturnValue({ + vi.mocked(SNSClient).mockImplementation( + vi.fn().mockReturnValue({ send: mockSend.mockResolvedValue({ Failed: [] }), }), ); @@ -222,40 +224,30 @@ describe("publishMessage", () => { Action: "login", }, }); - const { - mock: { - calls: [publishCommand], - }, - } = mockSend as { mock: { calls: PublishBatchCommand[] } }; - expect(publishCommand).toBeDefined(); - if (publishCommand !== undefined) { - expect(publishCommand.input).toEqual( - new PublishBatchCommand({ - TopicArn: "topic", - PublishBatchRequestEntries: [ - { - Id: "1", - Message: "message", - MessageAttributes: { - Entity: { - DataType: "String", - StringValue: "account", - }, - Action: { - DataType: "String", - StringValue: "login", - }, - }, + expect(vi.mocked(PublishBatchCommand)).toHaveBeenCalledWith({ + TopicArn: "topic", + PublishBatchRequestEntries: [ + { + Id: "1", + Message: "message", + MessageAttributes: { + Entity: { + DataType: "String", + StringValue: "account", }, - ], - }).input, - ); - } + Action: { + DataType: "String", + StringValue: "login", + }, + }, + }, + ], + }); }); test("should throw an error if the message fails to publish", async () => { - jest.mocked(SNSClient).mockImplementation( - jest.fn().mockReturnValue({ + vi.mocked(SNSClient).mockImplementation( + vi.fn().mockReturnValue({ send: mockSend.mockResolvedValue({ Failed: [{ Id: "1" }] }), }), ); diff --git a/packages/publisher-utils/vitest.config.ts b/packages/publisher-utils/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/publisher-utils/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/record_thumbnail_attacher/Dockerfile b/packages/record_thumbnail_attacher/Dockerfile index 3cc2840d..303030ac 100644 --- a/packages/record_thumbnail_attacher/Dockerfile +++ b/packages/record_thumbnail_attacher/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/record_thumbnail_attacher/jest.config.js b/packages/record_thumbnail_attacher/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/record_thumbnail_attacher/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/record_thumbnail_attacher/package.json b/packages/record_thumbnail_attacher/package.json index ca7a8978..13e5c30c 100644 --- a/packages/record_thumbnail_attacher/package.json +++ b/packages/record_thumbnail_attacher/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/aws-serverless": "^10.60.0", diff --git a/packages/record_thumbnail_attacher/src/index.test.ts b/packages/record_thumbnail_attacher/src/index.test.ts index b16c1829..f2972dd6 100644 --- a/packages/record_thumbnail_attacher/src/index.test.ts +++ b/packages/record_thumbnail_attacher/src/index.test.ts @@ -1,16 +1,20 @@ import type { Context } from "aws-lambda"; -import { mock } from "jest-mock-extended"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { constructSignedCdnUrl } from "@stela/s3-utils"; import { logger } from "@stela/logger"; import { db } from "./database"; import { handler } from "./index"; -jest.mock("./database"); -jest.mock("@stela/s3-utils", (): unknown => ({ - ...jest.requireActual("@stela/s3-utils"), - constructSignedCdnUrl: jest.fn(), -})); -jest.mock("@stela/logger"); +vi.mock("./database"); +vi.mock(import("@stela/s3-utils"), async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + constructSignedCdnUrl: vi.fn(), + }; +}); +vi.mock("@stela/logger"); describe("handler", () => { const loadFixtures = async (): Promise => { @@ -39,8 +43,8 @@ describe("handler", () => { afterEach(async () => { await clearDatabase(); - jest.clearAllMocks(); - jest.restoreAllMocks(); + vi.clearAllMocks(); + vi.restoreAllMocks(); }); test("should take no action if the file isn't a thumbnail", async () => { @@ -79,7 +83,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordThumbnail256Result = await db.query<{ thumbnail256: string; @@ -120,7 +124,7 @@ describe("handler", () => { }; let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } @@ -181,7 +185,7 @@ describe("handler", () => { }; let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } @@ -226,7 +230,7 @@ describe("handler", () => { }; let error = null; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (err) { error = err; } @@ -239,7 +243,7 @@ describe("handler", () => { const testUrl = "https://localcdn.permanent.org/_Liam/access_copies/e38e/8582/b417/430c/953d/5c7e/8040/1ae2/1_upload-cb45fa84-f0ea-4a9e-b1da-309e485a4f4a/thumbnails/710a1def-caf8-48f2-8eee-0848b4cfda10.jpg?&Expires=1739554780&Signature=testSignature&Key-Pair-Id=testKeyPairId"; - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); const event = { Records: [ @@ -276,7 +280,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordThumbnail256Result = await db.query<{ thumbnail256: string; @@ -327,7 +331,7 @@ describe("handler", () => { const testUrl = "https://localcdn.permanent.org/_Liam/access_copies/e38e/8582/b417/430c/953d/5c7e/8040/1ae2/1_upload-cb45fa84-f0ea-4a9e-b1da-309e485a4f4a/thumbnails/710a1def-caf8-48f2-8eee-0848b4cfda10.jpg?&Expires=1739554780&Signature=testSignature&Key-Pair-Id=testKeyPairId"; - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); const oneWeekFromNow = new Date(); oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7); @@ -376,7 +380,7 @@ describe("handler", () => { }, ], }; - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); const recordThumbnail256Result = await db.query<{ thumbDt: string; @@ -407,10 +411,10 @@ describe("handler", () => { const testUrl = "https://localcdn.permanent.org/_Liam/access_copies/e38e/8582/b417/430c/953d/5c7e/8040/1ae2/1_upload-cb45fa84-f0ea-4a9e-b1da-309e485a4f4a/thumbnails/710a1def-caf8-48f2-8eee-0848b4cfda10.jpg?&Expires=1739554780&Signature=testSignature&Key-Pair-Id=testKeyPairId"; - jest.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); + vi.mocked(constructSignedCdnUrl).mockReturnValue(testUrl); const dbError = new Error("Database error"); - jest.spyOn(db, "sql").mockRejectedValue(dbError); + vi.spyOn(db, "sql").mockRejectedValue(dbError); const event = { Records: [ @@ -448,7 +452,7 @@ describe("handler", () => { ], }; try { - await handler(event, mock(), jest.fn()); + await handler(event, mock(), vi.fn()); } catch (_) { // Do nothing } diff --git a/packages/record_thumbnail_attacher/vitest.config.ts b/packages/record_thumbnail_attacher/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/record_thumbnail_attacher/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/s3-utils/jest.config.js b/packages/s3-utils/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/s3-utils/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/s3-utils/package.json b/packages/s3-utils/package.json index 10f7a76f..a62c42eb 100644 --- a/packages/s3-utils/package.json +++ b/packages/s3-utils/package.json @@ -22,7 +22,7 @@ "eslint": "eslint --max-warnings 0 ./src --ext .ts", "lint": "npm run check-format && npm run check-types && npm run eslint", "build": "rm -rf dist/* && tsc -p tsconfig.build.json", - "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "vitest run" }, "dependencies": { "ajv": "^8.18.0", diff --git a/packages/s3-utils/src/index.test.ts b/packages/s3-utils/src/index.test.ts index 9ac37fd4..f268f523 100644 --- a/packages/s3-utils/src/index.test.ts +++ b/packages/s3-utils/src/index.test.ts @@ -1,11 +1,12 @@ import { getSignedUrl } from "aws-cloudfront-sign"; +import { describe, expect, test, vi } from "vitest"; import { constructSignedCdnUrl, getS3ObjectFromS3Message, getS3BucketFromS3Message, } from "./index"; -jest.mock("aws-cloudfront-sign"); +vi.mock("aws-cloudfront-sign"); describe("constructSignedCDNURL", () => { test("calls getSignedUrl correctly when no fileName is provided", () => { diff --git a/packages/s3-utils/vitest.config.ts b/packages/s3-utils/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/s3-utils/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/thumbnail_refresh/Dockerfile b/packages/thumbnail_refresh/Dockerfile index 0238066f..7cb328a9 100644 --- a/packages/thumbnail_refresh/Dockerfile +++ b/packages/thumbnail_refresh/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/thumbnail_refresh/jest.config.js b/packages/thumbnail_refresh/jest.config.js deleted file mode 100644 index c7fd2834..00000000 --- a/packages/thumbnail_refresh/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, -}; diff --git a/packages/thumbnail_refresh/package.json b/packages/thumbnail_refresh/package.json index c009835d..84206c73 100644 --- a/packages/thumbnail_refresh/package.json +++ b/packages/thumbnail_refresh/package.json @@ -26,7 +26,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/node": "^10.60.0", diff --git a/packages/thumbnail_refresh/src/service.test.ts b/packages/thumbnail_refresh/src/service.test.ts index 50de97e4..bf5317db 100644 --- a/packages/thumbnail_refresh/src/service.test.ts +++ b/packages/thumbnail_refresh/src/service.test.ts @@ -1,11 +1,12 @@ import { getSignedUrl } from "aws-cloudfront-sign"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; import { logger } from "@stela/logger"; import { refreshThumbnails } from "./service"; import { db } from "./database"; -jest.mock("aws-cloudfront-sign"); -jest.mock("@stela/logger"); -jest.mock("./database"); +vi.mock("aws-cloudfront-sign"); +vi.mock("@stela/logger"); +vi.mock("./database"); interface ThumbnailData { thumbnail256: string; @@ -135,13 +136,13 @@ describe("refreshThumbnails", () => { "https://testcdn.permanent.org/access_copies/a755/62ca/8bd5/40f0/9960/d05b/a5ea/8bfa/7028987_upload-b35bfcf6-9c51-47f9-a502-555b601dbcf0/thumbnails/c6561367-6bb4-4454-ad32-0bdb68df80fe.jpg?Expires=2757200649&Policy=new-test-policy&Signature=new-test-signature&Key-Pair-Id=test-key-pair"; beforeEach(async () => { - jest.mocked(getSignedUrl).mockReturnValue(testNewThumbnail256); + vi.mocked(getSignedUrl).mockReturnValue(testNewThumbnail256); await loadFixtures(); }); afterEach(async () => { - jest.restoreAllMocks(); - jest.clearAllMocks(); + vi.restoreAllMocks(); + vi.clearAllMocks(); await clearDatabase(); }); @@ -360,7 +361,7 @@ describe("refreshThumbnails", () => { test("should log and rethrow an error if database call to find items fails", async () => { expect.assertions(2); const errorMessage = "out of cheese - redo from start"; - jest.spyOn(db, "sql").mockRejectedValue(errorMessage); + vi.spyOn(db, "sql").mockRejectedValue(errorMessage); await refreshThumbnails().catch((err: unknown) => { expect(err).toEqual(errorMessage); }); @@ -369,10 +370,9 @@ describe("refreshThumbnails", () => { test("should log error if an individual update fails", async () => { const errorMessage = "out of cheese - redo from start"; - jest - .spyOn(db, "sql") + vi.spyOn(db, "sql") .mockImplementationOnce( - jest.fn().mockResolvedValue({ + vi.fn().mockResolvedValue({ rows: [ { recordId: "1", diff --git a/packages/thumbnail_refresh/vitest.config.ts b/packages/thumbnail_refresh/vitest.config.ts new file mode 100644 index 00000000..576b999a --- /dev/null +++ b/packages/thumbnail_refresh/vitest.config.ts @@ -0,0 +1 @@ +export { default } from "../../vitest.shared"; diff --git a/packages/trigger_archivematica/Dockerfile b/packages/trigger_archivematica/Dockerfile index 70d409b0..ddd08c48 100644 --- a/packages/trigger_archivematica/Dockerfile +++ b/packages/trigger_archivematica/Dockerfile @@ -7,7 +7,7 @@ COPY package.json ./ COPY package-lock.json ./ COPY tsconfig.build.json ./ COPY tsconfig.json ./ -COPY jest.config.js ./ +COPY vitest.shared.ts ./ COPY packages ./packages COPY patches ./patches diff --git a/packages/trigger_archivematica/jest.config.js b/packages/trigger_archivematica/jest.config.js deleted file mode 100644 index d88dc599..00000000 --- a/packages/trigger_archivematica/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -sharedConfig = require("../../jest.config"); -module.exports = { - ...sharedConfig, - moduleNameMapper: { - "^@stela/(.*)$": "/../$1/src", - }, - setupFiles: ["/jest.env.setup.js"], -}; diff --git a/packages/trigger_archivematica/package.json b/packages/trigger_archivematica/package.json index a7d0dace..a98548c9 100644 --- a/packages/trigger_archivematica/package.json +++ b/packages/trigger_archivematica/package.json @@ -27,7 +27,7 @@ "clear-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'DROP DATABASE IF EXISTS test_permanent;'", "create-database": "psql postgresql://postgres:permanent@localhost:5432 -c 'CREATE DATABASE test_permanent;'", "set-up-database": "docker exec --env='PGPASSWORD=permanent' permanent-database-1 pg_dump -U postgres permanent --schema-only | psql postgresql://postgres:permanent@localhost:5432/test_permanent", - "test": "npm run clear-database && npm run create-database && npm run set-up-database && node --experimental-vm-modules ../../node_modules/jest/bin/jest.js -i --silent=false" + "test": "npm run clear-database && npm run create-database && npm run set-up-database && vitest run" }, "dependencies": { "@sentry/aws-serverless": "^10.60.0", diff --git a/packages/trigger_archivematica/src/index.test.ts b/packages/trigger_archivematica/src/index.test.ts index a2e18e21..9918c5b6 100644 --- a/packages/trigger_archivematica/src/index.test.ts +++ b/packages/trigger_archivematica/src/index.test.ts @@ -1,23 +1,20 @@ import type { Context } from "aws-lambda"; -import { mock } from "jest-mock-extended"; +import { afterEach, beforeEach, describe, expect, test, vi } from "vitest"; +import { mock } from "vitest-mock-extended"; import { logger } from "@stela/logger"; import { triggerArchivematicaProcessing } from "@stela/archivematica-utils"; import { db } from "./database"; import { handler, extractRecordIdFromNewRecordMessage } from "./index"; -jest.mock("./database"); -jest.mock("@stela/archivematica-utils", () => ({ - triggerArchivematicaProcessing: jest.fn().mockResolvedValue({ - json: jest.fn(), - text: jest.fn(), +vi.mock("./database"); +vi.mock("@stela/archivematica-utils", () => ({ + triggerArchivematicaProcessing: vi.fn().mockResolvedValue({ + json: vi.fn(), + text: vi.fn(), ok: true, }), })); -jest.mock("@stela/logger", () => ({ - logger: { - error: jest.fn(), - }, -})); +vi.mock("@stela/logger"); const loadFixtures = async (): Promise => { await db.sql("fixtures.create_test_accounts"); @@ -178,7 +175,7 @@ describe("extractRecordIdFromRecordCreateMessage", () => { describe("handler", () => { beforeEach(async () => { await loadFixtures(); - jest.clearAllMocks(); + vi.clearAllMocks(); }); afterEach(async () => { @@ -214,7 +211,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); expect(triggerArchivematicaProcessing).toHaveBeenCalledWith( @@ -258,7 +255,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); expect(triggerArchivematicaProcessing).not.toHaveBeenCalled(); @@ -315,7 +312,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ); expect(triggerArchivematicaProcessing).toHaveBeenCalledTimes(2); @@ -342,7 +339,7 @@ describe("handler", () => { }); test("should throw error when database query fails", async () => { const dbError = new Error("Database connection failed"); - jest.spyOn(db, "sql").mockRejectedValueOnce(dbError); + vi.spyOn(db, "sql").mockRejectedValueOnce(dbError); await expect( handler( @@ -373,7 +370,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ), ).rejects.toThrow("Database connection failed"); @@ -383,9 +380,9 @@ describe("handler", () => { test("should throw error when Archivematica processing throws", async () => { const archivematicaError = new Error("Failed to trigger Archivematica"); - jest - .mocked(triggerArchivematicaProcessing) - .mockRejectedValueOnce(archivematicaError); + vi.mocked(triggerArchivematicaProcessing).mockRejectedValueOnce( + archivematicaError, + ); await expect( handler( @@ -416,7 +413,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ), ).rejects.toThrow("Failed to trigger Archivematica"); @@ -434,11 +431,9 @@ describe("handler", () => { }); test("should throw error when Archivematica processing fails without an exception", async () => { - jest - .mocked(triggerArchivematicaProcessing) - .mockImplementation( - jest.fn().mockResolvedValueOnce({ ok: false, status: 404 }), - ); + vi.mocked(triggerArchivematicaProcessing).mockImplementation( + vi.fn().mockResolvedValueOnce({ ok: false, status: 404 }), + ); await expect( handler( @@ -469,7 +464,7 @@ describe("handler", () => { ], }, mock(), - jest.fn(), + vi.fn(), ), ).rejects.toThrow("Call to Archivematica failed with status 404"); diff --git a/packages/trigger_archivematica/vitest.config.ts b/packages/trigger_archivematica/vitest.config.ts new file mode 100644 index 00000000..f903e3d3 --- /dev/null +++ b/packages/trigger_archivematica/vitest.config.ts @@ -0,0 +1,11 @@ +import { mergeConfig, defineConfig } from "vitest/config"; +import shared from "../../vitest.shared"; + +export default mergeConfig( + shared, + defineConfig({ + test: { + setupFiles: ["./vitest.env.setup.js"], + }, + }), +); diff --git a/packages/trigger_archivematica/jest.env.setup.js b/packages/trigger_archivematica/vitest.env.setup.js similarity index 100% rename from packages/trigger_archivematica/jest.env.setup.js rename to packages/trigger_archivematica/vitest.env.setup.js diff --git a/vitest.shared.ts b/vitest.shared.ts new file mode 100644 index 00000000..ffff0b10 --- /dev/null +++ b/vitest.shared.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "vitest/config"; +import { fileURLToPath } from "node:url"; + +export default defineConfig({ + resolve: { + alias: [ + { + find: /^@stela\/(.+)$/, + replacement: fileURLToPath(new URL("./packages/$1/src", import.meta.url)), + }, + ], + }, + test: { + environment: "node", + }, +});