diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..50ccbf3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + name: Test (Node ${{ matrix.node-version }}) + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: ["18.x", "20.x", "22.x"] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Run tests with jest + run: npm test diff --git a/.github/workflows/js.yml b/.github/workflows/js.yml deleted file mode 100644 index a03f498..0000000 --- a/.github/workflows/js.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Node.js CI - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build: - runs-on: ubuntu-latest - strategy: - matrix: - node-version: [18.x, 20.x, 22.x] - steps: - - uses: actions/checkout@v4 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - cache: 'npm' - - run: npm ci - - run: npm run build - - run: npm test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index b3e9512..28b66f0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,33 +1,55 @@ name: Publish to npm on: - push: - tags: - - 'v*' + push: + tags: + - "v*" jobs: - build: + test: + name: Test runs-on: ubuntu-latest + steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 with: - node-version: 20 - - run: npm ci - - run: npm run build - - run: npm test + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Run tests with jest + run: npm test - publish-npm: - needs: build + publish: + name: Publish to npm + needs: test runs-on: ubuntu-latest + steps: - uses: actions/checkout@v4 - - uses: actions/setup-node@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 with: - node-version: 20 - registry-url: https://registry.npmjs.org/ - - run: npm ci - - run: npm run build - - run: npm publish + node-version: "20" + cache: "npm" + registry-url: "https://registry.npmjs.org/" + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + + - name: Publish distribution to npm + run: npm publish env: - NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 2db4792..be9368e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,66 +1,22 @@ -node_modules/ -.node_modules/ -built/* -tests/cases/rwc/* -tests/cases/perf/* -!tests/cases/webharness/compilerToString.js -test-args.txt -~*.docx -\#*\# -.\#* -tests/baselines/local/* -tests/baselines/local.old/* -tests/services/baselines/local/* -tests/baselines/prototyping/local/* -tests/baselines/rwc/* -tests/baselines/reference/projectOutput/* -tests/baselines/local/projectOutput/* -tests/baselines/reference/testresults.tap -tests/baselines/symlinks/* -tests/services/baselines/prototyping/local/* -tests/services/browser/typescriptServices.js -src/harness/*.js -src/compiler/diagnosticInformationMap.generated.ts -src/compiler/diagnosticMessages.generated.json -src/parser/diagnosticInformationMap.generated.ts -src/parser/diagnosticMessages.generated.json -rwc-report.html -*.swp -build.json -*.actual -tests/webTestServer.js -tests/webTestServer.js.map -tests/webhost/*.d.ts -tests/webhost/webtsc.js -tests/cases/**/*.js -tests/cases/**/*.js.map -*.config -scripts/eslint/built/ -scripts/debug.bat -scripts/run.bat -scripts/**/*.js -scripts/**/*.js.map +# Build output +lib/ coverage/ -internal/ -**/.DS_Store -.settings -**/.vs -**/.vscode/* -!**/.vscode/tasks.json -!**/.vscode/settings.template.json -!**/.vscode/launch.template.json -!**/.vscode/extensions.json -!tests/cases/projects/projectOption/**/node_modules -!tests/cases/projects/NodeModulesSearch/**/* -!tests/baselines/reference/project/nodeModules*/**/* -.idea -yarn.lock -yarn-error.log -.parallelperf.* -tests/baselines/reference/dt -.failed-tests -TEST-results.xml -package-lock.json -.eslintcache +*.tgz + +# Dependencies +node_modules/ + +# Logs +npm-debug.log* *v8.log -/lib/ \ No newline at end of file + +# Environment +.env + +# IDE +.idea/ +.vscode/ +*.iml + +# OS +.DS_Store diff --git a/README.md b/README.md index 807a6f9..c82b960 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,7 @@ -# RegexSolver Node.js API Client - +# RegexSolver JS API Client [Homepage](https://regexsolver.com) | [Online Demo](https://regexsolver.com/demo) | [Documentation](https://docs.regexsolver.com) | [Developer Console](https://console.regexsolver.com) -This repository contains the source code of the Node.js library for [RegexSolver](https://regexsolver.com) API. - -RegexSolver is a powerful regular expression manipulation toolkit, that gives you the power to manipulate regex as if -they were sets. +**RegexSolver** is a powerful toolkit for building, combining, and analyzing regular expressions. It is designed for constraint solvers, test generators, and other systems that need advanced regex operations. ## Installation @@ -13,195 +9,134 @@ they were sets. npm install regexsolver ``` -## Usage - -In order to use the library you need to generate an API Token on our [Developer Console](https://console.regexsolver.com/). - -```javascript -import { RegexSolver, Term } from 'regexsolver'; - -RegexSolver.initialize("YOUR TOKEN HERE"); - -const term1 = Term.regex("(abc|de|fg){2,}"); -const term2 = Term.regex("de.*"); -const term3 = Term.regex(".*abc"); - -const term4 = Term.regex(".+(abc|de).+"); - -term1.intersection(term2, term3) - .then(result => result.subtraction(term4)) - .then(result => console.log(result.toString())); -``` - - -## Features - -- [Intersection](#intersection) -- [Union](#union) -- [Subtraction / Difference](#subtraction--difference) -- [Equivalence](#equivalence) -- [Subset](#subset) -- [Details](#details) -- [Generate Strings](#generate-strings) - -### Intersection +Requirements: **Node.js >= 18** -#### Request +## Quick Start -Compute the intersection of the provided terms and return the resulting term. - -The maximum number of terms is currently limited to 10. +1. Create an API token in the [Developer Console](https://console.regexsolver.com/). +2. Initialize the client and start working with terms. ```javascript -const term1 = Term.regex("(abc|de){2}"); -const term2 = Term.regex("de.*"); -const term3 = Term.regex(".*abc"); - -term1.intersection(term2, term3).then(result => { - console.log(result.toString()); -}); -``` - -#### Response - -``` -regex=deabc -``` +import { RegexSolverClient, Term } from 'regexsolver'; -### Union +async function main() { + const client = new RegexSolverClient({ apiToken: 'REGEXSOLVER_API_TOKEN' }); -Compute the union of the provided terms and return the resulting term. + const term1 = Term.regex("(abc|de|fg){2,}"); + const term2 = Term.regex("de.*"); -The maximum number of terms is currently limited to 10. + const intersection = await client.intersection(term1, term2); + const pattern = await client.getPattern(intersection); + console.log(pattern); // de(abc|de|fg)+ +} -#### Request - -```javascript -const term1 = Term.regex("abc"); -const term2 = Term.regex("de"); -const term3 = Term.regex("fghi"); - -term1.union(term2, term3).then(result => { - console.log(result.toString()); -}); +main(); ``` -#### Response +## Key Concepts & Limitations -``` -regex=(abc|de|fghi) -``` +RegexSolver supports a subset of regular expressions that adhere to the principles of regular languages. Here are the key characteristics and limitations of the regular expressions supported by RegexSolver: +- **Anchored Expressions:** All regular expressions in RegexSolver are anchored. This means that the expressions are treated as if they start and end at the boundaries of the input text. For example, the expression `abc` will match the string "abc" but not "xabc" or "abcx". +- **Lookahead/Lookbehind:** RegexSolver does not support lookahead (`(?=...)`) or lookbehind (`(?<=...)`) assertions. Using them returns an error. +- **Pure Regular Expressions:** RegexSolver focuses on pure regular expressions as defined in regular language theory. This means features that extend beyond regular languages, such as backreferences (`\1`, `\2`, etc.), are not supported. Any use of backreference would return an error. +- **Greedy/Ungreedy Quantifiers:** The concept of ungreedy (`*?`, `+?`, `??`) quantifiers is not supported. All quantifiers are treated as greedy. For example, `a*` or `a*?` will match the longest possible sequence of "a"s. +- **Line Feed and Dot:** RegexSolver handles all characters the same way. The dot `.` matches any Unicode character including line feed (`\n`). +- **Empty Regular Expressions:** The empty language (matches no string) is represented by constructs like `[]` (empty character class). This is distinct from the empty string. -### Subtraction / Difference +## Response Formats -Compute the first term minus the second and return the resulting term. +The API can handle terms in two formats: +- `regex`: a regular expression pattern +- `fair`: FAIR (Fast Automaton Internal Representation), a stable, signed format used internally by the engine -#### Request +By default, the engine returns whatever the operation produces, with no extra conversion. Override with `OperationOptions`, accepted by the operations that return a term: ```javascript -const term1 = Term.regex("(abc|de)"); -const term2 = Term.regex("de"); - -term1.subtraction(term2).then(result => { - console.log(result.toString()); -}); +import { Term, ResponseFormat } from 'regexsolver'; -``` - -#### Response - -``` -regex=abc -``` - -### Equivalence - -Analyze if the two provided terms are equivalent. +const term1 = Term.regex('abcde'); +const term2 = Term.regex('de'); -#### Request +const result1 = await client.union(term1, term2, { responseFormat: ResponseFormat.REGEX }); +console.log(result1.toString()); // regex=(abc)?de -```javascript -const term1 = Term.regex("(abc|de)"); -const term2 = Term.regex("(abc|de)*"); - -term1.isEquivalentTo(term2).then(result => { - console.log(result); -}); +const result2 = await client.union(term1, term2, { responseFormat: ResponseFormat.FAIR }); +console.log(result2.toString()); // fair=... ``` -#### Response +If the format does not matter, omit `responseFormat` or set it to `ResponseFormat.ANY`. -``` -false -``` +Regardless of the format, you can always call `getPattern()` to obtain the regex pattern of a term. -### Subset +## Bounding execution time -Analyze if the second term is a subset of the first. - -#### Request +Set a server-side compute timeout in milliseconds with `executionTimeout` in `OperationOptions`: ```javascript -const term1 = Term.regex("de"); -const term2 = Term.regex("(abc|de)"); - -term1.isSubsetOf(term2).then(result => { - console.log(result); -}); +import { TimeoutExceededError, Term } from 'regexsolver'; +// Limit the server-side compute time to 100 ms +try { + const term1 = Term.regex('.*ab.*c(de|fg).*dab.*c(de|fg).*ab.*c(de|fg).*dab.*c'); + const term2 = Term.regex('.*abc.*'); + + const res = await client.difference(term1, term2, { executionTimeout: 100 }); +} catch (error) { + if (error instanceof TimeoutExceededError) { + console.log(error.message); // The operation took too much time. + } +} ``` -#### Response +Timeout is best effort. The exact time is not guaranteed. -``` -true -``` +## API Overview -### Details +`RegexSolverClient` exposes the following methods. Every method accepts an optional options object as its last parameter: operations that return a term take `OperationOptions` (`responseFormat`, `deterministic`, `executionTimeout`), while analyze operations and `determinize()` take `ExecutionOptions` (`executionTimeout` only); the response format is not theirs to choose. `generateStrings()` takes a `GenerateStringsOptions` carrying its ordering, seed, length and charset options. -Compute the details of the provided term. +### Analyze -The computed details are: +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.equivalent(term1, term2, options?)` | `Promise` | `true` if `term1` and `term2` accept exactly the same language. | +| `client.getCardinality(term, options?)` | `Promise` | Returns the number of possible matched strings. | +| `client.getDot(term, options?)` | `Promise` | Returns a Graphviz DOT representation of the automaton. | +| `client.getLength(term, options?)` | `Promise` | Returns the minimum and maximum length of matched strings. | +| `client.getPattern(term, options?)` | `Promise` | Returns a regular expression pattern for the term. | +| `client.isEmpty(term, options?)` | `Promise` | `true` if the term matches no string. | +| `client.isEmptyString(term, options?)` | `Promise` | `true` if the term matches only the empty string. | +| `client.isTotal(term, options?)` | `Promise` | `true` if the term matches all possible strings. | +| `client.isDeterministic(term, options?)` | `Promise` | `true` if the term's automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated `generateStrings()` calls; call `determinize()` first if this is `false`. | +| `client.subset(subset, superset, options?)` | `Promise` | `true` if every string matched by `subset` is also matched by `superset`. | -- **Cardinality:** the number of possible values. -- **Length:** the minimum and maximum length of possible values. -- **Empty:** true if is an empty set (does not contain any value), false otherwise. -- **Total:** true if is a total set (contains all values), false otherwise. +### Compute -#### Request +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.complement(term, options?)` | `Promise` | Computes the complement of the given term. | +| `client.concat(term1, term2, ..., options?)` | `Promise` | Concatenates multiple terms in order. | +| `client.determinize(term, options?)` | `Promise` | Computes a deterministic FAIR for the given term, suitable for consistent pagination with `generateStrings()`. | +| `client.difference(base, excluded, options?)` | `Promise` | Computes the difference `base - excluded`. | +| `client.intersection(term1, term2, ..., options?)` | `Promise` | Computes the intersection of the given terms. | +| `client.repeat(term, min, max, options?)` | `Promise` | Computes the repetition of the term between `min` and `max` times. | +| `client.union(term1, term2, ..., options?)` | `Promise` | Computes the union of the given terms. | -```javascript -const term = Term.regex("(abc|de)"); +### Generate -term.getDetails().then(details => { - console.log(details.toString()); -}); -``` +| Method | Return | Description | +| -------- | ------- | ------- | +| `client.generateStrings(term, limit, offset, options?)` | `Promise` | Generates up to `limit` unique strings matched by `term`, skipping the first `offset` strings. The options object controls `pathOrder`, `characterOrder`, `seed`, `minLength`, `maxLength` and `charset`. | -#### Response +## Cross-Language Support -``` -Details[cardinality=Integer(2), length=Length[minimum=2, maximum=3], empty=false, total=false] -``` - -### Generate Strings +If you want to use this library with other programming languages, we provide: +- [regexsolver-java](https://github.com/RegexSolver/regexsolver-java) +- [regexsolver-python](https://github.com/RegexSolver/regexsolver-python) -Generate the given number of strings that can be matched by the provided term. +For more information about how to use the wrappers, you can refer to our [guide](https://docs.regexsolver.com/getting-started.html). -The maximum number of strings to generate is currently limited to 200. +You can also take a look at [regexsolver](https://github.com/RegexSolver/regexsolver) which contains the source code of the engine. -#### Request +## License -```javascript -const term = Term.regex("(abc|de){2}"); - -term.generateStrings(3).then(result => { - console.log(result); -}); -``` - -#### Response - -``` -[ 'deabc', 'abcde', 'dede' ] -``` +This project is licensed under the MIT License. diff --git a/generate-api.sh b/generate-api.sh new file mode 100755 index 0000000..0f6d649 --- /dev/null +++ b/generate-api.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +SPEC_FILE="../m-lab/shared/openapi.yaml" +OUT_DIR="./src/generated" + +echo "Running openapi-generator-cli..." +openapi-generator-cli generate \ + -i "$SPEC_FILE" \ + -g typescript-axios \ + -o "$OUT_DIR" + +echo "API Generation Complete." diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..31e5aa5 --- /dev/null +++ b/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * RegexSolver + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; + diff --git a/jest.config.js b/jest.config.js index b07ae7b..e63ddf2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,5 @@ module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', -}; \ No newline at end of file + preset: 'ts-jest', + testEnvironment: 'node', + testMatch: ['**/tests/**/*.test.ts'], +}; diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 0000000..91d9c43 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.21.0" + } +} diff --git a/package-lock.json b/package-lock.json index abe586e..a78b238 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,56 +1,47 @@ { "name": "regexsolver", - "version": "1.0.4", + "version": "1.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "regexsolver", - "version": "1.0.4", + "version": "1.1.0", "license": "MIT", "dependencies": { - "axios": "^1.7.4" + "axios": "~1.18.1" }, "devDependencies": { - "@types/jest": "^29.5.12", - "jest": "^29.7.0", - "nock": "^13.5.4", - "ts-jest": "^29.2.4", - "typescript": "^5.5.4" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@types/jest": "^30.0.0", + "@types/node": "^25.5.0", + "axios-mock-adapter": "^2.1.0", + "jest": "^30.3.0", + "ts-jest": "^29.4.6", + "typescript": "^5.9.3" }, "engines": { - "node": ">=6.0.0" + "node": ">=18" } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "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/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.29.7", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.2.tgz", - "integrity": "sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==", + "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": { @@ -58,22 +49,22 @@ } }, "node_modules/@babel/core": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", - "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.25.0", - "@babel/helper-compilation-targets": "^7.25.2", - "@babel/helper-module-transforms": "^7.25.2", - "@babel/helpers": "^7.25.0", - "@babel/parser": "^7.25.0", - "@babel/template": "^7.25.0", - "@babel/traverse": "^7.25.2", - "@babel/types": "^7.25.2", + "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.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", "gensync": "^1.0.0-beta.2", @@ -89,31 +80,32 @@ } }, "node_modules/@babel/generator": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.0.tgz", - "integrity": "sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==", + "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/types": "^7.25.0", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "@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" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", - "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", + "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.25.2", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.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" }, @@ -121,31 +113,40 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/helper-globals": { + "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": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", + "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.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", - "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", + "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.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", - "@babel/traverse": "^7.25.2" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -155,33 +156,19 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz", + "integrity": "sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "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": { @@ -189,9 +176,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "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": { @@ -199,9 +186,9 @@ } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", + "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": { @@ -209,121 +196,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.0.tgz", - "integrity": "sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "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/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.3.tgz", - "integrity": "sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==", + "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.25.2" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -388,13 +281,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz", - "integrity": "sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -430,13 +323,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", - "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz", + "integrity": "sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -556,13 +449,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", - "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -572,49 +465,48 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "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.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@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.25.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.3.tgz", - "integrity": "sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==", + "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.24.7", - "@babel/generator": "^7.25.0", - "@babel/parser": "^7.25.3", - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.2", - "debug": "^4.3.1", - "globals": "^11.1.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": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.25.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.2.tgz", - "integrity": "sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==", + "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.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -627,6 +519,58 @@ "dev": true, "license": "MIT" }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -645,9 +589,9 @@ } }, "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz", + "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==", "dev": true, "license": "MIT", "engines": { @@ -655,61 +599,61 @@ } }, "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", + "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", + "chalk": "^4.1.2", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", + "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "30.4.1", + "@jest/pattern": "30.4.0", + "@jest/reporters": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.4.1", + "jest-config": "30.4.2", + "jest-haste-map": "30.4.1", + "jest-message-util": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-resolve-dependencies": "30.4.2", + "jest-runner": "30.4.2", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "jest-watcher": "30.4.1", + "pretty-format": "30.4.1", + "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "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" @@ -720,117 +664,150 @@ } } }, + "node_modules/@jest/diff-sequences": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", + "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", + "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "^29.7.0" + "jest-mock": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "expect": "30.4.1", + "jest-snapshot": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", + "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "@jest/get-type": "30.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", + "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", + "@jest/types": "30.4.1", + "@sinonjs/fake-timers": "^15.4.0", "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", + "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/types": "30.4.1", + "jest-mock": "30.4.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", + "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" + "@types/node": "*", + "jest-regex-util": "30.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", + "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", + "@jest/console": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", + "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": "^4.0.0", + "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", + "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "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" @@ -842,139 +819,152 @@ } }, "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", + "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", + "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", + "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@jest/console": "30.4.1", + "@jest/types": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", + "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", + "@jest/test-result": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", + "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", + "@babel/core": "^7.27.4", + "@jest/types": "30.4.1", + "@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.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "pirates": "^4.0.7", "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", + "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/pattern": "30.4.0", + "@jest/schemas": "30.4.1", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" } }, - "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==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", - "engines": { - "node": ">=6.0.0" + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", "engines": { @@ -982,16 +972,16 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -999,10 +989,56 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.3.6.tgz", + "integrity": "sha512-SEeaJLb3qBNF/OaXnaR1NmmBbFYk1zC0ZH/52fATcRPLFg/p791YrcyFFy44Bo9sLaGuSuLp5Q6axbb/O+v/RA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.34.52", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.52.tgz", + "integrity": "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==", "dev": true, "license": "MIT" }, @@ -1017,13 +1053,24 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "15.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", + "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" + } + }, + "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": { + "tslib": "^2.4.0" } }, "node_modules/@types/babel__core": { @@ -1041,9 +1088,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", "dependencies": { @@ -1062,23 +1109,13 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*" + "@babel/types": "^7.28.2" } }, "node_modules/@types/istanbul-lib-coverage": { @@ -1109,24 +1146,24 @@ } }, "node_modules/@types/jest": { - "version": "29.5.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.12.tgz", - "integrity": "sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==", + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" + "expect": "^30.0.0", + "pretty-format": "^30.0.0" } }, "node_modules/@types/node": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", - "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "version": "25.9.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.5.tgz", + "integrity": "sha512-OScDchr2fwuUmWdf4kZ9h7PcJiYDVInhJizG/biAq3cAvqwYktuy/TYGGdZNMtNTFUP7rnb0NU4TUdm82kt4Rg==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.18.2" + "undici-types": ">=7.24.0 <7.24.7" } }, "node_modules/@types/stack-utils": { @@ -1137,9 +1174,9 @@ "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.33", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", - "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, "license": "MIT", "dependencies": { @@ -1153,78 +1190,449 @@ "dev": true, "license": "MIT" }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "ISC" }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, "dependencies": { - "sprintf-js": "~1.0.2" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" } }, - "node_modules/async": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", - "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } }, "node_modules/asynckit": { "version": "0.4.0", @@ -1233,92 +1641,90 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz", - "integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.18.1.tgz", + "integrity": "sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==", + "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/axios-mock-adapter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/axios-mock-adapter/-/axios-mock-adapter-2.1.0.tgz", + "integrity": "sha512-AZUe4OjECGCNNssH8SOdtneiQELsqTsat3SQQCWLPjN436/H+L9AjWfV7bF+Zg/YL9cgbhrz5671hoh+Tbn98w==", + "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" + "fast-deep-equal": "^3.1.3", + "is-buffer": "^2.0.5" + }, + "peerDependencies": { + "axios": ">= 0.17.0" } }, "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", + "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", + "@jest/transform": "30.4.1", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.4.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", "test-exclude": "^6.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" + "node": ">=12" } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", + "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "@types/babel__core": "^7.20.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", - "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, "license": "MIT", "dependencies": { @@ -1339,24 +1745,24 @@ "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0 || ^8.0.0-0" } }, "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", + "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" + "babel-plugin-jest-hoist": "30.4.0", + "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" } }, "node_modules/balanced-match": { @@ -1366,34 +1772,33 @@ "dev": true, "license": "MIT" }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/baseline-browser-mapping": { + "version": "2.11.12", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.12.tgz", + "integrity": "sha512-r7WnVImvVCeFpf2DOXfy41aPWzeNg3H/A2X4dKmy1QL0MSyyk/e7z8ihJ3N6Nn2PsdhkVlqnEfnUE4a05P2aTA==", "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/brace-expansion": { + "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": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" + "balanced-match": "^1.0.0" } }, "node_modules/browserslist": { - "version": "4.23.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", - "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", + "version": "4.28.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.7.tgz", + "integrity": "sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==", "dev": true, "funding": [ { @@ -1411,10 +1816,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001646", - "electron-to-chromium": "^1.5.4", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" + "baseline-browser-mapping": "^2.10.44", + "caniuse-lite": "^1.0.30001806", + "electron-to-chromium": "^1.5.393", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" }, "bin": { "browserslist": "cli.js" @@ -1453,6 +1859,19 @@ "dev": true, "license": "MIT" }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1474,9 +1893,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001651", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz", - "integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==", + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", "dev": true, "funding": [ { @@ -1522,9 +1941,9 @@ } }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -1538,9 +1957,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", - "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "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==", "dev": true, "license": "MIT" }, @@ -1559,6 +1978,69 @@ "node": ">=12" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -1571,9 +2053,9 @@ } }, "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, @@ -1623,32 +2105,10 @@ "dev": true, "license": "MIT" }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", "dependencies": { @@ -1661,13 +2121,12 @@ } }, "node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -1679,9 +2138,9 @@ } }, "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1722,36 +2181,31 @@ "node": ">=8" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.7.tgz", - "integrity": "sha512-6FTNWIWMxMy/ZY6799nBlPtF1DFDQ6VQJ7yyDP27SJNt5lwtQ5ufqVvHylb3fdQefvRcgA3fKcFMJi9OLwBRNw==", + "version": "1.5.400", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.400.tgz", + "integrity": "sha512-96EWDNjM59SYflgeV5Ylsf4EMiq1a25YjCnJH7cxn/AF2H3pILRweaUnoLax0yKHWdpOzY6JKEu45e8irqZIHA==", "dev": true, "license": "ISC" }, @@ -1769,26 +2223,71 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true, "license": "MIT" }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", "engines": { @@ -1843,32 +2342,48 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, + "license": "ISC" + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", + "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" + "@jest/expect-utils": "30.4.1", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-util": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -1886,52 +2401,6 @@ "bser": "2.1.1" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1947,9 +2416,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "funding": [ { "type": "individual", @@ -1966,15 +2435,34 @@ } } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", + "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.4", + "mime-types": "^2.1.35" }, "engines": { "node": ">= 6" @@ -2006,7 +2494,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2032,6 +2519,30 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -2042,6 +2553,19 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -2056,44 +2580,68 @@ } }, "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "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" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "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": ">=4" + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2104,11 +2652,37 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -2124,6 +2698,19 @@ "dev": true, "license": "MIT" }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -2190,20 +2777,28 @@ "dev": true, "license": "MIT" }, - "node_modules/is-core-module": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.0.tgz", - "integrity": "sha512-Dd+Lb2/zvk9SKy1TGCt1wFJFo/MWBPMX5x7KcvLajWTGuomczdQX61PvY5yK6SVACwpoexWo81IfFyoKY2QnTA==", + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4" } }, "node_modules/is-fullwidth-code-point": { @@ -2226,16 +2821,6 @@ "node": ">=6" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2284,9 +2869,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "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": { @@ -2312,24 +2897,24 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "istanbul-lib-coverage": "^3.0.0" }, "engines": { "node": ">=10" } }, "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2340,42 +2925,39 @@ "node": ">=8" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, - "license": "Apache-2.0", + "license": "BlueOak-1.0.0", "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" + "@isaacs/cliui": "^8.0.2" }, - "bin": { - "jake": "bin/cli.js" + "funding": { + "url": "https://github.com/sponsors/isaacs" }, - "engines": { - "node": ">=10" + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", + "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" + "@jest/core": "30.4.2", + "@jest/types": "30.4.1", + "import-local": "^3.2.0", + "jest-cli": "30.4.2" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "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" @@ -2387,76 +2969,75 @@ } }, "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", + "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", "dev": true, "license": "MIT", "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", + "execa": "^5.1.1", + "jest-util": "30.4.1", "p-limit": "^3.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", + "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.4.1", + "@jest/expect": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", + "chalk": "^4.1.2", "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-runtime": "30.4.2", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", + "pretty-format": "30.4.1", + "pure-rand": "^7.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "stack-utils": "^2.0.6" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", + "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" + "@jest/core": "30.4.2", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "yargs": "^17.7.2" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "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" @@ -2468,215 +3049,211 @@ } }, "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", + "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.4.0", + "@jest/test-sequencer": "30.4.1", + "@jest/types": "30.4.1", + "babel-jest": "30.4.1", + "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.4.2", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-runner": "30.4.2", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", + "pretty-format": "30.4.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "@types/node": "*", + "esbuild-register": ">=3.4.0", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "esbuild-register": { + "optional": true + }, "ts-node": { "optional": true } } }, "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", + "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/diff-sequences": "30.4.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", + "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", "dev": true, "license": "MIT", "dependencies": { - "detect-newline": "^3.0.0" + "detect-newline": "^3.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", + "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "chalk": "^4.1.2", + "jest-util": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", + "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-mock": "30.4.1", + "jest-util": "30.4.1", + "jest-validate": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", + "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", + "@jest/types": "30.4.1", "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.4.0", + "jest-util": "30.4.1", + "jest-worker": "30.4.1", + "picomatch": "^4.0.3", "walker": "^1.0.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "optionalDependencies": { - "fsevents": "^2.3.2" + "fsevents": "^2.3.3" } }, "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", + "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", + "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.4.1", + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", + "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.4.1", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-util": "30.4.1", + "picomatch": "^4.0.3", + "pretty-format": "30.4.1", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "stack-utils": "^2.0.6" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", + "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.4.1", "@types/node": "*", - "jest-util": "^29.7.0" + "jest-util": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -2698,153 +3275,154 @@ } }, "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "version": "30.4.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", + "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "dev": true, "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", + "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.4.1", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.4.1", + "jest-validate": "30.4.1", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", + "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" + "jest-regex-util": "30.4.0", + "jest-snapshot": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", + "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "30.4.1", + "@jest/environment": "30.4.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", + "chalk": "^4.1.2", "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.4.0", + "jest-environment-node": "30.4.1", + "jest-haste-map": "30.4.1", + "jest-leak-detector": "30.4.1", + "jest-message-util": "30.4.1", + "jest-resolve": "30.4.1", + "jest-runtime": "30.4.2", + "jest-util": "30.4.1", + "jest-watcher": "30.4.1", + "jest-worker": "30.4.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "version": "30.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", + "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.4.1", + "@jest/fake-timers": "30.4.1", + "@jest/globals": "30.4.1", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "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.4.1", + "jest-message-util": "30.4.1", + "jest-mock": "30.4.1", + "jest-regex-util": "30.4.0", + "jest-resolve": "30.4.1", + "jest-snapshot": "30.4.1", + "jest-util": "30.4.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", + "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", + "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.4.1", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.4.1", + "@jest/transform": "30.4.1", + "@jest/types": "30.4.1", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.4.1", + "graceful-fs": "^4.2.11", + "jest-diff": "30.4.1", + "jest-matcher-utils": "30.4.1", + "jest-message-util": "30.4.1", + "jest-util": "30.4.1", + "pretty-format": "30.4.1", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "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": { @@ -2855,39 +3433,39 @@ } }, "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", + "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.4.1", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", + "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", + "@jest/get-type": "30.1.0", + "@jest/types": "30.4.1", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "^29.7.0" + "pretty-format": "30.4.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-validate/node_modules/camelcase": { @@ -2904,39 +3482,40 @@ } }, "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", + "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/test-result": "30.4.1", + "@jest/types": "30.4.1", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" + "jest-util": "30.4.1", + "string-length": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", + "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.7.0", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.4.1", "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "supports-color": "^8.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-worker/node_modules/supports-color": { @@ -2963,9 +3542,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "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": { @@ -2977,16 +3556,16 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-parse-even-better-errors": { @@ -2996,13 +3575,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3016,16 +3588,6 @@ "node": ">=6" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -3090,9 +3652,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "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": { @@ -3119,6 +3681,15 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3126,20 +3697,6 @@ "dev": true, "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -3172,25 +3729,63 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.2" }, "engines": { - "node": "*" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3198,20 +3793,12 @@ "dev": true, "license": "MIT" }, - "node_modules/nock": { - "version": "13.5.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.5.4.tgz", - "integrity": "sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==", + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "json-stringify-safe": "^5.0.1", - "propagate": "^2.0.0" - }, - "engines": { - "node": ">= 10.13" - } + "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", @@ -3221,11 +3808,14 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.52", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.52.tgz", + "integrity": "sha512-MRlTqhAfoMx/4mhEbPo3Hi02g9LJZaJkka69V6h67Cb1gjrAG0jsTE4CZX1eptNx+VCAwJmfpnDIF4P0Nh1A7A==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -3331,6 +3921,13 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -3380,37 +3977,54 @@ "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", "dev": true, - "license": "MIT" + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "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": ">=8.6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", "engines": { @@ -3431,18 +4045,19 @@ } }, "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "version": "30.4.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", + "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/schemas": "30.4.1", + "ansi-styles": "^5.2.0", + "react-is-18": "npm:react-is@^18.3.1", + "react-is-19": "npm:react-is@^19.2.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { @@ -3458,40 +4073,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/propagate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", - "dev": true, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=10" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "dev": true, "funding": [ { @@ -3505,13 +4099,22 @@ ], "license": "MIT" }, - "node_modules/react-is": { + "node_modules/react-is-18": { + "name": "react-is", "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, + "node_modules/react-is-19": { + "name": "react-is", + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz", + "integrity": "sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==", + "dev": true, + "license": "MIT" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -3522,24 +4125,6 @@ "node": ">=0.10.0" } }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -3563,16 +4148,6 @@ "node": ">=8" } }, - "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -3607,18 +4182,17 @@ } }, "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "MIT" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } }, "node_modules/slash": { "version": "3.0.0", @@ -3665,27 +4239,69 @@ "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "^2.0.0" + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "dev": true, "license": "MIT", "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/string-width": { + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", @@ -3700,7 +4316,54 @@ "node": ">=8" } }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -3713,6 +4376,16 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -3759,17 +4432,20 @@ "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/synckit": { + "version": "0.11.13", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.13.tgz", + "integrity": "sha512-eNRKgb3z66Yp3D2CixVujOUvXLFUTij/zVnV8KRyvFdQwpz7I5DS8UfRkTeLzb64u+dkzDSdelE24izu+zSSUg==", "dev": true, "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.3.6" + }, "engines": { - "node": ">= 0.4" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/synckit" } }, "node_modules/test-exclude": { @@ -3787,52 +4463,75 @@ "node": ">=8" } }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "node_modules/test-exclude/node_modules/brace-expansion": { + "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": "BSD-3-Clause" + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=4" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "is-number": "^7.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8.0" + "node": "*" } }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/ts-jest": { - "version": "29.2.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.4.tgz", - "integrity": "sha512-3d6tgDyhCI29HlpwIq87sNuI+3Q6GLTTCeYRHCs7vDz+/3GCMwEtV9jezLyl4ZtnBgx00I7hm8PCP8cTksMGrw==", + "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": { - "bs-logger": "0.x", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.9", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "^7.5.3", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.8.5", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" @@ -3842,11 +4541,12 @@ }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" + "@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 <7" }, "peerDependenciesMeta": { "@babel/core": { @@ -3863,13 +4563,16 @@ }, "esbuild": { "optional": true + }, + "jest-util": { + "optional": true } } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "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": { @@ -3879,6 +4582,27 @@ "node": ">=10" } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -3903,9 +4627,9 @@ } }, "node_modules/typescript": { - "version": "5.5.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", - "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -3916,17 +4640,69 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", - "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==", + "version": "7.24.6", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", + "integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==", "dev": true, "license": "MIT" }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", + "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==", "dev": true, "funding": [ { @@ -3944,8 +4720,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -3995,7 +4771,33 @@ "node": ">= 8" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", @@ -4013,6 +4815,64 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4021,17 +4881,17 @@ "license": "ISC" }, "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "signal-exit": "^4.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/y18n": { @@ -4052,9 +4912,9 @@ "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "dev": true, "license": "MIT", "dependencies": { @@ -4080,6 +4940,51 @@ "node": ">=12" } }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 0ca10bb..4b08b7c 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,16 @@ { "name": "regexsolver", - "version": "1.0.4", - "main": "lib/index.js", - "typings": "lib/index.d.ts", - "types": "lib/index.d.ts", + "version": "1.1.0", + "main": "./lib/index.js", + "typings": "./lib/index.d.ts", + "types": "./lib/index.d.ts", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "import": "./lib/index.js", + "require": "./lib/index.js" + } + }, "files": [ "src/", "lib/" @@ -12,6 +19,9 @@ "test": "jest", "build": "tsc" }, + "engines": { + "node": ">=18" + }, "keywords": [ "Regular Expression", "regex", @@ -28,7 +38,7 @@ ], "author": "RegexSolver", "license": "MIT", - "description": "RegexSolver allows you to manipulate regular expressions as sets, enabling operations such as intersection, union, and subtraction.", + "description": "RegexSolver is a powerful toolkit for building, combining, and analyzing regular expressions.", "repository": { "type": "git", "url": "git+https://github.com/RegexSolver/regexsolver-js.git" @@ -41,13 +51,14 @@ "Alexandre van Beurden (https://github.com/alexvbrdn)" ], "dependencies": { - "axios": "^1.7.4" + "axios": "~1.18.1" }, "devDependencies": { - "@types/jest": "^29.5.12", - "ts-jest": "^29.2.4", - "jest": "^29.7.0", - "nock": "^13.5.4", - "typescript": "^5.5.4" + "@types/jest": "^30.0.0", + "@types/node": "^25.5.0", + "axios-mock-adapter": "^2.1.0", + "jest": "^30.3.0", + "ts-jest": "^29.4.6", + "typescript": "^5.9.3" } } diff --git a/src/RateLimiter.ts b/src/RateLimiter.ts new file mode 100644 index 0000000..75d0557 --- /dev/null +++ b/src/RateLimiter.ts @@ -0,0 +1,38 @@ +/** + * Shared across all client instances with the same API token. + * + * Holds a single deadline timestamp. `trigger` keeps the later of the current + * and the new deadline, so a longer `Retry-After` arriving while the limiter + * is already engaged is never dropped. `wait` sleeps until the deadline and + * re-checks it after every wake, so a deadline extended by a concurrent 429 + * is honored too. + */ +export class RateLimiter { + private deadline = 0; + + async wait(): Promise { + while (Date.now() < this.deadline) { + await new Promise((resolve) => + setTimeout(resolve, this.deadline - Date.now()), + ); + } + } + + trigger(retryAfterSeconds: number): void { + this.deadline = Math.max( + this.deadline, + Date.now() + retryAfterSeconds * 1000, + ); + } +} + +const rateLimiters = new Map(); + +export function getRateLimiter(apiToken: string): RateLimiter { + let limiter = rateLimiters.get(apiToken); + if (!limiter) { + limiter = new RateLimiter(); + rateLimiters.set(apiToken, limiter); + } + return limiter; +} diff --git a/src/RegexSolverClient.ts b/src/RegexSolverClient.ts new file mode 100644 index 0000000..d6ce67d --- /dev/null +++ b/src/RegexSolverClient.ts @@ -0,0 +1,980 @@ +import axios, { AxiosError, AxiosInstance, AxiosResponse } from "axios"; +import { + AccountApi, + AnalyzeApi, + ComputeApi, + GenerateApi, + Configuration, + TermRequest, + MultiTermsRequest, + TwoTermsRequest, + RepeatRequest, + GenerateStringsRequest, + RequestOptions as RequestOptionsDto, +} from "./generated"; +import { FairTerm, Term } from "./models/Term"; +import { AccountLimits } from "./models/AccountLimits"; +import { Cardinality, Infinite, Integer } from "./models/Cardinality"; +import { CharacterOrder, PathOrder } from "./models/GenerateStringsOrder"; +import { Length } from "./models/Length"; +import { ResponseFormat } from "./models/ResponseFormat"; +import * as Exceptions from "./exceptions"; +import { getRateLimiter, RateLimiter } from "./RateLimiter"; + +const VERSION = "1.1.0"; + +// Retry policy for 429 responses: retry as long as the total wait stays +// within the budget, adding full jitter on top of `Retry-After` so concurrent +// waiters do not re-collide as a single burst. The values are shared across +// all the official clients — change them together. +const RETRY_BUDGET_MS = 300_000; +const JITTER_BASE_S = 0.25; +const JITTER_CAP_S = 2.0; +const DEFAULT_RETRY_AFTER_S = 1.0; + +export interface RegexSolverConfig { + apiToken: string; + baseUrl?: string; + /** + * When true (the default), calls to concat/intersection/union carrying more + * terms than the account's per-request limit are transparently split into + * several requests and folded back into one result. Each constituent + * request counts against the monthly quota. + */ + autoBatch?: boolean; + /** + * Upper bound (>= 2) on the number of terms sent in a single request, + * overriding the limit fetched from the API when smaller. + */ + maxTermsPerRequest?: number; +} + +/** + * Options accepted by every operation. + */ +export interface ExecutionOptions { + /** + * Timeout in milliseconds for the operation. + */ + executionTimeout?: number; +} + +/** + * Options for operations that return a term. + * + * Analyze operations and determinize() take {@link ExecutionOptions} instead: + * they do not return a caller-shaped term, so responseFormat and deterministic + * would have no effect there. + */ +export interface OperationOptions extends ExecutionOptions { + /** + * Return format of the term. + */ + responseFormat?: ResponseFormat | string; + /** + * When true, guarantees the returned FAIR encodes a deterministic automaton. + * Only valid with responseFormat=ResponseFormat.FAIR or when responseFormat is + * unset (in which case it defaults to ResponseFormat.FAIR). Throws otherwise. + */ + deterministic?: boolean; +} + +/** + * Options accepted by generateStrings(). + */ +export interface GenerateStringsOptions extends ExecutionOptions { + /** + * Order in which the paths (shapes) of the language are scheduled. + * Defaults to sweep. + */ + pathOrder?: PathOrder | "sweep" | "interleave" | "shuffled"; + /** + * Order in which the strings within each path are produced. Defaults to + * ascending. + */ + characterOrder?: CharacterOrder | "ascending" | "shuffled"; + /** + * Seed behind the shuffled modes. The default seed is fixed, so two calls + * sharing a seed generate the same strings and `offset` pages through them + * consistently. + */ + seed?: number; + /** + * Shortest string to generate. Shorter strings are left out of the + * enumeration entirely, `offset` never counting them. + */ + minLength?: number; + /** + * Longest string to generate. + */ + maxLength?: number; + /** + * Restricts generation to the given characters, e.g. `[a-z]`. Paths + * requiring a character outside it are dropped. + */ + charset?: string; +} + +export class RegexSolverClient { + private readonly apiToken: string; + private readonly accountApi: AccountApi; + private readonly analyzeApi: AnalyzeApi; + private readonly computeApi: ComputeApi; + private readonly generateApi: GenerateApi; + private readonly axiosInstance: AxiosInstance; + private readonly rateLimiter: RateLimiter; + private readonly autoBatch: boolean; + private readonly maxTermsPerRequest: number | null; + private limitsPromise: Promise | null = null; + private serverMaxTerms: number | null = null; + + constructor(config: RegexSolverConfig) { + if (!config.apiToken) { + throw new Error("apiToken is required"); + } + if ( + config.maxTermsPerRequest !== undefined && + config.maxTermsPerRequest < 2 + ) { + throw new Error("maxTermsPerRequest must be at least 2"); + } + + this.apiToken = config.apiToken; + const baseUrl = config.baseUrl || "https://api.regexsolver.com/v1"; + this.rateLimiter = getRateLimiter(this.apiToken); + this.autoBatch = config.autoBatch ?? true; + this.maxTermsPerRequest = config.maxTermsPerRequest ?? null; + + const axiosConfig = { + baseURL: baseUrl, + headers: { + "User-Agent": `RegexSolver JS / ${VERSION}`, + Authorization: `Bearer ${this.apiToken}`, + }, + }; + + this.axiosInstance = axios.create(axiosConfig); + + const apiConfiguration = new Configuration({ + accessToken: this.apiToken, + basePath: baseUrl, + }); + + this.accountApi = new AccountApi( + apiConfiguration, + baseUrl, + this.axiosInstance, + ); + this.analyzeApi = new AnalyzeApi( + apiConfiguration, + baseUrl, + this.axiosInstance, + ); + this.computeApi = new ComputeApi( + apiConfiguration, + baseUrl, + this.axiosInstance, + ); + this.generateApi = new GenerateApi( + apiConfiguration, + baseUrl, + this.axiosInstance, + ); + } + + private buildOptions(options?: OperationOptions): RequestOptionsDto { + const dto: RequestOptionsDto = { schemaVersion: 1 }; + if (options?.executionTimeout !== undefined) { + dto.execution = { timeout: options.executionTimeout }; + } + + const { responseFormat, deterministic } = options ?? {}; + if (deterministic !== undefined && responseFormat !== undefined) { + const fmt = String(responseFormat); + if (fmt !== ResponseFormat.FAIR) { + throw new Error( + `deterministic can only be used with responseFormat=ResponseFormat.FAIR, got ${JSON.stringify(responseFormat)}`, + ); + } + } + + if (responseFormat !== undefined || deterministic !== undefined) { + dto.response = {}; + if (responseFormat !== undefined) { + dto.response.format = responseFormat as any; + } + if (deterministic !== undefined) { + dto.response.fair = { deterministic }; + if (responseFormat === undefined) { + // FairResponseOptions is only applied when the response format is + // "fair", so default to it to honor the deterministic request. + dto.response.format = ResponseFormat.FAIR as any; + } + } + } + return dto; + } + + private async executeWithRetry( + apiCall: () => Promise>, + ): Promise> { + let attempt = 0; + let firstFailureAt: number | null = null; + + while (true) { + await this.rateLimiter.wait(); + if (attempt > 0) { + const jitterS = + Math.random() * Math.min(JITTER_BASE_S * 2 ** attempt, JITTER_CAP_S); + await new Promise((resolve) => setTimeout(resolve, jitterS * 1000)); + } + try { + return await apiCall(); + } catch (error) { + if (!(axios.isAxiosError(error) && error.response)) { + throw error; + } + if (error.response.status !== 429) { + throw this.mapError(error); + } + + const retryAfter = + parseFloat(error.response.headers["retry-after"]) || + DEFAULT_RETRY_AFTER_S; + const now = Date.now(); + firstFailureAt = firstFailureAt ?? now; + if (now - firstFailureAt + retryAfter * 1000 > RETRY_BUDGET_MS) { + throw this.mapError(error); + } + + this.rateLimiter.trigger(retryAfter); + attempt += 1; + } + } + } + + private mapError(error: AxiosError): Error { + if (!error.response) return error; + + const statusCode = error.response.status; + const data = error.response.data; + + let message = error.message; + let errorCode = "UnknownError"; + const bodyString = typeof data === "string" ? data : JSON.stringify(data); + + if (data) { + message = data.error || message; + errorCode = data.errorCode || errorCode; + } + + message = message || "Unknown API Error"; + + switch (statusCode) { + case 400: + if (errorCode === "InvalidJson") + return new Exceptions.InvalidJsonError( + message, + statusCode, + bodyString, + ); + if (errorCode === "TooManyTerms") + return new Exceptions.TooManyTermsError( + message, + statusCode, + bodyString, + ); + if (errorCode === "TooFewTerms") + return new Exceptions.TooFewTermsError( + message, + statusCode, + bodyString, + ); + if (errorCode === "TimeoutTooLarge") + return new Exceptions.TimeoutTooLargeError( + message, + statusCode, + bodyString, + ); + if (errorCode === "TimeoutExceeded") + return new Exceptions.TimeoutExceededError( + message, + statusCode, + bodyString, + ); + if (errorCode === "InvalidNumberOfStringsToGenerate") + return new Exceptions.InvalidNumberOfStringsToGenerateError( + message, + statusCode, + bodyString, + ); + if (errorCode === "AutomatonTooManyStates") + return new Exceptions.AutomatonTooManyStatesError( + message, + statusCode, + bodyString, + ); + if (errorCode === "RegexSyntaxError") + return new Exceptions.RegexSyntaxError( + message, + statusCode, + bodyString, + ); + if (errorCode === "FairSyntaxError") + return new Exceptions.FairSyntaxError( + message, + statusCode, + bodyString, + ); + return new Exceptions.BadRequestError(message, statusCode, bodyString); + case 401: + if (errorCode === "MissingOrMalformedToken") + return new Exceptions.MissingOrMalformedTokenError( + message, + statusCode, + bodyString, + ); + if (errorCode === "InvalidToken") + return new Exceptions.InvalidTokenError( + message, + statusCode, + bodyString, + ); + return new Exceptions.UnauthorizedError( + message, + statusCode, + bodyString, + ); + case 403: + if (errorCode === "QuotaExceeded") + return new Exceptions.QuotaExceededError( + message, + statusCode, + bodyString, + ); + return new Exceptions.ForbiddenError(message, statusCode, bodyString); + case 404: + return new Exceptions.NotFoundError(message, statusCode, bodyString); + case 429: + const msg = + message === "Unknown API Error" + ? "Max retries exceeded for 429 Too Many Requests." + : message; + return new Exceptions.TooManyRequestsError(msg, statusCode, bodyString); + case 500: + return new Exceptions.InternalServerError( + message, + statusCode, + bodyString, + ); + default: + return new Exceptions.ApiError(message, statusCode, bodyString); + } + } + + // --- ACCOUNT OPERATIONS --- + + /** + * Fetches the plan limits applying to the account. + * + * The call never consumes request quota (it is only rate-limited) and the + * result is cached on the client, so calling it again is free. The cached + * maxTermsCount also drives auto-batching. + * @returns The five plan limits. + */ + public async getAccountLimits(): Promise { + if (!this.limitsPromise) { + this.limitsPromise = this.executeWithRetry(() => + this.accountApi.limits(), + ) + .then((response) => { + const limits = AccountLimits.fromDto(response.data.data!); + this.serverMaxTerms = limits.maxTermsCount; + return limits; + }) + .catch((error) => { + this.limitsPromise = null; + throw error; + }); + } + return this.limitsPromise; + } + + // --- AUTO-BATCHING --- + + /** The largest term count to send in one request, when known. */ + private effectiveMaxTerms(): number | null { + if (this.maxTermsPerRequest !== null) { + return this.serverMaxTerms !== null + ? Math.min(this.maxTermsPerRequest, this.serverMaxTerms) + : this.maxTermsPerRequest; + } + return this.serverMaxTerms; + } + + /** + * Run an n-ary operation (concat/intersection/union), transparently + * splitting the terms into several requests when they exceed the account's + * terms-per-request limit (auto-batching). + */ + private async runNary( + terms: Term[], + options: OperationOptions | undefined, + apiCall: (request: MultiTermsRequest) => Promise>, + ): Promise { + // Intermediate results are fed straight back into the next request, so + // only the final call carries the caller's response options; + // executionTimeout bounds every constituent request. + const call = async (batch: Term[], final: boolean): Promise => { + const request: MultiTermsRequest = { + terms: batch.map((t) => t.toDto()), + options: this.buildOptions( + final ? options : { executionTimeout: options?.executionTimeout }, + ), + }; + const response = await this.executeWithRetry(() => apiCall(request)); + return Term.fromDto(response.data.data); + }; + + let maxTerms = this.autoBatch ? this.effectiveMaxTerms() : null; + if (maxTerms !== null && terms.length > maxTerms) { + return this.fold(call, terms, maxTerms); + } + + try { + return await call(terms, true); + } catch (error) { + if ( + !this.autoBatch || + maxTerms !== null || + !(error instanceof Exceptions.TooManyTermsError) + ) { + throw error; + } + try { + await this.getAccountLimits(); + } catch { + throw error; // fall back to surfacing the original TooManyTerms + } + maxTerms = this.effectiveMaxTerms(); + if (maxTerms === null || maxTerms < 2 || terms.length <= maxTerms) { + throw error; + } + return this.fold(call, terms, maxTerms); + } + } + + /** + * Left fold: combine the first `maxTerms` terms, then keep feeding the + * accumulated result back with the next `maxTerms - 1` terms. + * Left-associative, so concat order is preserved; union and intersection + * are commutative and unaffected. + */ + private async fold( + call: (batch: Term[], final: boolean) => Promise, + terms: Term[], + maxTerms: number, + ): Promise { + let acc = await call(terms.slice(0, maxTerms), false); + let index = maxTerms; + while (index < terms.length) { + const batch = [acc, ...terms.slice(index, index + maxTerms - 1)]; + index += maxTerms - 1; + acc = await call(batch, index >= terms.length); + } + return acc; + } + + // --- ANALYZE OPERATIONS --- + + /** + * Computes how many unique strings the term matches. + * @param term Target term to analyze. + * @param options Options object. + * @returns Cardinality object. + */ + public async getCardinality( + term: Term, + options?: ExecutionOptions, + ): Promise { + const cached = term.getCachedCardinality(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.cardinality(request), + ); + + const cardinality = Cardinality.fromDto(response.data.data); + term.setCachedCardinality(cardinality); + term._setPropertiesMixin(cardinality as any); + return cardinality; + } + + /** + * Compute the minimum and maximum length of strings matched by the term. + * @param term Target term to analyze. + * @param options Options object. + * @returns Length object. + */ + public async getLength( + term: Term, + options?: ExecutionOptions, + ): Promise { + const cached = term.getCachedLength(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.length(request), + ); + + const length = Length.fromDto(response.data.data); + term.setCachedLength(length); + term._setPropertiesMixin(length as any); + return length; + } + + /** + * Check if the two terms accept exactly the same language. + * @param term1 First term. + * @param term2 Second term. + * @param options Options object. + * @returns True if both terms accept the same language. + */ + public async equivalent( + term1: Term, + term2: Term, + options?: ExecutionOptions, + ): Promise { + const request: TwoTermsRequest = { + terms: [term1.toDto(), term2.toDto()], + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.equivalent(request), + ); + return response.data.data.value; + } + + /** + * Check if the first term's language is a subset of the second term's language. + * @param subset Candidate subset term. + * @param superset Candidate superset term. + * @param options Options object. + * @returns True if subset's language is contained within superset's language. + */ + public async subset( + subset: Term, + superset: Term, + options?: ExecutionOptions, + ): Promise { + const request: TwoTermsRequest = { + terms: [subset.toDto(), superset.toDto()], + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.subset(request), + ); + return response.data.data.value; + } + + /** + * Check if the term matches no strings. + * @param term Target term to analyze. + * @param options Options object. + * @returns True if language is empty. + */ + public async isEmpty( + term: Term, + options?: ExecutionOptions, + ): Promise { + const cached = term.getCachedEmpty(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.empty(request), + ); + + const isEmpty = response.data.data.value; + term.setCachedEmpty(isEmpty); + + if (isEmpty) { + term.setCachedCardinality(new Integer(0)); + term.setCachedLength(new Length(null, null)); + } + return isEmpty; + } + + /** + * Check if the term matches only the empty string. + * @param term Target term to analyze. + * @param options Options object. + * @returns True if language contains only the empty string. + */ + public async isEmptyString( + term: Term, + options?: ExecutionOptions, + ): Promise { + const cached = term.getCachedEmptyString(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.emptyString(request), + ); + + const isEmptyString = response.data.data.value; + term.setCachedEmptyString(isEmptyString); + + if (isEmptyString) { + term.setCachedCardinality(new Integer(1)); + term.setCachedLength(new Length(0, 0)); + } + return isEmptyString; + } + + /** + * Check if the term matches all the possible strings. + * @param term Target term to analyze. + * @param options Options object. + * @returns True if language contains all possible strings. + */ + public async isTotal( + term: Term, + options?: ExecutionOptions, + ): Promise { + const cached = term.getCachedTotal(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.total(request), + ); + + const isTotal = response.data.data.value; + term.setCachedTotal(isTotal); + + if (isTotal) { + term.setCachedCardinality(new Infinite()); + term.setCachedLength(new Length(0, null)); + } + return isTotal; + } + + /** + * Check if the term's automaton is deterministic. + * Only a deterministic FAIR guarantees consistent string ordering across paginated generateStrings() calls; call determinize() first if this is false. + * @param term The term to analyze. + * @param options Options object. + * @returns True if the term's automaton is deterministic. + */ + public async isDeterministic( + term: Term, + options?: ExecutionOptions, + ): Promise { + if (!(term instanceof FairTerm)) { + return false; + } + const cached = term.getCachedDeterministic(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.deterministic(request), + ); + + const isDeterministic = response.data.data.value; + term.setCachedDeterministic(isDeterministic); + + return isDeterministic; + } + + /** + * Return a regular expression pattern that represents the term. + * @param term Target term to analyze. + * @param options Options object. + * @returns Regex pattern string. + */ + public async getPattern( + term: Term, + options?: ExecutionOptions, + ): Promise { + const existingPattern = term.getCachedPattern(); + if (existingPattern !== null) return existingPattern; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.pattern(request), + ); + + const pattern = response.data.data.value; + term.setCachedPattern(pattern); + return pattern; + } + + /** + * Build a Graphviz DOT representation of the term's automaton. + * @param term Target term to analyze. + * @param options Options object. + * @returns DOT string. + */ + public async getDot(term: Term, options?: ExecutionOptions): Promise { + const cached = term.getCachedDot(); + if (cached !== null) return cached; + + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.analyzeApi.dot(request), + ); + + const dot = response.data.data.value; + term.setCachedDot(dot); + return dot; + } + + // --- COMPUTE OPERATIONS --- + + /** + * Concatenate the given terms in order. + * @param terms Array of terms or variadic terms to concatenate. + * @returns New term representing the concatenation. + */ + public async concat(terms: Term[]): Promise; + public async concat(...terms: Term[]): Promise; + public async concat(terms: Term[], options?: OperationOptions): Promise; + public async concat(...args: any[]): Promise { + const { terms, options } = this.parseArgs(args); + return this.runNary(terms, options, (request) => + this.computeApi.concat(request), + ); + } + + /** + * Computes the intersection of the given terms. + * @param terms Array of terms or variadic terms to intersect. + * @returns New term representing the intersection. + */ + public async intersection(terms: Term[]): Promise; + public async intersection(...terms: Term[]): Promise; + public async intersection( + terms: Term[], + options?: OperationOptions, + ): Promise; + public async intersection(...args: any[]): Promise { + const { terms, options } = this.parseArgs(args); + return this.runNary(terms, options, (request) => + this.computeApi.intersection(request), + ); + } + + /** + * Computes the union of the given terms. + * @param terms Array of terms or variadic terms to unite. + * @returns New term representing the union. + */ + public async union(terms: Term[]): Promise; + public async union(...terms: Term[]): Promise; + public async union(terms: Term[], options?: OperationOptions): Promise; + public async union(...args: any[]): Promise { + const { terms, options } = this.parseArgs(args); + return this.runNary(terms, options, (request) => + this.computeApi.union(request), + ); + } + + private parseArgs(args: any[]): { + terms: Term[]; + options?: OperationOptions; + } { + if (args.length === 0) { + return { terms: [] }; + } + + if (Array.isArray(args[0])) { + return { + terms: args[0], + options: args[1], + }; + } + + // Variadic + // Check if last arg is options object + const lastArg = args[args.length - 1]; + if ( + args.length > 1 && + typeof lastArg === "object" && + lastArg !== null && + !(lastArg instanceof Term) + ) { + return { terms: args.slice(0, -1), options: lastArg }; + } + + return { terms: args }; + } + + /** + * Computes the difference between the two given terms. + * @param base Term to subtract from. + * @param excluded Term to exclude. + * @param options Options object. + * @returns New term representing the difference. + */ + public async difference( + base: Term, + excluded: Term, + options?: OperationOptions, + ): Promise { + const request: TwoTermsRequest = { + terms: [base.toDto(), excluded.toDto()], + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.computeApi.difference(request), + ); + return Term.fromDto(response.data.data); + } + + /** + * Repeat a term between `min` and `max` times. + * @param term Term to repeat. + * @param min Minimum number of repetitions. + * @param max Maximum number of repetitions (optional, unbounded if null). + * @param options Options object. + * @returns New term representing the repetition. + */ + public async repeat( + term: Term, + min: number, + max?: number | null, + options?: OperationOptions, + ): Promise { + const request: RepeatRequest = { + term: term.toDto(), + min, + max, + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.computeApi.repeat(request), + ); + return Term.fromDto(response.data.data); + } + + /** + * Computes the complement of the given term. + * @param term Term to complement. + * @param options Options object. + * @returns New term representing the complement. + */ + public async complement( + term: Term, + options?: OperationOptions, + ): Promise { + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.computeApi.complement(request), + ); + return Term.fromDto(response.data.data); + } + + /** + * Computes a deterministic FAIR automaton from the given term. + * A deterministic FAIR guarantees consistent string ordering across paginated + * generateStrings() calls. Use this when isDeterministic() is false + * before calling generateStrings() with an offset. + * @param term Term to determinize. + * @param options Options object. + * @returns A deterministic FAIR. + */ + public async determinize( + term: Term, + options?: ExecutionOptions, + ): Promise { + const request: TermRequest = { + term: term.toDto(), + options: this.buildOptions(options), + }; + const response = await this.executeWithRetry(() => + this.computeApi.determinize(request), + ); + return Term.fromDto(response.data.data); + } + + // --- GENERATE OPERATIONS --- + + /** + * Generates up to `limit` distinct strings matched by `term`, skipping the first `offset` strings. + * @param term Source term to generate strings from. + * @param limit Maximum number of unique strings to return. + * @param offset Number of matched strings to skip before starting to collect the results. Used for pagination. + * @param options Options object (ordering, seed, length bounds, charset, executionTimeout). + * @returns Array of unique strings. + */ + public async generateStrings( + term: Term, + limit: number, + offset: number, + options?: GenerateStringsOptions, + ): Promise { + const request: GenerateStringsRequest = { + term: term.toDto(), + limit, + offset, + options: this.buildOptions(options), + }; + if (options?.pathOrder !== undefined) { + request.pathOrder = options.pathOrder as GenerateStringsRequest["pathOrder"]; + } + if (options?.characterOrder !== undefined) { + request.characterOrder = + options.characterOrder as GenerateStringsRequest["characterOrder"]; + } + if (options?.seed !== undefined) { + request.seed = options.seed; + } + if (options?.minLength !== undefined) { + request.minLength = options.minLength; + } + if (options?.maxLength !== undefined) { + request.maxLength = options.maxLength; + } + if (options?.charset !== undefined) { + request.charset = options.charset; + } + + const response = await this.executeWithRetry(() => + this.generateApi.strings(request), + ); + + return response.data.data.strings.value; + } +} diff --git a/src/details.ts b/src/details.ts deleted file mode 100644 index a2a6769..0000000 --- a/src/details.ts +++ /dev/null @@ -1,42 +0,0 @@ -export class Cardinality { - constructor( - public type: 'Infinite' | 'BigInteger' | 'Integer', - public value?: number - ) { } - - isInfinite(): boolean { - return this.type == 'Infinite'; - } - - toString(): string { - if (this.type == 'Integer') { - return this.type + '(' + this.value + ')'; - } else { - return this.type; - } - } -} - -export class Length { - constructor( - public minimum: number, - public maximum?: number - ) { } - - toString(): string { - return "Length[minimum=" + this.minimum + ", maximum=" + this.maximum + "]"; - } -} - -export class Details { - constructor( - public cardinality: Cardinality, - public length: Length, - public empty: boolean, - public total: boolean - ) { } - - toString(): string { - return "Details[cardinality=" + this.cardinality + ", length=" + this.length + ", empty=" + this.empty + ", total=" + this.total + "]"; - } -} \ No newline at end of file diff --git a/src/exceptions.ts b/src/exceptions.ts new file mode 100644 index 0000000..0681d9d --- /dev/null +++ b/src/exceptions.ts @@ -0,0 +1,86 @@ +/** Base exception for all RegexSolver errors. */ +export class RegexSolverError extends Error { + constructor(message: string) { + super(message); + this.name = this.constructor.name; + + // Maintain proper stack trace for where our error was thrown (only available on V8) + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +} + +/** Base exception raised when the RegexSolver API returns an error response. */ +export class ApiError extends RegexSolverError { + public readonly statusCode?: number; + public readonly body?: string; + + constructor(message: string, statusCode?: number, body?: string) { + super(message); + this.statusCode = statusCode; + this.body = body; + } +} + +/** Raised when the API returns a 400 Bad Request error. */ +export class BadRequestError extends ApiError {} + +/** Raised when the provided JSON is invalid or cannot be parsed. */ +export class InvalidJsonError extends BadRequestError {} + +/** Raised when the number of terms provided exceeds the maximum allowed. */ +export class TooManyTermsError extends BadRequestError {} + +/** Raised when fewer terms are provided than the operation requires. */ +export class TooFewTermsError extends BadRequestError {} + +/** Raised when the requested `execution_timeout` exceeds the maximum allowed for your current plan. */ +export class TimeoutTooLargeError extends BadRequestError {} + +/** Raised when the execution of the request exceeds the provided `execution_timeout` or the maximum allowed for your current plan. */ +export class TimeoutExceededError extends BadRequestError {} + +/** Raised when the requested number of strings to generate is below the minimum or exceeds the maximum allowed. */ +export class InvalidNumberOfStringsToGenerateError extends BadRequestError {} + +/** Raised when the NFA/DFA exceeds the maximum allowed number of states for your current plan. */ +export class AutomatonTooManyStatesError extends BadRequestError {} + +/** Raised when the provided regular expression has invalid syntax. */ +export class RegexSyntaxError extends BadRequestError {} + +/** Raised when the provided FAIR value is malformed or cannot be decoded. */ +export class FairSyntaxError extends BadRequestError {} + +/** Raised when the API returns a 401 Unauthorized error. */ +export class UnauthorizedError extends ApiError {} + +/** Raised when the provided authentication token is missing or malformed. */ +export class MissingOrMalformedTokenError extends UnauthorizedError {} + +/** Raised when the provided authentication token is invalid. */ +export class InvalidTokenError extends UnauthorizedError {} + +/** Raised when the API returns a 403 Forbidden error. */ +export class ForbiddenError extends ApiError {} + +/** Raised when your account's monthly compute quota has been exceeded. */ +export class QuotaExceededError extends ForbiddenError {} + +/** Raised when the API returns a 404 Not Found error. + * Indicates that the requested API endpoint or resource does not exist. + */ +export class NotFoundError extends ApiError {} + +/** + * Raised when the API returns a 429 Too Many Requests error and max retries are exceeded. + * Indicates that your requests-per-second (req/s) rate limit has been exceeded. + */ +export class TooManyRequestsError extends ApiError {} + +/** + * Raised when the API returns a 500 Internal Server Error. + * Indicates an unexpected failure or panic on the RegexSolver compute servers. + */ +export class InternalServerError extends ApiError {} diff --git a/src/generated/.openapi-generator-ignore b/src/generated/.openapi-generator-ignore new file mode 100644 index 0000000..86832a5 --- /dev/null +++ b/src/generated/.openapi-generator-ignore @@ -0,0 +1,7 @@ +docs/ +git_push.sh +.npmignore +.travis.yml +.gitignore +README.md +LICENSE diff --git a/src/generated/.openapi-generator/FILES b/src/generated/.openapi-generator/FILES new file mode 100644 index 0000000..53250c0 --- /dev/null +++ b/src/generated/.openapi-generator/FILES @@ -0,0 +1,5 @@ +api.ts +base.ts +common.ts +configuration.ts +index.ts diff --git a/src/generated/.openapi-generator/VERSION b/src/generated/.openapi-generator/VERSION new file mode 100644 index 0000000..a29ba3d --- /dev/null +++ b/src/generated/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.21.0 diff --git a/src/generated/api.ts b/src/generated/api.ts new file mode 100644 index 0000000..ad35429 --- /dev/null +++ b/src/generated/api.ts @@ -0,0 +1,2016 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from './configuration'; +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; +// Some imports not used depending on template conditions +// @ts-ignore +import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction, replaceWithSerializableTypeIfNeeded } from './common'; +import type { RequestArgs } from './base'; +// @ts-ignore +import { BASE_PATH, COLLECTION_FORMATS, BaseAPI, RequiredError, operationServerMap } from './base'; + +/** + * The plan limits currently applying to the account. + */ +export interface AccountLimits { + 'type': AccountLimitsTypeEnum; + /** + * Maximum number of requests allowed per billing period. + */ + 'maxRequestsCount': number; + /** + * Maximum number of requests allowed per second. `0` means no rate limit is enforced. + */ + 'maxRequestsRate': number; + /** + * Maximum number of terms accepted in a single request. + */ + 'maxTermsCount': number; + /** + * Maximum execution timeout per request, in milliseconds. + */ + 'maxTimeout': number; + /** + * Maximum number of automaton states an operation may build. + */ + 'maxStatesCount': number; +} + +export const AccountLimitsTypeEnum = { + AccountLimits: 'accountLimits', +} as const; + +export type AccountLimitsTypeEnum = typeof AccountLimitsTypeEnum[keyof typeof AccountLimitsTypeEnum]; + +/** + * @type Cardinality + * Number of unique strings matched by a term. + */ +export type Cardinality = { type: 'bigInteger' } & CardinalityBigInteger | { type: 'infinite' } & CardinalityInfinite | { type: 'integer' } & CardinalityInteger; + +export interface Cardinality200Response { + 'success': boolean; + 'data': Cardinality; +} +/** + * The set of matched strings is finite but too large to be returned. + */ +export interface CardinalityBigInteger { + 'type': CardinalityBigIntegerTypeEnum; +} + +export const CardinalityBigIntegerTypeEnum = { + BigInteger: 'bigInteger', +} as const; + +export type CardinalityBigIntegerTypeEnum = typeof CardinalityBigIntegerTypeEnum[keyof typeof CardinalityBigIntegerTypeEnum]; + +/** + * The set of matched strings is infinite. + */ +export interface CardinalityInfinite { + 'type': CardinalityInfiniteTypeEnum; +} + +export const CardinalityInfiniteTypeEnum = { + Infinite: 'infinite', +} as const; + +export type CardinalityInfiniteTypeEnum = typeof CardinalityInfiniteTypeEnum[keyof typeof CardinalityInfiniteTypeEnum]; + +/** + * The set of matched strings is finite. + */ +export interface CardinalityInteger { + 'type': CardinalityIntegerTypeEnum; + /** + * Exact count. + */ + 'value': number; +} + +export const CardinalityIntegerTypeEnum = { + Integer: 'integer', +} as const; + +export type CardinalityIntegerTypeEnum = typeof CardinalityIntegerTypeEnum[keyof typeof CardinalityIntegerTypeEnum]; + +export interface Concat200Response { + 'success': boolean; + 'data': Term; +} +export interface Dot200Response { + 'success': boolean; + 'data': ModelString; +} +export interface Empty200Response { + 'success': boolean; + 'data': ModelBoolean; +} +export interface ErrorResponse { + 'success': boolean; + /** + * Human readable error message. + */ + 'error': string; + /** + * The error code. + */ + 'errorCode'?: string; +} +export interface ErrorResponse400 { + 'success': boolean; + /** + * Human readable error message. + */ + 'error': string; + 'errorCode'?: ErrorResponse400ErrorCodeEnum; +} + +export const ErrorResponse400ErrorCodeEnum = { + InvalidJson: 'InvalidJson', + TooManyTerms: 'TooManyTerms', + TooFewTerms: 'TooFewTerms', + TimeoutTooLarge: 'TimeoutTooLarge', + TimeoutExceeded: 'TimeoutExceeded', + InvalidNumberOfStringsToGenerate: 'InvalidNumberOfStringsToGenerate', + AutomatonTooManyStates: 'AutomatonTooManyStates', + RegexSyntaxError: 'RegexSyntaxError', + FairSyntaxError: 'FairSyntaxError', +} as const; + +export type ErrorResponse400ErrorCodeEnum = typeof ErrorResponse400ErrorCodeEnum[keyof typeof ErrorResponse400ErrorCodeEnum]; + +export interface ErrorResponse401 { + 'success': boolean; + /** + * Human readable error message. + */ + 'error': string; + 'errorCode'?: ErrorResponse401ErrorCodeEnum; +} + +export const ErrorResponse401ErrorCodeEnum = { + MissingOrMalformedToken: 'MissingOrMalformedToken', + InvalidToken: 'InvalidToken', +} as const; + +export type ErrorResponse401ErrorCodeEnum = typeof ErrorResponse401ErrorCodeEnum[keyof typeof ErrorResponse401ErrorCodeEnum]; + +export interface ErrorResponse403 { + 'success': boolean; + /** + * Human readable error message. + */ + 'error': string; + 'errorCode'?: ErrorResponse403ErrorCodeEnum; +} + +export const ErrorResponse403ErrorCodeEnum = { + QuotaExceeded: 'QuotaExceeded', +} as const; + +export type ErrorResponse403ErrorCodeEnum = typeof ErrorResponse403ErrorCodeEnum[keyof typeof ErrorResponse403ErrorCodeEnum]; + +/** + * Change how the engine executes the operation. + */ +export interface ExecutionOptions { + /** + * Timeout in milliseconds for the operation. + */ + 'timeout'?: number; +} +/** + * Options controlling the FAIR output. Only applied when response format is \"fair\". + */ +export interface FairResponseOptions { + /** + * When true, the returned FAIR is guaranteed to be a deterministic automaton, suitable for consistent pagination with /generate/strings. + */ + 'deterministic'?: boolean; +} +/** + * Order in which the strings within each path are produced. Orthogonal to `pathOrder`: it does not change *what* can be generated, only which strings are reached first. `ascending` expands each position from the low end of its character range first, so `[a-z]{8}` yields `aaaaaaaa`, `aaaaaaab`, ... — a stable, spec-defined order returning the smallest witnesses of a path first. `shuffled` applies a permutation drawn from `seed`, so `[a-z]{8}` yields something like `sjtwsive` instead: the strings look like real inputs. Random in look only — generation stays reproducible and pages with `offset`, though offsets are only consistent between calls sharing the same `seed`, and the exact sequence may change between releases. Use `charset` to restrict generation to specific characters. + */ + +export const GenerateStringsCharacterOrder = { + Ascending: 'ascending', + Shuffled: 'shuffled', +} as const; + +export type GenerateStringsCharacterOrder = typeof GenerateStringsCharacterOrder[keyof typeof GenerateStringsCharacterOrder]; + + +/** + * Order in which the paths of the language are scheduled — the *shapes* the term allows, as opposed to the characters filling them (`characterOrder`). `sweep` expands one path in full, shortest first, before moving to the next one: the cheapest way to page through a whole language with `offset`. `interleave` covers every path the term holds before any path is asked for a second string, so a `limit` smaller than the number of shapes is spent entirely on distinct shapes; slower than `sweep`, but better suited to deriving test cases. `shuffled` is `interleave` with same-length paths visited in an order drawn by `seed`. Shorter paths still come first, so the seed only draws among paths of equal length. All three are deterministic and page with `offset`; for `shuffled`, offsets are only consistent between calls sharing the same `seed`. + */ + +export const GenerateStringsPathOrder = { + Sweep: 'sweep', + Interleave: 'interleave', + Shuffled: 'shuffled', +} as const; + +export type GenerateStringsPathOrder = typeof GenerateStringsPathOrder[keyof typeof GenerateStringsPathOrder]; + + +/** + * Request to generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings and confined to lengths between `minLength` and `maxLength`. For consistent pagination, `term` should be deterministic. + */ +export interface GenerateStringsRequest { + /** + * Source term to generate strings from. + */ + 'term': Term; + /** + * Maximum number of unique strings to return. + */ + 'limit': number; + /** + * Number of matched strings to skip before starting to collect the results. Used for pagination. + */ + 'offset'?: number; + /** + * Shortest string to generate. Strings shorter than this are left out of the enumeration entirely, `offset` never counting them. + */ + 'minLength'?: number; + /** + * Longest string to generate. Strings longer than this are left out of the enumeration entirely, `offset` never counting them. A value below `minLength` leaves nothing to generate. + */ + 'maxLength'?: number; + /** + * Order in which the paths of the language are scheduled. Defaults to `sweep`. + */ + 'pathOrder'?: GenerateStringsPathOrder; + /** + * Order in which the strings within each path are produced. Defaults to `ascending`. + */ + 'characterOrder'?: GenerateStringsCharacterOrder; + /** + * Seed behind the `shuffled` modes of `pathOrder` and `characterOrder`; ignored when neither is used. The default seed is fixed rather than random, so two calls sharing a seed generate the same strings and `offset` pages through them consistently. Change it to draw a different sequence from the same term. + */ + 'seed'?: number; + /** + * Character class the generated strings are restricted to, such as `[a-z]` or `\\P{C}`. Paths needing a character outside of it are dropped entirely. If omitted, every character the term allows is used. + */ + 'charset'?: string | null; + 'options'?: RequestOptions; +} + + +/** + * Response containing distinct strings generated from the requested `term`. + */ +export interface GenerateStringsResponse { + 'type': GenerateStringsResponseTypeEnum; + /** + * The generated distinct strings. + */ + 'strings': Strings; +} + +export const GenerateStringsResponseTypeEnum = { + GeneratedStrings: 'generatedStrings', +} as const; + +export type GenerateStringsResponseTypeEnum = typeof GenerateStringsResponseTypeEnum[keyof typeof GenerateStringsResponseTypeEnum]; + +/** + * Minimum and maximum length of any string in the language. + */ +export interface Length { + 'type': LengthTypeEnum; + /** + * Shortest possible length, or null if empty. + */ + 'min': number | null; + /** + * Longest possible length, or null if unbounded. + */ + 'max': number | null; +} + +export const LengthTypeEnum = { + Length: 'length', +} as const; + +export type LengthTypeEnum = typeof LengthTypeEnum[keyof typeof LengthTypeEnum]; + +export interface Length200Response { + 'success': boolean; + 'data': Length; +} +export interface Limits200Response { + 'success': boolean; + 'data': AccountLimits; +} +/** + * Wrapper for a boolean value. + */ +export interface ModelBoolean { + 'type': ModelBooleanTypeEnum; + /** + * Boolean value. + */ + 'value': boolean; +} + +export const ModelBooleanTypeEnum = { + Boolean: 'boolean', +} as const; + +export type ModelBooleanTypeEnum = typeof ModelBooleanTypeEnum[keyof typeof ModelBooleanTypeEnum]; + +/** + * Wrapper for a string value. + */ +export interface ModelString { + 'type': ModelStringTypeEnum; + /** + * String value. + */ + 'value': string; +} + +export const ModelStringTypeEnum = { + String: 'string', +} as const; + +export type ModelStringTypeEnum = typeof ModelStringTypeEnum[keyof typeof ModelStringTypeEnum]; + +/** + * Request carrying 2 or more terms for n-ary operations. + */ +export interface MultiTermsRequest { + /** + * Terms to process. Order matters for some operations. + */ + 'terms': Array; + 'options'?: RequestOptions; +} +/** + * Request to repeat a term between `min` and `max` times. + */ +export interface RepeatRequest { + /** + * Term to repeat. + */ + 'term': Term; + /** + * Inclusive lower bound of repetitions. + */ + 'min': number; + /** + * Inclusive upper bound. If omitted or null, the repetition is unbounded. + */ + 'max'?: number | null; + 'options'?: RequestOptions; +} +/** + * Change how the engine handles the operation. + */ +export interface RequestOptions { + /** + * Client-expected schema version. + */ + 'schemaVersion': number; + 'response'?: ResponseOptions; + 'execution'?: ExecutionOptions; +} +/** + * Change how the engine returns results. + */ +export interface ResponseOptions { + /** + * Return format of the term. + */ + 'format'?: ResponseOptionsFormatEnum; + /** + * Options applied when format is \"fair\". Ignored otherwise. + */ + 'fair'?: FairResponseOptions; +} + +export const ResponseOptionsFormatEnum = { + Any: 'any', + Fair: 'fair', + Regex: 'regex', +} as const; + +export type ResponseOptionsFormatEnum = typeof ResponseOptionsFormatEnum[keyof typeof ResponseOptionsFormatEnum]; + +/** + * Wrapper for a list of strings. + */ +export interface Strings { + 'type': StringsTypeEnum; + /** + * Array of unique strings. + */ + 'value': Array; +} + +export const StringsTypeEnum = { + Strings: 'strings', +} as const; + +export type StringsTypeEnum = typeof StringsTypeEnum[keyof typeof StringsTypeEnum]; + +export interface Strings200Response { + 'success': boolean; + 'data': GenerateStringsResponse; +} +/** + * @type Term + * Serialized term. + */ +export type Term = { type: 'fair' } & TermFair | { type: 'regex' } & TermRegex; + +/** + * Term encoded as FAIR (Fast Automaton Internal Representation), a stable, signed format used internally by the engine. + */ +export interface TermFair { + 'type': TermFairTypeEnum; + /** + * FAIR payload. + */ + 'value': string; + 'metadata'?: TermFairMetadata; +} + +export const TermFairTypeEnum = { + Fair: 'fair', +} as const; + +export type TermFairTypeEnum = typeof TermFairTypeEnum[keyof typeof TermFairTypeEnum]; + +/** + * Metadata describing properties of a FAIR automaton. + */ +export interface TermFairMetadata { + /** + * Whether this FAIR encodes a deterministic automaton. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + */ + 'deterministic'?: boolean; +} +/** + * Term encoded as a regular expression pattern. + */ +export interface TermRegex { + 'type': TermRegexTypeEnum; + /** + * Regular expression pattern. + */ + 'value': string; +} + +export const TermRegexTypeEnum = { + Regex: 'regex', +} as const; + +export type TermRegexTypeEnum = typeof TermRegexTypeEnum[keyof typeof TermRegexTypeEnum]; + +/** + * Request carrying a single term. + */ +export interface TermRequest { + 'term': Term; + 'options'?: RequestOptions; +} +/** + * Request carrying exactly 2 terms. + */ +export interface TwoTermsRequest { + /** + * Exactly 2 terms. + */ + 'terms': Array; + 'options'?: RequestOptions; +} + +/** + * AccountApi - axios parameter creator + */ +export const AccountApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Return the plan limits applying to the account. + * @summary Limits + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + limits: async (options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/account/limits`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AccountApi - functional programming interface + */ +export const AccountApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AccountApiAxiosParamCreator(configuration) + return { + /** + * Return the plan limits applying to the account. + * @summary Limits + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async limits(options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.limits(options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AccountApi.limits']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * AccountApi - factory interface + */ +export const AccountApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AccountApiFp(configuration) + return { + /** + * Return the plan limits applying to the account. + * @summary Limits + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + limits(options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.limits(options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AccountApi - object-oriented interface + */ +export class AccountApi extends BaseAPI { + /** + * Return the plan limits applying to the account. + * @summary Limits + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public limits(options?: RawAxiosRequestConfig) { + return AccountApiFp(this.configuration).limits(options).then((request) => request(this.axios, this.basePath)); + } +} + + + +/** + * AnalyzeApi - axios parameter creator + */ +export const AnalyzeApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Compute how many strings the term matches. + * @summary Cardinality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + cardinality: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('cardinality', 'termRequest', termRequest) + const localVarPath = `/analyze/cardinality`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the term\'s automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @summary Deterministic + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deterministic: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('deterministic', 'termRequest', termRequest) + const localVarPath = `/analyze/deterministic`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Build a Graphviz DOT representation of the term\'s automaton. + * @summary Graphviz DOT + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + dot: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('dot', 'termRequest', termRequest) + const localVarPath = `/analyze/dot`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the term matches no strings. + * @summary Empty + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + empty: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('empty', 'termRequest', termRequest) + const localVarPath = `/analyze/empty`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the term matches only the empty string. + * @summary Empty String Only + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + emptyString: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('emptyString', 'termRequest', termRequest) + const localVarPath = `/analyze/empty_string`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the two terms accept exactly the same language. + * @summary Equivalent + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + equivalent: async (twoTermsRequest: TwoTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'twoTermsRequest' is not null or undefined + assertParamExists('equivalent', 'twoTermsRequest', twoTermsRequest) + const localVarPath = `/analyze/equivalent`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(twoTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Compute the minimum and maximum length of strings matched by the term. + * @summary Length + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + length: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('length', 'termRequest', termRequest) + const localVarPath = `/analyze/length`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Return a regular expression pattern that represents the term. + * @summary Pattern + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + pattern: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('pattern', 'termRequest', termRequest) + const localVarPath = `/analyze/pattern`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the first term\'s language is a subset of the second term\'s language. + * @summary Subset + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + subset: async (twoTermsRequest: TwoTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'twoTermsRequest' is not null or undefined + assertParamExists('subset', 'twoTermsRequest', twoTermsRequest) + const localVarPath = `/analyze/subset`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(twoTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Check if the term matches all the possible strings. + * @summary Totality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + total: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('total', 'termRequest', termRequest) + const localVarPath = `/analyze/total`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * AnalyzeApi - functional programming interface + */ +export const AnalyzeApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = AnalyzeApiAxiosParamCreator(configuration) + return { + /** + * Compute how many strings the term matches. + * @summary Cardinality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async cardinality(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.cardinality(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.cardinality']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the term\'s automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @summary Deterministic + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async deterministic(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.deterministic(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.deterministic']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Build a Graphviz DOT representation of the term\'s automaton. + * @summary Graphviz DOT + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async dot(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.dot(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.dot']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the term matches no strings. + * @summary Empty + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async empty(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.empty(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.empty']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the term matches only the empty string. + * @summary Empty String Only + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async emptyString(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.emptyString(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.emptyString']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the two terms accept exactly the same language. + * @summary Equivalent + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async equivalent(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.equivalent(twoTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.equivalent']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Compute the minimum and maximum length of strings matched by the term. + * @summary Length + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async length(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.length(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.length']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Return a regular expression pattern that represents the term. + * @summary Pattern + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async pattern(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.pattern(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.pattern']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the first term\'s language is a subset of the second term\'s language. + * @summary Subset + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async subset(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.subset(twoTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.subset']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Check if the term matches all the possible strings. + * @summary Totality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async total(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.total(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['AnalyzeApi.total']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * AnalyzeApi - factory interface + */ +export const AnalyzeApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = AnalyzeApiFp(configuration) + return { + /** + * Compute how many strings the term matches. + * @summary Cardinality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + cardinality(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.cardinality(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the term\'s automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @summary Deterministic + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + deterministic(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.deterministic(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Build a Graphviz DOT representation of the term\'s automaton. + * @summary Graphviz DOT + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + dot(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.dot(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the term matches no strings. + * @summary Empty + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + empty(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.empty(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the term matches only the empty string. + * @summary Empty String Only + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + emptyString(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.emptyString(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the two terms accept exactly the same language. + * @summary Equivalent + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + equivalent(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.equivalent(twoTermsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Compute the minimum and maximum length of strings matched by the term. + * @summary Length + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + length(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.length(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Return a regular expression pattern that represents the term. + * @summary Pattern + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + pattern(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.pattern(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the first term\'s language is a subset of the second term\'s language. + * @summary Subset + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + subset(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.subset(twoTermsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Check if the term matches all the possible strings. + * @summary Totality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + total(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.total(termRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * AnalyzeApi - object-oriented interface + */ +export class AnalyzeApi extends BaseAPI { + /** + * Compute how many strings the term matches. + * @summary Cardinality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public cardinality(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).cardinality(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the term\'s automaton is deterministic. Only a deterministic FAIR guarantees consistent string ordering across paginated /generate/strings requests; call /compute/determinize first if this is false. + * @summary Deterministic + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public deterministic(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).deterministic(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Build a Graphviz DOT representation of the term\'s automaton. + * @summary Graphviz DOT + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public dot(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).dot(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the term matches no strings. + * @summary Empty + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public empty(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).empty(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the term matches only the empty string. + * @summary Empty String Only + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public emptyString(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).emptyString(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the two terms accept exactly the same language. + * @summary Equivalent + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public equivalent(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).equivalent(twoTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Compute the minimum and maximum length of strings matched by the term. + * @summary Length + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public length(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).length(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Return a regular expression pattern that represents the term. + * @summary Pattern + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public pattern(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).pattern(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the first term\'s language is a subset of the second term\'s language. + * @summary Subset + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public subset(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).subset(twoTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Check if the term matches all the possible strings. + * @summary Totality + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public total(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return AnalyzeApiFp(this.configuration).total(termRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + + + +/** + * ComputeApi - axios parameter creator + */ +export const ComputeApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Compute the complement of the given term. + * @summary Complement + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + complement: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('complement', 'termRequest', termRequest) + const localVarPath = `/compute/complement`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Concatenate the given terms in order. + * @summary Concatenation + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + concat: async (multiTermsRequest: MultiTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'multiTermsRequest' is not null or undefined + assertParamExists('concat', 'multiTermsRequest', multiTermsRequest) + const localVarPath = `/compute/concat`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(multiTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Compute a deterministic FAIR. + * @summary Determinize + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + determinize: async (termRequest: TermRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'termRequest' is not null or undefined + assertParamExists('determinize', 'termRequest', termRequest) + const localVarPath = `/compute/determinize`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(termRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Compute the difference between the two given terms. + * @summary Difference + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + difference: async (twoTermsRequest: TwoTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'twoTermsRequest' is not null or undefined + assertParamExists('difference', 'twoTermsRequest', twoTermsRequest) + const localVarPath = `/compute/difference`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(twoTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Compute the intersection of the given terms. + * @summary Intersection + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + intersection: async (multiTermsRequest: MultiTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'multiTermsRequest' is not null or undefined + assertParamExists('intersection', 'multiTermsRequest', multiTermsRequest) + const localVarPath = `/compute/intersection`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(multiTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Repeat a term between `min` and `max` times. + * @summary Repeat + * @param {RepeatRequest} repeatRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + repeat: async (repeatRequest: RepeatRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'repeatRequest' is not null or undefined + assertParamExists('repeat', 'repeatRequest', repeatRequest) + const localVarPath = `/compute/repeat`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(repeatRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Compute the union of the given terms. + * @summary Union + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + union: async (multiTermsRequest: MultiTermsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'multiTermsRequest' is not null or undefined + assertParamExists('union', 'multiTermsRequest', multiTermsRequest) + const localVarPath = `/compute/union`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(multiTermsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * ComputeApi - functional programming interface + */ +export const ComputeApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = ComputeApiAxiosParamCreator(configuration) + return { + /** + * Compute the complement of the given term. + * @summary Complement + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async complement(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.complement(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.complement']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Concatenate the given terms in order. + * @summary Concatenation + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async concat(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.concat(multiTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.concat']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Compute a deterministic FAIR. + * @summary Determinize + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async determinize(termRequest: TermRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.determinize(termRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.determinize']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Compute the difference between the two given terms. + * @summary Difference + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async difference(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.difference(twoTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.difference']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Compute the intersection of the given terms. + * @summary Intersection + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async intersection(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.intersection(multiTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.intersection']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Repeat a term between `min` and `max` times. + * @summary Repeat + * @param {RepeatRequest} repeatRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async repeat(repeatRequest: RepeatRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.repeat(repeatRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.repeat']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Compute the union of the given terms. + * @summary Union + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async union(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.union(multiTermsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['ComputeApi.union']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * ComputeApi - factory interface + */ +export const ComputeApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = ComputeApiFp(configuration) + return { + /** + * Compute the complement of the given term. + * @summary Complement + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + complement(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.complement(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Concatenate the given terms in order. + * @summary Concatenation + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + concat(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.concat(multiTermsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Compute a deterministic FAIR. + * @summary Determinize + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + determinize(termRequest: TermRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.determinize(termRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Compute the difference between the two given terms. + * @summary Difference + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + difference(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.difference(twoTermsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Compute the intersection of the given terms. + * @summary Intersection + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + intersection(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.intersection(multiTermsRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Repeat a term between `min` and `max` times. + * @summary Repeat + * @param {RepeatRequest} repeatRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + repeat(repeatRequest: RepeatRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.repeat(repeatRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Compute the union of the given terms. + * @summary Union + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + union(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.union(multiTermsRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * ComputeApi - object-oriented interface + */ +export class ComputeApi extends BaseAPI { + /** + * Compute the complement of the given term. + * @summary Complement + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public complement(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).complement(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Concatenate the given terms in order. + * @summary Concatenation + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public concat(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).concat(multiTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Compute a deterministic FAIR. + * @summary Determinize + * @param {TermRequest} termRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public determinize(termRequest: TermRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).determinize(termRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Compute the difference between the two given terms. + * @summary Difference + * @param {TwoTermsRequest} twoTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public difference(twoTermsRequest: TwoTermsRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).difference(twoTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Compute the intersection of the given terms. + * @summary Intersection + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public intersection(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).intersection(multiTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Repeat a term between `min` and `max` times. + * @summary Repeat + * @param {RepeatRequest} repeatRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public repeat(repeatRequest: RepeatRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).repeat(repeatRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Compute the union of the given terms. + * @summary Union + * @param {MultiTermsRequest} multiTermsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public union(multiTermsRequest: MultiTermsRequest, options?: RawAxiosRequestConfig) { + return ComputeApiFp(this.configuration).union(multiTermsRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + + + +/** + * GenerateApi - axios parameter creator + */ +export const GenerateApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @summary Strings + * @param {GenerateStringsRequest} generateStringsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + strings: async (generateStringsRequest: GenerateStringsRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'generateStringsRequest' is not null or undefined + assertParamExists('strings', 'generateStringsRequest', generateStringsRequest) + const localVarPath = `/generate/strings`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication BearerAuth required + // http bearer authentication required + await setBearerAuthToObject(localVarHeaderParameter, configuration) + + localVarHeaderParameter['Content-Type'] = 'application/json'; + localVarHeaderParameter['Accept'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(generateStringsRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * GenerateApi - functional programming interface + */ +export const GenerateApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = GenerateApiAxiosParamCreator(configuration) + return { + /** + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @summary Strings + * @param {GenerateStringsRequest} generateStringsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async strings(generateStringsRequest: GenerateStringsRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.strings(generateStringsRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['GenerateApi.strings']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * GenerateApi - factory interface + */ +export const GenerateApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = GenerateApiFp(configuration) + return { + /** + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @summary Strings + * @param {GenerateStringsRequest} generateStringsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + strings(generateStringsRequest: GenerateStringsRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.strings(generateStringsRequest, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * GenerateApi - object-oriented interface + */ +export class GenerateApi extends BaseAPI { + /** + * Generate up to `limit` distinct strings matched by `term`, skipping the first `offset` strings, scheduling the paths of the language in `pathOrder`, producing the strings within each path in `characterOrder`, confined to lengths between `minLength` and `maxLength` and to the characters of `charset`. Strings are only guaranteed to be distinct within a single call; pagination across calls is only consistent (no repeats or gaps) if `term` is deterministic. Call `/analyze/deterministic` to check, and `/compute/determinize` first if needed. + * @summary Strings + * @param {GenerateStringsRequest} generateStringsRequest + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + public strings(generateStringsRequest: GenerateStringsRequest, options?: RawAxiosRequestConfig) { + return GenerateApiFp(this.configuration).strings(generateStringsRequest, options).then((request) => request(this.axios, this.basePath)); + } +} + + + diff --git a/src/generated/base.ts b/src/generated/base.ts new file mode 100644 index 0000000..6d4a962 --- /dev/null +++ b/src/generated/base.ts @@ -0,0 +1,62 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +import type { Configuration } from './configuration'; +// Some imports not used depending on template conditions +// @ts-ignore +import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; +import globalAxios from 'axios'; + +export const BASE_PATH = "https://api.regexsolver.com/v1".replace(/\/+$/, ""); + +export const COLLECTION_FORMATS = { + csv: ",", + ssv: " ", + tsv: "\t", + pipes: "|", +}; + +export interface RequestArgs { + url: string; + options: RawAxiosRequestConfig; +} + +export class BaseAPI { + protected configuration: Configuration | undefined; + + constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { + if (configuration) { + this.configuration = configuration; + this.basePath = configuration.basePath ?? basePath; + } + } +}; + +export class RequiredError extends Error { + constructor(public field: string, msg?: string) { + super(msg); + this.name = "RequiredError" + } +} + +interface ServerMap { + [key: string]: { + url: string, + description: string, + }[]; +} + +export const operationServerMap: ServerMap = { +} diff --git a/src/generated/common.ts b/src/generated/common.ts new file mode 100644 index 0000000..6a4ad72 --- /dev/null +++ b/src/generated/common.ts @@ -0,0 +1,127 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +import type { Configuration } from "./configuration"; +import type { RequestArgs } from "./base"; +import type { AxiosInstance, AxiosResponse } from 'axios'; +import { RequiredError } from "./base"; + +export const DUMMY_BASE_URL = 'https://example.com' + +/** + * + * @throws {RequiredError} + */ +export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { + if (paramValue === null || paramValue === undefined) { + throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); + } +} + +export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { + if (configuration && configuration.apiKey) { + const localVarApiKeyValue = typeof configuration.apiKey === 'function' + ? await configuration.apiKey(keyParamName) + : await configuration.apiKey; + object[keyParamName] = localVarApiKeyValue; + } +} + +export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { + if (configuration && (configuration.username || configuration.password)) { + object["auth"] = { username: configuration.username, password: configuration.password }; + } +} + +export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const accessToken = typeof configuration.accessToken === 'function' + ? await configuration.accessToken() + : await configuration.accessToken; + object["Authorization"] = "Bearer " + accessToken; + } +} + +export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { + if (configuration && configuration.accessToken) { + const localVarAccessTokenValue = typeof configuration.accessToken === 'function' + ? await configuration.accessToken(name, scopes) + : await configuration.accessToken; + object["Authorization"] = "Bearer " + localVarAccessTokenValue; + } +} + + +function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void { + if (parameter == null) return; + if (typeof parameter === "object") { + if (Array.isArray(parameter) || parameter instanceof Set) { + (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); + } + else { + Object.keys(parameter).forEach(currentKey => + setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`) + ); + } + } + else { + if (urlSearchParams.has(key)) { + urlSearchParams.append(key, parameter); + } + else { + urlSearchParams.set(key, parameter); + } + } +} + +export const setSearchParams = function (url: URL, ...objects: any[]) { + const searchParams = new URLSearchParams(url.search); + setFlattenedQueryParams(searchParams, objects); + url.search = searchParams.toString(); +} + +/** + * JSON serialization helper function which replaces instances of unserializable types with serializable ones. + * This function will run for every key-value pair encountered by JSON.stringify while traversing an object. + * Converting a set to a string will return an empty object, so an intermediate conversion to an array is required. + */ +// @ts-ignore +export const replaceWithSerializableTypeIfNeeded = function(key: string, value: any) { + if (value instanceof Set) { + return Array.from(value); + } else { + return value; + } +} + +export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { + const nonString = typeof value !== 'string'; + const needsSerialization = nonString && configuration && configuration.isJsonMime + ? configuration.isJsonMime(requestOptions.headers['Content-Type']) + : nonString; + return needsSerialization + ? JSON.stringify(value !== undefined ? value : {}, replaceWithSerializableTypeIfNeeded) + : (value || ""); +} + +export const toPathString = function (url: URL) { + return url.pathname + url.search + url.hash +} + +export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { + return >(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url}; + return axios.request(axiosRequestArgs); + }; +} diff --git a/src/generated/configuration.ts b/src/generated/configuration.ts new file mode 100644 index 0000000..67f7077 --- /dev/null +++ b/src/generated/configuration.ts @@ -0,0 +1,121 @@ +/* tslint:disable */ +/** + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + +interface AWSv4Configuration { + options?: { + region?: string + service?: string + } + credentials?: { + accessKeyId?: string + secretAccessKey?: string, + sessionToken?: string + } +} + +export interface ConfigurationParameters { + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + username?: string; + password?: string; + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + awsv4?: AWSv4Configuration; + basePath?: string; + serverIndex?: number; + baseOptions?: any; + formDataCtor?: new () => any; +} + +export class Configuration { + /** + * parameter for apiKey security + * @param name security name + */ + apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); + /** + * parameter for basic security + */ + username?: string; + /** + * parameter for basic security + */ + password?: string; + /** + * parameter for oauth2 security + * @param name security name + * @param scopes oauth2 scope + */ + accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); + /** + * parameter for aws4 signature security + * @param {Object} AWS4Signature - AWS4 Signature security + * @param {string} options.region - aws region + * @param {string} options.service - name of the service. + * @param {string} credentials.accessKeyId - aws access key id + * @param {string} credentials.secretAccessKey - aws access key + * @param {string} credentials.sessionToken - aws session token + * @memberof Configuration + */ + awsv4?: AWSv4Configuration; + /** + * override base path + */ + basePath?: string; + /** + * override server index + */ + serverIndex?: number; + /** + * base options for axios calls + */ + baseOptions?: any; + /** + * The FormData constructor that will be used to create multipart form data + * requests. You can inject this here so that execution environments that + * do not support the FormData class can still run the generated client. + * + * @type {new () => FormData} + */ + formDataCtor?: new () => any; + + constructor(param: ConfigurationParameters = {}) { + this.apiKey = param.apiKey; + this.username = param.username; + this.password = param.password; + this.accessToken = param.accessToken; + this.awsv4 = param.awsv4; + this.basePath = param.basePath; + this.serverIndex = param.serverIndex; + this.baseOptions = { + ...param.baseOptions, + headers: { + ...param.baseOptions?.headers, + }, + }; + this.formDataCtor = param.formDataCtor; + } + + /** + * Check if the given MIME is a JSON MIME. + * JSON MIME examples: + * application/json + * application/json; charset=UTF8 + * APPLICATION/JSON + * application/vnd.company+json + * @param mime - MIME (Multipurpose Internet Mail Extensions) + * @return True if the given MIME is JSON, false otherwise. + */ + public isJsonMime(mime: string): boolean { + const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); + return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); + } +} diff --git a/src/generated/index.ts b/src/generated/index.ts new file mode 100644 index 0000000..25d011c --- /dev/null +++ b/src/generated/index.ts @@ -0,0 +1,18 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * RegexSolver API + * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + * + * The version of the OpenAPI document: 1.1.0 + * + * + * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + * https://openapi-generator.tech + * Do not edit the class manually. + */ + + +export * from "./api"; +export * from "./configuration"; + diff --git a/src/index.ts b/src/index.ts index 8ab2f86..e1588ae 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,209 +1,8 @@ -import axios, { AxiosInstance } from "axios"; -import { Cardinality, Details, Length } from "./details"; - -export class RegexSolver { - private static instance: RegexSolver; - private apiClient: AxiosInstance; - - private constructor() { - if (!RegexSolver.instance) { - RegexSolver.instance = this; - } - return RegexSolver.instance; - } - - static getInstance() { - if (!RegexSolver.instance) { - RegexSolver.instance = new RegexSolver(); - } - return RegexSolver.instance; - } - - static initialize(apiToken, baseURL = null) { - const instance = RegexSolver.getInstance(); - if (!baseURL) { - baseURL = "https://api.regexsolver.com/" - } - instance.apiClient = axios.create({ - baseURL: baseURL, - headers: { - 'Authorization': `Bearer ${apiToken}`, - 'User-Agent': 'RegexSolver Node.js / 1.0.4', - } - }); - } - - computeIntersection(request: MultiTermsRequest): Promise { - return this.apiClient.post('/api/compute/intersection', request) - .then(response => loadTerm(response.data)) - .catch(error => { throw new ApiError(error.message) }); - } - - computeUnion(request: MultiTermsRequest): Promise { - return this.apiClient.post('/api/compute/union', request) - .then(response => loadTerm(response.data)) - .catch(error => { throw new ApiError(error.message) }); - } - - computeSubtraction(request: MultiTermsRequest): Promise { - return this.apiClient.post('/api/compute/subtraction', request) - .then(response => loadTerm(response.data)) - .catch(error => { throw new ApiError(error.message) }); - } - - getDetails(term: Term): Promise
{ - return this.apiClient.post('/api/analyze/details', term) - .then(response => loadDetails(response.data)) - .catch(error => { throw new ApiError(error.message) }); - } - - equivalence(request: MultiTermsRequest): Promise { - return this.apiClient.post('/api/analyze/equivalence', request) - .then(response => response.data.value) - .catch(error => { throw new ApiError(error.message) }); - } - - subset(request: MultiTermsRequest): Promise { - return this.apiClient.post('/api/analyze/subset', request) - .then(response => response.data.value) - .catch(error => { throw new ApiError(error.message) }); - } - - generateStrings(request: GenerateStringsRequest): Promise { - return this.apiClient.post('/api/generate/strings', request) - .then(response => response.data.value) - .catch(error => { throw new ApiError(error.message) }); - } -} - -export class Term { - private static readonly REGEX_PREFIX = 'regex'; - private static readonly FAIR_PREFIX = 'fair'; - private static readonly UNKNOWN_PREFIX = 'unknown'; - - private details?: Details; - constructor( - private type: 'regex' | 'fair', - private value: string - ) { - } - - static regex(pattern: string): Term { - return new Term(Term.REGEX_PREFIX, pattern); - } - - static fair(fair: string): Term { - return new Term(Term.FAIR_PREFIX, fair); - } - - getType(): 'regex' | 'fair' { - return this.type; - } - - getFair(): string | void { - if (this.type == Term.FAIR_PREFIX) { - return this.value; - } - return null; - } - - getPattern(): string | void { - if (this.type == Term.REGEX_PREFIX) { - return this.value; - } - return null; - } - - async getDetails(): Promise
{ - if (this.details) { - return this.details; - } - this.details = await RegexSolver.getInstance().getDetails(this); - return this.details; - } - - async generateStrings(count: number): Promise { - return await RegexSolver.getInstance().generateStrings({ term: this, count }); - } - - async intersection(...terms: Term[]): Promise { - return await RegexSolver.getInstance().computeIntersection({ terms: [this, ...terms] }); - } - - async union(...terms: Term[]): Promise { - return await RegexSolver.getInstance().computeUnion({ terms: [this, ...terms] }); - } - - async subtraction(term: Term): Promise { - return await RegexSolver.getInstance().computeSubtraction({ terms: [this, term] }); - } - - async isEquivalentTo(term: Term): Promise { - return await RegexSolver.getInstance().equivalence({ terms: [this, term] }); - } - - async isSubsetOf(term: Term): Promise { - return await RegexSolver.getInstance().subset({ terms: [this, term] }); - } - - serialize(): string { - let prefix = Term.UNKNOWN_PREFIX; - if (this.type == Term.REGEX_PREFIX) { - prefix = Term.REGEX_PREFIX; - } else if (this.type == Term.FAIR_PREFIX) { - prefix = Term.FAIR_PREFIX; - } - return prefix + "=" + this.value; - } - - static deserialize(string: string): Term | void { - if (string.startsWith(Term.REGEX_PREFIX)) { - return Term.regex(string.substring(this.REGEX_PREFIX.length + 1)); - } else if (string.startsWith(Term.FAIR_PREFIX)) { - return Term.fair(string.substring(this.FAIR_PREFIX.length + 1)); - } - return null; - } - - toString(): string { - return this.serialize(); - } -} - -interface TermTransient { - type: 'regex' | 'fair'; - value: string; -} - -function loadTerm(term: TermTransient): Term { - return new Term(term.type, term.value); -} - -interface TransientDetails { - cardinality: Cardinality; - length: number[]; - empty: boolean; - total: boolean; -} - -function loadDetails(data: TransientDetails): Details { - const cardinality = new Cardinality(data.cardinality.type, data.cardinality.value); - const length = new Length(data.length[0], data.length[1]); - - return new Details(cardinality, length, data.empty, data.total); -} - -export class ApiError extends Error { - constructor(message: string) { - super("The API returned the following error: " + message); - } -} - -interface MultiTermsRequest { - terms: Term[]; -} - -interface GenerateStringsRequest { - term: Term; - count: number; -} \ No newline at end of file +export * from "./RegexSolverClient"; +export * from "./models/Term"; +export * from "./models/AccountLimits"; +export * from "./models/Cardinality"; +export * from "./models/GenerateStringsOrder"; +export * from "./models/Length"; +export * from "./models/ResponseFormat"; +export * from "./exceptions"; diff --git a/src/models/AccountLimits.ts b/src/models/AccountLimits.ts new file mode 100644 index 0000000..8a2470f --- /dev/null +++ b/src/models/AccountLimits.ts @@ -0,0 +1,51 @@ +import { AccountLimits as AccountLimitsDto } from "../generated"; + +/** + * The plan limits currently applying to the account. + */ +export class AccountLimits { + /** Maximum number of requests allowed per billing period. */ + public readonly maxRequestsCount: number; + /** Maximum number of requests allowed per second. 0 means no rate limit is enforced. */ + public readonly maxRequestsRate: number; + /** Maximum number of terms accepted in a single request. */ + public readonly maxTermsCount: number; + /** Maximum execution timeout per request, in milliseconds. */ + public readonly maxTimeout: number; + /** Maximum number of automaton states an operation may build. */ + public readonly maxStatesCount: number; + + constructor( + maxRequestsCount: number, + maxRequestsRate: number, + maxTermsCount: number, + maxTimeout: number, + maxStatesCount: number, + ) { + this.maxRequestsCount = maxRequestsCount; + this.maxRequestsRate = maxRequestsRate; + this.maxTermsCount = maxTermsCount; + this.maxTimeout = maxTimeout; + this.maxStatesCount = maxStatesCount; + } + + public static fromDto(dto: AccountLimitsDto): AccountLimits { + return new AccountLimits( + dto.maxRequestsCount, + dto.maxRequestsRate, + dto.maxTermsCount, + dto.maxTimeout, + dto.maxStatesCount, + ); + } + + public toString(): string { + return ( + `` + ); + } +} diff --git a/src/models/Cardinality.ts b/src/models/Cardinality.ts new file mode 100644 index 0000000..6097fde --- /dev/null +++ b/src/models/Cardinality.ts @@ -0,0 +1,102 @@ +import { Cardinality as CardinalityDto } from "../generated"; +import { TermPropertiesMixin } from "./TermPropertiesMixin"; + +export abstract class Cardinality extends TermPropertiesMixin { + public abstract readonly type: "integer" | "bigInteger" | "infinite"; + + public static fromDto(dto: CardinalityDto): Cardinality { + if (dto.type === "integer") { + return new Integer(dto.value as number); + } else if (dto.type === "bigInteger") { + return new BigInteger(); + } else { + return new Infinite(); + } + } + + public isInfinite(): this is Infinite { + return this.type === "infinite"; + } + + public isBigInteger(): this is BigInteger { + return this.type === "bigInteger"; + } + + public isInteger(): this is Integer { + return this.type === "integer"; + } + + public toString(): string { + return ""; + } +} + +/** Indicates that the set of matched strings is infinite. */ +export class Infinite extends Cardinality { + public readonly type = "infinite"; + + public isEmpty(): boolean | undefined { + return false; + } + + public isEmptyString(): boolean | undefined { + return false; + } + + public toString(): string { + return ""; + } +} + +/** Indicates that the set of matched strings is finite but too large to be returned as a standard integer. */ +export class BigInteger extends Cardinality { + public readonly type = "bigInteger"; + + public isEmpty(): boolean | undefined { + return false; + } + + public isEmptyString(): boolean | undefined { + return false; + } + + public isTotal(): boolean | undefined { + return false; + } + + public toString(): string { + return ""; + } +} + +/** Indicates that the set of matched strings is finite and exactly calculable. + * @param value The exact count of uniquely matched strings. + */ +export class Integer extends Cardinality { + public readonly type = "integer"; + public readonly value: number; + + constructor(value: number) { + super(); + this.value = value; + } + + public isEmpty(): boolean | undefined { + return this.value === 0; + } + + public isEmptyString(): boolean | undefined { + if (this.value === 1) { + return undefined; + } + return false; + } + + public isTotal(): boolean | undefined { + return false; + } + + public toString(): string { + return ``; + } +} diff --git a/src/models/GenerateStringsOrder.ts b/src/models/GenerateStringsOrder.ts new file mode 100644 index 0000000..d022cb0 --- /dev/null +++ b/src/models/GenerateStringsOrder.ts @@ -0,0 +1,40 @@ +/** + * Order in which the paths of the language are scheduled when generating + * strings — the *shapes* the term allows, as opposed to the characters + * filling them. + */ +export enum PathOrder { + /** + * Expand one path in full, shortest first, before moving to the next one. + * The cheapest way to page through a whole language. + */ + SWEEP = "sweep", + /** + * Cover every path once before any path yields a second string. Best + * suited to deriving test cases. + */ + INTERLEAVE = "interleave", + /** + * Interleave with same-length paths visited in an order drawn from the + * seed. + */ + SHUFFLED = "shuffled", +} + +/** + * Order in which the strings within each path are produced when generating + * strings. Orthogonal to PathOrder: it does not change *what* can be + * generated, only which strings are reached first. + */ +export enum CharacterOrder { + /** + * Expand each position from the low end of its character range first — a + * stable order returning the smallest witnesses of a path first. + */ + ASCENDING = "ascending", + /** + * A permutation drawn from the seed, so the strings look like real inputs. + * Random in look only — generation stays reproducible. + */ + SHUFFLED = "shuffled", +} diff --git a/src/models/Length.ts b/src/models/Length.ts new file mode 100644 index 0000000..c1e9f2e --- /dev/null +++ b/src/models/Length.ts @@ -0,0 +1,46 @@ +import { Length as LengthDto } from "../generated"; +import { TermPropertiesMixin } from "./TermPropertiesMixin"; + +/** + * Represents the minimum and maximum lengths of any string matched by the term. + */ +export class Length extends TermPropertiesMixin { + /** The shortest possible matched string length, or null if the language is empty. */ + public readonly min: number | null; + /** The longest possible matched string length, or null if the length is unbounded. */ + public readonly max: number | null; + + constructor(min: number | null = null, max: number | null = null) { + super(); + this.min = min; + this.max = max; + } + + public static fromDto(dto: LengthDto): Length { + return new Length(dto.min, dto.max); + } + + public toString(): string { + return ``; + } + + public isEmpty(): boolean | undefined { + return this.min === null && this.max === null; + } + + public isEmptyString(): boolean | undefined { + return this.min === 0 && this.max === 0; + } + + public isTotal(): boolean | undefined { + if (this.min !== 0 || this.max !== null) { + return false; + } else { + return undefined; + } + } + + public isInfinite(): boolean { + return this.min !== null && this.max === null; + } +} diff --git a/src/models/ResponseFormat.ts b/src/models/ResponseFormat.ts new file mode 100644 index 0000000..4a8db15 --- /dev/null +++ b/src/models/ResponseFormat.ts @@ -0,0 +1,17 @@ +/** + * Defines the format in which the engine should return computed Terms. + */ +export enum ResponseFormat { + /** + * Allows the engine to return the result in the most efficient format. + */ + ANY = "any", + /** + * Fast Automaton Internal Representation, a stable internal format. + */ + FAIR = "fair", + /** + * Standard regular expression pattern. + */ + REGEX = "regex", +} diff --git a/src/models/Term.ts b/src/models/Term.ts new file mode 100644 index 0000000..b5d5f9d --- /dev/null +++ b/src/models/Term.ts @@ -0,0 +1,235 @@ +import { Term as TermDto, TermFair, TermRegex } from "../generated"; +import { Cardinality } from "./Cardinality"; +import { Length } from "./Length"; +import { TermPropertiesMixin } from "./TermPropertiesMixin"; + +/** How the engine renders a language that matches no string at all. */ +const EMPTY_LANGUAGE_PATTERN = "[]"; + +/** + * Represents a mathematical term (Regex or FAIR) on which operations can be performed. + */ +export abstract class Term { + private readonly value: string; + + // Shared Cache (Internal) + private _cardinality: Cardinality | null = null; + private _length: Length | null = null; + private _empty: boolean | null = null; + private _emptyString: boolean | null = null; + private _total: boolean | null = null; + protected _pattern: string | null = null; + private _dot: string | null = null; + + private _compiledRegex: RegExp | null = null; + + protected constructor(value: string) { + this.value = value; + } + + public abstract getPattern(): string | null; + public abstract getFair(): string | null; + public abstract toDto(): TermDto; + public abstract serialize(): string; + + public static regex(pattern: string): Term { + return new RegexTerm(pattern); + } + + public static fair(payload: string): Term { + return new FairTerm(payload, null); + } + + // --- Shared Behavior --- + + public getValue(): string { + return this.value; + } + + public _setPropertiesMixin(propertiesMixin: TermPropertiesMixin): void { + const empty = propertiesMixin.isEmpty(); + if (empty !== null && empty !== undefined) { + this.setCachedEmpty(empty); + } + + const emptyString = propertiesMixin.isEmptyString(); + if (emptyString !== null && emptyString !== undefined) { + this.setCachedEmptyString(emptyString); + } + + const total = propertiesMixin.isTotal(); + if (total !== null && total !== undefined) { + this.setCachedTotal(total); + } + } + + public matches(str: string): boolean { + const pattern = this.getPattern(); + if (pattern === null) { + throw new Error( + "The regex pattern of this term is not defined yet, call getPattern() on the client to set it.", + ); + } + + // The engine renders the empty language as "[]". By definition it matches + // nothing, and other engines reject the pattern outright. + if (pattern === EMPTY_LANGUAGE_PATTERN) { + return false; + } + + if (this._compiledRegex === null) { + try { + this._compiledRegex = new RegExp(`^(?:${pattern})$`, "s"); + } catch (e: any) { + throw new Error( + `Pattern '${pattern}' cannot be evaluated by JavaScript's RegExp module: ${e.message}`, + ); + } + } + + return this._compiledRegex.test(str); + } + + public static deserialize( + serialized: string | null | undefined, + ): Term | null { + if (!serialized || !serialized.includes("=")) { + return null; + } + + const index = serialized.indexOf("="); + const typeStr = serialized.substring(0, index); + const val = serialized.substring(index + 1); + + if (typeStr.toLowerCase() === "regex") { + return Term.regex(val); + } else if (typeStr.toLowerCase() === "fair") { + return Term.fair(val); + } + return null; + } + + public static fromDto(dto: TermDto): Term { + if (dto.type === "regex") { + return Term.regex(dto.value); + } else { + return new FairTerm(dto.value, dto.metadata?.deterministic ?? null); + } + } + + // --- Cache Getters and Setters --- + + public getCachedCardinality(): Cardinality | null { + return this._cardinality; + } + public setCachedCardinality(cardinality: Cardinality | null): void { + this._cardinality = cardinality; + } + + public getCachedLength(): Length | null { + return this._length; + } + public setCachedLength(length: Length | null): void { + this._length = length; + } + + public getCachedEmpty(): boolean | null { + return this._empty; + } + public setCachedEmpty(empty: boolean | null): void { + this._empty = empty; + } + + public getCachedEmptyString(): boolean | null { + return this._emptyString; + } + public setCachedEmptyString(emptyString: boolean | null): void { + this._emptyString = emptyString; + } + + public getCachedTotal(): boolean | null { + return this._total; + } + public setCachedTotal(total: boolean | null): void { + this._total = total; + } + + public getCachedPattern(): string | null { + return this._pattern; + } + public setCachedPattern(pattern: string | null): void { + this._pattern = pattern; + } + + public getCachedDot(): string | null { + return this._dot; + } + public setCachedDot(dot: string | null): void { + this._dot = dot; + } + + public equals(other: any): boolean { + if (this === other) return true; + if (!(other instanceof Term)) return false; + return this.serialize() === other.serialize(); + } + + public toString(): string { + return this.serialize(); + } +} + +export class RegexTerm extends Term { + constructor(value: string) { + super(value); + } + + public getPattern(): string | null { + return this.getValue(); + } + + public getFair(): string | null { + return null; + } + + public toDto(): TermDto { + return { type: "regex", value: this.getValue() } as TermRegex; + } + + public serialize(): string { + return "regex=" + this.getValue(); + } +} + +export class FairTerm extends Term { + private _deterministic: boolean | null = null; + + constructor(value: string, deterministic: boolean | null) { + super(value); + this._deterministic = deterministic; + } + + public getPattern(): string | null { + return this._pattern; + } + + public getFair(): string | null { + return this.getValue(); + } + + public toDto(): TermDto { + return { type: "fair", value: this.getValue() } as TermFair; + } + + public serialize(): string { + return "fair=" + this.getValue(); + } + + public getCachedDeterministic(): boolean | null { + return this._deterministic; + } + + public setCachedDeterministic(deterministic: boolean | null) { + this._deterministic = deterministic; + } +} diff --git a/src/models/TermPropertiesMixin.ts b/src/models/TermPropertiesMixin.ts new file mode 100644 index 0000000..f235ee6 --- /dev/null +++ b/src/models/TermPropertiesMixin.ts @@ -0,0 +1,33 @@ +/** + * A mixin providing default property inference for Term analytics. + * + * Returns `undefined` when a property cannot be strictly inferred from the current data alone. + */ +export abstract class TermPropertiesMixin { + /** + * Infers whether the term matches no strings at all. + * + * @returns {boolean | undefined} True if it definitely matches no strings, False if it matches at least one, or undefined if it cannot be inferred. + */ + public isEmpty(): boolean | undefined { + return undefined; + } + + /** + * Infers whether the term matches strictly the empty string (""). + * + * @returns {boolean | undefined} True if it definitely matches only the empty string, False if it matches other strings, or undefined if it cannot be inferred. + */ + public isEmptyString(): boolean | undefined { + return undefined; + } + + /** + * Infers whether the term matches all possible strings. + * + * @returns {boolean | undefined} True if it definitely matches all strings, False if it misses at least one string, or undefined if it cannot be inferred. + */ + public isTotal(): boolean | undefined { + return undefined; + } +} diff --git a/tests/RateLimiter.test.ts b/tests/RateLimiter.test.ts new file mode 100644 index 0000000..4b33bb5 --- /dev/null +++ b/tests/RateLimiter.test.ts @@ -0,0 +1,79 @@ +import { RateLimiter } from "../src/RateLimiter"; + +describe("RateLimiter", () => { + let rateLimiter: RateLimiter; + + beforeEach(() => { + rateLimiter = new RateLimiter(); + }); + + test("wait should resolve immediately if not blocked", async () => { + const start = Date.now(); + await rateLimiter.wait(); + const duration = Date.now() - start; + expect(duration).toBeLessThan(50); + }); + + test("trigger should block wait", async () => { + const retryAfter = 0.1; // 100ms + rateLimiter.trigger(retryAfter); + + const start = Date.now(); + await rateLimiter.wait(); + const duration = Date.now() - start; + + expect(duration).toBeGreaterThanOrEqual(100); + expect(duration).toBeLessThan(150); + }); + + test("a shorter retry-after never shrinks the pending deadline", async () => { + rateLimiter.trigger(0.2); + rateLimiter.trigger(0.1); // must not shorten the 200ms deadline + + const start = Date.now(); + await rateLimiter.wait(); + const duration = Date.now() - start; + + expect(duration).toBeGreaterThanOrEqual(190); + expect(duration).toBeLessThan(250); + }); + + test("a longer retry-after arriving while blocked extends the deadline", async () => { + rateLimiter.trigger(0.1); + rateLimiter.trigger(0.2); // the later deadline wins + + const start = Date.now(); + await rateLimiter.wait(); + const duration = Date.now() - start; + + expect(duration).toBeGreaterThanOrEqual(190); + }); + + test("a deadline extended while waiting is honored", async () => { + rateLimiter.trigger(0.1); + + const start = Date.now(); + const waiter = rateLimiter.wait(); + setTimeout(() => rateLimiter.trigger(0.2), 50); + await waiter; + const duration = Date.now() - start; + + // The waiter woke at the original deadline, re-checked, and slept again. + expect(duration).toBeGreaterThanOrEqual(240); + }); + + test("concurrent waits should all resolve after block is lifted", async () => { + const retryAfter = 0.1; // 100ms + rateLimiter.trigger(retryAfter); + + const start = Date.now(); + const p1 = rateLimiter.wait(); + const p2 = rateLimiter.wait(); + const p3 = rateLimiter.wait(); + + await Promise.all([p1, p2, p3]); + const duration = Date.now() - start; + + expect(duration).toBeGreaterThanOrEqual(100); + }); +}); diff --git a/tests/assets/response_error.json b/tests/assets/response_error.json deleted file mode 100644 index 0faf2d7..0000000 --- a/tests/assets/response_error.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "error", - "message": "A random error." -} \ No newline at end of file diff --git a/tests/assets/response_generateStrings.json b/tests/assets/response_generateStrings.json deleted file mode 100644 index 9ee8883..0000000 --- a/tests/assets/response_generateStrings.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "type": "strings", - "value": [ - "abcde", - "dede", - "deabc", - "abcabc" - ] -} \ No newline at end of file diff --git a/tests/assets/response_getDetails.json b/tests/assets/response_getDetails.json deleted file mode 100644 index 65e0539..0000000 --- a/tests/assets/response_getDetails.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "type": "details", - "cardinality": { - "type": "Integer", - "value": 2 - }, - "length": [ - 2, - 3 - ], - "empty": false, - "total": false -} \ No newline at end of file diff --git a/tests/assets/response_intersection.json b/tests/assets/response_intersection.json deleted file mode 100644 index e6b1a7a..0000000 --- a/tests/assets/response_intersection.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "deabc" -} \ No newline at end of file diff --git a/tests/assets/response_isEquivalentTo.json b/tests/assets/response_isEquivalentTo.json deleted file mode 100644 index 25147f3..0000000 --- a/tests/assets/response_isEquivalentTo.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "boolean", - "value": false -} \ No newline at end of file diff --git a/tests/assets/response_isSubsetOf.json b/tests/assets/response_isSubsetOf.json deleted file mode 100644 index 84ed493..0000000 --- a/tests/assets/response_isSubsetOf.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "boolean", - "value": true -} \ No newline at end of file diff --git a/tests/assets/response_subtraction.json b/tests/assets/response_subtraction.json deleted file mode 100644 index 478ac72..0000000 --- a/tests/assets/response_subtraction.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "abc" -} \ No newline at end of file diff --git a/tests/assets/response_union.json b/tests/assets/response_union.json deleted file mode 100644 index 27dae5e..0000000 --- a/tests/assets/response_union.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "regex", - "value": "(abc|de|fghi)" -} \ No newline at end of file diff --git a/tests/client.test.ts b/tests/client.test.ts new file mode 100644 index 0000000..45f86c9 --- /dev/null +++ b/tests/client.test.ts @@ -0,0 +1,645 @@ +import axios from "axios"; +import MockAdapter from "axios-mock-adapter"; +import { RegexSolverClient } from "../src/RegexSolverClient"; +import { Term } from "../src/models/Term"; +import * as Exceptions from "../src/exceptions"; +import { BigInteger, Infinite, Integer } from "../src/models/Cardinality"; + +describe("RegexSolverClient", () => { + let mock: any; + let client: RegexSolverClient; + + beforeEach(() => { + client = new RegexSolverClient({ apiToken: "test-token" }); + + mock = new MockAdapter((client as any).axiosInstance); + }); + + afterEach(() => { + mock.restore(); + }); + + test("getCardinality should work for integer", async () => { + mock.onPost("/analyze/cardinality").reply(200, { + success: true, + data: { type: "integer", value: 26 }, + }); + + const term = Term.regex("[a-z]"); + const cardinality = await client.getCardinality(term); + + expect(cardinality.isInteger()).toBe(true); + expect(cardinality).toEqual(new Integer(26)); + expect(term.getCachedCardinality()).toBe(cardinality); + }); + + test("getCardinality should work for infinite", async () => { + mock.onPost("/analyze/cardinality").reply(200, { + success: true, + data: { type: "infinite" }, + }); + + const term = Term.regex(".*"); + const cardinality = await client.getCardinality(term); + + expect(cardinality.isInfinite()).toBe(true); + expect(cardinality).toBeInstanceOf(Infinite); + expect(term.getCachedCardinality()).toBe(cardinality); + }); + + test("getCardinality should work for bigInteger", async () => { + mock.onPost("/analyze/cardinality").reply(200, { + success: true, + data: { type: "bigInteger" }, + }); + + const term = Term.regex(".{100}"); + const cardinality = await client.getCardinality(term); + + expect(cardinality.isBigInteger()).toBe(true); + expect(cardinality).toBeInstanceOf(BigInteger); + expect(term.getCachedCardinality()).toBe(cardinality); + }); + + test("getLength should work", async () => { + mock.onPost("/analyze/length").reply(200, { + success: true, + data: { type: "length", min: 1, max: 4 }, + }); + + const term = Term.regex("(abc)?d"); + const length = await client.getLength(term); + + expect(length.min).toBe(1); + expect(length.max).toBe(4); + expect(term.getCachedLength()).toBe(length); + }); + + test("isEmpty should work", async () => { + mock.onPost("/analyze/empty").reply(200, { + success: true, + data: { value: true }, + }); + + const term = Term.regex("[]"); + const emptyValue = await client.isEmpty(term); + expect(emptyValue).toBe(true); + expect(term.getCachedEmpty()).toBe(true); + }); + + test("isEmptyString should work", async () => { + mock.onPost("/analyze/empty_string").reply(200, { + success: true, + data: { value: true }, + }); + + const term = Term.regex(""); + const result = await client.isEmptyString(term); + expect(result).toBe(true); + expect(term.getCachedEmptyString()).toBe(true); + }); + + test("isTotal should work", async () => { + mock.onPost("/analyze/total").reply(200, { + success: true, + data: { value: true }, + }); + + const term = Term.regex(".*"); + const result = await client.isTotal(term); + expect(result).toBe(true); + expect(term.getCachedTotal()).toBe(result); + }); + + test("getPattern should work", async () => { + mock.onPost("/analyze/pattern").reply(200, { + success: true, + data: { value: "a" }, + }); + + const term = Term.fair("..."); + const result = await client.getPattern(term); + expect(result).toBe("a"); + // getCachedPattern() explicitly verifies our internal cache got updated properly + expect(term.getCachedPattern()).toBe("a"); + }); + + test("getDot should work", async () => { + mock.onPost("/analyze/dot").reply(200, { + success: true, + data: { value: "digraph {...}" }, + }); + + const term = Term.regex("a"); + const result = await client.getDot(term); + expect(result).toBe("digraph {...}"); + expect(term.getCachedDot()).toBe(result); + }); + + test("equivalent should work", async () => { + mock.onPost("/analyze/equivalent").reply(200, { + success: true, + data: { value: true }, + }); + + const t1 = Term.regex("a"); + const t2 = Term.regex("a"); + const result = await client.equivalent(t1, t2); + expect(result).toBe(true); + }); + + test("subset should work", async () => { + mock.onPost("/analyze/subset").reply(200, { + success: true, + data: { value: true }, + }); + + const t1 = Term.regex("a"); + const t2 = Term.regex("a|b"); + const result = await client.subset(t1, t2); + expect(result).toBe(true); + }); + + test("intersection should work", async () => { + mock.onPost("/compute/intersection").reply(200, { + success: true, + data: { type: "regex", value: "a" }, + }); + + const t1 = Term.regex("a"); + const t2 = Term.regex("ab"); + const result = await client.intersection([t1, t2]); + expect(result.getValue()).toBe("a"); + }); + + test("union should work", async () => { + mock.onPost("/compute/union").reply(200, { + success: true, + data: { type: "regex", value: "a|b" }, + }); + + const t1 = Term.regex("a"); + const t2 = Term.regex("b"); + const result = await client.union([t1, t2]); + expect(result.getValue()).toBe("a|b"); + }); + + test("difference should work", async () => { + mock.onPost("/compute/difference").reply(200, { + success: true, + data: { type: "regex", value: "a" }, + }); + + const t1 = Term.regex("a|b"); + const t2 = Term.regex("b"); + const result = await client.difference(t1, t2); + expect(result.getValue()).toBe("a"); + }); + + test("concat should work", async () => { + mock.onPost("/compute/concat").reply(200, { + success: true, + data: { type: "regex", value: "ab" }, + }); + + const t1 = Term.regex("a"); + const t2 = Term.regex("b"); + const result = await client.concat([t1, t2]); + expect(result.getValue()).toBe("ab"); + }); + + test("repeat should work", async () => { + mock.onPost("/compute/repeat").reply(200, { + success: true, + data: { type: "regex", value: "a{2,3}" }, + }); + + const term = Term.regex("a"); + const result = await client.repeat(term, 2, 3); + expect(result.getValue()).toBe("a{2,3}"); + }); + + test("complement should work", async () => { + mock.onPost("/compute/complement").reply(200, { + success: true, + data: { type: "regex", value: "[^a]*" }, + }); + + const term = Term.regex("a*"); + const result = await client.complement(term); + expect(result.getValue()).toBe("[^a]*"); + }); + + test("generateStrings should work", async () => { + mock.onPost("/generate/strings").reply(200, { + success: true, + data: { + type: "generatedStrings", + strings: { + type: "strings", + value: ["", "a", "aa"], + }, + }, + }); + + const term = Term.regex("a*"); + const result = await client.generateStrings(term, 3, 0); + expect(result).toEqual(["", "a", "aa"]); + }); + + test("error mapping for 400 Bad Request - Invalid JSON", async () => { + mock.onPost("/analyze/cardinality").reply(400, { + success: false, + error: "Invalid JSON body", + errorCode: "InvalidJson", + }); + + await expect(client.getCardinality(Term.regex("a"))).rejects.toThrow( + Exceptions.InvalidJsonError, + ); + }); + + test("error mapping for 400 Bad Request - Too Many Terms", async () => { + mock.onPost("/compute/union").reply(400, { + success: false, + error: "Too many terms", + errorCode: "TooManyTerms", + }); + + await expect(client.union([Term.regex("a")])).rejects.toThrow( + Exceptions.TooManyTermsError, + ); + }); + + test("error mapping for 400 Bad Request - Timeout Too Large", async () => { + mock.onPost("/analyze/cardinality").reply(400, { + success: false, + error: "Timeout too large", + errorCode: "TimeoutTooLarge", + }); + + await expect(client.getCardinality(Term.regex("a"))).rejects.toThrow( + Exceptions.TimeoutTooLargeError, + ); + }); + + test("error mapping for 400 Bad Request - Timeout Exceeded", async () => { + mock.onPost("/analyze/cardinality").reply(400, { + success: false, + error: "Timeout exceeded", + errorCode: "TimeoutExceeded", + }); + + await expect(client.getCardinality(Term.regex("a"))).rejects.toThrow( + Exceptions.TimeoutExceededError, + ); + }); + + test("error mapping for 400 Bad Request - Invalid Number Of Strings To Generate", async () => { + mock.onPost("/generate/strings").reply(400, { + success: false, + error: "Invalid number of strings", + errorCode: "InvalidNumberOfStringsToGenerate", + }); + + await expect( + client.generateStrings(Term.regex("a"), 10, 0), + ).rejects.toThrow(Exceptions.InvalidNumberOfStringsToGenerateError); + }); + + test("error mapping for 401 Unauthorized - Missing or Malformed Token", async () => { + mock.onPost("/analyze/cardinality").reply(401, { + success: false, + error: "Missing token", + errorCode: "MissingOrMalformedToken", + }); + + await expect(client.getCardinality(Term.regex("abc"))).rejects.toThrow( + Exceptions.MissingOrMalformedTokenError, + ); + }); + + test("error mapping for 401 Unauthorized - Invalid Token", async () => { + mock.onPost("/analyze/cardinality").reply(401, { + success: false, + error: "Invalid token", + errorCode: "InvalidToken", + }); + + await expect(client.getCardinality(Term.regex("abc"))).rejects.toThrow( + Exceptions.InvalidTokenError, + ); + }); + + test("error mapping for 403 Forbidden - Quota Exceeded", async () => { + mock.onPost("/analyze/cardinality").reply(403, { + success: false, + error: "Quota exceeded", + errorCode: "QuotaExceeded", + }); + + await expect(client.getCardinality(Term.regex("abc"))).rejects.toThrow( + Exceptions.QuotaExceededError, + ); + }); + + test("error mapping for 404 Not Found", async () => { + mock.onPost("/analyze/cardinality").reply(404, { + success: false, + error: "Not Found", + }); + + await expect(client.getCardinality(Term.regex("abc"))).rejects.toThrow( + Exceptions.NotFoundError, + ); + }); + + test("error mapping for 500 Internal Server Error", async () => { + mock.onPost("/analyze/cardinality").reply(500, { + success: false, + error: "Internal server error", + }); + + await expect(client.getCardinality(Term.regex("abc"))).rejects.toThrow( + Exceptions.InternalServerError, + ); + }); + + test("constructor rejects an empty apiToken", () => { + expect(() => new RegexSolverClient({ apiToken: "" })).toThrow( + "apiToken is required", + ); + }); + + test("constructor rejects maxTermsPerRequest below 2", () => { + expect( + () => + new RegexSolverClient({ apiToken: "test-token", maxTermsPerRequest: 1 }), + ).toThrow("maxTermsPerRequest must be at least 2"); + }); + + test("getAccountLimits should work and be memoized", async () => { + mock.onGet("/account/limits").reply(200, { + success: true, + data: { + type: "accountLimits", + maxRequestsCount: 1000, + maxRequestsRate: 10, + maxTermsCount: 4, + maxTimeout: 60000, + maxStatesCount: 8192, + }, + }); + + const limits = await client.getAccountLimits(); + expect(limits.maxRequestsCount).toBe(1000); + expect(limits.maxRequestsRate).toBe(10); + expect(limits.maxTermsCount).toBe(4); + expect(limits.maxTimeout).toBe(60000); + expect(limits.maxStatesCount).toBe(8192); + + await client.getAccountLimits(); + expect(mock.history.get.length).toBe(1); + }); + + test("proactive batching folds oversized concat calls in order", async () => { + const batchClient = new RegexSolverClient({ + apiToken: "batch-token", + maxTermsPerRequest: 3, + }); + const batchMock = new MockAdapter((batchClient as any).axiosInstance); + for (const value of ["r0", "r1", "r2", "r3"]) { + batchMock.onPost("/compute/concat").replyOnce(200, { + success: true, + data: { type: "regex", value }, + }); + } + + const terms = Array.from({ length: 8 }, (_, i) => Term.regex(`t${i}`)); + const result = await batchClient.concat(terms, { + responseFormat: "regex", + }); + expect(result.getValue()).toBe("r3"); + + const bodies = batchMock.history.post.map((r) => JSON.parse(r.data)); + expect(bodies.length).toBe(4); + // Left fold preserves concat order: contiguous chunks, accumulator first. + expect(bodies[0].terms.map((t: any) => t.value)).toEqual([ + "t0", + "t1", + "t2", + ]); + expect(bodies[1].terms.map((t: any) => t.value)).toEqual([ + "r0", + "t3", + "t4", + ]); + expect(bodies[2].terms.map((t: any) => t.value)).toEqual([ + "r1", + "t5", + "t6", + ]); + expect(bodies[3].terms.map((t: any) => t.value)).toEqual(["r2", "t7"]); + // Only the final request carries the caller's response options. + expect(bodies[0].options.response).toBeUndefined(); + expect(bodies[1].options.response).toBeUndefined(); + expect(bodies[2].options.response).toBeUndefined(); + expect(bodies[3].options.response).toEqual({ format: "regex" }); + // The limit was known up front, so no limits fetch happened. + expect(batchMock.history.get.length).toBe(0); + batchMock.restore(); + }); + + test("reactive batching fetches the limits once and re-runs batched", async () => { + mock.onGet("/account/limits").reply(200, { + success: true, + data: { + type: "accountLimits", + maxRequestsCount: 1000, + maxRequestsRate: 10, + maxTermsCount: 4, + maxTimeout: 60000, + maxStatesCount: 8192, + }, + }); + mock.onPost("/compute/union").replyOnce(400, { + success: false, + error: "9 terms provided. Maximum allowed is 4.", + errorCode: "TooManyTerms", + }); + for (const value of ["r0", "r1", "r2"]) { + mock.onPost("/compute/union").replyOnce(200, { + success: true, + data: { type: "regex", value }, + }); + } + + const terms = Array.from({ length: 9 }, (_, i) => Term.regex(`t${i}`)); + const result = await client.union(terms); + expect(result.getValue()).toBe("r2"); + + expect(mock.history.get.length).toBe(1); + const bodies = mock.history.post.map((r: any) => JSON.parse(r.data)); + expect(bodies.length).toBe(4); + expect(bodies[1].terms.map((t: any) => t.value)).toEqual([ + "t0", + "t1", + "t2", + "t3", + ]); + expect(bodies[2].terms.map((t: any) => t.value)).toEqual([ + "r0", + "t4", + "t5", + "t6", + ]); + expect(bodies[3].terms.map((t: any) => t.value)).toEqual([ + "r1", + "t7", + "t8", + ]); + }); + + test("autoBatch: false surfaces TooManyTerms without fetching limits", async () => { + const noBatchClient = new RegexSolverClient({ + apiToken: "no-batch-token", + autoBatch: false, + }); + const noBatchMock = new MockAdapter((noBatchClient as any).axiosInstance); + noBatchMock.onPost("/compute/union").reply(400, { + success: false, + error: "9 terms provided. Maximum allowed is 4.", + errorCode: "TooManyTerms", + }); + + const terms = Array.from({ length: 9 }, (_, i) => Term.regex(`t${i}`)); + await expect(noBatchClient.union(terms)).rejects.toThrow( + Exceptions.TooManyTermsError, + ); + expect(noBatchMock.history.get.length).toBe(0); + noBatchMock.restore(); + }); + + test("a failed limits fetch rethrows the original TooManyTerms", async () => { + mock.onGet("/account/limits").reply(500, { + success: false, + error: "Internal server error", + }); + mock.onPost("/compute/union").reply(400, { + success: false, + error: "9 terms provided. Maximum allowed is 4.", + errorCode: "TooManyTerms", + }); + + const terms = Array.from({ length: 9 }, (_, i) => Term.regex(`t${i}`)); + await expect(client.union(terms)).rejects.toThrow( + Exceptions.TooManyTermsError, + ); + // The memo was cleared on rejection, so a later call fetches again. + await expect(client.getAccountLimits()).rejects.toThrow( + Exceptions.InternalServerError, + ); + expect(mock.history.get.length).toBe(2); + }); + + test("generateStrings serializes the ordering options", async () => { + mock.onPost("/generate/strings").reply(200, { + success: true, + data: { + type: "generatedStrings", + strings: { type: "strings", value: ["xy"] }, + }, + }); + + const result = await client.generateStrings(Term.regex("[a-z]{2}"), 5, 0, { + pathOrder: "interleave", + characterOrder: "shuffled", + seed: 42, + minLength: 1, + maxLength: 10, + charset: "[a-z]", + }); + expect(result).toEqual(["xy"]); + + const body = JSON.parse(mock.history.post[0].data); + expect(body.pathOrder).toBe("interleave"); + expect(body.characterOrder).toBe("shuffled"); + expect(body.seed).toBe(42); + expect(body.minLength).toBe(1); + expect(body.maxLength).toBe(10); + expect(body.charset).toBe("[a-z]"); + }); + + test("generateStrings omits unset options from the body", async () => { + mock.onPost("/generate/strings").reply(200, { + success: true, + data: { + type: "generatedStrings", + strings: { type: "strings", value: ["a"] }, + }, + }); + + await client.generateStrings(Term.regex("a"), 1, 0); + + const body = JSON.parse(mock.history.post[0].data); + expect(body.pathOrder).toBeUndefined(); + expect(body.characterOrder).toBeUndefined(); + expect(body.seed).toBeUndefined(); + expect(body.minLength).toBeUndefined(); + expect(body.maxLength).toBeUndefined(); + expect(body.charset).toBeUndefined(); + }); + + test("more consecutive 429s than the old retry cap still succeed", async () => { + jest.spyOn(Math, "random").mockReturnValue(0); + for (let i = 0; i < 3; i++) { + mock.onPost("/analyze/cardinality").replyOnce( + 429, + { success: false, error: "Too many requests" }, + { "retry-after": "0.02" }, + ); + } + mock.onPost("/analyze/cardinality").reply(200, { + success: true, + data: { type: "integer", value: 26 }, + }); + + const cardinality = await client.getCardinality(Term.regex("[a-z]")); + expect(cardinality).toEqual(new Integer(26)); + expect(mock.history.post.length).toBe(4); + (Math.random as jest.Mock).mockRestore(); + }); + + test("rate limit with retry-after should work and block concurrent requests", async () => { + // First call 429 + mock.onPost("/analyze/cardinality").replyOnce( + 429, + { + success: false, + error: "Too many requests", + errorCode: "RateLimitExceeded", + }, + { "retry-after": "0.1" }, + ); + + // Second call 200 + mock.onPost("/analyze/cardinality").reply(200, { + success: true, + data: { type: "integer", value: 26 }, + }); + + const start = Date.now(); + const term = Term.regex("[a-z]"); + + // Parallel calls + const p1 = client.getCardinality(term); + const p2 = client.getCardinality(term); + + const [c1, c2] = await Promise.all([p1, p2]); + const duration = Date.now() - start; + + expect(c1).toEqual(new Integer(26)); + expect(c2).toEqual(new Integer(26)); + expect(duration).toBeGreaterThanOrEqual(100); + }); +}); diff --git a/tests/models.test.ts b/tests/models.test.ts new file mode 100644 index 0000000..d14bacb --- /dev/null +++ b/tests/models.test.ts @@ -0,0 +1,67 @@ +import { BigInteger, Infinite, Integer } from "../src/models/Cardinality"; +import { Length } from "../src/models/Length"; + +describe("Cardinality", () => { + test("Integer should work", () => { + const c = new Integer(10); + expect(c.value).toBe(10); + expect(c.isEmpty()).toBe(false); + expect(c.isEmptyString()).toBe(false); + expect(c.isTotal()).toBe(false); + expect(c.toString()).toBe(""); + }); + + test("Integer zero should work", () => { + const c = new Integer(0); + expect(c.isEmpty()).toBe(true); + expect(c.isEmptyString()).toBe(false); + }); + + test("Integer one should work", () => { + const c = new Integer(1); + expect(c.isEmpty()).toBe(false); + expect(c.isEmptyString()).toBe(undefined); + }); + + test("BigInteger should work", () => { + const c = new BigInteger(); + expect(c.isEmpty()).toBe(false); + expect(c.isEmptyString()).toBe(false); + expect(c.isTotal()).toBe(false); + expect(c.toString()).toBe(""); + }); + + test("Infinite should work", () => { + const c = new Infinite(); + expect(c.isEmpty()).toBe(false); + expect(c.isEmptyString()).toBe(false); + expect(c.toString()).toBe(""); + }); +}); + +describe("Length", () => { + test("Length should work", () => { + const l = new Length(1, 5); + expect(l.min).toBe(1); + expect(l.max).toBe(5); + expect(l.isEmpty()).toBe(false); + expect(l.isEmptyString()).toBe(false); + expect(l.isTotal()).toBe(false); + expect(l.toString()).toBe(""); + }); + + test("Length empty should work", () => { + const l = new Length(null, null); + expect(l.isEmpty()).toBe(true); + }); + + test("Length empty string should work", () => { + const l = new Length(0, 0); + expect(l.isEmptyString()).toBe(true); + }); + + test("Length total candidate should work", () => { + const l = new Length(0, null); + expect(l.isTotal()).toBe(undefined); + }); +}); diff --git a/tests/serialization.test.ts b/tests/serialization.test.ts deleted file mode 100644 index 7466afc..0000000 --- a/tests/serialization.test.ts +++ /dev/null @@ -1,18 +0,0 @@ -import {Term} from '../src/index'; - -describe('term serialization', () => { - function assertSerialization(term: Term) { - const serialized = term.serialize() - const deserialized = Term.deserialize(serialized) - - expect(deserialized).toEqual(term); - } - - it('serialize and deserialize term correctly', () => { - assertSerialization(Term.regex(".*")); - assertSerialization(Term.regex("")); - - assertSerialization(Term.fair("rgmsW[1g2LvP=Gr&V>sLc#w-!No&(opHq@B-9o[LpP-a#fYI+")); - assertSerialization(Term.fair("")); - }); -}); \ No newline at end of file diff --git a/tests/term-operation.test.ts b/tests/term-operation.test.ts deleted file mode 100644 index e310381..0000000 --- a/tests/term-operation.test.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { RegexSolver } from '../src'; -import { Term } from '../src'; -import { promises as fs } from 'fs'; -import * as nock from 'nock'; - - -describe('term operations', () => { - beforeAll(() => { - RegexSolver.initialize("TOKEN"); - }); - - it('get details', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_getDetails.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/analyze/details') - .reply(200, response); - - const term = Term.regex("(abc|de)"); - const details = await term.getDetails(); - - expect(details.toString()).toEqual("Details[cardinality=Integer(2), length=Length[minimum=2, maximum=3], empty=false, total=false]"); - }); - - it('generate strings', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_generateStrings.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/generate/strings') - .reply(200, response); - - const term = Term.regex("(abc|de){2}"); - const strings = await term.generateStrings(10); - - expect(strings.length).toEqual(4); - }); - - it('intersection', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_intersection.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/compute/intersection') - .reply(200, response); - - const term1 = Term.regex("(abc|de){2}"); - const term2 = Term.regex("de.*"); - const term3 = Term.regex(".*abc"); - - const result = await term1.intersection(term2, term3); - - expect(result.toString()).toEqual("regex=deabc"); - }); - - it('union', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_union.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/compute/union') - .reply(200, response); - - const term1 = Term.regex("abc"); - const term2 = Term.regex("de"); - const term3 = Term.regex("fghi"); - - const result = await term1.union(term2, term3); - - expect(result.toString()).toEqual("regex=(abc|de|fghi)"); - }); - - it('subtraction', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_subtraction.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/compute/subtraction') - .reply(200, response); - - const term1 = Term.regex("(abc|de)"); - const term2 = Term.regex("de"); - - const result = await term1.subtraction(term2); - - expect(result.toString()).toEqual("regex=abc"); - }); - - it('is equivalent to', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_isEquivalentTo.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/analyze/equivalence') - .reply(200, response); - - const term1 = Term.regex("(abc|de)"); - const term2 = Term.fair("rgmsW[1g2LvP=Gr&V>sLc#w-!No&(oq@Sf>X).?lI3{uh{80qWEH[#0.pHq@B-9o[LpP-a#fYI+"); - - const result = await term1.isEquivalentTo(term2); - - expect(result).toBe(false); - }); - - it('is subset of', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_isSubsetOf.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/analyze/subset') - .reply(200, response); - - const term1 = Term.regex("de"); - const term2 = Term.regex("(abc|de)"); - - const result = await term1.isSubsetOf(term2); - - expect(result).toBe(true); - }); - - it('error response correctly handled', async () => { - const response = JSON.parse(await fs.readFile("tests/assets/response_error.json", 'utf-8')); - nock('https://api.regexsolver.com/api/') - .post('/compute/intersection') - .reply(200, response); - - const term1 = Term.regex("abc"); - const term2 = Term.regex("de"); - - try { - await term1.intersection(term2); - } catch (error) { - expect(error.message).toEqual("The API returned the following error: A random error."); - } - }); -}); \ No newline at end of file diff --git a/tests/term.test.ts b/tests/term.test.ts new file mode 100644 index 0000000..6032c0d --- /dev/null +++ b/tests/term.test.ts @@ -0,0 +1,88 @@ +import { Term, RegexTerm, FairTerm } from "../src/models/Term"; +import { Integer } from "../src/models/Cardinality"; + +describe("Term", () => { + test("creation should work", () => { + const regexTerm = Term.regex("abc"); + expect(regexTerm).toBeInstanceOf(RegexTerm); + expect(regexTerm.getValue()).toBe("abc"); + + const fairTerm = Term.fair("payload"); + expect(fairTerm).toBeInstanceOf(FairTerm); + expect(fairTerm.getValue()).toBe("payload"); + }); + + test("getFair and getPattern should work", () => { + const regexTerm = Term.regex("abc"); + expect(regexTerm.getPattern()).toBe("abc"); + expect(regexTerm.getFair()).toBeNull(); + + const fairTerm = Term.fair("payload"); + expect(fairTerm.getFair()).toBe("payload"); + expect(fairTerm.getPattern()).toBeNull(); + + fairTerm.setCachedPattern("abc"); + expect(fairTerm.getPattern()).toBe("abc"); + }); + + test("matches should work for regex terms", () => { + const term = Term.regex("[a-z]+"); + expect(term.matches("abc")).toBe(true); + expect(term.matches("123")).toBe(false); + expect(term.matches("ABC")).toBe(false); + }); + + test("matches should work with dotAll equivalent", () => { + const term = Term.regex(".+"); + expect(term.matches("abc\ndef")).toBe(true); + }); + + test("matches should be anchored", () => { + const term = Term.regex("abc"); + expect(term.matches("abcd")).toBe(false); + expect(term.matches("xabc")).toBe(false); + }); + + test("matches should throw for fair terms without cached pattern", () => { + const term = Term.fair("payload"); + expect(() => term.matches("abc")).toThrow( + "The regex pattern of this term is not defined yet", + ); + }); + + test("serialize/deserialize should work", () => { + const term = Term.regex("[a-z]+"); + const serialized = term.serialize(); + expect(serialized).toBe("regex=[a-z]+"); + + const deserialized = Term.deserialize(serialized); + if (deserialized === null) { + fail("Deserialized term should not be null"); + } + expect(deserialized).toBeInstanceOf(RegexTerm); + expect(deserialized.getValue()).toBe("[a-z]+"); + + const fairTerm = Term.fair("payload"); + const deserializedFair = Term.deserialize(fairTerm.serialize()); + expect(deserializedFair).toEqual(fairTerm); + }); + + test("deserialize should return null for invalid format", () => { + expect(Term.deserialize("invalid")).toBeNull(); + expect(Term.deserialize("unknown=value")).toBeNull(); + }); + + test("toDto should work", () => { + const term = Term.regex("[a-z]+"); + const dto = term.toDto(); + expect(dto.type).toBe("regex"); + expect(dto.value).toBe("[a-z]+"); + }); + + test("fromDto should work", () => { + const dto = { type: "regex" as const, value: "[a-z]+" }; + const term = Term.fromDto(dto); + expect(term).toBeInstanceOf(RegexTerm); + expect(term.getValue()).toBe("[a-z]+"); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index d26fa3a..14c0084 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,15 +1,19 @@ { - "version": "1.6.2", - "compilerOptions": { - "module": "commonjs", - "declaration": true, - "outDir": "lib/", - "lib": [ - "es2015", - "dom" - ] - }, - "files": [ - "./src/index.ts" - ] -} \ No newline at end of file + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["es2020", "dom"], + "declaration": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "lib/", + "baseUrl": ".", + "paths": { + "*": ["node_modules/*"] + } + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "tests", "lib"] +}