diff --git a/.agent/skills/tdd-flow/skill.md b/.agent/skills/tdd-flow/skill.md index 368a6a8..0eff7ac 100644 --- a/.agent/skills/tdd-flow/skill.md +++ b/.agent/skills/tdd-flow/skill.md @@ -7,9 +7,9 @@ triggers: ## Workflow Steps 1. **Red Phase:** Write ONE failing test. Explain the failure. **STOP.** -- Requirement: All tests generated in this phase must adhere to the Test Expectations defined in the ai_instruction file (specifically: No mocking, real HTTP requests, and semantic validation). +- Requirement: All tests generated in this phase must follow the API contract and testing requirements in `AGENTS.md` (specifically: no mocking, real HTTP requests for endpoint coverage and integration tests, and semantic validation). 2. **Green Phase:** Write the simplest possible implementation to pass that specific test. **STOP.** 3. **Refactor Phase:** Suggest improvements to the implementation. Do not change tests. ## Constraint -- Do not jump to Step 2 until the user confirms Step 1 passes (or fails correctly). \ No newline at end of file +- Do not jump to Step 2 until the user confirms Step 1 passes (or fails correctly). diff --git a/AGENTS.md b/AGENTS.md index 3581f11..a3a4b65 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,9 +1,28 @@ -All AI agents (Codex, Copilot, Antigravity) must adhere to the rules defined in .agent/rules/ and this file. +# Agent Instructions -# Project Standards & Agent Behavior +All AI agents (Codex, Copilot, Antigravity) must follow this file and the rules in `.agent/rules/`. -- **Primary Workflow:** We use the `tdd-flow` skill for all new feature development. -- **Test Style:** Focus on behavior-driven assertions. No mocking. -- **Anti-Pattern Guardrail:** Do not "hallucinate" implementation for skipped tests. If a test is ignored, the underlying code must remain untouched. -- **Language/Framework:** JavaScript/TypeScript with Jest for testing. -- **Spec-Strictness:** When generating tests for the SDK, only assert properties explicitly defined in the OpenAPI specification provided. Do not invent "common sense" validations that are not codified in the schema. Call out any ambiguities or gaps in the spec for human review instead of making assumptions. \ No newline at end of file +## Project standards + +- The project uses JavaScript/TypeScript and Jest. +- Use the `tdd-flow` skill for feature implementation and bug fixes. +- Preserve existing implementation when a test is skipped. Do not implement behavior inferred from ignored tests. +- Focus tests on observable behavior. Do not use mocks. + +## API contract + +- The [Mailinator OpenAPI specification](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml) is the source of truth for supported API behavior. +- Only implement or assert properties and validation rules explicitly defined by the specification. Report ambiguities or gaps for human review instead of filling them with assumptions. +- A request class generally maps to one OpenAPI `operationId` and belongs in the module matching that operation's tag. +- Mailinator API request paths must use the `/api/v2/` prefix. +- Export new request classes and response types from both the module's `index.ts` and `src/index.ts`. +- Use the `AUTHORIZATION` constant for authenticated requests. Requests that do not require a token must implement `RequestWithoutToken`. +- Do not remove deprecated or undocumented endpoints without explicit confirmation. + +## Testing and verification + +- Endpoint coverage and integration tests must make real HTTP requests; do not use request-mocking tools. +- Assertions must validate contract-defined response semantics rather than mere existence. +- After implementation, run `npx tsc --noEmit` and `npm test`. + +See [`docs/openapi-alignment.md`](docs/openapi-alignment.md) for the SDK architecture, OpenAPI gap-analysis workflow, and implementation checklist. diff --git a/AI_INSTRUCTIONS.md b/AI_INSTRUCTIONS.md deleted file mode 100644 index 6e4382f..0000000 --- a/AI_INSTRUCTIONS.md +++ /dev/null @@ -1,184 +0,0 @@ -# AI Instructions - -This document explains the relationship between this Javascript client and the Mailinator OpenAPI specification. - -**OpenAPI Specification:** [Found on GitHub](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml) - -## Codebase Structure - -The codebase structure in `src/` directly reflects the logical organization of the Mailinator API. - -- **Modules:** The subdirectories in `src/` (e.g., `src/message`, `src/authenticator`, `src/domain`) correspond to the **Tags** defined in the OpenAPI specification. - - `src/message` corresponds to the `Messages` tag. - - `src/authenticator` corresponds to the `Authenticator` tag. - - `src/domain` corresponds to the `Domains` tag. - - `src/rule` corresponds to the `Rules` tag. - - `src/stats` corresponds to the `Stats` tag. - -## Request Pattern - -This client uses a **Request Object** pattern. Specific API operations are encapsulated in their own Request classes. - -- **Naming Convention:** Request classes are named `{Operation}Request.ts`. -- **Mapping:** Each Request class typically maps to a single Operation ID in the OpenAPI spec. - - Example: `GetInboxRequest.ts` maps to the `listInboxMessages` operation (GET `/api/v2/domains/{domain}/inboxes/{inbox}`). - - Example: `PostMessageRequest.ts` maps to the `postMessage` operation (POST `/api/v2/domains/{domain}/inboxes/{inbox}`). - - Note: When `GetInboxRequest` is called without an `inbox`, it now uses a wildcard inbox (`*`) and resolves to `/api/v2/domains/{domain}/inboxes/*`. - -## Execution - -Requests are executed using the `MailinatorClient`. - -```typescript -const client = new MailinatorClient("api_token"); -const request = new GetInboxRequest("domain.com", "inbox_name"); -const response = await client.request(request); -``` - -## Entities - -Response schemas from the OpenAPI spec are defined as interfaces/classes in the corresponding module directory or the root of `src`. -- Example: `src/message/Inbox.ts` corresponds to the `InboxMessagesResponse` schema. - ---- - -## Gap Analysis Workflow - -Use this workflow whenever you want to audit the SDK against the OpenAPI spec, identify missing or extra coverage, and bring the two into alignment. - -### Step 1 — Fetch the OpenAPI Specification - -Retrieve the raw YAML from: - -``` -https://raw.githubusercontent.com/manybrain/mailinatordocs/main/openapi/mailinator-api.yaml -``` - -> The rendered GitHub page is at https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml -> but always read the **raw** URL for machine parsing. - -Extract every `paths` entry. For each path, record: -- The HTTP method (`get`, `post`, `put`, `delete`, etc.) -- The full path string (e.g. `/api/v2/domains/{domain}/inboxes/{inbox}`) -- The `operationId` -- The tag (maps to the SDK module directory) -- All query parameters defined under `parameters` - -### Step 2 — Catalog the SDK - -For each `*Request.ts` file under `src/`: -1. Identify the HTTP method used (`restClient.get`, `.create`, `.replace`, `.del`). -2. Extract the hardcoded URL template string (look for `_resolveTemplateUrl` or a `const URL =` declaration). -3. Note any query parameters set on `_options.queryParameters.params`. -4. Note if the class is marked `@deprecated`. - -Also enumerate the top-level module directories in `src/` and cross-reference them against the OpenAPI `tags` list. - -### Step 3 — Identify Gaps - -Produce a gap report with four sections: - -#### A. In the spec but missing from the SDK -List every `operationId` that has no corresponding `*Request.ts`. This is what needs to be **added**. - -#### B. In the SDK but not in the spec -List every `*Request.ts` whose URL has no matching path+method in the spec. -- If it is marked `@deprecated`, note that separately. -- If it is not deprecated but still absent from the spec, flag it for clarification (it may be an undocumented endpoint). - -#### C. URL path mismatches -Compare the base path used by each SDK class against the spec. -- The spec base URL is `https://api.mailinator.com` and all paths start with `/api/v2/`. -- The SDK **must** use `/api/v2/` not `/v2/`. Flag any class using the wrong prefix. - -#### D. Query parameter gaps -For each existing SDK class, compare the query parameters it sends against the spec's declared parameters for that operation. List any parameters the spec defines that the SDK does not implement. - -### Step 4 — Build a Plan - -Before making any changes, write out a plan that includes: - -1. **New request classes to add** — one class per missing `operationId`, grouped by module directory. -2. **URL fixes** — list every file where the prefix needs to change from `/v2/` to `/api/v2/`. -3. **Query parameter additions** — list every file and which parameters to add. -4. **Deprecated classes** — decide whether to remove them or keep with the existing `@deprecated` annotation. Do not remove without confirmation. -5. **Model/schema updates** — if new endpoints return new schemas, list the new TypeScript interfaces to create. - -Present the plan to the user and wait for approval before proceeding. - -### Step 5 — Implement - -Follow the existing patterns in the codebase: - -#### Adding a new Request class - -Use an existing class as a template — e.g. `src/message/GetInboxMessageRequest.ts`. - -```typescript -import { Request } from '../Request'; -import { IRequestOptions, IRestResponse } from 'typed-rest-client/RestClient'; -import restClient from '../MailinatorRestClient'; -import { AUTHORIZATION } from '../Constants'; -import { MyResponseType } from './MyResponseType'; - -const _resolveTemplateUrl = (domain: string, messageId: string) => { - return `https://api.mailinator.com/api/v2/domains/${domain}/messages/${messageId}`; -}; - -export class MyNewRequest implements Request { - constructor(private readonly domain: string, - private readonly messageId: string) {} - - execute(apiToken: string): Promise> { - const _options: IRequestOptions = { - additionalHeaders: { [AUTHORIZATION]: apiToken } - }; - return restClient.get(_resolveTemplateUrl(this.domain, this.messageId), _options); - } -} -``` - -Key rules: -- **Always** use `/api/v2/` as the path prefix — never `/v2/`. -- Place the file in the module directory that matches the operation's OpenAPI tag. -- Export the class from the module's `index.ts`. -- Add a corresponding TypeScript interface if the response schema is new. - -#### Fixing a URL prefix - -Change `/v2/` → `/api/v2/` in the `_resolveTemplateUrl` function or `const URL` declaration. - -#### Adding a missing query parameter - -Add an `if` block in `execute()`: -```typescript -if (this.myParam !== undefined) { - _options.queryParameters!.params['my_param'] = this.myParam; -} -``` -And add the corresponding constructor parameter. - -### Step 6 — Verify - -After implementing: -1. Run `npx tsc --noEmit` — must produce zero errors. -2. Run `npm test` — all existing tests must pass. -3. Manually verify that at least one new request class can be instantiated and the URL it generates matches the spec path exactly. - -### Notes on SDK Conventions - -| Convention | Detail | -|---|---| -| Version source | `package.json` → `version` field. `src/Constants.ts` reads it dynamically — do **not** hardcode it. | -| Auth header | Always `AUTHORIZATION` constant from `src/Constants.ts`, never a string literal. | -| No-token requests | Implement `RequestWithoutToken` (used for webhook injection). | -| Deprecated marker | Add `/** @deprecated ... */` JSDoc above the class declaration. | -| Module exports | Every new class must be added to the module's `index.ts` and to `src/index.ts`. | - -### Test Expectations - -- Integration tests should exercise real HTTP requests to Mailinator endpoints. Do not use request-mocking tools for endpoint coverage tests. -- Assertions must validate response semantics, not just existence. Prefer checking: - - expected HTTP success behavior (or explicit failure with returned status code), - - expected JSON shape (required keys), - - important field-level values (for example, IDs or arrays) relevant to the endpoint contract. diff --git a/README.md b/README.md index abeea15..2ab67ee 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ See [EXAMPLES.md](EXAMPLES.md) for more code examples on how to use the client. ## Development +See [OpenAPI alignment](docs/openapi-alignment.md) for the SDK architecture, specification gap-analysis workflow, and implementation checklist. + #### Build tests * `npm test` diff --git a/ROADMAP.md b/ROADMAP.md index 89f0b2c..ef9b917 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,6 +1,6 @@ # ROADMAP -- [x] Add AI_INSTRUCTIONS.md that explain the link between this client and the OpenAPI specification. That is the source of truth for this repo. +- [x] Document the relationship between this client and the OpenAPI specification, the source of truth for this repository. - [x] Pull examples out of README.md add to separate file(s). Make sure the examples are clear and accurate. - [x] Add section on how to publish updates to npm to README.md - [x] Add depreciation warning to endpoints that exist here and not in the OpenAPI specification. diff --git a/docs/openapi-alignment.md b/docs/openapi-alignment.md new file mode 100644 index 0000000..c350d39 --- /dev/null +++ b/docs/openapi-alignment.md @@ -0,0 +1,114 @@ +# OpenAPI Alignment + +The [Mailinator OpenAPI specification](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml) is the source of truth for this SDK. Use the [raw specification](https://raw.githubusercontent.com/manybrain/mailinatordocs/main/openapi/mailinator-api.yaml) for automated or machine-assisted analysis. + +Agent behavior and non-negotiable repository rules live in [`AGENTS.md`](../AGENTS.md). This document describes the SDK architecture and the repeatable process for comparing it with the specification. + +## SDK architecture + +The directories under `src/` correspond to logical Mailinator API areas and, where applicable, OpenAPI tags. API operations use request classes named `{Operation}Request.ts`. + +Each request class generally maps to one OpenAPI `operationId` and: + +- implements `Request`, or `RequestWithoutToken` when authentication is not required; +- constructs a URL under `https://api.mailinator.com/api/v2/`; +- uses `MailinatorRestClient` to execute the appropriate HTTP method; +- uses types in the corresponding module for request and response schemas; and +- is exported by both the module's `index.ts` and the root `src/index.ts`. + +Requests are executed through `MailinatorClient`: + +```typescript +const client = new MailinatorClient("api_token"); +const request = new GetInboxRequest("domain.com", "inbox_name"); +const response = await client.request(request); +``` + +## Gap-analysis workflow + +### 1. Read the specification + +From every entry under `paths`, record: + +- HTTP method and full path; +- `operationId`; +- tag; +- path and query parameters; +- request body schema; and +- response schemas and status codes. + +Also record the top-level tags and component schemas used by those operations. + +### 2. Catalog the SDK + +For every `*Request.ts` under `src/`, record: + +- class and module name; +- HTTP method; +- resolved URL template; +- constructor inputs and query parameters; +- request and response types; +- module and root exports; and +- deprecation status. + +Inspect the implementation rather than inferring behavior from the class name. + +### 3. Compare both sides + +Report these categories separately: + +1. **Missing SDK operations:** specification operations with no corresponding request class. +2. **SDK-only operations:** request classes with no matching specification path and method. Identify deprecated classes separately; flag other cases for clarification. +3. **Path or method mismatches:** including any URL that does not use `/api/v2/`. +4. **Parameter gaps:** contract-defined path, query, or body fields missing from the request class, plus SDK fields absent from the contract. +5. **Schema gaps:** missing or inconsistent request and response types. +6. **Export gaps:** implemented classes or types missing from a module index or `src/index.ts`. + +Do not treat an operation as matching based only on a similar name. Match its HTTP method and normalized path, then verify its `operationId` and schemas. + +### 4. Prepare an implementation plan + +Before changing code, list: + +- new request classes grouped by module; +- path and method corrections; +- parameter changes; +- model or schema changes; +- export updates; and +- deprecated or undocumented endpoints requiring a human decision. + +Do not remove deprecated or undocumented endpoints without confirmation. + +### 5. Implement using existing conventions + +Use the closest current request class as the template. In particular: + +- use `/api/v2/` in Mailinator API paths; +- use `AUTHORIZATION` from `src/Constants.ts` rather than a string literal; +- use `RequestWithoutToken` for unauthenticated requests; +- add `/** @deprecated ... */` above deprecated class declarations; and +- update the module index and `src/index.ts` for every public addition. + +Follow the `tdd-flow` skill and the testing requirements in `AGENTS.md` for feature implementation and bug fixes. + +### 6. Verify + +Run: + +```bash +npx tsc --noEmit +npm test +``` + +For new or corrected requests, also verify that the resolved HTTP method, path, parameters, and contract-defined response semantics match the specification. Integration tests must use real Mailinator endpoints and must not use request-mocking tools. + +## Stable conventions + +| Convention | Requirement | +| --- | --- | +| Version source | Use the `version` field in `package.json`; `src/Constants.ts` reads it dynamically. | +| Authentication | Use the `AUTHORIZATION` constant from `src/Constants.ts`. | +| Unauthenticated requests | Implement `RequestWithoutToken`. | +| API prefix | Use `/api/v2/`. | +| Deprecation | Add a JSDoc `@deprecated` marker and require confirmation before removal. | +| Public exports | Export through the module index and `src/index.ts`. | diff --git a/jest.config.js b/jest.config.js index f192b60..201495c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,5 +1,7 @@ module.exports = { - transform: {'^.+\\.ts?$': 'ts-jest'}, + transform: { + '^.+\\.ts?$': ['ts-jest', {tsconfig: 'tsconfig.test.json'}] + }, testEnvironment: 'node', setupFiles: ['dotenv/config'], testRegex: '/tests/.*\\.(test|spec)?\\.(ts|tsx)$', diff --git a/package-lock.json b/package-lock.json index dcf2427..eab19fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.1.1", "license": "The Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0.txt)", "dependencies": { - "@types/node": "^25.9.3", + "@types/node": "^25.9.5", "typed-rest-client": "^3.0.0" }, "devDependencies": { @@ -17,19 +17,18 @@ "dotenv": "^17.4.2", "jest": "^30.4.2", "tmp": "^0.2.7", - "ts-jest": "^29.4.11", - "typescript": "^6.0.3", - "uuid": "^14.0.0" + "ts-jest": "^29.4.12", + "typescript": "^6.0.3" } }, "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", + "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", + "@babel/helper-validator-identifier": "^7.29.7", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -38,9 +37,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "dev": true, "license": "MIT", "engines": { @@ -48,21 +47,21 @@ } }, "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -79,14 +78,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -96,14 +95,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -113,9 +112,9 @@ } }, "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz", + "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==", "dev": true, "license": "MIT", "engines": { @@ -123,29 +122,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz", + "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -165,9 +164,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "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": { @@ -175,9 +174,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "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", "engines": { @@ -185,9 +184,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz", + "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==", "dev": true, "license": "MIT", "engines": { @@ -195,27 +194,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", - "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", - "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.29.0" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -464,33 +463,33 @@ } }, "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", + "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" + "@babel/code-frame": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.8", + "@babel/helper-globals": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -498,14 +497,14 @@ } }, "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -903,9 +902,9 @@ } }, "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -1286,9 +1285,9 @@ } }, "node_modules/@types/node": { - "version": "25.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.3.tgz", - "integrity": "sha512-603BddQMv3pUcr4U2dhujk83N2tTDVr/34wII2B6bJy6g+8WD6yUb11jszNs0gdi4PesVWl7ABt8nYMVpnLUcg==", + "version": "25.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.5.tgz", + "integrity": "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==", "license": "MIT", "dependencies": { "undici-types": ">=7.24.0 <7.24.7" @@ -1841,19 +1840,22 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "version": "2.11.13", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.13.tgz", + "integrity": "sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==", "dev": true, "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -1862,9 +1864,9 @@ } }, "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", "dev": true, "funding": [ { @@ -1882,11 +1884,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" @@ -1975,9 +1977,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001769", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz", - "integrity": "sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==", + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", "dev": true, "funding": [ { @@ -2225,9 +2227,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "version": "1.5.403", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.403.tgz", + "integrity": "sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==", "dev": true, "license": "ISC" }, @@ -3017,9 +3019,9 @@ } }, "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -3378,9 +3380,9 @@ } }, "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -3600,9 +3602,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "version": "3.15.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.1.tgz", + "integrity": "sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==", "dev": true, "license": "MIT", "dependencies": { @@ -3849,11 +3851,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -4141,12 +4146,13 @@ "license": "MIT" }, "node_modules/qs": { - "version": "6.15.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", - "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -4534,9 +4540,9 @@ "license": "BSD-3-Clause" }, "node_modules/ts-jest": { - "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", + "version": "29.4.12", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.12.tgz", + "integrity": "sha512-Ov6ClY53Fflh6BGAnY2DlTq1hYDrTycz2PVTXBWFW2CU+9zrEqAp9fWdGXl42EXO5RLSFAcAZ2JFKbP+zBTFfw==", "dev": true, "license": "MIT", "dependencies": { @@ -4546,7 +4552,7 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.8.0", + "semver": "^7.8.5", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, @@ -4587,9 +4593,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", - "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, "license": "ISC", "bin": { @@ -4747,9 +4753,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", "dev": true, "funding": [ { @@ -4777,20 +4783,6 @@ "browserslist": ">= 4.21.0" } }, - "node_modules/uuid": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", - "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", - "dev": true, - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist-node/bin/uuid" - } - }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", diff --git a/package.json b/package.json index 34e1e27..89288e9 100644 --- a/package.json +++ b/package.json @@ -34,16 +34,20 @@ }, "homepage": "https://github.com/manybrain/mailinator-javascript-client", "dependencies": { - "@types/node": "^25.9.3", + "@types/node": "^25.9.5", "typed-rest-client": "^3.0.0" }, + "overrides": { + "typed-rest-client": { + "qs": "6.15.3" + } + }, "devDependencies": { "@types/jest": "^30.0.0", "dotenv": "^17.4.2", "jest": "^30.4.2", "tmp": "^0.2.7", - "ts-jest": "^29.4.11", - "typescript": "^6.0.3", - "uuid": "^14.0.0" + "ts-jest": "^29.4.12", + "typescript": "^6.0.3" } } diff --git a/tests/TestUtils.ts b/tests/TestUtils.ts index 7537688..108c383 100644 --- a/tests/TestUtils.ts +++ b/tests/TestUtils.ts @@ -1,4 +1,4 @@ -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {MessageToPost} from '../src/message/MessageToPost'; import {PostMessageRequest} from '../src/message/PostMessageRequest'; import {getApiToken} from "./TestEnv"; @@ -16,7 +16,7 @@ import { Webhook } from '../src/webhook/Webhook'; export const postMessage = (domain: string, inbox: string) => { - const random: string = uuid(); + const random: string = randomUUID(); const message = new MessageToPost("raul", `testPostMessageRequest JS ${random}`, `text ${random}`); @@ -48,7 +48,7 @@ export const createNewRule = async () => { condition.condition_data.field = "to"; condition.condition_data.value = "raul"; - const random: string = uuid(); + const random: string = randomUUID(); const ruleToCreate = new RuleToCreate(); ruleToCreate.name = `rule name ${random}`; @@ -73,4 +73,4 @@ export const getWehhookToAdd = () => { webhookToAdd.to = "jack"; return webhookToAdd; -} \ No newline at end of file +} diff --git a/tests/domain/CreateDomainRequest.test.ts b/tests/domain/CreateDomainRequest.test.ts index f2aca8a..0b73c81 100644 --- a/tests/domain/CreateDomainRequest.test.ts +++ b/tests/domain/CreateDomainRequest.test.ts @@ -1,5 +1,5 @@ import {DeleteDomainRequest} from '../../src/domain'; -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {createNewDomain} from '../TestUtils'; import {EnabledIfEnvironmentVariable, EnabledIfEnvironmentVariables, itIf} from "../ConditionalTest"; import {ENV_API_TOKEN, getApiToken} from "../TestEnv"; @@ -13,7 +13,7 @@ describe.skip('CreateDomainRequest Tests', function () { ) )('testCreateDomainRequest', async () => { - const random: string = uuid(); + const random: string = randomUUID(); const domainNameToCreate = `jstest${random}.testinator.com`; const response = await createNewDomain(domainNameToCreate); expect(response.statusCode).toBe(200); diff --git a/tests/domain/DeleteDomainRequest.test.ts b/tests/domain/DeleteDomainRequest.test.ts index 81a2999..1bab9fe 100644 --- a/tests/domain/DeleteDomainRequest.test.ts +++ b/tests/domain/DeleteDomainRequest.test.ts @@ -1,5 +1,5 @@ import {DeleteDomainRequest} from '../../src/domain'; -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {createNewDomain} from '../TestUtils'; import {ENV_API_TOKEN, getApiToken} from "../TestEnv"; import {EnabledIfEnvironmentVariable, EnabledIfEnvironmentVariables, itIf} from "../ConditionalTest"; @@ -13,7 +13,7 @@ describe.skip('DeleteDomainRequest Tests', function () { ) )('testDeleteDomainRequest', async () => { - const random: string = uuid(); + const random: string = randomUUID(); const domainNameToCreate = `jstest${random}.testinator.com`; const createDomainResponse = await createNewDomain(domainNameToCreate); diff --git a/tests/message/DeleteInboxMessagesRequest.test.ts b/tests/message/DeleteInboxMessagesRequest.test.ts index 8154073..d5c0af2 100644 --- a/tests/message/DeleteInboxMessagesRequest.test.ts +++ b/tests/message/DeleteInboxMessagesRequest.test.ts @@ -1,5 +1,5 @@ import {DeleteInboxMessagesRequest} from '../../src/message'; -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {postMessage} from '../TestUtils'; import {ENV_API_TOKEN, ENV_DOMAIN_PRIVATE, getApiToken, getPrivateDomain} from "../TestEnv"; import {EnabledIfEnvironmentVariable, EnabledIfEnvironmentVariables, itIf} from "../ConditionalTest"; @@ -14,7 +14,7 @@ describe('DeleteInboxMessagesRequest Tests', function () { )('testDeleteInboxMessagesRequest', async () => { const domain = getPrivateDomain(); - const inbox = `inbox ${uuid()}`; + const inbox = `inbox ${randomUUID()}`; await postMessage(domain, inbox); await postMessage(domain, inbox); await postMessage(domain, inbox); diff --git a/tests/message/GetInboxMessageRequest.test.ts b/tests/message/GetInboxMessageRequest.test.ts index 463ec7d..034ecbe 100644 --- a/tests/message/GetInboxMessageRequest.test.ts +++ b/tests/message/GetInboxMessageRequest.test.ts @@ -1,5 +1,5 @@ import {GetInboxMessageRequest} from '../../src/message'; -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {postMessage} from '../TestUtils'; import { ENV_API_TOKEN, @@ -44,7 +44,7 @@ describe('GetInboxMessageRequest Tests', function () { ) )('testInboxMessageRequestWhenMessageDoesNotExist', async () => { - const random: string = uuid(); + const random: string = randomUUID(); const request = new GetInboxMessageRequest(getPrivateDomain(), getInboxTest(), random); await expect(request.execute(getApiToken())).rejects.toThrow() }); diff --git a/tests/message/GetMessageRequest.test.ts b/tests/message/GetMessageRequest.test.ts index a412f8d..bcd4a5f 100644 --- a/tests/message/GetMessageRequest.test.ts +++ b/tests/message/GetMessageRequest.test.ts @@ -1,5 +1,5 @@ import {GetMessageRequest} from '../../src/message'; -import {v4 as uuid} from 'uuid'; +import {randomUUID} from 'node:crypto'; import {postMessage} from '../TestUtils'; import { ENV_API_TOKEN, @@ -45,7 +45,7 @@ describe('GetMessageRequest Tests', function () { ) )('testInboxMessageRequestWhenMessageDoesNotExist', async () => { - const random: string = uuid(); + const random: string = randomUUID(); const request = new GetMessageRequest(getPrivateDomain(), random); await expect(request.execute(getApiToken())).rejects.toThrow() }); diff --git a/tests/rule/GetRuleRequest.test.ts b/tests/rule/GetRuleRequest.test.ts index 22d0852..001636b 100644 --- a/tests/rule/GetRuleRequest.test.ts +++ b/tests/rule/GetRuleRequest.test.ts @@ -1,5 +1,4 @@ import {DeleteRuleRequest, GetRuleRequest} from "../../src/rule"; -import {v4 as uuid} from 'uuid'; import {createNewRule, getFirstAvailableDomain} from '../TestUtils'; import {ENV_API_TOKEN, getApiToken} from "../TestEnv"; import {EnabledIfEnvironmentVariable, EnabledIfEnvironmentVariables, itIf} from "../ConditionalTest"; diff --git a/tsconfig.test.json b/tsconfig.test.json new file mode 100644 index 0000000..d3712d3 --- /dev/null +++ b/tsconfig.test.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": false, + "types": [ + "node", + "jest" + ] + }, + "include": [ + "src", + "tests" + ], + "exclude": [ + "node_modules" + ] +}