diff --git a/.github/workflows/auto-update.yml b/.github/workflows/auto-update.yml index 9d3bb10..1dd0c4a 100644 --- a/.github/workflows/auto-update.yml +++ b/.github/workflows/auto-update.yml @@ -2,7 +2,7 @@ name: Automatic Updates on: schedule: - - cron: "30 3 * * 4" + - cron: '30 3 * * 4' workflow_dispatch: permissions: diff --git a/.github/workflows/build-pr.yml b/.github/workflows/build-pr.yml index 920eb6b..247fbbf 100644 --- a/.github/workflows/build-pr.yml +++ b/.github/workflows/build-pr.yml @@ -1,7 +1,6 @@ name: Build Pull Request -on: - pull_request +on: pull_request jobs: build-pr: diff --git a/LICENSE.md b/LICENSE.md index ac7c0dc..8036035 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -191,7 +191,7 @@ such warranty or additional liability. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the -brackets!) The text should be enclosed in the appropriate comment +brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. diff --git a/README.md b/README.md index 7caa544..4697622 100644 --- a/README.md +++ b/README.md @@ -14,27 +14,26 @@ It focuses in providing an _easy_ and _terse_ syntax to define a simple schema, used to ensure that an object is _**correct**_ and from which _**proper**_ typing can be inferred. -* [Quick Start](#quick-start) -* [Inferring Types](#inferring-types) -* Validators - * [Strings](#string-validator) - * [Numbers](#number-validator) - * [Booleans](#boolean-validator) - * [Constants](#constant-validator) - * [Any](#any-validator) - * [Arrays](#array-validator) - * [Dates](#date-validator) - * [Tuples](#tuple-validator) - * [Objects](#object-validator) (yes, this is the important one!!!) - * [Optionals](#optional-validator) - * [Any of, all of](#union-validators) -* [Extra Validators](#extra-validators) -* [Validation Options](#validation-options) -* [A (slightly more) complex example](#a-complex-example) -* [Generating DTS files](#generating-dts-files) -* [Copyright Notice](NOTICE.md) -* [License](LICENSE.md) - +- [Quick Start](#quick-start) +- [Inferring Types](#inferring-types) +- Validators + - [Strings](#string-validator) + - [Numbers](#number-validator) + - [Booleans](#boolean-validator) + - [Constants](#constant-validator) + - [Any](#any-validator) + - [Arrays](#array-validator) + - [Dates](#date-validator) + - [Tuples](#tuple-validator) + - [Objects](#object-validator) (yes, this is the important one!!!) + - [Optionals](#optional-validator) + - [Any of, all of](#union-validators) +- [Extra Validators](#extra-validators) +- [Validation Options](#validation-options) +- [A (slightly more) complex example](#a-complex-example) +- [Generating DTS files](#generating-dts-files) +- [Copyright Notice](NOTICE.md) +- [License](LICENSE.md) Quick Start ----------- @@ -47,7 +46,6 @@ import { number, object, string, validate } from 'justus' // Create a validator, validating _objects_ with a specific schema const validator = object({ - // The "foo" property in the objects to validate must be a "string" // with a minimum length of one character foo: string({ minLength: 1 }), @@ -55,7 +53,7 @@ const validator = object({ // The "bar" property in the objects to validate must be a "number" bar: number, -// Always use `as const`: it correctly infers types for constants, tuples, ... + // Always use `as const`: it correctly infers types for constants, tuples, ... } as const) // Use the validator to validate the object specified as the second argument @@ -75,18 +73,20 @@ _shorthand_ inline syntax. From our example above: ```typescript import { number, string, validate } from 'justus' -const validated = validate({ - foo: string({ minLength: 1 }), - bar: number, -} as const, { - foo: 'xyz', - bar: 123, -}) +const validated = validate( + { + foo: string({ minLength: 1 }), + bar: number, + } as const, + { + foo: 'xyz', + bar: 123, + }, +) ``` ... you get the drill! See below in each _validator_ for their shorthand syntax. - Inferring Types --------------- @@ -116,9 +116,9 @@ Similarly, it might be useful to have access to a minimal type required as a validation input. This obviously differs from the input for several reasons, like: -* optionals with default: on input we should represent `optional(type, default)` +- optionals with default: on input we should represent `optional(type, default)` as `type`, but on input this should be `type | undefined` -* type conversions: the `date` validator converts numbers or strings always +- type conversions: the `date` validator converts numbers or strings always into `Date` objects, but the input type should be `Date | string | number` The `InferInput` helps in this case: @@ -142,7 +142,6 @@ type MyInputType = InferInput // } ``` - String Validator ---------------- @@ -157,9 +156,9 @@ const s2 = string({ minLength: 1 }) // validate non empty strings #### Options -* `minLength?: number`: The _minimum_ length of a valid `string` -* `maxLength?: number`: The _maximum_ length of a valid `string` -* `pattern?: RegExp`: A `RegExp` enforcing a particular pattern for a valid `string` +- `minLength?: number`: The _minimum_ length of a valid `string` +- `maxLength?: number`: The _maximum_ length of a valid `string` +- `pattern?: RegExp`: A `RegExp` enforcing a particular pattern for a valid `string` #### Branded strings @@ -214,7 +213,6 @@ const validator = object({ }) ``` - Number Validator ---------------- @@ -230,13 +228,13 @@ const n3 = number({ fromString: true }) // parse strings like "12.34" or "0x0CAF #### Options -* `multipleOf?: number`: The value for which a `number` must be multiple of for it to be valid -* `maximum?: number`: The _inclusive_ maximum value for a valid `number` -* `minimum?: number`: The _inclusive_ minimum value for a valid `number` -* `exclusiveMaximum?: number`: The _exclusive_ maximum value for a valid `number` -* `exclusiveMinimum?: number`: The _exclusive_ minimum value for a valid `number` -* `allowNaN?: boolean`: Whether to allow `NaN` or not (default: `false`) -* `fromString?: boolean`: Whether to parse numbers from strings or not (default: `false`) +- `multipleOf?: number`: The value for which a `number` must be multiple of for it to be valid +- `maximum?: number`: The _inclusive_ maximum value for a valid `number` +- `minimum?: number`: The _inclusive_ minimum value for a valid `number` +- `exclusiveMaximum?: number`: The _exclusive_ maximum value for a valid `number` +- `exclusiveMinimum?: number`: The _exclusive_ minimum value for a valid `number` +- `allowNaN?: boolean`: Whether to allow `NaN` or not (default: `false`) +- `fromString?: boolean`: Whether to parse numbers from strings or not (default: `false`) #### Branded numbers @@ -289,7 +287,6 @@ const validator = object({ }) ``` - Boolean Validator ----------------- @@ -317,8 +314,6 @@ const validator = object({ const bool = validate(validator, myValue) ``` - - Constant Validator ------------------ @@ -358,7 +353,6 @@ result.baz // <- its type will be `false` (or "boolean" if you didn't use "as co result.nil // <- its type will be `null` (or "any" if you didn't use "as const") ``` - Any Validator ------------- @@ -368,7 +362,7 @@ The _any_ validator is represented by the `any` constant: import { any, object, validate } from 'justus' const validator = object({ - foo: any // it's a constant, no options! + foo: any, // it's a constant, no options! }) const result = validate(validator, something) @@ -376,7 +370,6 @@ const result = validate(validator, something) result.foo // <- its type will be `any` ``` - Array Validator --------------- @@ -392,10 +385,10 @@ const a3 = arrayOf(number) // array of numbers #### Options -* `maxItems?: number`: The _maximum_ number of elements a valid `Array` -* `minItems?: number`: The _minimum_ number of elements a valid `Array` -* `uniqueItems?: boolean`: Indicates if the `Array`'s elements must be unique -* `items?: V`: The _type_ of each individual item in the `Array` */ +- `maxItems?: number`: The _maximum_ number of elements a valid `Array` +- `minItems?: number`: The _minimum_ number of elements a valid `Array` +- `uniqueItems?: boolean`: Indicates if the `Array`'s elements must be unique +- `items?: V`: The _type_ of each individual item in the `Array` */ #### Shorthand syntax @@ -420,7 +413,6 @@ const a1 = array({ items: string }) const a2 = arrayOf(string) // same as above, just more readable ``` - Date Validator -------------- @@ -438,11 +430,11 @@ const d2 = date({ format: 'iso' }) // validate ISO dates #### Options -* `format?: 'iso' | 'timestamp'`: The format for dates, `iso` for _ISO Dates_ +- `format?: 'iso' | 'timestamp'`: The format for dates, `iso` for _ISO Dates_ (as outlined in RFC 3339) or `timestamp` for the number of milliseconds since the epoch -* `from?: Date`: The earliest value a date can have -* `until?: Date`: The latest value a date can have +- `from?: Date`: The earliest value a date can have +- `until?: Date`: The latest value a date can have #### Shorthand syntax @@ -456,7 +448,6 @@ const validator = object({ }) ``` - Tuple Validator --------------- @@ -468,11 +459,11 @@ Tuple validators are created using the `tuple` function: import { tuple, string, number, boolean } from 'justus' // Validates 3 elements tuple: (in order) a string, a number and a boolean -const t1 = tuple([ string, number, boolean ]) +const t1 = tuple([string, number, boolean]) // Validates a tuple whose first element is a string, followed by zero or more // numbers, and wholse last element is a boolean -const t2 = tuple([ string, ...number, boolean ]) // yay! rest parameters! +const t2 = tuple([string, ...number, boolean]) // yay! rest parameters! ``` As shown above, any `Validator` (or one of its shorthands) can be used as a @@ -489,7 +480,7 @@ const myObject = object({ }) // This is the silliest tuple ever written, but outlines our intentions: -const sillyTuple = tuple([ 'start', ...myObject, 'end' ] as const) +const sillyTuple = tuple(['start', ...myObject, 'end'] as const) // Validate using our tuple: validate(sillyTuple, [ @@ -500,7 +491,6 @@ validate(sillyTuple, [ ]) ``` - Object Validator ---------------- @@ -567,15 +557,15 @@ result2.baz // <-- additional property, this will be "boolean" Here `allowAdditionalProperties` is also a function, which can take some parameters to configure its behaviour: -* `...allowAdditionalProperties`: default shorthand, allows additional +- `...allowAdditionalProperties`: default shorthand, allows additional properties and will infer the `any` type for them. -* `...allowAdditionalProperties()`: as a function, and same as above, it allows +- `...allowAdditionalProperties()`: as a function, and same as above, it allows additional properties and will infer the `any` type for them. -* `...allowAdditionalProperties(true)`: as a function, and same as above, it +- `...allowAdditionalProperties(true)`: as a function, and same as above, it allows additional properties and will infer the `any` type for them. -* `...allowAdditionalProperties(false)`: as a function, it _forbids_ any +- `...allowAdditionalProperties(false)`: as a function, it _forbids_ any additional property in objects, useful when extending objects (see below) -* `...allowAdditionalProperties(... type ...)`: as a function, it allows +- `...allowAdditionalProperties(... type ...)`: as a function, it allows additional properties in objects and ensures their type is correct #### Extending objects @@ -661,7 +651,6 @@ const o2 = objectOf({ test: number }) // here "o2" will have the shape "Record" ``` - Optional Validator ------------------ @@ -701,7 +690,6 @@ const r2 = validate(o1, { foo: 321 }) // here "r2" will be "{ foo: 321 }" (overrides the default value) ``` - Union Validators ---------------- @@ -737,7 +725,6 @@ const result = validate(oneOf(number, string), something) result // <-- its type will be "number | string" ``` - Extra Validators ---------------- @@ -746,17 +733,16 @@ in order to reduce the bundle size when Justus is bundled in client apps. Those are: -* `arn`: Validate an ARN (Amazon Resource Name) as a string - * `import { arn } from 'justus/extra/arn'` -* `parseArn`: Validate an ARN (Amazon Resource Name) and parse its components - * `import { parseArn } from 'justus/extra/arn'` -* `ean13`: Validate a standard _EAN-13_ barcode number (as a string) - * `import { ean13 } from 'justus/extra/ean13'` -* `url`: Validate a string URL and converts it into a proper `URL` object - * `import { url } from 'justus/extra/url'` -* `uuid`: Validate a string UUID plain and simple - * `import { uuid } from 'justus/extra/uuid'` - +- `arn`: Validate an ARN (Amazon Resource Name) as a string + - `import { arn } from 'justus/extra/arn'` +- `parseArn`: Validate an ARN (Amazon Resource Name) and parse its components + - `import { parseArn } from 'justus/extra/arn'` +- `ean13`: Validate a standard _EAN-13_ barcode number (as a string) + - `import { ean13 } from 'justus/extra/ean13'` +- `url`: Validate a string URL and converts it into a proper `URL` object + - `import { url } from 'justus/extra/url'` +- `uuid`: Validate a string UUID plain and simple + - `import { uuid } from 'justus/extra/uuid'` Validation Options ------------------ @@ -764,14 +750,14 @@ Validation Options The `validate(...)` function accepts (as a third parameter) some validation options. Those are: -* `stripAdditionalProperties`: the `validate(...)` function will ignore any +- `stripAdditionalProperties`: the `validate(...)` function will ignore any object property that was not declared in the schema, and will strip them out of the returned object (rather than failing). -* `stripForbiddenProperties`: the `validate(...)` function will ignore any +- `stripForbiddenProperties`: the `validate(...)` function will ignore any _forbidden_ property that was declared in the schema (for more info see [below](#ensure-properties-never-exist)), and will strip them out of the returned object (rather than failing). -* `stripOptionalNulls`: the `validate(...)` function will ignore _optional_ +- `stripOptionalNulls`: the `validate(...)` function will ignore _optional_ properties with `null` values and strip them out of the returned object. This is convenient when validating/stripping results coming from a database table, where columns are declared as _nullable_. @@ -793,7 +779,6 @@ const result2 = validate(schema, object, { }) ``` - A complex example ----------------- @@ -807,7 +792,7 @@ couple of different flavors, either V1 or V2 with some subtle differences: import { arrayOf, date, number, object, oneOf, string, tuple, validate } from 'justus' // Our V1 time-series tuple is simply a timestamp followed by a numeric value -const entryv1 = tuple([ date, number ] as const) +const entryv1 = tuple([date, number] as const) // Our V1 response from the time series database declares the version and data const responsev1 = object({ @@ -817,7 +802,7 @@ const responsev1 = object({ // Our V2 time-series tuple is a timestamp, followed by a number and zero or // more strings indicating some remarks on the measurements -const entryv2 = tuple([ date, number, ...string ] as const) +const entryv2 = tuple([date, number, ...string] as const) // Response for V2 is the same as V1, with some extra stuff const responsev2 = object({ @@ -852,7 +837,6 @@ if (result.version === 1) { } ``` - Generating DTS files -------------------- @@ -900,13 +884,13 @@ The resulting `dts` will be a `string` containing the DTS as follows: ```typescript export type UUID = string & { - __brand_uuid : never; -}; + __brand_uuid: never +} export type Product = { - uuid: UUID; - price: number & { - __brand_price: never; - }; - name: string; -}; + uuid: UUID + price: number & { + __brand_price: never + } + name: string +} ``` diff --git a/build.ts b/build.ts index f30377f..4f97847 100644 --- a/build.ts +++ b/build.ts @@ -1,55 +1,74 @@ -import { - banner, - exec, - find, - hookAfter, - log, - mkdtemp, - plugjs, - resolve, - rmrf, - tasks, -} from '@plugjs/build' +import '@plugjs/cov8' +import '@plugjs/expect5' +import { oxc } from '@plugjs/oxc' +import { banner, find, isDirectory, plugjs, rmrf } from '@plugjs/plug' import '@plugjs/tsd' +import { tsc } from '@plugjs/tsgo' -const localBuild = plugjs({ - ...tasks({ - exportsGlob: '((index|dts-generator).*)|(extra/**.*)', - extraLint: [ [ '**/*.test-d.ts', { directory: 'test-d' } ] ], - }), +export default plugjs({ + /** Flag indicating whether linting/formatting errors should be fixed or not */ + fix: 'false', - /** Run `tsd` */ + /** Transpile all sources and produce some JavaScript code in 'dist' */ + async transpile(): Promise { + banner('Transpiling TypeScript Sources') + if (isDirectory('dist')) await rmrf('dist') + await tsc('src/tsconfig.json') + }, + + /** Run all tests */ + async test(): Promise { + banner('Running Tests') + await rmrf('.coverage-data') // wipe existing coverage data + // await tsc('test/tsconfig.json', { noEmit: true }) // type check our tests + await find('**/*.test.*', { directory: 'test' }) // find all our test files + .test({ coverageDir: '.coverage-data' }) // run tests + }, + + /** Run type definition tests */ async tsd(): Promise { await this.transpile() banner('Testing type definitions') - await find('**/*.test-d.ts', { directory: 'test-d' }).tsd() + await find('**/*.test-d.ts', { directory: 'test-d' }).tsd({ + cwd: 'test-d', + }) }, - /** Text compilation of *dependant* packages */ - async test_dependants(): Promise { - await this.transpile() - - banner('Testing transpilation of dependant packages') - const tmpdir = mkdtemp() + /** Run tests capturing errors, but always producing coverage */ + async coverage(): Promise { try { - // copy files to the temporary directory - await find('**/*', { directory: 'test/sources' }) - .copy(tmpdir) - - // instell ourselves as a module in the temporary directory - await exec('npm', 'install', '--no-save', '--prefix', tmpdir, resolve('.')) - - // run tsc to make sure that all types are exported correctly - await find('**/*.ts', { directory: tmpdir }).tsc() - - log('Sources compiled successfully') + await this.test() } finally { - await rmrf(tmpdir) + banner('Preparing coverage report') + await find('**/*.ts', { directory: 'src', ignore: 'configs/*.ts' }) // + .coverage('.coverage-data', { + reportDir: 'coverage', + minimumCoverage: 100, + minimumFileCoverage: 100, + }) } }, -}) -hookAfter(localBuild, 'test', [ 'tsd', 'test_dependants' ]) + /** Format and lint all our sources (optionally fixing them) */ + async lint(): Promise { + banner('Linting Sources') + await oxc({ fix: this.fix === 'true' }) + }, -export default localBuild + /** Generate our exports from the list of transpiled files */ + async exports(): Promise { + await this.transpile() + + banner('Generating Exports') + await find('index.*', 'dts-generator.*', 'extra/**.*', { directory: 'dist' }).exports({}) + }, + + /** Default task: transpile, test and lint */ + async default(): Promise { + await this.transpile() + await this.tsd() + await this.coverage() + await this.lint() + }, +}) diff --git a/eslint.config.mjs b/eslint.config.mjs deleted file mode 100644 index 5240ab2..0000000 --- a/eslint.config.mjs +++ /dev/null @@ -1,53 +0,0 @@ -import configurations from '@plugjs/eslint-plugin' - -export default [ - ...configurations, - - // ===== DEFINE THE LOCATION OF OUR TSCONFIG.JSON FILES ====================== - { - languageOptions: { - parserOptions: { - createDefaultProgram: false, - project: [ - './tsconfig.json', - './test/tsconfig.json', - './test-d/tsconfig.json', - ], - }, - }, - }, - - // ===== ENSURE THAT OUR MAIN FILES DEPEND ONLY ON PROPER DEPENDENCIES ======= - { - files: [ 'src/**' ], - rules: { - // Turn _ON_ dependencies checks only for sources - 'import-x/no-extraneous-dependencies': [ 'error', { - 'devDependencies': true, - 'peerDependencies': true, - 'optionalDependencies': true, - 'bundledDependencies': false, - } ], - }, - }, - - // ===== PROJECT LOCAL RULES ================================================= - // Add any extra rule not tied to a specific "files" pattern here, e.g.: - // { - // rules: { - // 'camelcase': 'off', - // }, - // }, - - // ===== IGNORED FILES ======================================================= - // REMEMBER! Ignores *must* be in its own configuration, they can not coexist - // with "rules", "languageOptions", "files", ... or anything else, otherwise - // ESLint will blaantly ignore the ignore files! - { - ignores: [ - 'coverage/', - 'dist/', - 'node_modules/', - ], - }, -] diff --git a/oxfmt.config.ts b/oxfmt.config.ts new file mode 100644 index 0000000..4664918 --- /dev/null +++ b/oxfmt.config.ts @@ -0,0 +1,2 @@ +import config from '@plugjs/oxc/configs/oxfmt' +export default config diff --git a/oxlint.config.ts b/oxlint.config.ts new file mode 100644 index 0000000..81242bb --- /dev/null +++ b/oxlint.config.ts @@ -0,0 +1,11 @@ +import config from '@plugjs/oxc/configs/oxlint.node' +import { defineConfig } from 'oxlint' + +export default defineConfig({ + extends: [config], + ignorePatterns: ['test-d'], + env: { ...config.env }, // https://github.com/oxc-project/oxc/issues/20087 + rules: { + 'typescript/no-misused-spread': 'off', + }, +}) diff --git a/package-lock.json b/package-lock.json index 525eccd..28a0105 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,21 @@ { "name": "justus", - "version": "0.5.145", + "version": "0.6.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "justus", - "version": "0.5.145", + "version": "0.6.0", "license": "Apache-2.0", "devDependencies": { - "@plugjs/build": "^0.7.4", + "@plugjs/cov8": "^0.7.5", + "@plugjs/expect5": "^0.7.5", + "@plugjs/oxc": "^0.1.7", + "@plugjs/plug": "^0.7.5", "@plugjs/tsd": "^0.7.5", - "typescript": "<6" + "@plugjs/tsgo": "^0.0.3", + "typescript": "<7" } }, "node_modules/@babel/code-frame": { @@ -45,7 +49,6 @@ "integrity": "sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^22.18.0 || >=24.11.0" } @@ -56,7 +59,6 @@ "integrity": "sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^22.18.0 || >=24.11.0" } @@ -67,7 +69,6 @@ "integrity": "sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/types": "^8.0.4" }, @@ -84,7 +85,6 @@ "integrity": "sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-string-parser": "^8.0.0", "@babel/helper-validator-identifier": "^8.0.4" @@ -93,43 +93,6 @@ "node": "^22.18.0 || >=24.11.0" } }, - "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, - "peer": 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, - "peer": 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, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -143,7 +106,6 @@ "os": [ "aix" ], - "peer": true, "engines": { "node": ">=18" } @@ -161,7 +123,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -179,7 +140,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -197,7 +157,6 @@ "os": [ "android" ], - "peer": true, "engines": { "node": ">=18" } @@ -215,7 +174,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -233,7 +191,6 @@ "os": [ "darwin" ], - "peer": true, "engines": { "node": ">=18" } @@ -251,7 +208,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -269,7 +225,6 @@ "os": [ "freebsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -287,7 +242,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -305,7 +259,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -323,7 +276,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -341,7 +293,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -359,7 +310,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -377,7 +327,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -395,7 +344,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -413,7 +361,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -431,7 +378,6 @@ "os": [ "linux" ], - "peer": true, "engines": { "node": ">=18" } @@ -449,7 +395,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -467,7 +412,6 @@ "os": [ "netbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -485,7 +429,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -503,7 +446,6 @@ "os": [ "openbsd" ], - "peer": true, "engines": { "node": ">=18" } @@ -521,7 +463,6 @@ "os": [ "openharmony" ], - "peer": true, "engines": { "node": ">=18" } @@ -539,7 +480,6 @@ "os": [ "sunos" ], - "peer": true, "engines": { "node": ">=18" } @@ -557,7 +497,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -575,7 +514,6 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } @@ -593,4037 +531,1460 @@ "os": [ "win32" ], - "peer": true, "engines": { "node": ">=18" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz", - "integrity": "sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==", + "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==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "eslint-visitor-keys": "^3.4.3" + "@sinclair/typebox": "^0.27.8" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, - "funding": { - "url": "https://opencollective.com/eslint" + "engines": { + "node": ">= 8" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">= 8" } }, - "node_modules/@eslint/config-array": { - "version": "0.23.5", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", - "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "Apache-2.0", - "peer": true, + "license": "MIT", "dependencies": { - "@eslint/object-schema": "^3.0.5", - "debug": "^4.3.1", - "minimatch": "^10.2.4" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": ">= 8" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.7.0.tgz", - "integrity": "sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==", + "node_modules/@oxfmt/binding-android-arm-eabi": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.65.0.tgz", + "integrity": "sha512-M10Gs1SSpTNI6ahGx3M/OlIdUF4hkaP6OgUb+MS79t/Pgflk3r1nW5gPFqsZGUAXg0H1AfANT9AvLdBSTIhZKg==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@eslint/core": "^1.2.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", - "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "node_modules/@oxfmt/binding-android-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.65.0.tgz", + "integrity": "sha512-6DXH5sftNlaHpWJG50hFMF+Qxtq5D2TmahvcDPxWNcGIf8qrC9Y0YgHYcYZ2hlWzaccKXh/f3GcssH8vtkl4JA==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/css-tree": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@eslint/css-tree/-/css-tree-4.0.5.tgz", - "integrity": "sha512-iPmijIAq4hlIJB86PYmY/fcZORHtjphSqICDbwuw32A/JmkhZQ/K/6TjHE03zqf3n5yABpVcbRAMG8Mi9ojy8g==", + "node_modules/@oxfmt/binding-darwin-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.65.0.tgz", + "integrity": "sha512-K9m7lr53pcOLETNsC88sWes/GWHUGjZyHx95UhYcSXy0r30haLdeXlSufSenEAtoLaW753WN8/l4M7GYcRt6cg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "mdn-data": "2.29.0", - "source-map-js": "^1.2.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/js": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", - "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "node_modules/@oxfmt/binding-darwin-x64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.65.0.tgz", + "integrity": "sha512-sTNwIx1gre3MyiHOPLu7IGW4UyMScYL4DTmJT01p4vzB0En+OJUQz6KuH8t0PpsClRSaMuY3b0QmtoPItfO8Lg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "eslint": "^10.0.0" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/object-schema": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", - "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "node_modules/@oxfmt/binding-freebsd-x64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.65.0.tgz", + "integrity": "sha512-lYZMVIiIpnjGu5hJb2jxA8NYQ/e0OTGuaiAf4dqlGPNnPmUTu23FZRMltmjro/KkQm1uE4NT4n5yJ2zWmKcpfA==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", - "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.65.0.tgz", + "integrity": "sha512-gIdXFAt/bURnjxuoedDEWdZ0PEWEmdDcm8qdpoFYYvW3QMk/5D4vUaH4mlMeRpeTdST4izUgHVO6RawQ4QulJw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@eslint/core": "^1.2.1", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/core": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", - "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "node_modules/@oxfmt/binding-linux-arm-musleabihf": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.65.0.tgz", + "integrity": "sha512-jJVyADto7gA2AaX5qAjAexrxx9PJQaKWOe8PICE7yKMbjBRyOHcmj9TtVJ+MZYDUQ3hodU0AcoTj0jFQ1W4C6Q==", + "cpu": [ + "arm" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanfs/types": "^0.15.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/node": { - "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", - "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "node_modules/@oxfmt/binding-linux-arm64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.65.0.tgz", + "integrity": "sha512-p3RFkB+u7u+8up99b/NEcI1hdpLDiGgJYNwDorB60n7eH+eKposAKuMBxx+NqB3b+sJP4CZmYDh9G7X62tUsKg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@humanfs/core": "^0.19.2", - "@humanfs/types": "^0.15.0", - "@humanwhocodes/retry": "^0.4.0" - }, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanfs/types": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", - "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "node_modules/@oxfmt/binding-linux-arm64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.65.0.tgz", + "integrity": "sha512-5Prb0uFzJHr+OUD/qS/TmU526wD+PaHDsm3KoRiUXbMIDpTSErjeQYkK3OQeshAvD/PuLa9WGEi9WPajjdOZJg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@oxfmt/binding-linux-ppc64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.65.0.tgz", + "integrity": "sha512-S8svxTp81obnF3admN9yd+u2rOYXtyzThLGBTg1PY6TPtGcC09BaaXLQD+TBSMa7yvqhCDZ8DFri+S/yG60qCg==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "node_modules/@oxfmt/binding-linux-riscv64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.65.0.tgz", + "integrity": "sha512-WtXBr75G/h2qOHy8SiGtC1R6aS3jt4mE52v1D8AtwMXIgoOmSNP9lKvbSaTRoL0e5wsMPoi6T72QWDYPu+S+nA==", + "cpu": [ + "riscv64" + ], "dev": true, - "license": "Apache-2.0", - "peer": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxfmt/binding-linux-riscv64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.65.0.tgz", + "integrity": "sha512-YwSLVvpaz4o/nv/miiPEBJz+eJ+VmbgNIrao6RccK9ce+L5EA8wP+ZD0uFeq6wKOza6zoWv/dR0sj6lip6R3EA==", + "cpu": [ + "riscv64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz", - "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==", + "node_modules/@oxfmt/binding-linux-s390x-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.65.0.tgz", + "integrity": "sha512-XQTPqgvyrgkKcFq+Tp2eK6JS7sqqJ+nRmy2Fav4j3I+i4dJoPJm7YwEdoeSDX9xkqj9jZ/lWfF3bXUWztIrn6A==", + "cpu": [ + "s390x" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, - "peer": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.3" - }, + "os": [ + "linux" + ], "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.4", - "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@oxfmt/binding-linux-x64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.65.0.tgz", + "integrity": "sha512-cjZlx6S/VkeCNWCbwZriTnLnZeTcV3DEyeRGSw/2wwLP9viq+C0bJ4bC1k/ZLkFxDcB1lUgSasPkYGP1bdraOg==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@oxfmt/binding-linux-x64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.65.0.tgz", + "integrity": "sha512-2azCjxdLtK4zCcIOU1dlXlU0xxfbPi6EjwWx7Ac7teWPidIIDOcIhudup83xNCKYhtqeVd/gaVDOxbUq4syXWA==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@plugjs/build": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@plugjs/build/-/build-0.7.4.tgz", - "integrity": "sha512-G2IMSfa5lZr1NrTwdcdnwUmwSZxhDzUNJFG/9igqKz1lfyLday/smpUXHD/cf1nKoYuBYHpasnIujAM/NXqsww==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "bootstrap-plugjs-build": "dist/bootstrap.mjs" - }, - "peerDependencies": { - "@plugjs/cov8": "^0.7.5", - "@plugjs/eslint": "^0.7.5", - "@plugjs/eslint-plugin": "^0.7.7", - "@plugjs/expect5": "^0.7.5", - "@plugjs/plug": "^0.7.5", - "@plugjs/typescript": "^0.7.5" - } - }, - "node_modules/@plugjs/cov8": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/cov8/-/cov8-0.7.5.tgz", - "integrity": "sha512-MD7bBJvrrZUtHfmxOqfqehGPAR/zmEh87yo82jyZFtbX2cf3Rz/bSv51Cefb6u9zmcNW2EullkExzfU8Z+B/zw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@babel/parser": "^8.0.4", - "@babel/types": "^8.0.4", - "@plugjs/cov8-html": "^0.2.7", - "@plugjs/tsrun": "^0.7.8", - "source-map": "^0.8.0" - }, - "bin": { - "cov8": "dist/cli.js" - }, - "engines": { - "node": ">=22.16.0" - }, - "peerDependencies": { - "@plugjs/plug": "0.7.5" - } - }, - "node_modules/@plugjs/cov8-html": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@plugjs/cov8-html/-/cov8-html-0.2.7.tgz", - "integrity": "sha512-kD4EKpIBrqSL1FrUED/C6WdQYbYDgOLmTiT20RchCnEQ3kOTBjM0iCnzugH8OpfJNrKWo+h/PlgXzQydmt2H+A==", - "dev": true, - "license": "Apache-2.0", - "peer": true - }, - "node_modules/@plugjs/eslint": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/eslint/-/eslint-0.7.5.tgz", - "integrity": "sha512-8jkNp6EAHBjtYx0/YdYkB8nI8V4487wQfveh6hmHNmxO2XMmxtRqAZQrsLhUkjEF/YZGq+2jU4wwPAd4KggyjQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "eslint": "^10.9.1" - }, - "engines": { - "node": ">=22.16.0" - }, - "peerDependencies": { - "@plugjs/plug": "0.7.5" - } - }, - "node_modules/@plugjs/eslint-plugin": { - "version": "0.7.7", - "resolved": "https://registry.npmjs.org/@plugjs/eslint-plugin/-/eslint-plugin-0.7.7.tgz", - "integrity": "sha512-dzrA5eG5OI4EJn+yKSDNcD7mVcjoRG7z5c6SstSQx23Dv2oyeq7lcO3YRQuNjz9ebEzOa2ugWRx7GJ9S6Ttpog==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@eslint/js": "^10.0.1", - "@stylistic/eslint-plugin": "^5.10.0", - "eslint-import-resolver-node": "^0.4.0", - "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-import-x": "^4.17.1", - "eslint-plugin-unicorn": "^73.0.0", - "globals": "^17.11.0", - "typescript-eslint": "^8.68.0" - }, - "bin": { - "eslint-check-deprecated-rules": "dist/check.js" - }, - "peerDependencies": { - "eslint": "^10.9.1" - } - }, - "node_modules/@plugjs/expect5": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/expect5/-/expect5-0.7.5.tgz", - "integrity": "sha512-kQgdkH0z+ENoVsmnRa7/s/tmMMtLeiAQnmpzuj36g9amtQD52DmRuHbqFvuqHWhZnSvgbkYhzaeYlT9ICO/lAQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@plugjs/tsrun": "^0.7.8" - }, - "bin": { - "expect5": "dist/cli.js" - }, - "engines": { - "node": ">=22.16.0" - }, - "peerDependencies": { - "@plugjs/plug": "0.7.5" - } - }, - "node_modules/@plugjs/plug": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/plug/-/plug-0.7.5.tgz", - "integrity": "sha512-KW3oGtSHWQynRmz1GtKSYldeutOYBSyaAKNznZJR7TxUnjP7vP/dHmFDL1WUK+KeAM/Uc+ZP0Os/eu7sydUSEw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "@plugjs/tsrun": "^0.7.8", - "@types/node": "<23", - "esbuild": "^0.28.2", - "jsonc-parser": "^3.3.1", - "picomatch": "^4.0.7" - }, - "bin": { - "plug": "dist/cli.js" - }, - "engines": { - "node": ">=22.16.0" - } - }, - "node_modules/@plugjs/tsd": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/tsd/-/tsd-0.7.5.tgz", - "integrity": "sha512-x+JwnYTthLWX0v62PcyebaVpsEWFcZv7bHT4taIuButIIdQ5FiAk2IKnpoFLZGnDXDyWoDQROMJyJXAZQFc7CQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tsd": "^0.33.0" - }, - "engines": { - "node": ">=22.16.0" - }, - "peerDependencies": { - "@plugjs/plug": "0.7.5" - } - }, - "node_modules/@plugjs/tsrun": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/@plugjs/tsrun/-/tsrun-0.7.8.tgz", - "integrity": "sha512-yk9axM/05tKBgLP9Yy6dp+xbPWeV8X6LRWweRuOsVEx7AEHyoFrvg+pT6/pKNtEl8VdR/Uy7trlQF58jtJXv2Q==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "esbuild": "^0.28.2" - }, - "bin": { - "tsrun": "dist/tsrun.mjs" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@plugjs/typescript": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@plugjs/typescript/-/typescript-0.7.5.tgz", - "integrity": "sha512-a14BqNJ7xZPyJ+6CWmzUC2TPN4p3z5g7oeSNWr92+I8h+Beb6E276azuzwAvJxQyT08v9uvXKJPXRWm/ySciYw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "dependencies": { - "typescript": "<7" - }, - "engines": { - "node": ">=22.16.0" - }, - "peerDependencies": { - "@plugjs/plug": "0.7.5" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.12", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", - "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@stylistic/eslint-plugin": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", - "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/types": "^8.56.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^9.0.0 || ^10.0.0" - } - }, - "node_modules/@tsd/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-JSSdNiS0wgd8GHhBwnMAI18Y8XPhLVN+dNelPfZCXFhy9Lb3NbnFyp9JKxxr54jSUkEJPk3cidvCoHducSaRMQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.17" - } - }, - "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, - "peer": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/eslint": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", - "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/esrecurse": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", - "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@types/estree": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", - "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.20.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", - "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "undici-types": "~6.21.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.68.0.tgz", - "integrity": "sha512-WASHDpCm6qO5jj9g1a+8NiW5+GCkAyLReR56/4VruYmNgfUmqpxOfZ2Yfb8xGfJPWv5Qi6LSD8sXdces3vbp/Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.68.0", - "@typescript-eslint/type-utils": "8.68.0", - "@typescript-eslint/utils": "8.68.0", - "@typescript-eslint/visitor-keys": "8.68.0", - "ignore": "^7.0.5", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.68.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", - "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.68.0.tgz", - "integrity": "sha512-fHq2VC1kpyYfvEcbiMjOpySY4WS7voEp89yAThrHRX5sm9j2lzYppCb2umFMEed4fWcyeLjHxrz0mpjNBaBxMQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/scope-manager": "8.68.0", - "@typescript-eslint/types": "8.68.0", - "@typescript-eslint/typescript-estree": "8.68.0", - "@typescript-eslint/visitor-keys": "8.68.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.68.0.tgz", - "integrity": "sha512-5GQtWZCXFcFYux955pvoS02WLc49pXNlvIxocKjS0clvwo3in1RdlzVKyiqQH9vE5AKWFLTaUgeQkOrTS+0Qxw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.68.0", - "@typescript-eslint/types": "^8.68.0", - "debug": "^4.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.68.0.tgz", - "integrity": "sha512-T5eXpcaJNg8bhjHJ8Rjp68Vq/QBteYtTKY8TZqVNPaUbuz0f6jI9t6aDkylwvalpAB9XTTFeFOjrjXAZ3YvmVA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "8.68.0", - "@typescript-eslint/visitor-keys": "8.68.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.68.0.tgz", - "integrity": "sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.68.0.tgz", - "integrity": "sha512-X77zqoY1EjeWGs/0JNxeaMfp5C5lIz4Tw8y66F1Ne8Faq6g424sBNYM6xBAqElfGZPLpWS+CZAp0DXyKDzWiHg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "8.68.0", - "@typescript-eslint/typescript-estree": "8.68.0", - "@typescript-eslint/utils": "8.68.0", - "debug": "^4.4.3", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.68.0.tgz", - "integrity": "sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.68.0.tgz", - "integrity": "sha512-OKKsD0tYmoNiU5PW2zehO1yO56jYOm1ShYlxon/Z0SJNidAkdVg86eg9ruRuoXf8xfnuWZGbwDsStkoXbZtIIA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/project-service": "8.68.0", - "@typescript-eslint/tsconfig-utils": "8.68.0", - "@typescript-eslint/types": "8.68.0", - "@typescript-eslint/visitor-keys": "8.68.0", - "debug": "^4.4.3", - "minimatch": "^10.2.2", - "semver": "^7.7.3", - "tinyglobby": "^0.2.15", - "ts-api-utils": "^2.5.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.68.0.tgz", - "integrity": "sha512-PB5gJMMOg0Q5P1tsgWtEAqQacJXq0qEqRHDX/YJ4FaTMLfZPpHB3gjl2EJuiZyPABxmj4ZQYiY9m1bdAJ5y7tQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.68.0", - "@typescript-eslint/types": "8.68.0", - "@typescript-eslint/typescript-estree": "8.68.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.68.0.tgz", - "integrity": "sha512-YR65gGdGvTUAWLldC3xLOvOzamdGzB4A5/N8rehEaHs3Zvoe39BhgY+u0SPch1OvrVTfLcc55wsSgK2NcnTS/A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "8.68.0", - "eslint-visitor-keys": "^5.0.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "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", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "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", - "optional": true, - "os": [ - "android" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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, - "peer": true, - "dependencies": { - "@emnapi/core": "1.10.0", - "@emnapi/runtime": "1.10.0", - "@napi-rs/wasm-runtime": "^1.1.4" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "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", - "optional": true, - "os": [ - "win32" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "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" - ], - "peer": true - }, - "node_modules/acorn": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", - "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peer": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/ajv": { - "version": "6.15.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", - "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-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-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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/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/array-buffer-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", - "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "is-array-buffer": "^3.0.5" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", - "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", - "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async-function": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", - "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.11.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.19.tgz", - "integrity": "sha512-Grytf1xOxOEMTGRwx6rLGKkTabd4vMg3VrKdj/7joCmV0qgh4QwMMO6xh34YEXQqirAuUdgQGa5orJQQ+69RBw==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", - "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "baseline-browser-mapping": "^2.11.12", - "caniuse-lite": "^1.0.30001809", - "electron-to-chromium": "^1.5.402", - "node-releases": "^2.0.53", - "update-browserslist-db": "^1.3.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/builtin-modules": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.3.0.tgz", - "integrity": "sha512-hMQUl2bUFG339QygPM97E+mc8OY1IAchORZxm4a/frcYwKzozMzRVDBwHW0NjOqGElLm2O37AVQE8ikxlZHrMQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/call-bind": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", - "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "get-intrinsic": "^1.3.0", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0", - "peer": true - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/change-case": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", - "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/ci-info": { - "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": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/comment-parser": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.8.tgz", - "integrity": "sha512-rKZTGo4fzKYna8UcL0isTg5wkBNla7bxTypLwZQXjIdi++IdP1OJ41rI5Mti3/jltkPujbu4i9LIARYA+zpotQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 12.0.0" - } - }, - "node_modules/convert-hrtime": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", - "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/core-js-compat": { - "version": "3.50.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz", - "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "browserslist": "^4.28.7" - }, - "engines": { - "node": ">=6.4.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", - "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", - "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/inspect-js" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", - "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/detect-indent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", - "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.415", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.415.tgz", - "integrity": "sha512-958V+Kbhtgz+SxXeEVKBjrlKRBIDAYvUJfwhjxMZ5S6ut9jAl7l9ZKBkBrvjyjZE36PabLUo2L8kEeV5O4vgJg==", - "dev": true, - "license": "ISC", - "peer": true - }, - "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/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", - "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.2", - "arraybuffer.prototype.slice": "^1.0.4", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "data-view-buffer": "^1.0.2", - "data-view-byte-length": "^1.0.2", - "data-view-byte-offset": "^1.0.1", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "es-set-tostringtag": "^2.1.0", - "es-to-primitive": "^1.3.0", - "function.prototype.name": "^1.1.8", - "get-intrinsic": "^1.3.0", - "get-proto": "^1.0.1", - "get-symbol-description": "^1.1.0", - "globalthis": "^1.0.4", - "gopd": "^1.2.0", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "internal-slot": "^1.1.0", - "is-array-buffer": "^3.0.5", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.2", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.2.1", - "is-set": "^2.0.3", - "is-shared-array-buffer": "^1.0.4", - "is-string": "^1.1.1", - "is-typed-array": "^1.1.15", - "is-weakref": "^1.1.1", - "math-intrinsics": "^1.1.0", - "object-inspect": "^1.13.4", - "object-keys": "^1.1.1", - "object.assign": "^4.1.7", - "own-keys": "^1.0.1", - "regexp.prototype.flags": "^1.5.4", - "safe-array-concat": "^1.1.3", - "safe-push-apply": "^1.0.0", - "safe-regex-test": "^1.1.0", - "set-proto": "^1.0.0", - "stop-iteration-iterator": "^1.1.0", - "string.prototype.trim": "^1.2.10", - "string.prototype.trimend": "^1.0.9", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.3", - "typed-array-byte-length": "^1.0.3", - "typed-array-byte-offset": "^1.0.4", - "typed-array-length": "^1.0.7", - "unbox-primitive": "^1.1.0", - "which-typed-array": "^1.1.19" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-abstract-get": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", - "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.2", - "is-callable": "^1.2.7", - "object-inspect": "^1.13.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "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==", - "dev": true, - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, - "license": "MIT", - "peer": true, - "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/es-shim-unscopables": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", - "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-to-primitive": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", - "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-abstract-get": "^1.0.0", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "is-callable": "^1.2.7", - "is-date-object": "^1.1.0", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.28.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", - "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "peer": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.2", - "@esbuild/android-arm": "0.28.2", - "@esbuild/android-arm64": "0.28.2", - "@esbuild/android-x64": "0.28.2", - "@esbuild/darwin-arm64": "0.28.2", - "@esbuild/darwin-x64": "0.28.2", - "@esbuild/freebsd-arm64": "0.28.2", - "@esbuild/freebsd-x64": "0.28.2", - "@esbuild/linux-arm": "0.28.2", - "@esbuild/linux-arm64": "0.28.2", - "@esbuild/linux-ia32": "0.28.2", - "@esbuild/linux-loong64": "0.28.2", - "@esbuild/linux-mips64el": "0.28.2", - "@esbuild/linux-ppc64": "0.28.2", - "@esbuild/linux-riscv64": "0.28.2", - "@esbuild/linux-s390x": "0.28.2", - "@esbuild/linux-x64": "0.28.2", - "@esbuild/netbsd-arm64": "0.28.2", - "@esbuild/netbsd-x64": "0.28.2", - "@esbuild/openbsd-arm64": "0.28.2", - "@esbuild/openbsd-x64": "0.28.2", - "@esbuild/openharmony-arm64": "0.28.2", - "@esbuild/sunos-x64": "0.28.2", - "@esbuild/win32-arm64": "0.28.2", - "@esbuild/win32-ia32": "0.28.2", - "@esbuild/win32-x64": "0.28.2" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.1.tgz", - "integrity": "sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==", - "dev": true, - "license": "MIT", - "peer": true, - "workspaces": [ - "packages/*" - ], - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.7.0", - "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.2", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.2", - "eslint-visitor-keys": "^5.0.1", - "espree": "^11.2.0", - "esquery": "^1.7.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.5", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-formatter-pretty": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", - "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "^7.2.13", - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.0", - "eslint-rule-docs": "^1.1.5", - "log-symbols": "^4.0.0", - "plur": "^4.0.0", - "string-width": "^4.2.0", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint-import-context": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", - "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "get-tsconfig": "^4.10.1", - "stable-hash-x": "^0.2.0" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-context" - }, - "peerDependencies": { - "unrs-resolver": "^1.0.0" - }, - "peerDependenciesMeta": { - "unrs-resolver": { - "optional": true - } - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.4.0.tgz", - "integrity": "sha512-wV22NewD4lwrMp94THds3/MjW7qPYupLj3wxLZCYkKrSLfVslRS/7lcbogiEwn9oT4cunDDCsTiBo/V16WlEUQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.16.2", - "resolve": "^2.0.0-next.7" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.5.tgz", - "integrity": "sha512-nbE5XLph6TLtGYcu/U6e6ZVXyKBhbDWK5cLGk76eJ7NdZpwf1P9EFkpt1Z01mNZNrrilsAYWKH6zUkL4reoXbw==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "debug": "^4.4.1", - "eslint-import-context": "^0.1.8", - "get-tsconfig": "^4.10.1", - "is-bun-module": "^2.0.0", - "stable-hash-x": "^0.2.0", - "tinyglobby": "^0.2.14", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^16.17.0 || >=18.6.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-import-resolver-typescript" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-import-x": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz", - "integrity": "sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "^8.56.0", - "comment-parser": "^1.4.1", - "debug": "^4.4.1", - "eslint-import-context": "^0.1.9", - "is-glob": "^4.0.3", - "minimatch": "^9.0.3 || ^10.1.2", - "semver": "^7.7.2", - "stable-hash-x": "^0.2.0", - "unrs-resolver": "^1.9.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-import-x" - }, - "peerDependencies": { - "@typescript-eslint/utils": "^8.56.0", - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "eslint-import-resolver-node": "*" - }, - "peerDependenciesMeta": { - "@typescript-eslint/utils": { - "optional": true - }, - "eslint-import-resolver-node": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-unicorn": { - "version": "73.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-73.0.0.tgz", - "integrity": "sha512-V0YatLe9nkGhXEXKe2Qljb1EY0sJHwDV0HUF1NKFwtsHh/fU7qGHDgv+6fchzZcgU2/7noHo2gdjnmo0P2uDPw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.9.1", - "@eslint/css-tree": "^4.0.4", - "browserslist": "^4.28.4", - "change-case": "^5.4.4", - "ci-info": "^4.4.0", - "core-js-compat": "^3.49.0", - "detect-indent": "^7.0.2", - "entities": "^4.5.0", - "find-up-simple": "^1.0.1", - "globals": "^17.7.0", - "indent-string": "^5.0.0", - "is-builtin-module": "^5.0.0", - "is-identifier": "^1.1.0", - "pluralize": "^8.0.0", - "quote-js-string": "^0.1.0", - "regjsparser": "^0.13.2", - "reserved-identifiers": "^1.2.0", - "semver": "^7.8.5", - "strip-indent": "^4.1.1", - "yaml": "^2.9.0" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" - }, - "peerDependencies": { - "eslint": ">=10.4" - } - }, - "node_modules/eslint-rule-docs": { - "version": "1.1.235", - "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", - "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "peer": true, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/espree": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.16.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "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": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-up-simple": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", - "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", - "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", - "dev": true, - "license": "ISC", - "peer": true - }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-callable": "^1.2.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function-timeout": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-1.0.2.tgz", - "integrity": "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/function.prototype.name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", - "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2", - "hasown": "^2.0.4", - "is-callable": "^1.2.7", - "is-document.all": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/generator-function": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", - "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - } - }, - "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==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/get-symbol-description": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", - "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.14.3", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.3.tgz", - "integrity": "sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "17.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.11.0.tgz", - "integrity": "sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", - "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/@oxfmt/binding-openharmony-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.65.0.tgz", + "integrity": "sha512-KXQ7xi1e/voP0IQaw6fG6XY4Z5+Llf1XmRSZS1t7pVFCecFJ0iXaboKmVwjFtp5MLlT5iWQrJ2U1C3GJdZ2u+Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/has-proto": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", - "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "node_modules/@oxfmt/binding-win32-arm64-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.65.0.tgz", + "integrity": "sha512-2FbbjG5jEqLSLKVJwBap84uJfpn5Y5A53KEO0aUNr+zeiRB9nyPUIFMcSbZVMFLitfBytFWRNngozXYjb6Rsbw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxfmt/binding-win32-ia32-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.65.0.tgz", + "integrity": "sha512-LJ+ZacAPSjegDOnSLyA1TMWAhdDrsK4el3REdr1oL2UtVBCMhO2II/Sb3cEW6mF2MfLhl8hDNCSvc7KSbgk3LQ==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "peer": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "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==", + "node_modules/@oxfmt/binding-win32-x64-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.65.0.tgz", + "integrity": "sha512-higu9cWEO6XXFzATD1jf0mCK34rNfN2H9JrJie7QB1IhleVpTh0QlLH9Ip2C1H/Nd5n0v5pvRtC+5R0uE4HpVg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/hasown": { - "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==", + "node_modules/@oxlint-tsgolint/darwin-arm64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-7.0.2001.tgz", + "integrity": "sha512-CUJEdbSZ54+Xy9OXqOhWLTKZKV0BBiV7C2i/ygyVmXtkUNXx5YCzN8DpSSshTAKktoL7S+tnQ/ftFG/i7X896w==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/identifier-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/identifier-regex/-/identifier-regex-1.1.0.tgz", - "integrity": "sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==", + "node_modules/@oxlint-tsgolint/darwin-x64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-7.0.2001.tgz", + "integrity": "sha512-pXfBb5BqONCcgrXQNUZWXgiYmRSWJzd97S8i41VVOh6ut0tyo+cJ5FKFpczDHxiVNfj/3e7c9B4MtztNdpIVCw==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "reserved-identifiers": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "node_modules/@oxlint-tsgolint/linux-arm64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-7.0.2001.tgz", + "integrity": "sha512-roP7zujb/QDPzDwEKsFFpzNHHy91/Y7oX9vQXk78ekyZtcQj1QXDIMH33gjDdHBfRl4K9pZ36xhRgrP4Zr+R8A==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "engines": { - "node": ">= 4" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/@oxlint-tsgolint/linux-x64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-7.0.2001.tgz", + "integrity": "sha512-UDezNqdECVmngu2TPnjaS1YoAmcTaBoI5lV9vk3VahBxoi+I5r9k3iJTT7qZoYWOXTD/7T7bNcwRgrocR6BscQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.8.19" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "node_modules/@oxlint-tsgolint/win32-arm64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-7.0.2001.tgz", + "integrity": "sha512-uJZhqB6pdXLuN+AD1F5082byyQti/NPmJA77GtcFlmT2HzRelqbNls3SaIqxpjdFgvSBF9g0yOKGBkGFg7kX8Q==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/internal-slot": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", - "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "node_modules/@oxlint-tsgolint/win32-x64": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-7.0.2001.tgz", + "integrity": "sha512-FkDRm8hx9OwzGQqyWG1tO5QrTLRApff9DzSgpz9QZau37BR8d1VYKOxMLGf6shPZntJFoTwIIJYT68VndYDCog==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.2", - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/irregular-plurals": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", - "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", + "node_modules/@oxlint/binding-android-arm-eabi": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.80.0.tgz", + "integrity": "sha512-RM3Plj+biQpxa5d1GOOX6ciDlcUROmm4OZ/pLTpitkQt2mJv4jhtY4cbgaetOm5UKWZe05/TGQ6o1Vl8EOHkrA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", - "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "node_modules/@oxlint/binding-android-arm64": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.80.0.tgz", + "integrity": "sha512-YlO5JEf0Yr2bUUlu8O8daVcUxtcGGbcSmyV7E7nSbJbfAdxTE0PFPwgnIlw7wXJaTYjb+qs5hI5q3jxUkI7cAw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-async-function": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", - "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "node_modules/@oxlint/binding-darwin-arm64": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.80.0.tgz", + "integrity": "sha512-BULDOyO3AhsmdWfQeIUCykDt3dd7XZBGLhp1eIh56skRv01O+cNjNPwXMIbeW1x4+pxcln5if72wcRgViVo7PA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "async-function": "^1.0.0", - "call-bound": "^1.0.3", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-bigint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", - "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "node_modules/@oxlint/binding-darwin-x64": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.80.0.tgz", + "integrity": "sha512-YJ4JzLw7N5TDSQFlA0hAQGHvnDZgyypm1yunObVWcWiF9KM7eGCJKYKLgTC2Fi/57OdnBhbj4OkzPGdFQJ6HyA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "has-bigints": "^1.0.2" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-boolean-object": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", - "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "node_modules/@oxlint/binding-freebsd-x64": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.80.0.tgz", + "integrity": "sha512-AYUIk5QnL0s8oWAYsREZwkRYy1SupJTXALo93J1TgzHywxQtdM99FecRMQ87MXEdPQ0j1TmEpeeq3fGNkpvMqg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-builtin-module": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", - "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "node_modules/@oxlint/binding-linux-arm-gnueabihf": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.80.0.tgz", + "integrity": "sha512-9hBZVANupQ89W9dXyE0n8doCyaW5pDyGn3y6XlIMPZ+rIKuyqkr3SNUXmVJIhuvUq0NBU3RBiSXXE69l4XI6KA==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "builtin-modules": "^5.0.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-bun-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", - "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "node_modules/@oxlint/binding-linux-arm-musleabihf": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.80.0.tgz", + "integrity": "sha512-SvS2uKqzY+pbfuvAHzH4338R6Zwo805GAwrIMVvK1KxoOWCIjZUdfzTCvilD7z6JK91v011+zYMryabhDo2AsQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "semver": "^7.7.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/@oxlint/binding-linux-arm64-gnu": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.80.0.tgz", + "integrity": "sha512-tCLadyqRVL3pQTRPNg7cjXKvcvS4fbyXeQHhKk5BTJ1oftQln5/yIIWbu/Xom/DX41zv2P9QGt6+D/TtQVtY3A==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "peer": true, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "node_modules/@oxlint/binding-linux-arm64-musl": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.80.0.tgz", + "integrity": "sha512-XfpCNRlOPcLlJl4Bn/FUhjqlR6BVavEykERBf/MV7YA9VZDa5g5znVqYhyviMafcxS9Pe/i/kPvHNO0U6svEHQ==", + "cpu": [ + "arm64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-data-view": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", - "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "node_modules/@oxlint/binding-linux-ppc64-gnu": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.80.0.tgz", + "integrity": "sha512-3I4yMwcFG9NeO8ioY6JBBuKsIm5GL/x7MATt1S4tVWaxPu5HcJ+XnLUbcVBTxG8q2Wu56HSj+NmXQiVYb1lp6A==", + "cpu": [ + "ppc64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", - "is-typed-array": "^1.1.13" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-date-object": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", - "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "node_modules/@oxlint/binding-linux-riscv64-gnu": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.80.0.tgz", + "integrity": "sha512-E1wAKymkpe1/E8helzBKdm81OBOF+ezxRyXRMEuik3ZpWDER5CPOKZwF66RsdwW98uwZv8UTFremUQtC1CzdJA==", + "cpu": [ + "riscv64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-tostringtag": "^1.0.2" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-document.all": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", - "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "node_modules/@oxlint/binding-linux-riscv64-musl": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.80.0.tgz", + "integrity": "sha512-+gLRGD4sIo3+VA++iham5UxD9tKSoJ/VOrROCEXIcknrYtQg6iIQgvjN0cpiRF7N6UYC7pJbvHJlDnMge5LRpQ==", + "cpu": [ + "riscv64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.4" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/@oxlint/binding-linux-s390x-gnu": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.80.0.tgz", + "integrity": "sha512-aR0PrzHj9leW3NmzBAAP4EzdoBNoJcs9sjnIQPIwyRnBGYrRbXUIpEB5Q39AqK3PLY5JK5uEhDQDiUa1QSAstw==", + "cpu": [ + "s390x" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-finalizationregistry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", - "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "node_modules/@oxlint/binding-linux-x64-gnu": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.80.0.tgz", + "integrity": "sha512-vSVh5cSo3Xxs6ghBCcFJlpbkbENzDog1qXtoXLa/HC3aCrR4XO76GZbXmQoCPHnu99nQpdCeC3H9tdNICfDh7A==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "glibc" + ], "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/@oxlint/binding-linux-x64-musl": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.80.0.tgz", + "integrity": "sha512-FfzBXpNQ8u7/ZI/p8bl73MeZ508Ax3hxWp3SiJpEFiC+BB9XcXy5FAZHTLKDPSzrUpxQZSZJAVdDmuJp/+HDBQ==", + "cpu": [ + "x64" + ], "dev": true, + "libc": [ + "musl" + ], "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-generator-function": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", - "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "node_modules/@oxlint/binding-openharmony-arm64": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.80.0.tgz", + "integrity": "sha512-zMzbkumtmprCgRwoYNzcB3iC39fXdJIMLMU33KdCjEGLlJGOEt1+LwQ4LF8ndLzAEKVz4BR0y3V6Xrkk3Nm3yA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.4", - "generator-function": "^2.0.0", - "get-proto": "^1.0.1", - "has-tostringtag": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/@oxlint/binding-win32-arm64-msvc": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.80.0.tgz", + "integrity": "sha512-ib6iRcrXsk4t1fm3iKcwksyWh1ZkZXC/2mEzakl0ai2+6HZunf1WWMZ/xP9EJAvw9g9K4UVTC3NF/+G2qLrbTQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.10.0" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-identifier/-/is-identifier-1.1.0.tgz", - "integrity": "sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==", + "node_modules/@oxlint/binding-win32-ia32-msvc": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.80.0.tgz", + "integrity": "sha512-xhRWBMpLxZvgKAH6+DJZmpP+W8Y8UdQOSU1JfxSWNXsaBaRGW77j+1hCuNHlzj7OH4SPN8fYd1q0o2qrDtoVyw==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "identifier-regex": "^1.1.0", - "super-regex": "^1.1.0" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "node_modules/@oxlint/binding-win32-x64-msvc": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.80.0.tgz", + "integrity": "sha512-yAnO7lwBYQnz2pcfBPIGQQZWIX5zd5R/1aAKIF3oE+TVj7IhoHcROjOkz3sRDngzqhfPKfFaXqug5j5rE5dn6Q==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "peer": true, + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "node_modules/@plugjs/cov8": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@plugjs/cov8/-/cov8-0.7.5.tgz", + "integrity": "sha512-MD7bBJvrrZUtHfmxOqfqehGPAR/zmEh87yo82jyZFtbX2cf3Rz/bSv51Cefb6u9zmcNW2EullkExzfU8Z+B/zw==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", + "dependencies": { + "@babel/parser": "^8.0.4", + "@babel/types": "^8.0.4", + "@plugjs/cov8-html": "^0.2.7", + "@plugjs/tsrun": "^0.7.8", + "source-map": "^0.8.0" + }, + "bin": { + "cov8": "dist/cli.js" + }, "engines": { - "node": ">= 0.4" + "node": ">=22.16.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@plugjs/plug": "0.7.5" } }, - "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==", + "node_modules/@plugjs/cov8-html": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@plugjs/cov8-html/-/cov8-html-0.2.7.tgz", + "integrity": "sha512-kD4EKpIBrqSL1FrUED/C6WdQYbYDgOLmTiT20RchCnEQ3kOTBjM0iCnzugH8OpfJNrKWo+h/PlgXzQydmt2H+A==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } + "license": "Apache-2.0" }, - "node_modules/is-number-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", - "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "node_modules/@plugjs/expect5": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@plugjs/expect5/-/expect5-0.7.5.tgz", + "integrity": "sha512-kQgdkH0z+ENoVsmnRa7/s/tmMMtLeiAQnmpzuj36g9amtQD52DmRuHbqFvuqHWhZnSvgbkYhzaeYlT9ICO/lAQ==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" + "@plugjs/tsrun": "^0.7.8" + }, + "bin": { + "expect5": "dist/cli.js" }, "engines": { - "node": ">= 0.4" + "node": ">=22.16.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@plugjs/plug": "0.7.5" } }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "node_modules/@plugjs/oxc": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@plugjs/oxc/-/oxc-0.1.7.tgz", + "integrity": "sha512-SlC1uSQvpvMpiAyu2hcXldAvYC7KHanQ5Y8/jKcrqZaPzl/QCP8ugPYMvaRrT8w79mYJB5xeJnkdQ9rgbsnzMA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "license": "Apache-2.0", + "dependencies": { + "oxfmt": "^0.65.0", + "oxlint": "^1.80.0", + "oxlint-tsgolint": "^7.0.2001" + }, + "peerDependencies": { + "@plugjs/plug": "^0.7.5" } }, - "node_modules/is-regex": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", - "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "node_modules/@plugjs/plug": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@plugjs/plug/-/plug-0.7.5.tgz", + "integrity": "sha512-KW3oGtSHWQynRmz1GtKSYldeutOYBSyaAKNznZJR7TxUnjP7vP/dHmFDL1WUK+KeAM/Uc+ZP0Os/eu7sydUSEw==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", "dependencies": { - "call-bound": "^1.0.2", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "@plugjs/tsrun": "^0.7.8", + "@types/node": "<23", + "esbuild": "^0.28.2", + "jsonc-parser": "^3.3.1", + "picomatch": "^4.0.7" }, - "engines": { - "node": ">= 0.4" + "bin": { + "plug": "dist/cli.js" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "dev": true, - "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=22.16.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", - "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "node_modules/@plugjs/tsd": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@plugjs/tsd/-/tsd-0.7.5.tgz", + "integrity": "sha512-x+JwnYTthLWX0v62PcyebaVpsEWFcZv7bHT4taIuButIIdQ5FiAk2IKnpoFLZGnDXDyWoDQROMJyJXAZQFc7CQ==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", "dependencies": { - "call-bound": "^1.0.3" + "tsd": "^0.33.0" }, "engines": { - "node": ">= 0.4" + "node": ">=22.16.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@plugjs/plug": "0.7.5" } }, - "node_modules/is-string": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", - "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "node_modules/@plugjs/tsgo": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@plugjs/tsgo/-/tsgo-0.0.3.tgz", + "integrity": "sha512-QB/55P79cfUIxsSDbO7c25TpWYGIBkF4dTK2OZocuqw0JnvkFH30vBV288oh3XSJbss1HA2XpgbeJLxqkmkqWg==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", "dependencies": { - "call-bound": "^1.0.3", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "typescript": "^7.1.0-dev" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@plugjs/plug": "^0.7.5" } }, - "node_modules/is-symbol": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", - "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "node_modules/@plugjs/tsgo/node_modules/typescript": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-13Vi1I0Ka8BAYZzKC8z/H6j3i0if6HGecfDmOyBhKqpmG1E4hQpU62yrGgNdgRW/coz91NvqqAM39H3rN/VpxA==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "has-symbols": "^1.1.0", - "safe-regex-test": "^1.1.0" + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" }, "engines": { - "node": ">= 0.4" + "node": ">=16.20.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optionalDependencies": { + "@typescript/typescript-darwin-arm64": "7.1.0-dev.20260828.1", + "@typescript/typescript-darwin-x64": "7.1.0-dev.20260828.1", + "@typescript/typescript-linux-arm": "7.1.0-dev.20260828.1", + "@typescript/typescript-linux-arm64": "7.1.0-dev.20260828.1", + "@typescript/typescript-linux-x64": "7.1.0-dev.20260828.1", + "@typescript/typescript-win32-arm64": "7.1.0-dev.20260828.1", + "@typescript/typescript-win32-x64": "7.1.0-dev.20260828.1" } }, - "node_modules/is-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "node_modules/@plugjs/tsrun": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@plugjs/tsrun/-/tsrun-0.7.8.tgz", + "integrity": "sha512-yk9axM/05tKBgLP9Yy6dp+xbPWeV8X6LRWweRuOsVEx7AEHyoFrvg+pT6/pKNtEl8VdR/Uy7trlQF58jtJXv2Q==", "dev": true, - "license": "MIT", - "peer": true, + "license": "Apache-2.0", "dependencies": { - "which-typed-array": "^1.1.16" + "esbuild": "^0.28.2" }, - "engines": { - "node": ">= 0.4" + "bin": { + "tsrun": "dist/tsrun.mjs" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=22.0.0" } }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "node_modules/@sinclair/typebox": { + "version": "0.27.12", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.12.tgz", + "integrity": "sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "license": "MIT" }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "node_modules/@tsd/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-JSSdNiS0wgd8GHhBwnMAI18Y8XPhLVN+dNelPfZCXFhy9Lb3NbnFyp9JKxxr54jSUkEJPk3cidvCoHducSaRMQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=14.17" } }, - "node_modules/is-weakref": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", - "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "node_modules/@types/eslint": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz", + "integrity": "sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "call-bound": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@types/estree": "*", + "@types/json-schema": "*" } }, - "node_modules/is-weakset": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", - "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.20.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.1.tgz", + "integrity": "sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "call-bound": "^1.0.3", - "get-intrinsic": "^1.2.6" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "undici-types": "~6.21.0" } }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-6vdBDrQeChwFudD7+8YXLjfGT4WR5XN85BqZaLaNwRQQghiV+eY8qQUu8lqFKMurnysw5Des/2i+GnFz7Aaw2w==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "peer": true + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } }, - "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==", + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-paJc5Io0pT22lVTNfMhR9DrwAQAZJ2AuHQiMgqnaQuryk7Wk5rRsYZllCNynltXtTdAEdciWFjP4wBMdkrnzwg==", + "cpu": [ + "x64" + ], "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" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=16.20.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==", + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-HIJZZWEqy9rw+aNwqb5J0HoPwi7ljHe3ofteWbLoat1EnRAUonuqFad4MLxkmGEaQjAtApvxuBDU7NvMoCnNuw==", + "cpu": [ + "arm" + ], "dev": true, - "license": "MIT", + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=16.20.0" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-em/FC+QMz55RI4hV4sqWR20pzOkSpJMlyNoHUgPtvnZTTjPPrI4ljZMchCbUDOgV+Lv4YfO8IlUIT6IpXRknuw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-Bcp+KkaEQnYXLEvHaFTFxp1XfL+Fpmr2iIrstjnuwiw+P1iEZKVbicFPgjz7gQmxJ4f4r7ZopB7jgHqmg0WFcg==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "jsesc": "bin/jsesc" - }, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=16.20.0" } }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-aPs+oBDkbSjzzfj6H+fzPLF1uDv0FHn3ZLm1pydGtBR/481SRk0Z0pE3ecqSQHq3SoxFp2J35czBoGH4Wpncbw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT", - "peer": true + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.1.0-dev.20260828.1", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.1.0-dev.20260828.1.tgz", + "integrity": "sha512-hHf6eJwrjZQEd5g84OWgUjcl1mfSPFVzXaklDrco8/NAO4cjXjoWjYy1+XDtL8nztykuq61DL60mpJRfDGwNcw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT" + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "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", - "peer": true + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "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", - "peer": true + "engines": { + "node": ">=8" + } }, - "node_modules/jsonc-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", - "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "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", - "peer": true + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "json-buffer": "3.0.1" + "engines": { + "node": ">=8" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "fill-range": "^7.1.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "p-locate": "^5.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "color-name": "~1.1.4" }, "engines": { - "node": ">=10" + "node": ">=7.0.0" } }, - "node_modules/make-asynchronous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/make-asynchronous/-/make-asynchronous-1.1.0.tgz", - "integrity": "sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "p-event": "^6.0.0", - "type-fest": "^4.6.0", - "web-worker": "^1.5.0" + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" }, "engines": { - "node": ">=18" + "node": ">=0.10.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "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==", + "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, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/mdn-data": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.29.0.tgz", - "integrity": "sha512-pVxQFCcaYUEAH853+v7yoI/qzhxXSq1bTb9obMYGYAN1c3Hen+XDCEvr296XhstrwlSTNgOR7mCSD4JPjbJe5A==", + "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": "CC0-1.0", - "peer": true + "license": "MIT" }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "is-arrayish": "^0.2.1" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=10" + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" } }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "node_modules/eslint-formatter-pretty": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-4.1.0.tgz", + "integrity": "sha512-IsUTtGxF1hrH6lMWiSl1WbGaiP01eT6kzywdY1U+zLc0MP+nwEnUiS9UI8IaOTUhTeQJLlCEWIbXINBH4YJbBQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", + "dependencies": { + "@types/eslint": "^7.2.13", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.0", + "eslint-rule-docs": "^1.1.5", + "log-symbols": "^4.0.0", + "plur": "^4.0.0", + "string-width": "^4.2.0", + "supports-hyperlinks": "^2.0.0" + }, "engines": { "node": ">=10" }, @@ -4631,271 +1992,202 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/eslint-rule-docs": { + "version": "1.1.235", + "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz", + "integrity": "sha512-+TQ+x4JdTnDoFEXXb3fDvfGOwnyNV7duH8fXWTPD1ieaBmB8omj7Gw/pMBBu4uI2uJCCU8APDaQJzWuXnTsH4A==", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } + "license": "MIT" }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">=8.6" + "node": ">=8.6.0" } }, - "node_modules/micromatch/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==", + "node_modules/fastq": { + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.2.tgz", + "integrity": "sha512-UpGiiODyCGprM8EPP6JodP6jC9Rws6TCuiDOD+nn0CJhR8guI3g/ozo4ugL0vJ+Yz1UtJuuRPqvQuybVOF1VQA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "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", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", - "dev": true, - "license": "BlueOak-1.0.0", - "peer": true, "dependencies": { - "brace-expansion": "^5.0.8" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">=8" } }, - "node_modules/minimist-options": { + "node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "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==", + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true, "license": "MIT", - "peer": true + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "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==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "napi-postinstall": "lib/cli.js" + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" }, "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" + "node": ">= 6" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/node-exports-info": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", - "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "array.prototype.flatmap": "^1.3.3", - "es-errors": "^1.3.0", - "object.entries": "^1.1.9", - "semver": "^6.3.1" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-exports-info/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/node-releases": { - "version": "2.0.54", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", - "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=18" + "node": ">=8" } }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/hasown": { + "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==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">= 0.4" + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.4" + "node": ">= 4" } }, - "node_modules/object.assign": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", - "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0", - "has-symbols": "^1.1.0", - "object-keys": "^1.1.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/object.entries": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", - "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "node_modules/irregular-plurals": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-3.5.0.tgz", + "integrity": "sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } + "license": "MIT" }, - "node_modules/own-keys": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.2.tgz", - "integrity": "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==", + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", - "object-keys": "^1.1.1", - "safe-push-apply": "^1.0.0" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -4904,167 +2196,158 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/p-event": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-6.0.1.tgz", - "integrity": "sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "p-timeout": "^6.1.2" - }, "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "p-limit": "^3.0.2" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/p-timeout": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", - "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "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", - "peer": true, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.12.0" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "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==", "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" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "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", - "peer": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "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/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, - "license": "ISC" + "license": "MIT" }, - "node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" + "dependencies": { + "p-locate": "^4.1.0" }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "engines": { + "node": ">=8" } }, - "node_modules/plur": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", - "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", "dependencies": { - "irregular-plurals": "^3.2.0" + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" }, "engines": { "node": ">=10" @@ -5073,192 +2356,270 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pluralize": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, - "license": "MIT", - "peer": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">= 0.8.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true, - "license": "MIT", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", - "peer": true, "engines": { - "node": ">=6" + "node": ">= 8" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, - "node_modules/quote-js-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/quote-js-string/-/quote-js-string-0.1.0.tgz", - "integrity": "sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==", + "node_modules/micromatch/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", - "peer": true, "engines": { - "node": ">=22" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sindresorhus/quote-js-string?sponsor=1" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/oxfmt": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.65.0.tgz", + "integrity": "sha512-SgS5VgnP42T0zl3zWD+xoH8FCqg1SAFnSRoOT/qeoa6gxcYIqrDMOmcXIg/EWSN92Du4ogB4riuKhKd6Y4CGhw==", "dev": true, "license": "MIT", "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "tinypool": "2.1.0" + }, + "bin": { + "oxfmt": "bin/oxfmt" }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxfmt/binding-android-arm-eabi": "0.65.0", + "@oxfmt/binding-android-arm64": "0.65.0", + "@oxfmt/binding-darwin-arm64": "0.65.0", + "@oxfmt/binding-darwin-x64": "0.65.0", + "@oxfmt/binding-freebsd-x64": "0.65.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.65.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.65.0", + "@oxfmt/binding-linux-arm64-gnu": "0.65.0", + "@oxfmt/binding-linux-arm64-musl": "0.65.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.65.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.65.0", + "@oxfmt/binding-linux-riscv64-musl": "0.65.0", + "@oxfmt/binding-linux-s390x-gnu": "0.65.0", + "@oxfmt/binding-linux-x64-gnu": "0.65.0", + "@oxfmt/binding-linux-x64-musl": "0.65.0", + "@oxfmt/binding-openharmony-arm64": "0.65.0", + "@oxfmt/binding-win32-arm64-msvc": "0.65.0", + "@oxfmt/binding-win32-ia32-msvc": "0.65.0", + "@oxfmt/binding-win32-x64-msvc": "0.65.0" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + }, + "vite-plus": { + "optional": true + } } }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/oxlint": { + "version": "1.80.0", + "resolved": "https://registry.npmjs.org/oxlint/-/oxlint-1.80.0.tgz", + "integrity": "sha512-5nTiSps4qdbCWLbxzuO00alHkEO2exR9YMN/ig6QXWrLsYSG0KaObOAM+l6oU2LcKPWoSAGYbkZIGEu1ViiWKA==", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "bin": { + "oxlint": "bin/oxlint" }, "engines": { - "node": ">=8" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxlint/binding-android-arm-eabi": "1.80.0", + "@oxlint/binding-android-arm64": "1.80.0", + "@oxlint/binding-darwin-arm64": "1.80.0", + "@oxlint/binding-darwin-x64": "1.80.0", + "@oxlint/binding-freebsd-x64": "1.80.0", + "@oxlint/binding-linux-arm-gnueabihf": "1.80.0", + "@oxlint/binding-linux-arm-musleabihf": "1.80.0", + "@oxlint/binding-linux-arm64-gnu": "1.80.0", + "@oxlint/binding-linux-arm64-musl": "1.80.0", + "@oxlint/binding-linux-ppc64-gnu": "1.80.0", + "@oxlint/binding-linux-riscv64-gnu": "1.80.0", + "@oxlint/binding-linux-riscv64-musl": "1.80.0", + "@oxlint/binding-linux-s390x-gnu": "1.80.0", + "@oxlint/binding-linux-x64-gnu": "1.80.0", + "@oxlint/binding-linux-x64-musl": "1.80.0", + "@oxlint/binding-openharmony-arm64": "1.80.0", + "@oxlint/binding-win32-arm64-msvc": "1.80.0", + "@oxlint/binding-win32-ia32-msvc": "1.80.0", + "@oxlint/binding-win32-x64-msvc": "1.80.0" + }, + "peerDependencies": { + "oxlint-tsgolint": ">=7.0.2001", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "oxlint-tsgolint": { + "optional": true + }, + "vite-plus": { + "optional": true + } } }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/oxlint-tsgolint": { + "version": "7.0.2001", + "resolved": "https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-7.0.2001.tgz", + "integrity": "sha512-KjK/XLcXr1DSyonKhsuFqJRiuKqcyG9j3LJ8nkOsrLzGvodBPqzHOKauy10asLMDI0sUpvb+1sxlzff3udZvfg==", "dev": true, "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" + "bin": { + "tsgolint": "bin/tsgolint.js" }, - "engines": { - "node": ">=8" + "optionalDependencies": { + "@oxlint-tsgolint/darwin-arm64": "7.0.2001", + "@oxlint-tsgolint/darwin-x64": "7.0.2001", + "@oxlint-tsgolint/linux-arm64": "7.0.2001", + "@oxlint-tsgolint/linux-x64": "7.0.2001", + "@oxlint-tsgolint/win32-arm64": "7.0.2001", + "@oxlint-tsgolint/win32-x64": "7.0.2001" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { + "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", @@ -5274,7 +2635,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/p-locate": { + "node_modules/p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", @@ -5287,240 +2648,130 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "node": ">=6" } }, - "node_modules/read-pkg/node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "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==", "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "MIT" }, - "node_modules/redent/node_modules/indent-string": { + "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/redent/node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } + "license": "ISC" }, - "node_modules/reflect.getprototypeof": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.9", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.7", - "get-proto": "^1.0.1", - "which-builtin-type": "^1.2.1" - }, "engines": { - "node": ">= 0.4" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", - "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "node_modules/plur": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/plur/-/plur-4.0.0.tgz", + "integrity": "sha512-4UGewrYgqDFw9vV6zNV+ADmPAUAfJPKtGvb/VdpQAx25X5f3xXdGdyOEVFwkl8Hl/tl7+xbeHqSEM+D5/TirUg==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regjsparser": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.2.tgz", - "integrity": "sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, "dependencies": { - "jsesc": "~3.1.0" + "irregular-plurals": "^3.2.0" }, - "bin": { - "regjsparser": "bin/parser" - } - }, - "node_modules/reserved-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/reserved-identifiers/-/reserved-identifiers-1.2.0.tgz", - "integrity": "sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==", - "dev": true, - "license": "MIT", - "peer": true, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/resolve": { - "version": "2.0.0-next.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", - "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "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==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.2", - "node-exports-info": "^1.6.0", - "object-keys": "^1.1.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "peer": true, - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "license": "MIT", "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -5536,172 +2787,137 @@ "url": "https://feross.org/support" } ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } + "license": "MIT" }, - "node_modules/safe-array-concat": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", - "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "get-intrinsic": "^1.3.0", - "has-symbols": "^1.1.0", - "isarray": "^2.0.5" - }, "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/safe-push-apply": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", - "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "es-errors": "^1.3.0", - "isarray": "^2.0.5" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/safe-regex-test": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", - "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "is-regex": "^1.2.1" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } + "license": "ISC" }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, - "license": "MIT", - "peer": true, + "license": "BSD-2-Clause", "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/set-proto": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", - "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "dunder-proto": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, - "node_modules/shebang-regex": { + "node_modules/redent": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "license": "MIT", - "peer": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", - "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.4", - "side-channel-list": "^1.0.1", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "engines": { "node": ">= 0.4" @@ -5710,63 +2926,52 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/side-channel-list": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", - "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.4" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "license": "MIT", - "peer": true, "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "queue-microtask": "^1.2.2" } }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=10" } }, "node_modules/slash": { @@ -5785,22 +2990,10 @@ "integrity": "sha512-d8EqvL+k/SOXCreS/SUzg2ciyHqBBLcN/yuRjFsbvVhHTE2pgei7oAhmPM7kWFbkX6OSMQfUq4KbkF3au9lhYQ==", "dev": true, "license": "BSD-3-Clause", - "peer": true, "engines": { "node": ">= 12" } }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/spdx-correct": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", @@ -5834,111 +3027,22 @@ "version": "3.0.23", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/stable-hash-x": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", - "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/stop-iteration-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", - "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "es-errors": "^1.3.0", - "internal-slot": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", - "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "define-data-property": "^1.1.4", - "define-properties": "^1.2.1", - "es-abstract": "^1.24.2", - "es-object-atoms": "^1.1.2", - "has-property-descriptors": "^1.0.2", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", - "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "dev": true, + "license": "CC0-1.0" }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "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", - "peer": true, "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, "node_modules/strip-ansi": { @@ -5955,36 +3059,16 @@ } }, "node_modules/strip-indent": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", - "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/super-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-1.1.0.tgz", - "integrity": "sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "function-timeout": "^1.0.1", - "make-asynchronous": "^1.0.1", - "time-span": "^5.1.0" + "min-indent": "^1.0.0" }, "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/supports-color": { @@ -6027,39 +3111,14 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/time-span": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", - "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "convert-hrtime": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "node_modules/tinypool": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", + "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", "dev": true, "license": "MIT", - "peer": true, - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" + "node": "^20.0.0 || >=22.0.0" } }, "node_modules/to-regex-range": { @@ -6085,20 +3144,6 @@ "node": ">=8" } }, - "node_modules/ts-api-utils": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", - "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, "node_modules/tsd": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.33.0.tgz", @@ -6121,129 +3166,23 @@ "node": ">=14.16" } }, - "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, - "peer": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", - "peer": true, "engines": { - "node": ">=16" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", - "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", - "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", - "for-each": "^0.3.3", - "gopd": "^1.2.0", - "has-proto": "^1.2.0", - "is-typed-array": "^1.1.15", - "reflect.getprototypeof": "^1.0.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", - "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bind": "^1.0.9", - "for-each": "^0.3.5", - "gopd": "^1.2.0", - "is-typed-array": "^1.1.15", - "possible-typed-array-names": "^1.1.0", - "reflect.getprototypeof": "^1.0.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6254,140 +3193,12 @@ "node": ">=14.17" } }, - "node_modules/typescript-eslint": { - "version": "8.68.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.68.0.tgz", - "integrity": "sha512-MHy0Y0ynqeEbx/S45+i/bBssdy3X6KNBfmJAP35GrgtNxu2TQ5K5xsFDhAnmsq1jvpdoZOPG1LGtJo0HWqYCrQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.68.0", - "@typescript-eslint/parser": "8.68.0", - "@typescript-eslint/typescript-estree": "8.68.0", - "@typescript-eslint/utils": "8.68.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", - "typescript": ">=4.8.4 <6.1.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", - "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.3", - "has-bigints": "^1.0.2", - "has-symbols": "^1.1.0", - "which-boxed-primitive": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, - "license": "MIT", - "peer": true - }, - "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", - "peer": true, - "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.3.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", - "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "peer": true, - "dependencies": { - "punycode": "^2.1.0" - } + "license": "MIT" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -6400,135 +3211,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/web-worker": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", - "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", - "dev": true, - "license": "Apache-2.0", - "peer": true - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "peer": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", - "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-bigint": "^1.1.0", - "is-boolean-object": "^1.2.1", - "is-number-object": "^1.1.1", - "is-string": "^1.1.1", - "is-symbol": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-builtin-type": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", - "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "call-bound": "^1.0.2", - "function.prototype.name": "^1.1.6", - "has-tostringtag": "^1.0.2", - "is-async-function": "^2.0.0", - "is-date-object": "^1.1.0", - "is-finalizationregistry": "^1.1.0", - "is-generator-function": "^1.0.10", - "is-regex": "^1.2.1", - "is-weakref": "^1.0.2", - "isarray": "^2.0.5", - "which-boxed-primitive": "^1.1.0", - "which-collection": "^1.0.2", - "which-typed-array": "^1.1.16" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.22", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", - "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.9", - "call-bound": "^1.0.4", - "for-each": "^0.3.5", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", @@ -6536,23 +3218,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", - "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", - "dev": true, - "license": "ISC", - "peer": true, - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yargs-parser": { "version": "20.2.9", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", @@ -6562,20 +3227,6 @@ "engines": { "node": ">=10" } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index 3cf9157..2def553 100644 --- a/package.json +++ b/package.json @@ -1,116 +1,76 @@ { "name": "justus", - "version": "0.5.145", + "version": "0.6.0", "description": "A JavaScript validation library, with types!", - "main": "./dist/index.cjs", - "module": "./dist/index.mjs", + "keywords": [ + "javascript", + "typescript", + "validation" + ], + "homepage": "https://github.com/juitnow/justus#readme", + "bugs": { + "url": "https://github.com/juitnow/justus/issues" + }, + "license": "Apache-2.0", + "author": "Juit Developers ", + "repository": { + "type": "git", + "url": "git+ssh://git@github.com/juitnow/justus.git" + }, + "directories": { + "test": "test" + }, + "files": [ + "*.md", + "dist/", + "src/" + ], + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", "exports": { ".": { - "require": { - "types": "./dist/index.d.ts", - "default": "./dist/index.cjs" - }, - "import": { - "types": "./dist/index.d.ts", - "default": "./dist/index.mjs" - } + "types": "./dist/index.d.ts", + "default": "./dist/index.js" }, "./dts-generator": { - "require": { - "types": "./dist/dts-generator.d.ts", - "default": "./dist/dts-generator.cjs" - }, - "import": { - "types": "./dist/dts-generator.d.ts", - "default": "./dist/dts-generator.mjs" - } + "types": "./dist/dts-generator.d.ts", + "default": "./dist/dts-generator.js" }, "./extra/arn": { - "require": { - "types": "./dist/extra/arn.d.ts", - "default": "./dist/extra/arn.cjs" - }, - "import": { - "types": "./dist/extra/arn.d.ts", - "default": "./dist/extra/arn.mjs" - } + "types": "./dist/extra/arn.d.ts", + "default": "./dist/extra/arn.js" }, "./extra/ean13": { - "require": { - "types": "./dist/extra/ean13.d.ts", - "default": "./dist/extra/ean13.cjs" - }, - "import": { - "types": "./dist/extra/ean13.d.ts", - "default": "./dist/extra/ean13.mjs" - } + "types": "./dist/extra/ean13.d.ts", + "default": "./dist/extra/ean13.js" }, "./extra/email": { - "require": { - "types": "./dist/extra/email.d.ts", - "default": "./dist/extra/email.cjs" - }, - "import": { - "types": "./dist/extra/email.d.ts", - "default": "./dist/extra/email.mjs" - } + "types": "./dist/extra/email.d.ts", + "default": "./dist/extra/email.js" }, "./extra/url": { - "require": { - "types": "./dist/extra/url.d.ts", - "default": "./dist/extra/url.cjs" - }, - "import": { - "types": "./dist/extra/url.d.ts", - "default": "./dist/extra/url.mjs" - } + "types": "./dist/extra/url.d.ts", + "default": "./dist/extra/url.js" }, "./extra/uuid": { - "require": { - "types": "./dist/extra/uuid.d.ts", - "default": "./dist/extra/uuid.cjs" - }, - "import": { - "types": "./dist/extra/uuid.d.ts", - "default": "./dist/extra/uuid.mjs" - } + "types": "./dist/extra/uuid.d.ts", + "default": "./dist/extra/uuid.js" } }, - "types": "./dist/index.d.ts", "scripts": { "build": "plug", - "coverage": "plug coverage", - "dev": "plug coverage -w src -w test", + "dev": "plug -w src -w test -w test-d", "lint": "plug lint", - "test": "plug test", - "transpile": "plug transpile" + "lintfix": "plug lint fix=true" }, - "author": "Juit Developers ", - "license": "Apache-2.0", "devDependencies": { - "@plugjs/build": "^0.7.4", + "@plugjs/cov8": "^0.7.5", + "@plugjs/expect5": "^0.7.5", + "@plugjs/oxc": "^0.1.7", + "@plugjs/plug": "^0.7.5", "@plugjs/tsd": "^0.7.5", - "typescript": "<6" - }, - "directories": { - "test": "test" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/juitnow/justus.git" - }, - "keywords": [ - "validation", - "typescript", - "javascript" - ], - "bugs": { - "url": "https://github.com/juitnow/justus/issues" - }, - "homepage": "https://github.com/juitnow/justus#readme", - "files": [ - "*.md", - "dist/", - "src/" - ] + "@plugjs/tsgo": "^0.0.3", + "typescript": "<7" + } } diff --git a/src/dts-generator.ts b/src/dts-generator.ts index ef59593..ea6b63d 100644 --- a/src/dts-generator.ts +++ b/src/dts-generator.ts @@ -1,33 +1,43 @@ /* eslint-disable @typescript-eslint/no-unsafe-function-type */ import ts from 'typescript' -import { assertSchema } from './errors' -import { EAN13Validator, ean13 } from './extra/ean13' -import { EmailValidator } from './extra/email' -import { URLValidator, url } from './extra/url' -import { UUIDValidator, uuid } from './extra/uuid' -import { getValidator } from './utilities' -import { AnyValidator, any } from './validators/any' -import { AnyArrayValidator, ArrayValidator, array } from './validators/array' -import { AnyBigIntValidator, BigIntValidator, bigint } from './validators/bigint' -import { BooleanValidator, boolean } from './validators/boolean' -import { ConstantValidator } from './validators/constant' -import { DateValidator, date } from './validators/date' -import { NeverValidator, never } from './validators/never' -import { AnyNumberValidator, NumberValidator, number } from './validators/number' -import { AnyObjectValidator, ObjectValidator, object } from './validators/object' -import { OptionalValidator } from './validators/optional' -import { AnyStringValidator, StringValidator, string } from './validators/string' -import { TupleValidator } from './validators/tuple' -import { AllOfValidator, OneOfValidator } from './validators/union' - +import { assertSchema } from './errors.ts' +import { EAN13Validator, ean13 } from './extra/ean13.ts' +import { EmailValidator } from './extra/email.ts' +import { URLValidator, url } from './extra/url.ts' +import { UUIDValidator, uuid } from './extra/uuid.ts' +import { getValidator } from './utilities.ts' +import { AnyValidator, any } from './validators/any.ts' +import { AnyArrayValidator, ArrayValidator, array } from './validators/array.ts' +import { AnyBigIntValidator, BigIntValidator, bigint } from './validators/bigint.ts' +import { BooleanValidator, boolean } from './validators/boolean.ts' +import { ConstantValidator } from './validators/constant.ts' +import { DateValidator, date } from './validators/date.ts' +import { NeverValidator, never } from './validators/never.ts' +import { AnyNumberValidator, NumberValidator, number } from './validators/number.ts' +import { AnyObjectValidator, ObjectValidator, object } from './validators/object.ts' +import { OptionalValidator } from './validators/optional.ts' +import { AnyStringValidator, StringValidator, string } from './validators/string.ts' +import { TupleValidator } from './validators/tuple.ts' +import { AllOfValidator, OneOfValidator } from './validators/union.ts' + +import type { Validation, Validator } from './types.ts' import type { TypeNode } from 'typescript' -import type { Validation, Validator } from './types' /* Our "main" validators */ const coreValidators = new Set([ - any, array, bigint, boolean, date, ean13, - never, number, object, string, url, uuid, + any, + array, + bigint, + boolean, + date, + ean13, + never, + number, + object, + string, + url, + uuid, ]) /* ========================================================================== * @@ -37,14 +47,13 @@ const coreValidators = new Set([ /** Check that two of our generated types are equal */ function typeEqual(a: TypeNode, b: TypeNode): boolean { function eq(a: any, b: any): boolean { - if ((typeof a === 'object' && a != null) && - (typeof b === 'object' && b != null) ) { + if (typeof a === 'object' && a != null && typeof b === 'object' && b != null) { for (const key in a) { - if (! eq(a[key], b[key])) return false + if (!eq(a[key], b[key])) return false } for (const key in b) { /* coverage ignore if */ - if (! eq(a[key], b[key])) return false + if (!eq(a[key], b[key])) return false } return true } else { @@ -67,7 +76,8 @@ type TypeGenerator = ( ) => ts.TypeNode /** The generic constructor of a `Validator` instance. */ -type ValidatorConstructor = { // = { +type ValidatorConstructor = { + // = { new (...args: any[]): V } @@ -80,8 +90,8 @@ const generators = new Map>() /** Register a `TypeGenerator` function for a `Validator`. */ export function registerTypeGenerator( - validator: V | ValidatorConstructor, - generator: TypeGenerator, + validator: V | ValidatorConstructor, + generator: TypeGenerator, ): void { generators.set(validator, generator) } @@ -96,20 +106,17 @@ export function registerTypeGenerator( * When `isInput` is `true` then the _input_ type will be generated (that is, * optional fields will be considered as optional). */ -export function generateTypes( - validations: Record, - isInput: boolean = false, -): string { +export function generateTypes(validations: Record, isInput: boolean = false): string { /* Mapping from names to validators */ const validators = new Map() /* Reverse mapping of first validator to their exported name */ const references = new Map() /* Convert all our input validations into proper validators we can examine */ - for (const [ name, validation ] of Object.entries(validations)) { + for (const [name, validation] of Object.entries(validations)) { const validator = getValidator(validation) validators.set(name, validator) - if ((! references.has(validator)) && (! coreValidators.has(validator))) { + if (!references.has(validator) && !coreValidators.has(validator)) { references.set(validator, name) } } @@ -119,16 +126,19 @@ export function generateTypes( /* Then convert all our `TypeNode`s into alias declarations */ const aliases: ts.TypeAliasDeclaration[] = [] - for (const [ name, type ] of types.entries()) { + for (const [name, type] of types.entries()) { const alias = ts.factory.createTypeAliasDeclaration(exportModifiers, name, [], type) aliases.push(alias) } /* And finally print out all our type aliases */ - return ts.createPrinter().printList( + return ts + .createPrinter() + .printList( ts.ListFormat.SourceFileStatements, ts.factory.createNodeArray(aliases), - ts.createSourceFile('types.d.ts', '', ts.ScriptTarget.Latest)) + ts.createSourceFile('types.d.ts', '', ts.ScriptTarget.Latest), + ) } /** @@ -138,7 +148,7 @@ export function generateTypes( * declaration of the validator itself. For example: * * ```ts - * const testValidator = object({ test: optional(string, 'myValue' ) }) + * const testValidator = object({ test: optional(string, 'myValue') }) * generateDeclarations({ testValidator }) * ``` * @@ -152,7 +162,7 @@ export function generateTypes( */ export function generateDeclarations(validations: Record): string { /* Array of names: the exported constant, the input type, and the validated output type */ - const names: { name: string, output: string, input: string }[] = [] + const names: { name: string; output: string; input: string }[] = [] /* Map of all validators for validated output type generation, and name references */ const outputValidators = new Map() const outputReferences = new Map() @@ -161,11 +171,9 @@ export function generateDeclarations(validations: Record): s const inputReferences = new Map() /* Go through _all_ validations one by one and prepare names and validators */ - for (const [ name, validation ] of Object.entries(validations)) { + for (const [name, validation] of Object.entries(validations)) { /* Prep the name prefix for input and output types */ - const prefix = /validator$/i.test(name) ? name.slice(0, -9) : - /validation$/i.test(name) ? name.slice(0, -10) : - name + const prefix = /validator$/i.test(name) ? name.slice(0, -9) : /validation$/i.test(name) ? name.slice(0, -10) : name /* Output and input name */ const output = `${prefix.slice(0, 1).toUpperCase()}${prefix.slice(1)}` const input = `${prefix.slice(0, 1).toUpperCase()}${prefix.slice(1)}Input` @@ -176,8 +184,8 @@ export function generateDeclarations(validations: Record): s names.push({ name, output, input }) outputValidators.set(output, validator) inputValidators.set(input, validator) - if (! outputReferences.has(validator)) outputReferences.set(validator, output) - if (! inputReferences.has(validator)) inputReferences.set(validator, input) + if (!outputReferences.has(validator)) outputReferences.set(validator, output) + if (!inputReferences.has(validator)) inputReferences.set(validator, input) } /* Generate all output and input types */ @@ -192,11 +200,11 @@ export function generateDeclarations(validations: Record): s /* Get output and input types, asserting their existance */ const outputType = outputTypes.get(output) const inputType = inputTypes.get(input) - const validation = validations[name] + const validation = validations[name]! const validator = outputValidators.get(output) - assertSchema(!! outputType, `No output type "${output}" generated for validation "${name}"`) - assertSchema(!! inputType, `No input type "${input}" generated for validation "${name}"`) - assertSchema(!! validator, `No validator for "${name}"`) + assertSchema(!!outputType, `No output type "${output}" generated for validation "${name}"`) + assertSchema(!!inputType, `No input type "${input}" generated for validation "${name}"`) + assertSchema(!!validator, `No validator for "${name}"`) /* Check if input and output types are equal */ const sameType = typeEqual(inputType, outputType) @@ -212,63 +220,69 @@ export function generateDeclarations(validations: Record): s const inputDeclaration = ts.factory.createTypeAliasDeclaration(exportModifiers, input, [], inputAlias) /* Variable declaration type */ - const variableDeclarationType = generateVariableDeclarationType(validation, validator, outputReferences, inputReferences) + const variableDeclarationType = generateVariableDeclarationType( + validation, + validator, + outputReferences, + inputReferences, + ) /* Variable statement: export const myTypeValidator = ... */ - const variableDeclaration = - ts.factory.createVariableStatement( - exportModifiers, // "export" - ts.factory.createVariableDeclarationList([ - ts.factory.createVariableDeclaration( - name, // ..................................... "myTypeValidator" - undefined, // no exclamation token - variableDeclarationType, - ), - ], ts.NodeFlags.Const), // ......................... "const" - ) + const variableDeclaration = ts.factory.createVariableStatement( + exportModifiers, // "export" + ts.factory.createVariableDeclarationList( + [ + ts.factory.createVariableDeclaration( + name, // ..................................... "myTypeValidator" + undefined, // no exclamation token + variableDeclarationType, + ), + ], + ts.NodeFlags.Const, + ), // ......................... "const" + ) /* Comments for the generated nodes */ ts.addSyntheticLeadingComment( - outputDeclaration, - ts.SyntaxKind.MultiLineCommentTrivia, - ` ${`----- ${name} `.padEnd(74, '-')} `, - true, // newline + outputDeclaration, + ts.SyntaxKind.MultiLineCommentTrivia, + ` ${`----- ${name} `.padEnd(74, '-')} `, + true, // newline ) ts.addSyntheticLeadingComment( - outputDeclaration, - ts.SyntaxKind.MultiLineCommentTrivia, - `* Validated type for {@link ${name}} `, - true, // newline + outputDeclaration, + ts.SyntaxKind.MultiLineCommentTrivia, + `* Validated type for {@link ${name}} `, + true, // newline ) ts.addSyntheticLeadingComment( - inputDeclaration, - ts.SyntaxKind.MultiLineCommentTrivia, - `* Input type for {@link ${name}} `, - true, // newline + inputDeclaration, + ts.SyntaxKind.MultiLineCommentTrivia, + `* Input type for {@link ${name}} `, + true, // newline ) ts.addSyntheticLeadingComment( - variableDeclaration, - ts.SyntaxKind.MultiLineCommentTrivia, - `* The \`${name}\` validator `, - true, // newline + variableDeclaration, + ts.SyntaxKind.MultiLineCommentTrivia, + `* The \`${name}\` validator `, + true, // newline ) /* Push our statements */ - statements.push( - outputDeclaration, - inputDeclaration, - variableDeclaration, - ) + statements.push(outputDeclaration, inputDeclaration, variableDeclaration) } /* Pretty print our DTS */ - return ts.createPrinter().printList( + return ts + .createPrinter() + .printList( ts.ListFormat.SourceFileStatements, ts.factory.createNodeArray(statements), - ts.createSourceFile('types.d.ts', '', ts.ScriptTarget.Latest)) + ts.createSourceFile('types.d.ts', '', ts.ScriptTarget.Latest), + ) } /* ========================================================================== * @@ -291,29 +305,28 @@ function isValidator(validation: Validation): validation is Validator { /* We must have a "validate" function which is NOT a validator itself: this * is an edge case when a schema is defined as { validate: string } */ - return ('validate' in validation) && (typeof validation.validate === 'function') + return 'validate' in validation && typeof validation.validate === 'function' } /** Generate an inline type import from "justus" */ -function generateJustusTypeImport( - typeName: string, - typeArguments: ts.TypeNode[] = [], -): ts.TypeNode { - return ts.factory.createImportTypeNode( // .................... "import" - ts.factory.createLiteralTypeNode( - ts.factory.createStringLiteral('justus'), // .......... "justus" - ), - undefined, // import assertions - ts.factory.createIdentifier(typeName), // ................. "JustusType" - typeArguments) // ......................................... "" +function generateJustusTypeImport(typeName: string, typeArguments: ts.TypeNode[] = []): ts.TypeNode { + return ts.factory.createImportTypeNode( + // .................... "import" + ts.factory.createLiteralTypeNode( + ts.factory.createStringLiteral('justus'), // .......... "justus" + ), + undefined, // import assertions + ts.factory.createIdentifier(typeName), // ................. "JustusType" + typeArguments, + ) // ......................................... "" } /** Generate the _type_ for a variable declaration associated with a validator */ function generateVariableDeclarationType( - validation: Validation, - validator: Validator, - outputReferences: Map, - inputReferences: Map, + validation: Validation, + validator: Validator, + outputReferences: Map, + inputReferences: Map, ): ts.TypeNode { /* Validation can be one of the following: * - validator @@ -326,7 +339,7 @@ function generateVariableDeclarationType( if (isValidator(validation)) { const validatedType = generateTypeNode(validator, outputReferences, false) const validatedInput = generateTypeNode(validator, inputReferences, true) - return generateJustusTypeImport('Validator', [ validatedType, validatedInput ]) + return generateJustusTypeImport('Validator', [validatedType, validatedInput]) } /* This will take care of constants */ @@ -338,29 +351,37 @@ function generateVariableDeclarationType( if (validator instanceof ObjectValidator) { const properties: ts.PropertySignature[] = [] - for (const [ key, valueValidator ] of validator.validators.entries()) { + for (const [key, valueValidator] of validator.validators.entries()) { const value = validator.schema[key] const type = generateVariableDeclarationType(value, valueValidator, outputReferences, inputReferences) - properties.push(ts.factory.createPropertySignature( + properties.push( + ts.factory.createPropertySignature( readonlyModifiers, key, undefined, // no question mark - type)) + type, + ), + ) } if (validator.additionalProperties) { const additional = validator.additionalProperties const type = generateVariableDeclarationType(additional, additional, outputReferences, inputReferences) - properties.push(ts.factory.createPropertySignature( + properties.push( + ts.factory.createPropertySignature( readonlyModifiers, ts.factory.createComputedPropertyName( - ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier('Symbol'), - 'justusAdditionalValidator')), + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('Symbol'), + 'justusAdditionalValidator', + ), + ), undefined, // no question mark - type)) + type, + ), + ) } return ts.factory.createTypeLiteralNode(properties) @@ -369,7 +390,7 @@ function generateVariableDeclarationType( /* For anything else (including tuples) we use our generic validator handling */ const validatedType = generateTypeNode(validator, outputReferences, false) const validatedInput = generateTypeNode(validator, inputReferences, true) - return generateJustusTypeImport('Validator', [ validatedType, validatedInput ]) + return generateJustusTypeImport('Validator', [validatedType, validatedInput]) } /* ========================================================================== * @@ -378,15 +399,15 @@ function generateVariableDeclarationType( /** Generate all TypeScript `TypeNode` following the validators specified. */ function generateTypeNodes( - validators: ReadonlyMap, - references: ReadonlyMap, - isInput: boolean, + validators: ReadonlyMap, + references: ReadonlyMap, + isInput: boolean, ): Map { /* Our types map, */ const types = new Map() /* Walk through our validators map, and produce all `TypeNode`s */ - for (const [ name, validator ] of validators.entries()) { + for (const [name, validator] of validators.entries()) { /* Here we _clone_ our references map, and remove the validator being * exported, if it has the same name. This will make sure that we don't * have any loops in our types or things like `type Foo = Foo`. */ @@ -402,20 +423,20 @@ function generateTypeNodes( /** Generate a TypeScript `TypeNode` for the given validator instance. */ function generateTypeNode( - validator: Validator, - references: ReadonlyMap, - isInput: boolean, + validator: Validator, + references: ReadonlyMap, + isInput: boolean, ): ts.TypeNode { const reference = references.get(validator) if (reference) return ts.factory.createTypeReferenceNode(reference) const generator = generators.get(validator) || generators.get(validator.constructor) - assertSchema(!! generator, `Type generator for "${validator.constructor.name}" not found`) + assertSchema(!!generator, `Type generator for "${validator.constructor.name}" not found`) const type = generator(validator, references, isInput) // If the validator is not optional (or has no default value and we're // generating an _input_ type), then we return the type straight - if (!(validator.optional || (isInput && (validator.defaultValue !== undefined)))) { + if (!(validator.optional || (isInput && validator.defaultValue !== undefined))) { return type } @@ -424,11 +445,11 @@ function generateTypeNode( // If the type is already a union type, we simply add our "undefined" if (ts.isUnionTypeNode(type)) { - return ts.factory.createUnionTypeNode([ ...type.types, undefinedType ]) + return ts.factory.createUnionTypeNode([...type.types, undefinedType]) } // Create a new type "type | undefined" - return ts.factory.createUnionTypeNode([ type, undefinedType ]) + return ts.factory.createUnionTypeNode([type, undefinedType]) } /* ========================================================================== */ @@ -445,19 +466,20 @@ const neverType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword) const stringType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword) const undefinedType = ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword) const recordType = ts.factory.createMappedTypeNode( - undefined, // readonly - ts.factory.createTypeParameterDeclaration([], 'key', stringType), - undefined, // name type - undefined, // question token - anyType, // type of the mapped key - undefined) // members + undefined, // readonly + ts.factory.createTypeParameterDeclaration([], 'key', stringType), + undefined, // name type + undefined, // question token + anyType, // type of the mapped key + undefined, +) // members // "Optional" modifier (the "?" token ) const optionalKeyword = ts.factory.createToken(ts.SyntaxKind.QuestionToken) // "export" modifier for declarations -const exportModifiers = [ ts.factory.createModifier(ts.SyntaxKind.ExportKeyword) ] +const exportModifiers = [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)] // "readonly" modifier for declarations -const readonlyModifiers = [ ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword ) ] +const readonlyModifiers = [ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)] /* ========================================================================== */ @@ -480,65 +502,71 @@ registerTypeGenerator(ArrayValidator, (validator, references, isInput) => { return ts.factory.createArrayTypeNode(itemType) }) -registerTypeGenerator(BigIntValidator, (validator: BigIntValidator, _references, isInput) => { +registerTypeGenerator(BigIntValidator, (validator, _references, isInput) => { if (isInput) { - const types: ts.TypeNode[] = [ bigintType ] + const types: ts.TypeNode[] = [bigintType] if (validator.fromNumber) types.push(numberType) if (validator.fromString) types.push(stringType) - return types.length === 1 ? types[0] : ts.factory.createUnionTypeNode(types) + return types.length === 1 ? types[0]! : ts.factory.createUnionTypeNode(types) } - if (! validator.brand) return bigintType + if (!validator.brand) return bigintType const signature = ts.factory.createPropertySignature(undefined, `__brand_${validator.brand}`, undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ bigintType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([bigintType, literal]) }) registerTypeGenerator(BooleanValidator, (validator, _references, isInput) => { - return (isInput && validator.fromString) ? - ts.factory.createUnionTypeNode([ - booleanType, - ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('true')), - ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('false')), - ]) : - booleanType + return isInput && validator.fromString + ? ts.factory.createUnionTypeNode([ + booleanType, + ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('true')), + ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral('false')), + ]) + : booleanType }) registerTypeGenerator(ConstantValidator, (validator) => { const literal = - typeof validator.constant === 'number' ? ts.factory.createNumericLiteral(validator.constant) : - typeof validator.constant === 'string' ? ts.factory.createStringLiteral(validator.constant) : - typeof validator.constant === 'bigint' ? ts.factory.createBigIntLiteral(`${validator.constant}n`) : - validator.constant === false ? ts.factory.createFalse() : - validator.constant === true ? ts.factory.createTrue() : - validator.constant === null ? ts.factory.createNull() : - undefined - - assertSchema(!! literal, `Invalid constant "${validator.constant}"`) + typeof validator.constant === 'number' + ? ts.factory.createNumericLiteral(validator.constant) + : typeof validator.constant === 'string' + ? ts.factory.createStringLiteral(validator.constant) + : typeof validator.constant === 'bigint' + ? ts.factory.createBigIntLiteral(`${validator.constant}n`) + : validator.constant === false + ? ts.factory.createFalse() + : validator.constant === true + ? ts.factory.createTrue() + : validator.constant === null + ? ts.factory.createNull() + : undefined + + assertSchema(!!literal, `Invalid constant "${validator.constant}"`) return ts.factory.createLiteralTypeNode(literal) }) registerTypeGenerator(DateValidator, (validator: DateValidator, _references, isInput) => { - return isInput ? - validator.format === 'iso' ? stringType : - validator.format === 'timestamp' ? numberType : - ts.factory.createUnionTypeNode([ dateType, numberType, stringType ]) : - dateType + return isInput + ? validator.format === 'iso' + ? stringType + : validator.format === 'timestamp' + ? numberType + : ts.factory.createUnionTypeNode([dateType, numberType, stringType]) + : dateType }) registerTypeGenerator(NumberValidator, (validator: NumberValidator, _references, isInput) => { if (isInput) { - return validator.fromString ? - ts.factory.createUnionTypeNode([ numberType, stringType ]) : - numberType + return validator.fromString ? ts.factory.createUnionTypeNode([numberType, stringType]) : numberType } - if (! validator.brand) return numberType + if (!validator.brand) return numberType const signature = ts.factory.createPropertySignature(undefined, `__brand_${validator.brand}`, undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ numberType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([numberType, literal]) }) registerTypeGenerator(OptionalValidator, (validator: OptionalValidator, references, isInput: boolean) => { @@ -548,26 +576,28 @@ registerTypeGenerator(OptionalValidator, (validator: OptionalValidator, referenc }) registerTypeGenerator(StringValidator, (validator: StringValidator, _references, isInput) => { - if ((! validator.brand) || (isInput)) return stringType + if (!validator.brand || isInput) return stringType const signature = ts.factory.createPropertySignature(undefined, `__brand_${validator.brand}`, undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ stringType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([stringType, literal]) }) registerTypeGenerator(TupleValidator, (validator: TupleValidator, references, isInput) => { const members = validator.members // count how many rest parameters do we have.. - const { count, first, next } = - members.reduce(({ count, first, next }, { single }, i) => { - if (! single) { + const { count, first, next } = members.reduce( + ({ count, first, next }, { single }, i) => { + if (!single) { if (i < first) first = i next = i + 1 count += 1 } return { count, first, next } - }, { count: 0, first: members.length, next: -1 }) + }, + { count: 0, first: members.length, next: -1 }, + ) // if we have zero or one rest parameter, things are easy... if (count < 2) { @@ -585,18 +615,15 @@ registerTypeGenerator(TupleValidator, (validator: TupleValidator, reference // We have two or more rest parameters... we need combine everything between // the first and the last one in a giant union! - const before = members.slice(0, first) - .map(({ validator }) => generateTypeNode(validator, references, isInput)) - const types = members.slice(first, next) - .map(({ validator }) => generateTypeNode(validator, references, isInput)) - const after = members.slice(next) - .map(({ validator }) => generateTypeNode(validator, references, isInput)) + const before = members.slice(0, first).map(({ validator }) => generateTypeNode(validator, references, isInput)) + const types = members.slice(first, next).map(({ validator }) => generateTypeNode(validator, references, isInput)) + const after = members.slice(next).map(({ validator }) => generateTypeNode(validator, references, isInput)) const union = ts.factory.createUnionTypeNode(types) const array = ts.factory.createArrayTypeNode(union) const rest = ts.factory.createRestTypeNode(array) - return ts.factory.createTupleTypeNode([ ...before, rest, ...after ]) + return ts.factory.createTupleTypeNode([...before, rest, ...after]) }) registerTypeGenerator(AllOfValidator, (validator, references, isInput) => { @@ -612,19 +639,14 @@ registerTypeGenerator(OneOfValidator, (validator, references, isInput) => { registerTypeGenerator(ObjectValidator, (validator, references, isInput) => { const properties: ts.PropertySignature[] = [] - for (const [ key, valueValidator ] of validator.validators.entries()) { + for (const [key, valueValidator] of validator.validators.entries()) { const type = generateTypeNode(valueValidator, references, isInput) // the optional keyword (question mark) is added when either the validator // is optional or, when in input mode, there is no default value - const optional = (isInput && valueValidator.defaultValue !== undefined) || - valueValidator.optional + const optional = (isInput && valueValidator.defaultValue !== undefined) || valueValidator.optional - const signature = ts.factory.createPropertySignature( - undefined, - key, - optional ? optionalKeyword : undefined, - type) + const signature = ts.factory.createPropertySignature(undefined, key, optional ? optionalKeyword : undefined, type) properties.push(signature) } @@ -633,17 +655,18 @@ registerTypeGenerator(ObjectValidator, (validator, references, isInput) => { const propertyType = generateTypeNode(validator.additionalProperties, references, isInput) const extra = ts.factory.createMappedTypeNode( - undefined, // readonly - ts.factory.createTypeParameterDeclaration([], 'key', stringType), - undefined, // name type - undefined, // question token - propertyType, // type - undefined) // members + undefined, // readonly + ts.factory.createTypeParameterDeclaration([], 'key', stringType), + undefined, // name type + undefined, // question token + propertyType, // type + undefined, + ) // members if (properties.length === 0) return extra const type = ts.factory.createTypeLiteralNode(properties) - return ts.factory.createIntersectionTypeNode([ type, extra ]) + return ts.factory.createIntersectionTypeNode([type, extra]) } else { return ts.factory.createTypeLiteralNode(properties) } @@ -652,33 +675,33 @@ registerTypeGenerator(ObjectValidator, (validator, references, isInput) => { /* ===== EXTRA TYPES ======================================================== */ registerTypeGenerator(EAN13Validator, (_validator, _references, isInput) => { - if (isInput) return ts.factory.createUnionTypeNode([ numberType, stringType ]) + if (isInput) return ts.factory.createUnionTypeNode([numberType, stringType]) const signature = ts.factory.createPropertySignature(undefined, '__ean_13', undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ stringType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([stringType, literal]) }) registerTypeGenerator(EmailValidator, (_validator, _references, isInput) => { if (isInput) return stringType const signature = ts.factory.createPropertySignature(undefined, '__email', undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ stringType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([stringType, literal]) }) registerTypeGenerator(UUIDValidator, (_validator, _references, isInput) => { if (isInput) return stringType const signature = ts.factory.createPropertySignature(undefined, '__uuid', undefined, neverType) - const literal = ts.factory.createTypeLiteralNode([ signature ]) - return ts.factory.createIntersectionTypeNode([ stringType, literal ]) + const literal = ts.factory.createTypeLiteralNode([signature]) + return ts.factory.createIntersectionTypeNode([stringType, literal]) }) registerTypeGenerator(URLValidator, (_validator, _references, isInput) => { const urlType = ts.factory.createTypeReferenceNode('URL') if (isInput) { - return ts.factory.createUnionTypeNode([ urlType, stringType ]) + return ts.factory.createUnionTypeNode([urlType, stringType]) } else { return urlType } diff --git a/src/errors.ts b/src/errors.ts index 3394953..29614bd 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-function-type */ -export type ValidationErrors = { path: (string | number)[], message: string }[] +export type ValidationErrors = { path: (string | number)[]; message: string }[] /** Combine the components of a _path_ into a human readable string */ function pathToString(path: (string | number)[]): string { @@ -9,14 +9,12 @@ function pathToString(path: (string | number)[]): string { }, '') } -/** - * A `ValidationError` wraps one or more errors encountered during validation. - */ +/** A `ValidationError` wraps one or more errors encountered during validation. */ export class ValidationError extends Error { /** An `Array` of validation errors encountered while validating */ readonly errors!: ValidationErrors /** Our stack, always present as we enforce it in the constructor */ - readonly stack!: string + override readonly stack!: string /** * Create a new `ValidationError` instance from a `ValidationErrorBuilder` @@ -29,41 +27,37 @@ export class ValidationError extends Error { constructor(cause: any, constructor?: Function) constructor(cause: any, path: (string | number)[], constructor?: Function) - constructor( - builderOrCause: any, - constructorOrPath?: Function | ((string | number)[]), - maybeConstructor?: Function, - ) { + constructor(builderOrCause: any, constructorOrPath?: Function | (string | number)[], maybeConstructor?: Function) { let constructor: Function let errors: ValidationErrors if (builderOrCause instanceof ValidationErrorBuilder) { errors = builderOrCause.errors + // oxlint-disable-next-line typescript/unbound-method constructor = builderOrCause.assert } else { const path = Array.isArray(constructorOrPath) ? constructorOrPath : [] if (builderOrCause instanceof ValidationError) { - errors = builderOrCause.errors.map(({ path: subpath, message }) => - ({ path: [ ...path, ...subpath ], message })) + errors = builderOrCause.errors.map(({ path: subpath, message }) => ({ path: [...path, ...subpath], message })) } else { - errors = [ { path, message: `${builderOrCause}` } ] + errors = [{ path, message: `${builderOrCause}` }] } constructor = - typeof maybeConstructor === 'function' ? maybeConstructor : - typeof constructorOrPath === 'function' ? constructorOrPath : - ValidationError + typeof maybeConstructor === 'function' + ? maybeConstructor + : typeof constructorOrPath === 'function' + ? constructorOrPath + : ValidationError } const details = errors - .map(({ path, message }) => ({ key: pathToString(path), message })) - .map(({ key, message }) => key ? `${key}: ${message}` : message) - .join('\n ') + .map(({ path, message }) => ({ key: pathToString(path), message })) + .map(({ key, message }) => (key ? `${key}: ${message}` : message)) + .join('\n ') - const message = errors.length !== 1 ? - `Found ${errors.length} validation errors` : - 'Found 1 validation error' + const message = errors.length !== 1 ? `Found ${errors.length} validation errors` : 'Found 1 validation error' super(`${message}\n ${details}`) @@ -74,9 +68,7 @@ export class ValidationError extends Error { ValidationError.prototype.name = 'ValidationError' -/** - * Helper class to build a `ValidationError` associated p - */ +/** Helper class to build a `ValidationError` associated p */ export class ValidationErrorBuilder { /** The current list of validation errors */ readonly errors: ValidationErrors = [] @@ -85,15 +77,15 @@ export class ValidationErrorBuilder { * Record a validation error associated with the specified key. * * @param error - The error (normally a `string` or a `ValidationError`) - * to record and associate with the given key + * to record and associate with the given key * @param key - The key in an object, or index in an array where the - * vaildation error was encountered + * vaildation error was encountered */ record(error: any, ...key: (string | number)[]): this { - const path = [ ...key ] + const path = [...key] if (error instanceof ValidationError) { error.errors.forEach(({ path: subpath, message }) => { - this.errors.push({ path: [ ...path, ...subpath ], message }) + this.errors.push({ path: [...path, ...subpath], message }) }) } else { this.errors.push({ path, message: `${error}` }) @@ -113,11 +105,9 @@ export class ValidationErrorBuilder { } } -/** - * Simple assertion function throwing `ValidationError`(s) with an empty path - */ +/** Simple assertion function throwing `ValidationError`(s) with an empty path */ export function assertValidation(what: boolean | undefined, message: string): asserts what { - if (! what) throw new ValidationError(message, assertValidation) + if (!what) throw new ValidationError(message, assertValidation) } /** @@ -125,5 +115,5 @@ export function assertValidation(what: boolean | undefined, message: string): as * constructing a `Validator` from a `Schema` or validation constraints. */ export function assertSchema(what: boolean | undefined, message: string): asserts what { - if (! what) throw new TypeError(message) + if (!what) throw new TypeError(message) } diff --git a/src/extra/arn.ts b/src/extra/arn.ts index 8ee7b70..e21b962 100644 --- a/src/extra/arn.ts +++ b/src/extra/arn.ts @@ -1,46 +1,37 @@ -import { assertValidation } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertValidation } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' /* ===== TYPES ============================================================= */ /** The type for a validated _string_ ARN (Amazon Resource Name) */ -export type ArnString< - Service extends string = string, - ResourceType extends string = string, -> = string & { __arn: never } -& ( string extends Service ? string : { [ k in `__arn_service_${Service}`] : never }) -& ( string extends ResourceType ? string : { [ k in `__arn_resource_${ResourceType}`] : never }) +export type ArnString = string & { + __arn: never +} & (string extends Service ? string : { [k in `__arn_service_${Service}`]: never }) & + (string extends ResourceType ? string : { [k in `__arn_resource_${ResourceType}`]: never }) /** The type for a _parsed_ ARN (Amazon Resource Name) */ -export interface ParsedArn< - Service extends string = string, - ResourceType extends string = string, -> { - /** The full */ - Arn: ArnString, - Partition: string, - Service: Service, - Region: string, - Account: string, - Resource: [ ResourceType, ...string[] ], +export interface ParsedArn { + /** The full */ + Arn: ArnString + Partition: string + Service: Service + Region: string + Account: string + Resource: [ResourceType, ...string[]] } /* ===== INTERNALS ========================================================== */ -function assertComponent( - actual: string, - expected: T | undefined, - kind: string, -): asserts actual is T { +function assertComponent(actual: string, expected: T | undefined, kind: string): asserts actual is T { if (expected === undefined) return assertValidation(actual === expected, `ARN ${kind} "${actual}" mismatch (expected "${expected}")`) } /** Validate a string and convert it into into an {@link ParsedArn} */ function parse( - value: unknown, - service?: Service, - type?: ResourceType, + value: unknown, + service?: Service, + type?: ResourceType, ): ParsedArn { assertValidation(typeof value === 'string', 'Value is not a "string"') @@ -48,19 +39,17 @@ function parse( assertValidation(segments.length >= 6, 'Invalid components in ARN') - const [ pfx, prt, svc, rgn, act, ...res ] = segments + const [pfx, prt, svc, rgn, act, ...res] = segments assertValidation(pfx === 'arn', 'ARN must start with "arn:"') - assertValidation(!! prt, 'Missing partition in ARN') - assertValidation(!! svc, 'Missing service in ARN') - assertValidation(!! act, 'Missing account ID in ARN') - assertValidation(!! res[0], 'Missing resource ID in ARN') + assertValidation(!!prt, 'Missing partition in ARN') + assertValidation(!!svc, 'Missing service in ARN') + assertValidation(!!act, 'Missing account ID in ARN') + assertValidation(!!res[0], 'Missing resource ID in ARN') - const [ [ resType, ...resArray ], resString ] = res[0].includes('/') ? - [ res[0].split('/'), res[0] ] : - [ res, res.join(':') ] + const [[resType, ...resArray], resString] = res[0].includes('/') ? [res[0].split('/'), res[0]] : [res, res.join(':')] - assertValidation(!! resType, 'Invalid resource ID in ARN') + assertValidation(!!resType, 'Invalid resource ID in ARN') assertComponent(svc, service, 'Service') assertComponent(resType, type, 'Resource Type') @@ -73,7 +62,7 @@ function parse( Service: svc, // as Service, Region: rgn || '', Account: act, - Resource: [ resType, ...resArray ], // as [ ResourceType, ...string[] ], + Resource: [resType, ...resArray], // as [ ResourceType, ...string[] ], } } @@ -88,13 +77,16 @@ export class ParsedArnValidator< * Create a new {@link ParsedArnValidator} instance. * * @param service The (optional) service the ARN should be pointing to - * (e.g. `iam` or `elasticloadbalancing`) + * (e.g. `iam` or `elasticloadbalancing`) * @param resourceType The (optional) resource _type_ the ARN should be - * representing (e.g. `role` in the `iam` service, or - * `targetgroup` in the `elasticloadbalancing` service) + * representing (e.g. `role` in the `iam` service, or + * `targetgroup` in the `elasticloadbalancing` service) */ constructor(service?: Service, resourceType?: ResourceType) - constructor(private _service?: Service, private _type?: ResourceType) { + constructor( + private _service?: Service, + private _type?: ResourceType, + ) { super() } @@ -112,13 +104,16 @@ export class ArnValidator< * Create a new {@link ArnValidator} instance. * * @param service The (optional) service the ARN should be pointing to - * (e.g. `iam` or `elasticloadbalancing`) + * (e.g. `iam` or `elasticloadbalancing`) * @param resourceType The (optional) resource _type_ the ARN should be - * representing (e.g. `role` in the `iam` service, or - * `targetgroup` in the `elasticloadbalancing` service) + * representing (e.g. `role` in the `iam` service, or + * `targetgroup` in the `elasticloadbalancing` service) */ constructor(service?: Service, resourceType?: ResourceType) - constructor(private _service?: Service, private _type?: ResourceType) { + constructor( + private _service?: Service, + private _type?: ResourceType, + ) { super() } @@ -137,11 +132,9 @@ export class ArnValidator< * component of the ARN's resource (e.g. `role` in the `iam` service, or * `targetgroup` in the `elasticloadbalancing` service) */ -export function parseArnFactory< - Service extends string = string, - ResourceType extends string = string>( - service: Service, - resourceType?: ResourceType, +export function parseArnFactory( + service: Service, + resourceType?: ResourceType, ): ParsedArnValidator { return new ParsedArnValidator(service, resourceType) } @@ -154,11 +147,9 @@ export function parseArnFactory< * component of the ARN's resource (e.g. `role` in the `iam` service, or * `targetgroup` in the `elasticloadbalancing` service) */ -export function arnFactory< - Service extends string = string, - ResourceType extends string = string>( - service: Service, - resourceType?: ResourceType, +export function arnFactory( + service: Service, + resourceType?: ResourceType, ): ArnValidator { return new ArnValidator(service, resourceType) } diff --git a/src/extra/ean13.ts b/src/extra/ean13.ts index 7784fdc..28ce47a 100644 --- a/src/extra/ean13.ts +++ b/src/extra/ean13.ts @@ -1,5 +1,5 @@ -import { assertValidation } from '../errors' -import { StringValidator } from '../validators/string' +import { assertValidation } from '../errors.ts' +import { StringValidator } from '../validators/string.ts' export type EAN13String = string & { __ean_13: never } @@ -8,14 +8,14 @@ export class EAN13Validator extends StringValidator()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})$/ +export const EMAIL_EXPR = + /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,})$/ export type EmailString = string & { __email: never } @@ -9,8 +10,8 @@ export class EmailValidator extends StringValidator { super({ minLength: 5, maxLength: 128, pattern: EMAIL_EXPR }) } - validate(value: unknown): EmailString - validate(value: unknown): string { + override validate(value: unknown): EmailString + override validate(value: unknown): string { return super.validate(value).toLowerCase() } } diff --git a/src/extra/url.ts b/src/extra/url.ts index 12cc0ff..028644f 100644 --- a/src/extra/url.ts +++ b/src/extra/url.ts @@ -1,10 +1,9 @@ -import { ValidationError, ValidationErrorBuilder } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' -import { ConstantValidator } from '../validators/constant' -import { ObjectValidator } from '../validators/object' +import { ValidationError, ValidationErrorBuilder } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' +import { ConstantValidator } from '../validators/constant.ts' +import { ObjectValidator } from '../validators/object.ts' -import type { ValidationOptions } from '..' -import type { Schema, Validator } from '../types' +import type { Schema, ValidationOptions, Validator } from '../types.ts' const KEYS: Exclude[] = [ 'href', @@ -29,34 +28,34 @@ const OPTIONS: ValidationOptions = { /** Constraints to validate a `URL` with. */ export interface URLConstraints { /** Constraint to validate the `href` component of the `URL`. */ - href?: string | Validator, + href?: string | Validator /** Constraint to validate the `origin` component of the `URL`. */ - origin?: string | Validator, + origin?: string | Validator /** Constraint to validate the `protocol` component of the `URL`. */ - protocol?: string | Validator, + protocol?: string | Validator /** Constraint to validate the `username` component of the `URL`. */ - username?: string | Validator, + username?: string | Validator /** Constraint to validate the `password` component of the `URL`. */ - password?: string | Validator, + password?: string | Validator /** Constraint to validate the `host` (`hostname:port`) component of the `URL`. */ - host?: string | Validator, + host?: string | Validator /** Constraint to validate the `hostname` component of the `URL`. */ - hostname?: string | Validator, + hostname?: string | Validator /** Constraint to validate the `port` component of the `URL`. */ - port?: string | Validator, + port?: string | Validator /** Constraint to validate the `pathname` component of the `URL`. */ - pathname?: string | Validator, + pathname?: string | Validator /** Constraint to validate the `search` component of the `URL` as a string. */ - search?: string | Validator, + search?: string | Validator /** Constraint to validate the `hash` component of the `URL`. */ - hash?: string | Validator, + hash?: string | Validator /** * Schema used to validate the `searchParams` component of the `URL`. * * The `searchParams` will be normalized in a `Record`, where * only the _first_ value associated with a search parameter will be checked. */ - searchParams?: Schema, + searchParams?: Schema } /** A `Validator` validating URLs and converting them to `URL` instances. */ @@ -115,7 +114,7 @@ export class URLValidator extends AbstractValidator { if (this.searchParams) { const parameters: Record = {} - url.searchParams.forEach((value, key) => parameters[key] = value) + url.searchParams.forEach((value, key) => (parameters[key] = value)) try { this.searchParams.validate(parameters, OPTIONS) diff --git a/src/extra/uuid.ts b/src/extra/uuid.ts index 67f8d30..bbfcce6 100644 --- a/src/extra/uuid.ts +++ b/src/extra/uuid.ts @@ -1,4 +1,4 @@ -import { StringValidator } from '../validators/string' +import { StringValidator } from '../validators/string.ts' export const UUID_EXPR = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i @@ -9,8 +9,8 @@ export class UUIDValidator extends StringValidator { super({ minLength: 36, maxLength: 36, pattern: UUID_EXPR }) } - validate(value: unknown): UUIDString - validate(value: unknown): string { + override validate(value: unknown): UUIDString + override validate(value: unknown): string { return super.validate(value).toLowerCase() } } diff --git a/src/index.ts b/src/index.ts index 01f0204..d7a8df9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,43 +3,43 @@ * ========================================================================== */ // All our types and utilities -export * from './errors' -export * from './schema' -export * from './types' -export * from './utilities' +export * from './errors.ts' +export * from './schema.ts' +export * from './types.ts' +export * from './utilities.ts' // Validators -export { AnyValidator, any } from './validators/any' -export { AnyArrayValidator, ArrayValidator, array, arrayOf } from './validators/array' -export { AnyBigIntValidator, BigIntValidator, bigint } from './validators/bigint' -export { BooleanValidator, boolean } from './validators/boolean' -export { ConstantValidator, constant } from './validators/constant' -export { DateValidator, date } from './validators/date' -export { NeverValidator, never } from './validators/never' -export { AnyNumberValidator, NumberValidator, number } from './validators/number' -export { AnyObjectValidator, ObjectValidator, object, objectOf } from './validators/object' -export { OptionalValidator, optional } from './validators/optional' -export { AnyStringValidator, StringValidator, string } from './validators/string' -export { TupleValidator, tuple } from './validators/tuple' -export { AllOfValidator, OneOfValidator, allOf, oneOf } from './validators/union' +export { any, AnyValidator } from './validators/any.ts' +export { AnyArrayValidator, array, arrayOf, ArrayValidator } from './validators/array.ts' +export { AnyBigIntValidator, bigint, BigIntValidator } from './validators/bigint.ts' +export { boolean, BooleanValidator } from './validators/boolean.ts' +export { constant, ConstantValidator } from './validators/constant.ts' +export { date, DateValidator } from './validators/date.ts' +export { never, NeverValidator } from './validators/never.ts' +export { AnyNumberValidator, number, NumberValidator } from './validators/number.ts' +export { AnyObjectValidator, object, objectOf, ObjectValidator } from './validators/object.ts' +export { optional, OptionalValidator } from './validators/optional.ts' +export { AnyStringValidator, string, StringValidator } from './validators/string.ts' +export { tuple, TupleValidator } from './validators/tuple.ts' +export { allOf, AllOfValidator, oneOf, OneOfValidator } from './validators/union.ts' // Validator Types -export type { ArrayConstraints, arrayValidatorFactory } from './validators/array' -export type { BrandedBigIntConstraints, bigintValidatorFactory } from './validators/bigint' -export type { BooleanConstraints, booleanValidatorFactory } from './validators/boolean' -export type { DateConstraints, dateValidatorFactory } from './validators/date' -export type { BrandedNumberConstraints, numberValidatorFactory } from './validators/number' -export type { objectValidatorFactory } from './validators/object' -export type { BrandedStringConstraints, StringConstraints, stringValidatorFactory } from './validators/string' -export type { TupleMember } from './validators/tuple' +export type { ArrayConstraints, arrayValidatorFactory } from './validators/array.ts' +export type { bigintValidatorFactory, BrandedBigIntConstraints } from './validators/bigint.ts' +export type { BooleanConstraints, booleanValidatorFactory } from './validators/boolean.ts' +export type { DateConstraints, dateValidatorFactory } from './validators/date.ts' +export type { BrandedNumberConstraints, numberValidatorFactory } from './validators/number.ts' +export type { objectValidatorFactory } from './validators/object.ts' +export type { BrandedStringConstraints, StringConstraints, stringValidatorFactory } from './validators/string.ts' +export type { TupleMember } from './validators/tuple.ts' /* ========================================================================== * * VALIDATE FUNCTION (our main entry point) * * ========================================================================== */ -import { getValidator } from './utilities' +import { getValidator } from './utilities.ts' -import type { InferValidation, Validation, ValidationOptions } from './types' +import type { InferValidation, Validation, ValidationOptions } from './types.ts' /** * Validate a _value_ using the specified `Validation`. @@ -48,9 +48,9 @@ import type { InferValidation, Validation, ValidationOptions } from './types' * reported as an error. */ export function validate( - validation: V, - value: any, - options?: ValidationOptions, + validation: V, + value: any, + options?: ValidationOptions, ): InferValidation { const opts: ValidationOptions = { partialValidation: false, @@ -78,9 +78,9 @@ export function validate( * ``` */ export function strip( - validation: V, - value: any, - options?: ValidationOptions, + validation: V, + value: any, + options?: ValidationOptions, ): InferValidation { const opts: ValidationOptions = { partialValidation: false, @@ -113,9 +113,9 @@ export function strip( * `Partial<...>` type. */ export function partial( - validation: V, - value: any, - options?: ValidationOptions, + validation: V, + value: any, + options?: ValidationOptions, ): Partial> { return getValidator(validation).validate(value, { partialValidation: true, diff --git a/src/registry.ts b/src/registry.ts index 09d8f4d..3de938c 100644 --- a/src/registry.ts +++ b/src/registry.ts @@ -1,13 +1,13 @@ -import { assertSchema } from './errors' +import { assertSchema } from './errors.ts' -import type { ConstantValidator } from './validators/constant' -import type { ObjectValidator } from './validators/object' -import type { TupleValidator } from './validators/tuple' +import type { ConstantValidator } from './validators/constant.ts' +import type { ObjectValidator } from './validators/object.ts' +import type { TupleValidator } from './validators/tuple.ts' type RegistryTypes = { - constant: typeof ConstantValidator, - object: typeof ObjectValidator, - tuple: typeof TupleValidator, + constant: typeof ConstantValidator + object: typeof ObjectValidator + tuple: typeof TupleValidator } const _registry: Partial = {} @@ -22,7 +22,7 @@ export const registry = { /** Retrieves the specified validator constructor */ get(key: K): RegistryTypes[K] { const value = _registry[key] - assertSchema(!! value, `No validator found for "${key}"`) + assertSchema(!!value, `No validator found for "${key}"`) return value }, } diff --git a/src/schema.ts b/src/schema.ts index f48d757..4f2a5fa 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -1,12 +1,7 @@ -import { getValidator } from './utilities' -import { any } from './validators/any' +import { getValidator } from './utilities.ts' +import { any } from './validators/any.ts' -import type { - AdditionalProperties, - InferValidation, - Validation, - Validator, -} from './types' +import type { AdditionalProperties, InferValidation, Validation, Validator } from './types.ts' /* ========================================================================== * * ADDITIONAL PROPERTIES IN SCHEMAS * @@ -18,7 +13,7 @@ function additionalProperties(allow: true): AdditionalProperties> function additionalProperties(allow: false): AdditionalProperties function additionalProperties(validation: V): AdditionalProperties>> -function additionalProperties(options?: Validation | boolean): AdditionalProperties { +function additionalProperties(options?: Validation): AdditionalProperties { if (options === false) return { [Symbol.justusAdditionalValidator]: false } if (options === true) return { [Symbol.justusAdditionalValidator]: any } @@ -34,8 +29,8 @@ function additionalProperties(options?: Validation | boolean): AdditionalPropert * * @param allow - A `boolean` or a `Validator` instance */ -export const allowAdditionalProperties = additionalProperties as - typeof additionalProperties & AdditionalProperties> +export const allowAdditionalProperties = additionalProperties as typeof additionalProperties & + AdditionalProperties> // Remember to inject our `any` validator as the default for when // `allowAdditionalProperties` is _not_ used as a function diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..ef220dd --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,15 @@ +{ + // Inherit options from the root configuration file + "extends": "../tsconfig.json", + // Make sure we actually emit the transpiled files from here + "compilerOptions": { + "rootDir": ".", + "noEmit": false, + "declaration": true, + "sourceMap": true, + "declarationMap": true, + "outDir": "../dist" + }, + // Only include what's in the sources here + "include": ["."] +} diff --git a/src/types.ts b/src/types.ts index e23b28f..90201ae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -24,18 +24,16 @@ Object.defineProperties(Symbol, { * BASIC VALIDATION TYPES * * ========================================================================== */ -/** - * Options to be using while validating. - */ +/** Options to be using while validating. */ export interface ValidationOptions { /** Strip additional, undeclared properties from objects (default: `false`) */ - stripAdditionalProperties?: boolean, + stripAdditionalProperties?: boolean /** Strip `null`s from an object when associated with an optional key (default: `false`) */ - stripOptionalNulls?: boolean, + stripOptionalNulls?: boolean /** Ignore and strip forbidden (`never`) properties from objects (default: `false`) */ - stripForbiddenProperties?: boolean, - /** Perform a _partial_ validation, treating all properties as optional (default: `false`) */ - partialValidation?: boolean, + stripForbiddenProperties?: boolean + /** Perform a _partial_ validation, treating all properties as optional (default: `false`) */ + partialValidation?: boolean } /** @@ -58,10 +56,10 @@ export interface Validator extends Iterable>; + [Symbol.iterator](): Generator> } /** @@ -70,10 +68,10 @@ export interface Validator extends Iterable Validator, ->(validator: V, factory: F): F & V { +export function makeValidatorFactory Validator>( + validator: V, + factory: F, +): F & V { return Object.assign(factory, { optional: validator.optional, defaultValue: validator.defaultValue, @@ -87,18 +85,21 @@ export function makeValidatorFactory< * A `Validator` is an object capable of validating a given _value_ and * (possibly) converting it the required type `T`. */ -export abstract class AbstractValidator -implements Validator, Iterable> { +export abstract class AbstractValidator implements Validator, Iterable> { [Symbol.justusValidator] = this optional: boolean = false defaultValue: T | undefined = undefined /** Validate a _value_ and optionally convert it to the required `Type` */ - abstract validate(value: unknown, options?: ValidationOptions | undefined): T + abstract validate(value: unknown, options?: ValidationOptions): T - /** Allow any `Validator` to be used as a rest parameter in `Tuple`s */ - * [Symbol.iterator](): Generator> { + /** + * Allow any `Validator` to be used as a rest parameter in `Tuple`s + * + * @yields {TupleRestParameter} The rest parameter representation of this validator. + */ + *[Symbol.iterator](): Generator> { yield { [Symbol.justusRestValidator]: this } } } @@ -109,56 +110,67 @@ implements Validator, Iterable> { * * Those are: * - * * A `Validator` instance or a _zero-arguments_ function returning one - * * A `Tuple` or a `Schema`, validated as arrays or objects - * * Either `null`, a `boolean`, a `number`, a `bigint` or a `string` for constants + * - A `Validator` instance or a _zero-arguments_ function returning one + * - A `Tuple` or a `Schema`, validated as arrays or objects + * - Either `null`, a `boolean`, a `number`, a `bigint` or a `string` for constants */ export type Validation = | Validator // Validator instances - | Tuple | Schema // Tuples or schemas (arrays, objects) - | null | boolean | bigint | number | string // Primitives, mapped as constants - -/** - * Infer the type returned by a `Validation` when validating. - */ + | Tuple + | Schema // Tuples or schemas (arrays, objects) + | null + | boolean + | bigint + | number + | string // Primitives, mapped as constants + +/** Infer the type returned by a `Validation` when validating. */ export type InferValidation = // Validators return their validation type - V extends Validator ? T : - - // Primitives are returned as constants - V extends undefined ? V : - V extends boolean ? V : - V extends bigint ? V : - V extends number ? V : - V extends string ? V : - V extends null ? V : - - // Tuples are inferred using their own types - V extends Tuple ? InferTuple : - - // Anyhing else can only be a schema - InferSchema - -/** - * Infer the type compatible with a `Validation`'s input. - */ + V extends Validator + ? T + : // Primitives are returned as constants + V extends undefined + ? V + : V extends boolean + ? V + : V extends bigint + ? V + : V extends number + ? V + : V extends string + ? V + : V extends null + ? V + : // Tuples are inferred using their own types + V extends Tuple + ? InferTuple + : // Anyhing else can only be a schema + InferSchema + +/** Infer the type compatible with a `Validation`'s input. */ export type InferInput = // Validators return their validation type - V extends Validator ? T : - - // Primitives are returned as constants - V extends undefined ? V : - V extends boolean ? V : - V extends bigint ? V : - V extends number ? V : - V extends string ? V : - V extends null ? V : - - // // Tuples are inferred using their own types - V extends Tuple ? InferInputTuple : - - // // Anyhing else can only be a schema - InferInputSchema + V extends Validator + ? T + : // Primitives are returned as constants + V extends undefined + ? V + : V extends boolean + ? V + : V extends bigint + ? V + : V extends number + ? V + : V extends string + ? V + : V extends null + ? V + : // // Tuples are inferred using their own types + V extends Tuple + ? InferInputTuple + : // // Anyhing else can only be a schema + InferInputSchema /* ========================================================================== * * TUPLES * @@ -166,21 +178,15 @@ export type InferInput = /** Infer the type validated by a `Validation` or `TupleRestParameter` */ export type InferValidationOrTupleRest = - T extends TupleRestParameter ? X : - T extends Validation ? InferValidation : - never + T extends TupleRestParameter ? X : T extends Validation ? InferValidation : never /** Infer the input type for a `Validation` or `TupleRestParameter` */ export type InferInputValidationOrTupleRest = - T extends TupleRestParameter ? X : - T extends Validation ? InferInput : - never + T extends TupleRestParameter ? X : T extends Validation ? InferInput : never /* -------------------------------------------------------------------------- */ -/** - * A `Tuple` is defined to be an array of `Validation` or `TupleRest` - */ +/** A `Tuple` is defined to be an array of `Validation` or `TupleRest` */ export type Tuple = readonly (Validation | TupleRestParameter)[] /** @@ -193,50 +199,46 @@ export type Tuple = readonly (Validation | TupleRestParameter)[] * * ``` * const nonEmptyString = string({ minLength: 1 }) - * const myTuple = tuple([ number, ...nonEmptyString ]) + * const myTuple = tuple([number, ...nonEmptyString]) * ``` */ export type TupleRestParameter = { [Symbol.justusRestValidator]: Validator } -/** - * Infer the type returned by a `TupleValidator` when validating an array. - */ -export type InferTuple = - T extends Tuple ? - T extends readonly [] ? [] : - T extends readonly [ Validation, ...any[] ] ? - T extends readonly [ infer V, ...infer Rest ] ? - [ InferValidation, ...InferTuple ] : - never : - T extends readonly [ ...any[], Validation ] ? - T extends readonly [ ...infer Rest, infer V ] ? - [ ...InferTuple, InferValidation ] : - never : - T extends readonly (infer V)[] ? - [ ...InferValidationOrTupleRest[] ] : - never : - never - -/** - * Infer a time compatible with a `TupleValidator`'s input. - */ -export type InferInputTuple = - T extends Tuple ? - T extends readonly [] ? [] : - T extends readonly [ Validation, ...any[] ] ? - T extends readonly [ infer V, ...infer Rest ] ? - [ InferInput, ...InferInputTuple ] : - never : - T extends readonly [ ...any[], Validation ] ? - T extends readonly [ ...infer Rest, infer V ] ? - [ ...InferInputTuple, InferInput ] : - never : - T extends readonly (infer V)[] ? - [ ...InferInputValidationOrTupleRest[] ] : - never : - never +/** Infer the type returned by a `TupleValidator` when validating an array. */ +export type InferTuple = T extends Tuple + ? T extends readonly [] + ? [] + : T extends readonly [Validation, ...any[]] + ? T extends readonly [infer V, ...infer Rest] + ? [InferValidation, ...InferTuple] + : never + : T extends readonly [...any[], Validation] + ? T extends readonly [...infer Rest, infer V] + ? [...InferTuple, InferValidation] + : never + : T extends readonly (infer V)[] + ? [...InferValidationOrTupleRest[]] + : never + : never + +/** Infer a time compatible with a `TupleValidator`'s input. */ +export type InferInputTuple = T extends Tuple + ? T extends readonly [] + ? [] + : T extends readonly [Validation, ...any[]] + ? T extends readonly [infer V, ...infer Rest] + ? [InferInput, ...InferInputTuple] + : never + : T extends readonly [...any[], Validation] + ? T extends readonly [...infer Rest, infer V] + ? [...InferInputTuple, InferInput] + : never + : T extends readonly (infer V)[] + ? [...InferInputValidationOrTupleRest[]] + : never + : never /* ========================================================================== * * OBJECT SCHEMAS * @@ -247,8 +249,8 @@ export type InferInputTuple = * how they should be validated. */ export interface Schema { - [ key: string ]: Validation - [ Symbol.justusAdditionalValidator ]?: Validator | false + [key: string]: Validation + [Symbol.justusAdditionalValidator]?: Validator | false } /** @@ -256,7 +258,7 @@ export interface Schema { * properties, and the `Validator` used to validate them. */ export interface AdditionalProperties { - [ Symbol.justusAdditionalValidator ]: V + [Symbol.justusAdditionalValidator]: V } /* ========================================================================== * @@ -264,56 +266,52 @@ export interface AdditionalProperties { * ========================================================================== */ /** Utility type to "prettify" a type */ -type Prettify = { [ K in keyof T ]: T[K] } & {} +type Prettify = { [K in keyof T]: T[K] } & {} /** Infer the type validated by a `Schema` */ export type InferSchema = - S extends AdditionalProperties> ? - Prettify<{ [ key in string ] : V } & InferSchema2> : - Prettify> + S extends AdditionalProperties> + ? Prettify<{ [key in string]: V } & InferSchema2> + : Prettify> /** Infer the property types described by a `Schema` */ export type InferSchema2 = { // this first part of the type infers all keys from the schema into their // type, but makes *each* key optional... we'll restrict in the next part... - -readonly [ key in keyof S as key extends string ? key : never ] ? : InferValidation + -readonly [key in keyof S as key extends string ? key : never]?: InferValidation } & { // this second part infers *only* keys that _do not_ contain a "undefined" // in their unions, and associates them with the inferred value, basically // making the key *non optional* - -readonly [ key in keyof S as - key extends string ? - undefined extends InferValidation ? - never : - key : - never ] -? : - InferValidation + -readonly [ + key in keyof S as key extends string ? (undefined extends InferValidation ? never : key) : never + ]-?: InferValidation } /** Infer the input type compatible with a `Schema` */ export type InferInputSchema = - S extends AdditionalProperties> ? - Prettify<{ [ key in string ] : X } & InferInputSchema2> : - Prettify> + S extends AdditionalProperties> + ? Prettify<{ [key in string]: X } & InferInputSchema2> + : Prettify> /** Infer the input type of the properties described by a `Schema` */ export type InferInputSchema2 = { // this first part of the type infers all keys from the schema into their // type, but makes *each* key optional... we'll restrict in the next part... - -readonly [ key in keyof S as key extends string ? key : never ] ? : InferInput + -readonly [key in keyof S as key extends string ? key : never]?: InferInput } & { // this second part infers *only* keys that _do not_ contain a "undefined" // in their unions, and associates them with the inferred value, basically // making the key *non optional* - -readonly [ key in keyof S as - key extends string ? - InferInput extends never ? - never : - undefined extends InferInput ? - never : - key : - never ] -? : - InferInput + -readonly [ + key in keyof S as key extends string + ? InferInput extends never + ? never + : undefined extends InferInput + ? never + : key + : never + ]-?: InferInput } /* ========================================================================== * @@ -322,5 +320,5 @@ export type InferInputSchema2 = { /** Utility type to infer primitive branding according to a string */ export type Branding = { - [ brand in `__brand_${S}` ] : never + [brand in `__brand_${S}`]: never } diff --git a/src/utilities.ts b/src/utilities.ts index f8acd37..e27a6e4 100644 --- a/src/utilities.ts +++ b/src/utilities.ts @@ -1,7 +1,7 @@ -import { assertSchema } from './errors' -import { registry } from './registry' +import { assertSchema } from './errors.ts' +import { registry } from './registry.ts' -import type { InferInput, InferValidation, Schema, Validation, Validator } from './types' +import type { InferInput, InferValidation, Schema, Validation, Validator } from './types.ts' /* ========================================================================== * * UTILITY FUNCTIONS * @@ -16,8 +16,8 @@ export function getValidator(validation: Validation): Validator { if (validation === null) return new (registry.get('constant'))(null) // Anything with a validor associated with - if (( validation)[Symbol.justusValidator]) { - return ( validation)[Symbol.justusValidator] as Validator + if ((validation)[Symbol.justusValidator]) { + return (validation)[Symbol.justusValidator] as Validator } // Other types diff --git a/src/validators/any.ts b/src/validators/any.ts index ea4b533..6ad89ab 100644 --- a/src/validators/any.ts +++ b/src/validators/any.ts @@ -1,4 +1,4 @@ -import { AbstractValidator } from '../types' +import { AbstractValidator } from '../types.ts' /** A `Validator` validating _anything_. */ export class AnyValidator extends AbstractValidator { diff --git a/src/validators/array.ts b/src/validators/array.ts index 38563c4..917b1d9 100644 --- a/src/validators/array.ts +++ b/src/validators/array.ts @@ -1,9 +1,9 @@ -import { assertSchema, assertValidation, ValidationErrorBuilder } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' -import { getValidator } from '../utilities' -import { any } from './any' +import { assertSchema, assertValidation, ValidationErrorBuilder } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' +import { getValidator } from '../utilities.ts' +import { any } from './any.ts' -import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types' +import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types.ts' /* ========================================================================== * * ARRAYS VALIDATION * @@ -12,20 +12,20 @@ import type { InferInput, InferValidation, Validation, ValidationOptions, Valida /** Constraints to validate an `Array` with. */ export interface ArrayConstraints { /** The _maximum_ number of elements a valid `Array`: `value.length <= maxItems` */ - maxItems?: number, + maxItems?: number /** The _minimum_ number of elements a valid `Array`: `value.length >= minItems` */ - minItems?: number, + minItems?: number /** A flag indicating whether an `Array`'s elements must be unique */ - uniqueItems?: boolean, + uniqueItems?: boolean /** A `Validator` validating each individual item in an `Array` */ - items?: V, + items?: V } /** Basic validator for `Array` instances. */ export class AnyArrayValidator extends AbstractValidator { validate(value: unknown): T[] { assertValidation(Array.isArray(value), 'Value is not an "array"') - return [ ...value ] + return [...value] } } @@ -39,12 +39,7 @@ export class ArrayValidator extends AbstractValidator { constructor(options: ArrayConstraints> = {}) { super() - const { - items = any, - maxItems = Number.POSITIVE_INFINITY, - minItems = 0, - uniqueItems = false, - } = options + const { items = any, maxItems = Number.POSITIVE_INFINITY, minItems = 0, uniqueItems = false } = options assertSchema(minItems >= 0, `Constraint "minItems" (${minItems}) must be non-negative`) assertSchema(maxItems >= 0, `Constraint "maxItems" (${maxItems}) must be non-negative`) @@ -59,14 +54,12 @@ export class ArrayValidator extends AbstractValidator { validate(value: unknown, options?: ValidationOptions): T[] { assertValidation(Array.isArray(value), 'Value is not an "array"') - assertValidation(value.length >= this.minItems, - `Array must have a minimum length of ${this.minItems}`) + assertValidation(value.length >= this.minItems, `Array must have a minimum length of ${this.minItems}`) - assertValidation(value.length <= this.maxItems, - `Array must have a maximum length of ${this.maxItems}`) + assertValidation(value.length <= this.maxItems, `Array must have a maximum length of ${this.maxItems}`) const builder = new ValidationErrorBuilder() - const clone: any[] = new Array(value.length) + const clone: any[] = Array.from({ length: value.length }) value.forEach((item, i) => { try { @@ -90,7 +83,7 @@ export class ArrayValidator extends AbstractValidator { /* -------------------------------------------------------------------------- */ export function arrayValidatorFactory( - constraints: ArrayConstraints, + constraints: ArrayConstraints, ): ArrayValidator, InferInput> { const items = constraints.items ? getValidator(constraints.items) : any return new ArrayValidator({ ...constraints, items }) diff --git a/src/validators/bigint.ts b/src/validators/bigint.ts index 52914ec..3a2911e 100644 --- a/src/validators/bigint.ts +++ b/src/validators/bigint.ts @@ -1,26 +1,26 @@ -import { assertSchema, assertValidation, ValidationError } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertSchema, assertValidation, ValidationError } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' -import type { Branding, Validator } from '../types' +import type { Branding, Validator } from '../types.ts' /* ========================================================================== */ /** Constraints to validate a `bigint` with. */ export interface BigIntConstraints { /** The value for which a `bigint` must be multiple of for it to be valid */ - multipleOf?: bigint | number, + multipleOf?: bigint | number /** The _inclusive_ maximum value for a valid `bigint`: `value <= maximum` */ - maximum?: bigint | number, + maximum?: bigint | number /** The _inclusive_ minimum value for a valid `bigint`: `value >= minimum` */ - minimum?: bigint | number, + minimum?: bigint | number /** The _exclusive_ maximum value for a valid `bigint`: `value < exclusiveMaximum` */ - exclusiveMaximum?: bigint | number, + exclusiveMaximum?: bigint | number /** The _exclusive_ minimum value for a valid `bigint`: `value > exclusiveMaximum` */ - exclusiveMinimum?: bigint | number, + exclusiveMinimum?: bigint | number /** Allow bigints to be parsed from strings (e.g. `123.456` or `0x0CAFE`, default: `false`) */ - fromString?: boolean, + fromString?: boolean /** Allow bigints to be parsed from numbers (default: `true`) */ - fromNumber?: boolean, + fromNumber?: boolean } /** Constraints to validate a `bigint` with extra branding information. */ @@ -68,7 +68,7 @@ export class BigIntValidator extends AbstractValidato fromNumber = true, } = constraints - if ('brand' in constraints) this.brand = ( constraints).brand + if ('brand' in constraints) this.brand = (constraints).brand this.fromString = fromString this.fromNumber = fromNumber @@ -78,23 +78,29 @@ export class BigIntValidator extends AbstractValidato const _minimum = minimum === undefined ? undefined : BigInt(minimum) const _multipleOf = multipleOf === undefined ? undefined : BigInt(multipleOf) - if ((_maximum !== undefined) && (_minimum !== undefined)) { + if (_maximum !== undefined && _minimum !== undefined) { assertSchema(_maximum >= _minimum, `Constraint "minimum" (${_minimum}) is greater than "maximum" (${_maximum})`) } - if ((_exclusiveMaximum !== undefined) && (_minimum !== undefined)) { - assertSchema(_exclusiveMaximum > _minimum, - `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "minimum" (${_minimum})`) + if (_exclusiveMaximum !== undefined && _minimum !== undefined) { + assertSchema( + _exclusiveMaximum > _minimum, + `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "minimum" (${_minimum})`, + ) } - if ((_exclusiveMinimum !== undefined) && (_maximum != undefined)) { - assertSchema(_maximum > _exclusiveMinimum, - `Constraint "maximum" (${_maximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`) + if (_exclusiveMinimum !== undefined && _maximum != undefined) { + assertSchema( + _maximum > _exclusiveMinimum, + `Constraint "maximum" (${_maximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`, + ) } - if ((_exclusiveMinimum != undefined) && (_exclusiveMaximum !== undefined)) { - assertSchema(_exclusiveMaximum > _exclusiveMinimum, - `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`) + if (_exclusiveMinimum != undefined && _exclusiveMaximum !== undefined) { + assertSchema( + _exclusiveMaximum > _exclusiveMinimum, + `Constraint "exclusiveMaximum" (${_exclusiveMaximum}) must be greater than "exclusiveMinimum" (${_exclusiveMinimum})`, + ) } if (_multipleOf !== undefined) { @@ -110,8 +116,7 @@ export class BigIntValidator extends AbstractValidato validate(value: unknown): N { // Allow parsing from strings or numbers - if (((typeof value === 'string') && (this.fromString)) || - ((typeof value === 'number') && (this.fromNumber))) { + if ((typeof value === 'string' && this.fromString) || (typeof value === 'number' && this.fromNumber)) { try { value = BigInt(value) } catch { @@ -121,16 +126,20 @@ export class BigIntValidator extends AbstractValidato assertValidation(typeof value === 'bigint', 'Value is not a "bigint"') - assertValidation(((this.minimum === undefined) || (value >= this.minimum)), - `BigInt is less than ${this.minimum}`) - assertValidation(((this.maximum === undefined) || (value <= this.maximum)), - `BigInt is greater than ${this.maximum}`) - assertValidation((this.exclusiveMinimum === undefined) || (value > this.exclusiveMinimum), - `BigInt is less than or equal to ${this.exclusiveMinimum}`) - assertValidation((this.exclusiveMaximum === undefined) || (value < this.exclusiveMaximum), - `BigInt is greater than or equal to ${this.exclusiveMaximum}`) - assertValidation((this.multipleOf === undefined) || (!(value % this.multipleOf)), - `BigInt is not a multiple of ${this.multipleOf}`) + assertValidation(this.minimum === undefined || value >= this.minimum, `BigInt is less than ${this.minimum}`) + assertValidation(this.maximum === undefined || value <= this.maximum, `BigInt is greater than ${this.maximum}`) + assertValidation( + this.exclusiveMinimum === undefined || value > this.exclusiveMinimum, + `BigInt is less than or equal to ${this.exclusiveMinimum}`, + ) + assertValidation( + this.exclusiveMaximum === undefined || value < this.exclusiveMaximum, + `BigInt is greater than or equal to ${this.exclusiveMaximum}`, + ) + assertValidation( + this.multipleOf === undefined || !(value % this.multipleOf), + `BigInt is not a multiple of ${this.multipleOf}`, + ) return value as N } @@ -138,7 +147,9 @@ export class BigIntValidator extends AbstractValidato export function bigintValidatorFactory(constraints: BigIntConstraints): BigIntValidator export function bigintValidatorFactory(constraints: BigIntConstraints): BigIntValidator -export function bigintValidatorFactory(constraints: BrandedBigIntConstraints): BigIntValidator> +export function bigintValidatorFactory( + constraints: BrandedBigIntConstraints, +): BigIntValidator> export function bigintValidatorFactory(constraints: BigIntConstraints): Validator { return new BigIntValidator(constraints) } diff --git a/src/validators/boolean.ts b/src/validators/boolean.ts index a2ca41e..e2a3ebe 100644 --- a/src/validators/boolean.ts +++ b/src/validators/boolean.ts @@ -1,5 +1,5 @@ -import { assertValidation } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertValidation } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' /** Constraints to validate a `boolean` with. */ export interface BooleanConstraints { @@ -9,10 +9,9 @@ export interface BooleanConstraints { * The string in question _MUST_ be either `true` or `false`, and will be * compared regardless of case. */ - fromString?: boolean, + fromString?: boolean } - /** A `Validator` validating `boolean`s. */ export class BooleanValidator extends AbstractValidator { readonly fromString: boolean @@ -25,7 +24,7 @@ export class BooleanValidator extends AbstractValidator { validate(value: unknown): boolean { // Allow parsing from strings - if ((typeof value === 'string') && (this.fromString)) { + if (typeof value === 'string' && this.fromString) { const string = value.toLowerCase() const parsed = string === 'true' ? true : string === 'false' ? false : undefined assertValidation(parsed !== undefined, 'Boolean can not be parsed from string') diff --git a/src/validators/constant.ts b/src/validators/constant.ts index b8da68a..a5e11bd 100644 --- a/src/validators/constant.ts +++ b/src/validators/constant.ts @@ -1,8 +1,8 @@ -import { assertValidation } from '../errors' -import { registry } from '../registry' -import { AbstractValidator } from '../types' +import { assertValidation } from '../errors.ts' +import { registry } from '../registry.ts' +import { AbstractValidator } from '../types.ts' -import type { Validator } from '../types' +import type { Validator } from '../types.ts' /** A `Validator` for _constants_. */ export class ConstantValidator extends AbstractValidator { diff --git a/src/validators/date.ts b/src/validators/date.ts index f9e8585..79ed927 100644 --- a/src/validators/date.ts +++ b/src/validators/date.ts @@ -1,5 +1,5 @@ -import { assertSchema, assertValidation, ValidationError } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertSchema, assertValidation, ValidationError } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' /** Lifted from AngularJS: matches a valid RFC 3339 string. */ const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/ @@ -12,11 +12,11 @@ export interface DateConstraints { * When the format is set to `unix-timestamp`, the validator will accept * numeric timestamps in seconds from the Epoch instead of milliseconds. */ - format?: 'iso' | 'timestamp' | 'unix-timestamp', + format?: 'iso' | 'timestamp' | 'unix-timestamp' /** The earliest value a date can have */ - from?: Date, + from?: Date /** The latest value a date can have */ - until?: Date, + until?: Date } /** A `Validator` validating dates and converting them to `Date` instances. */ @@ -30,9 +30,11 @@ export class DateValidator extends AbstractValidator= from.getTime(), - `Constraint "until" (${until.toISOString()}) must not be before "from" (${from.toISOString()})`) + if (from != undefined && until !== undefined) { + assertSchema( + until.getTime() >= from.getTime(), + `Constraint "until" (${until.toISOString()}) must not be before "from" (${from.toISOString()})`, + ) } this.format = format @@ -42,14 +44,18 @@ export class DateValidator extends AbstractValidator { - optional = true as const + override optional = true as const validate(value: unknown, options: ValidationOptions = {}): never { const { stripForbiddenProperties } = options // @ts-expect-error the type declaration should never return, but we do! - if (stripForbiddenProperties || (value === undefined)) return + if (stripForbiddenProperties || value === undefined) return throw new ValidationError('Forbidden property') } } diff --git a/src/validators/number.ts b/src/validators/number.ts index 2ab2556..5b248d4 100644 --- a/src/validators/number.ts +++ b/src/validators/number.ts @@ -1,7 +1,7 @@ -import { assertSchema, assertValidation, ValidationError } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertSchema, assertValidation, ValidationError } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' -import type { Branding, Validator } from '../types' +import type { Branding, Validator } from '../types.ts' /* ========================================================================== */ @@ -11,9 +11,9 @@ const MULTIPLIER = Math.pow(10, PRECISION) // multiplier for precision function countDecimals(n: number): number { // match the parts of the exponential form of the number const match = n.toExponential().match(/^\d+(\.\d+)?e([+-]\d+)$/) - if (! match) throw new RangeError(`Can't calculate digits for number "${n}"`) + if (!match) throw new RangeError(`Can't calculate digits for number "${n}"`) // number of digits in the absolute value, minus whatever is the exp - const digits = ((match[1] || '.').length - 1) - (parseInt(match[2])) + const digits = (match[1] || '.').length - 1 - parseInt(match[2]!) return digits < 0 ? 0 : digits } @@ -22,19 +22,19 @@ function countDecimals(n: number): number { /** Constraints to validate a `number` with. */ export interface NumberConstraints { /** The value for which a `number` must be multiple of for it to be valid */ - multipleOf?: number, + multipleOf?: number /** The _inclusive_ maximum value for a valid `number`: `value <= maximum` */ - maximum?: number, + maximum?: number /** The _inclusive_ minimum value for a valid `number`: `value >= minimum` */ - minimum?: number, + minimum?: number /** The _exclusive_ maximum value for a valid `number`: `value < exclusiveMaximum` */ - exclusiveMaximum?: number, + exclusiveMaximum?: number /** The _exclusive_ minimum value for a valid `number`: `value > exclusiveMaximum` */ - exclusiveMinimum?: number, + exclusiveMinimum?: number /** Allow numbers to be parsed from strings (e.g. `123.456` or `0x0CAFE`, default: `false`) */ - fromString?: boolean, + fromString?: boolean /** Whether to allow `NaN` or not (default: `false`) */ - allowNaN?: boolean, + allowNaN?: boolean } /** Constraints to validate a `number` with extra branding information. */ @@ -47,14 +47,14 @@ export interface BrandedNumberConstraints extends NumberConstr export class AnyNumberValidator extends AbstractValidator { validate(value: unknown): number { assertValidation(typeof value === 'number', 'Value is not a "number"') - assertValidation(! isNaN(value), 'Number is "NaN"') + assertValidation(!isNaN(value), 'Number is "NaN"') return value } } /** A `Validator` validating `number`s with constaints. */ export class NumberValidator extends AbstractValidator { - #isMultipleOf?: ((value: number) => boolean) + #isMultipleOf?: (value: number) => boolean readonly allowNaN: boolean readonly exclusiveMaximum?: number @@ -78,23 +78,29 @@ export class NumberValidator extends AbstractValidato multipleOf, } = constraints - if ('brand' in constraints) this.brand = ( constraints).brand + if ('brand' in constraints) this.brand = (constraints).brand assertSchema(maximum >= minimum, `Constraint "minimum" (${minimum}) is greater than "maximum" (${maximum})`) if (exclusiveMaximum !== undefined) { - assertSchema(exclusiveMaximum > minimum, - `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "minimum" (${minimum})`) + assertSchema( + exclusiveMaximum > minimum, + `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "minimum" (${minimum})`, + ) } if (exclusiveMinimum !== undefined) { - assertSchema(maximum > exclusiveMinimum, - `Constraint "maximum" (${maximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`) + assertSchema( + maximum > exclusiveMinimum, + `Constraint "maximum" (${maximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`, + ) } - if ((exclusiveMinimum != undefined) && (exclusiveMaximum !== undefined)) { - assertSchema(exclusiveMaximum > exclusiveMinimum, - `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`) + if (exclusiveMinimum != undefined && exclusiveMaximum !== undefined) { + assertSchema( + exclusiveMaximum > exclusiveMinimum, + `Constraint "exclusiveMaximum" (${exclusiveMaximum}) must be greater than "exclusiveMinimum" (${exclusiveMinimum})`, + ) } if (multipleOf !== undefined) { @@ -103,13 +109,13 @@ export class NumberValidator extends AbstractValidato if (decimals === 0) { // Easy case is when we only have to deal with integers... - this.#isMultipleOf = (value): boolean => ! (value % multipleOf) + this.#isMultipleOf = (value): boolean => !(value % multipleOf) } else if (decimals <= PRECISION) { // We have some "decimal" part (max 6 decimal digits), multiply... this.#isMultipleOf = (value): boolean => { try { if (countDecimals(value) > PRECISION) return false - return ! ((value * MULTIPLIER) % (multipleOf * MULTIPLIER)) + return !((value * MULTIPLIER) % (multipleOf * MULTIPLIER)) } catch (error: any) { throw new ValidationError(error.message) } @@ -131,9 +137,9 @@ export class NumberValidator extends AbstractValidato validate(value: unknown): N { // Allow parsing from strings - if ((typeof value === 'string') && (this.fromString)) { + if (typeof value === 'string' && this.fromString) { const parsed = +`${value}` - assertValidation(! isNaN(parsed), 'Number can not be parsed from string') + assertValidation(!isNaN(parsed), 'Number can not be parsed from string') value = parsed } @@ -147,14 +153,20 @@ export class NumberValidator extends AbstractValidato assertValidation(value >= this.minimum, `Number is less than ${this.minimum}`) assertValidation(value <= this.maximum, `Number is greater than ${this.maximum}`) - assertValidation((this.exclusiveMinimum === undefined) || (value > this.exclusiveMinimum), - `Number is less than or equal to ${this.exclusiveMinimum}`) + assertValidation( + this.exclusiveMinimum === undefined || value > this.exclusiveMinimum, + `Number is less than or equal to ${this.exclusiveMinimum}`, + ) - assertValidation((this.exclusiveMaximum === undefined) || (value < this.exclusiveMaximum), - `Number is greater than or equal to ${this.exclusiveMaximum}`) + assertValidation( + this.exclusiveMaximum === undefined || value < this.exclusiveMaximum, + `Number is greater than or equal to ${this.exclusiveMaximum}`, + ) - assertValidation(this.#isMultipleOf ? this.#isMultipleOf(value) : true, - `Number is not a multiple of ${this.multipleOf}`) + assertValidation( + this.#isMultipleOf ? this.#isMultipleOf(value) : true, + `Number is not a multiple of ${this.multipleOf}`, + ) return value as N } @@ -162,7 +174,9 @@ export class NumberValidator extends AbstractValidato export function numberValidatorFactory(constraints: NumberConstraints): NumberValidator export function numberValidatorFactory(constraints: NumberConstraints): NumberValidator -export function numberValidatorFactory(constraints: BrandedNumberConstraints): NumberValidator> +export function numberValidatorFactory( + constraints: BrandedNumberConstraints, +): NumberValidator> export function numberValidatorFactory(constraints: NumberConstraints): Validator { return new NumberValidator(constraints) } diff --git a/src/validators/object.ts b/src/validators/object.ts index 33d1dd4..5ed8d3d 100644 --- a/src/validators/object.ts +++ b/src/validators/object.ts @@ -1,14 +1,18 @@ -import { assertValidation, ValidationErrorBuilder } from '../errors' -import { registry } from '../registry' -import { AbstractValidator, makeValidatorFactory } from '../types' -import { getValidator } from '../utilities' +import { assertValidation, ValidationErrorBuilder } from '../errors.ts' +import { registry } from '../registry.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' +import { getValidator } from '../utilities.ts' import type { InferInputSchema, - InferSchema, InferValidation, Schema, TupleRestParameter, Validation, + InferSchema, + InferValidation, + Schema, + TupleRestParameter, + Validation, ValidationOptions, Validator, -} from '../types' +} from '../types.ts' /* ========================================================================== * * OBJECT VALIDATOR * @@ -37,7 +41,7 @@ export class ObjectValidator extends AbstractValidator extends AbstractValidator = {} - for (const [ key, validator ] of this.validators.entries()) { - const optional = (!! validator.optional) || (!! partialValidation) + for (const [key, validator] of this.validators.entries()) { + const optional = !!validator.optional || !!partialValidation const original = record[key] // strip any optional "null" value if told to do so - if (stripOptionalNulls && optional && (original === null)) { + if (stripOptionalNulls && optional && original === null) { continue } @@ -73,7 +77,7 @@ export class ObjectValidator extends AbstractValidator extends AbstractValidator extends AbstractValidator { if (record[key] !== undefined) builder.record('Unknown property', key) }) @@ -115,7 +119,9 @@ export class ObjectValidator extends AbstractValidator(schema: S): S & { +export function objectValidatorFactory( + schema: S, +): S & { [Symbol.iterator](): Generator, InferInputSchema>> } { const validator = new ObjectValidator(schema) diff --git a/src/validators/optional.ts b/src/validators/optional.ts index f2a895d..72653fa 100644 --- a/src/validators/optional.ts +++ b/src/validators/optional.ts @@ -1,18 +1,16 @@ -import { AbstractValidator } from '../types' -import { getValidator } from '../utilities' +import { AbstractValidator } from '../types.ts' +import { getValidator } from '../utilities.ts' -import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types' +import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types.ts' -/** - * A `Validator` for _optional_ properties (that is `type | undefined`). - */ +/** A `Validator` for _optional_ properties (that is `type | undefined`). */ export class OptionalValidator< T = any, // the type of the "validation", that is the optional type to validate I = T, // the _input_ type of the "validation", that is anything acceptable D = undefined, // the default value (or undefined) > extends AbstractValidator { validator: Validator - defaultValue: T | undefined + override defaultValue: T | undefined constructor(validator: Validator) constructor(validator: Validator, defaultValue: D) @@ -45,17 +43,19 @@ export class OptionalValidator< * * @param validation - A `Validation` to be marked as _optional_. */ -export function optional< - V extends Validation, ->(validation: V): OptionalValidator, InferInput, undefined> - -export function optional< - V extends Validation, D, ->(validation: V, defaultValue: D): OptionalValidator, InferInput, D> - -export function optional< - V extends Validation, D, ->(validation: V, defaultValue?: D): OptionalValidator, InferInput, D> { +export function optional( + validation: V, +): OptionalValidator, InferInput, undefined> + +export function optional( + validation: V, + defaultValue: D, +): OptionalValidator, InferInput, D> + +export function optional( + validation: V, + defaultValue?: D, +): OptionalValidator, InferInput, D> { const validator = getValidator(validation) return new OptionalValidator(validator, defaultValue) } diff --git a/src/validators/string.ts b/src/validators/string.ts index 98744cf..77df5f5 100644 --- a/src/validators/string.ts +++ b/src/validators/string.ts @@ -1,16 +1,16 @@ -import { assertSchema, assertValidation } from '../errors' -import { AbstractValidator, makeValidatorFactory } from '../types' +import { assertSchema, assertValidation } from '../errors.ts' +import { AbstractValidator, makeValidatorFactory } from '../types.ts' -import type { Branding, Validator } from '../types' +import type { Branding, Validator } from '../types.ts' /** Constraints to validate a `string` with. */ export interface StringConstraints { /** The _maximum_ length of a valid `string`: `value.length <= maxLength` */ - maxLength?: number, + maxLength?: number /** The _minimum_ length of a valid `string`: `value.length >= minLength` */ - minLength?: number, + minLength?: number /** A `RegExp` enforcing a particular pattern for a valid `string`: `pattern.test(value)` */ - pattern?: RegExp, + pattern?: RegExp } /** Constraints to validate a `string` with extra branding information. */ @@ -37,17 +37,16 @@ export class StringValidator extends Abst constructor(constraints: StringConstraints = {}) { super() - const { - minLength = 0, - maxLength = Number.MAX_SAFE_INTEGER, - pattern, - } = constraints + const { minLength = 0, maxLength = Number.MAX_SAFE_INTEGER, pattern } = constraints - if ('brand' in constraints) this.brand = ( constraints).brand + if ('brand' in constraints) this.brand = (constraints).brand assertSchema(minLength >= 0, `Constraint "minLength" (${minLength}) must be non-negative`) assertSchema(maxLength >= 0, `Constraint "maxLength" (${maxLength}) must be non-negative`) - assertSchema(minLength <= maxLength, `Constraint "minLength" (${minLength}) is greater than "maxLength" (${maxLength})`) + assertSchema( + minLength <= maxLength, + `Constraint "minLength" (${minLength}) is greater than "maxLength" (${maxLength})`, + ) this.maxLength = maxLength this.minLength = minLength @@ -57,14 +56,14 @@ export class StringValidator extends Abst validate(value: unknown): S { assertValidation(typeof value === 'string', 'Value is not a "string"') - assertValidation(value.length >= this.minLength, - `String must have a minimum length of ${this.minLength}`) + assertValidation(value.length >= this.minLength, `String must have a minimum length of ${this.minLength}`) - assertValidation(value.length <= this.maxLength, - `String must have a maximum length of ${this.maxLength}`) + assertValidation(value.length <= this.maxLength, `String must have a maximum length of ${this.maxLength}`) - assertValidation(this.pattern ? this.pattern.test(value) : true, - `String does not match required pattern ${this.pattern}`) + assertValidation( + this.pattern ? this.pattern.test(value) : true, + `String does not match required pattern ${this.pattern}`, + ) return value as S } @@ -72,7 +71,9 @@ export class StringValidator extends Abst export function stringValidatorFactory(constraints: StringConstraints): StringValidator export function stringValidatorFactory(constraints: StringConstraints): StringValidator -export function stringValidatorFactory(constraints: BrandedStringConstraints): StringValidator> +export function stringValidatorFactory( + constraints: BrandedStringConstraints, +): StringValidator> export function stringValidatorFactory(constraints: StringConstraints): Validator { return new StringValidator(constraints) } diff --git a/src/validators/tuple.ts b/src/validators/tuple.ts index 09b1d50..17bf607 100644 --- a/src/validators/tuple.ts +++ b/src/validators/tuple.ts @@ -1,7 +1,7 @@ -import { assertValidation, ValidationError } from '../errors' -import { registry } from '../registry' -import { AbstractValidator } from '../types' -import { getValidator } from '../utilities' +import { assertValidation, ValidationError } from '../errors.ts' +import { registry } from '../registry.ts' +import { AbstractValidator } from '../types.ts' +import { getValidator } from '../utilities.ts' import type { InferInputTuple, @@ -11,10 +11,11 @@ import type { Validation, ValidationOptions, Validator, -} from '../types' +} from '../types.ts' export interface TupleMember { - single: boolean, validator: Validator + single: boolean + validator: Validator } /** A `Validator` for _tuples_. */ @@ -27,9 +28,10 @@ export class TupleValidator extends AbstractValidatoritem)[Symbol.justusRestValidator] }) } else { members.push({ single: true, validator: getValidator(item) }) @@ -51,28 +53,28 @@ export class TupleValidator extends AbstractValidator 1) { throw new ValidationError(`Tuple defines ${missing} missing validations`) @@ -86,10 +88,11 @@ export class TupleValidator extends AbstractValidator, ...Tuple ] -| readonly [ ...Tuple, Validation | TupleRestParameter ] -| readonly [ ...Tuple ], // ... this is bascially an array... +export function tuple< + T extends + | readonly [Validation | TupleRestParameter, ...Tuple] + | readonly [...Tuple, Validation | TupleRestParameter] + | readonly [...Tuple], // ... this is bascially an array... >(tuple: T): Validator, InferInputTuple> { return new TupleValidator(tuple) } diff --git a/src/validators/union.ts b/src/validators/union.ts index cb120df..10ff5d8 100644 --- a/src/validators/union.ts +++ b/src/validators/union.ts @@ -1,48 +1,42 @@ -import { assertSchema, ValidationErrorBuilder } from '../errors' -import { AbstractValidator } from '../types' -import { getValidator } from '../utilities' - -import type { - InferInput, - InferValidation, - Validation, - ValidationOptions, - Validator, -} from '../types' +import { assertSchema, ValidationErrorBuilder } from '../errors.ts' +import { AbstractValidator } from '../types.ts' +import { getValidator } from '../utilities.ts' + +import type { InferInput, InferValidation, Validation, ValidationOptions, Validator } from '../types.ts' /* -------------------------------------------------------------------------- */ export type OneOfArguments = readonly Validation[] -export type InferOneOfValidation = - A extends readonly [ infer First, ...infer Rest ] ? - First extends Validation ? - Rest extends OneOfArguments ? - InferValidation | InferOneOfValidation : - InferValidation : - never : - A extends readonly (infer Type)[] ? - Type extends Validation ? - InferValidation : - never : - never - -export type InferOneOfInput = - A extends readonly [ infer First, ...infer Rest ] ? - First extends Validation ? - Rest extends OneOfArguments ? - InferInput | InferOneOfInput : - InferInput : - never : - A extends readonly (infer Type)[] ? - Type extends Validation ? - InferInput : - never : - never +export type InferOneOfValidation = A extends readonly [infer First, ...infer Rest] + ? First extends Validation + ? Rest extends OneOfArguments + ? InferValidation | InferOneOfValidation + : InferValidation + : never + : A extends readonly (infer Type)[] + ? Type extends Validation + ? InferValidation + : never + : never + +export type InferOneOfInput = A extends readonly [infer First, ...infer Rest] + ? First extends Validation + ? Rest extends OneOfArguments + ? InferInput | InferOneOfInput + : InferInput + : never + : A extends readonly (infer Type)[] + ? Type extends Validation + ? InferInput + : never + : never /** A `Validator` validating a value as _one of_ the specified arguments. */ -export class OneOfValidator - extends AbstractValidator, InferOneOfInput> { +export class OneOfValidator extends AbstractValidator< + InferOneOfValidation, + InferOneOfInput +> { readonly validators: readonly Validator[] constructor(args: A) { @@ -71,29 +65,29 @@ export function oneOf(...args: A): OneOfValidator { /* -------------------------------------------------------------------------- */ -export type AllOfArguments = readonly [ Validation, ...Validation[] ] - -export type InferAllOfValidation = - A extends readonly [ infer First, ...infer Rest ] ? - First extends Validation ? - Rest extends AllOfArguments ? - InferValidation & InferAllOfValidation : - InferValidation : - never : - never - -export type InferAllOfInput = - A extends readonly [ infer First, ...infer Rest ] ? - First extends Validation ? - Rest extends AllOfArguments ? - InferInput & InferAllOfInput : - InferInput : - never : - never +export type AllOfArguments = readonly [Validation, ...Validation[]] + +export type InferAllOfValidation = A extends readonly [infer First, ...infer Rest] + ? First extends Validation + ? Rest extends AllOfArguments + ? InferValidation & InferAllOfValidation + : InferValidation + : never + : never + +export type InferAllOfInput = A extends readonly [infer First, ...infer Rest] + ? First extends Validation + ? Rest extends AllOfArguments + ? InferInput & InferAllOfInput + : InferInput + : never + : never /** A `Validator` validating a value as _all of_ the specified arguments. */ -export class AllOfValidator - extends AbstractValidator, InferAllOfInput> { +export class AllOfValidator extends AbstractValidator< + InferAllOfValidation, + InferAllOfInput +> { readonly validators: readonly Validator[] constructor(args: A) { diff --git a/test-d/00-primitives.test-d.ts b/test-d/00-primitives.test-d.ts index ca25e19..0fd7b14 100644 --- a/test-d/00-primitives.test-d.ts +++ b/test-d/00-primitives.test-d.ts @@ -1,14 +1,6 @@ import { expectType, printType } from 'tsd' -import { - any, - bigint, - boolean, - constant, - number, - string, - validate, -} from '../src' +import { any, bigint, boolean, constant, number, string, validate } from '../src/index.ts' printType('__file_marker__') diff --git a/test-d/01-arrays.test-d.ts b/test-d/01-arrays.test-d.ts index fc505c0..a6e775d 100644 --- a/test-d/01-arrays.test-d.ts +++ b/test-d/01-arrays.test-d.ts @@ -1,15 +1,6 @@ import { expectType, printType } from 'tsd' -import { - any, - array, - arrayOf, - boolean, - constant, - number, - string, - validate, -} from '../src' +import { any, array, arrayOf, boolean, constant, number, string, validate } from '../src/index.ts' printType('__file_marker__') diff --git a/test-d/02-objects.test-d.ts b/test-d/02-objects.test-d.ts index fffba13..8812799 100644 --- a/test-d/02-objects.test-d.ts +++ b/test-d/02-objects.test-d.ts @@ -1,17 +1,7 @@ import { expectAssignable, expectType, printType } from 'tsd' -import { - any, - array, - arrayOf, - boolean, - constant, - number, - object, - string, - validate, -} from '../src' -import { objectOf } from '../src/validators/object' +import { any, array, arrayOf, boolean, constant, number, object, string, validate } from '../src/index.ts' +import { objectOf } from '../src/validators/object.ts' printType('__file_marker__') @@ -22,14 +12,17 @@ type BrandedString = string & { __branded_string: never } // plain exports expectType>(validate(object, null)) -const o1 = validate(object({ - x: any, - b: boolean, - n: number, - s: string, - a: array, - o: object, -}), null) +const o1 = validate( + object({ + x: any, + b: boolean, + n: number, + s: string, + a: array, + o: object, + }), + null, +) expectType(o1.x) expectType(o1.b) @@ -39,22 +32,25 @@ expectType(o1.a) expectType>(o1.o) expectAssignable<{ - x?: any, - b: boolean, - n: number, - s: string, - a: any[], - o: Record, + x?: any + b: boolean + n: number + s: string + a: any[] + o: Record }>(o1) // -------------------------------------------------------------------------- // // constructed validators -const o2 = validate(object({ - n: number({}), - s: string({}), - a: arrayOf(boolean), - o: object({ x: boolean }), -}), null) +const o2 = validate( + object({ + n: number({}), + s: string({}), + a: arrayOf(boolean), + o: object({ x: boolean }), + }), + null, +) expectType(o2.n) expectType(o2.s) @@ -62,20 +58,23 @@ expectType(o2.a) expectType(o2.o.x) expectAssignable<{ - n: number, - s: string, - a: boolean[], - o: { x: boolean }, + n: number + s: string + a: boolean[] + o: { x: boolean } }>(o2) // -------------------------------------------------------------------------- // // constructed validators -const o3 = validate(object({ - n: number({}), - s: string({}), - a: array({ items: string({}) }), - o: object({ x: string({}) }), -}), null) +const o3 = validate( + object({ + n: number({}), + s: string({}), + a: array({ items: string({}) }), + o: object({ x: string({}) }), + }), + null, +) expectType(o3.n) expectType(o3.s) @@ -83,22 +82,25 @@ expectType(o3.a) expectType(o3.o.x) expectAssignable<{ - n: number, - s: string, - a: string[], - o: { x: string }, + n: number + s: string + a: string[] + o: { x: string } }>(o3) // -------------------------------------------------------------------------- // // constants -const o4 = validate(object({ - z: constant(null), - t: constant(true), - f: constant(false), - n: constant(12345), - s: constant('xyz'), -}), null) +const o4 = validate( + object({ + z: constant(null), + t: constant(true), + f: constant(false), + n: constant(12345), + s: constant('xyz'), + }), + null, +) expectType(o4.z) expectType(o4.t) @@ -107,23 +109,26 @@ expectType<12345>(o4.n) expectType<'xyz'>(o4.s) expectAssignable<{ - z: null, - t: true, - f: false, - n: 12345, - s: 'xyz', + z: null + t: true + f: false + n: 12345 + s: 'xyz' }>(o4) // -------------------------------------------------------------------------- // // simple constants (here we need "as const" on numbers and strings) -const o5 = validate(object({ - z: null, - t: true, - f: false, - n: 12345 as const, - s: 'xyz' as const, -}), null) +const o5 = validate( + object({ + z: null, + t: true, + f: false, + n: 12345 as const, + s: 'xyz' as const, + }), + null, +) expectType(o5.z) expectType(o5.t) @@ -132,27 +137,30 @@ expectType<12345>(o5.n) expectType<'xyz'>(o5.s) expectAssignable<{ - z: null, - t: true, - f: false, - n: 12345, - s: 'xyz', + z: null + t: true + f: false + n: 12345 + s: 'xyz' }>(o5) // -------------------------------------------------------------------------- // // "branded" primitives -const o6 = validate(object({ - n: number({}), - s: string({}), -}), null) +const o6 = validate( + object({ + n: number({}), + s: string({}), + }), + null, +) expectType(o6.n) expectType(o6.s) expectAssignable<{ - n: BrandedNumber, - s: BrandedString, + n: BrandedNumber + s: BrandedString }>(o6) // -------------------------------------------------------------------------- // @@ -161,8 +169,8 @@ expectAssignable<{ const o7 = validate(objectOf(number), null) expectType>(o7) -const o8 = validate(objectOf([ 1, 2, 3 ] as const), null) -expectType>(o8) +const o8 = validate(objectOf([1, 2, 3] as const), null) +expectType>(o8) const o9 = validate(objectOf({ test: boolean }), null) expectAssignable>(o9) diff --git a/test-d/03-optional.test-d.ts b/test-d/03-optional.test-d.ts index 77c19b2..fa45a36 100644 --- a/test-d/03-optional.test-d.ts +++ b/test-d/03-optional.test-d.ts @@ -13,9 +13,9 @@ import { OptionalValidator, string, validate, -} from '../src' +} from '../src/index.ts' -import type { InferValidation } from '../src' +import type { InferValidation } from '../src/index.ts' printType('__file_marker__') @@ -25,33 +25,39 @@ type BrandedString = string & { __branded_string: never } // -------------------------------------------------------------------------- // // combining modifiers -const o1 = validate(object({ - x: string, - o: optional(string), - oo: optional(optional(string)), -}), null) +const o1 = validate( + object({ + x: string, + o: optional(string), + oo: optional(optional(string)), + }), + null, +) expectType(o1.x) expectType(o1.o) expectType(o1.oo) expectAssignable<{ - readonly x: string, - o?: string | undefined, - oo?: string | undefined, + readonly x: string + o?: string | undefined + oo?: string | undefined }>(o1) // -------------------------------------------------------------------------- // // plain exports -const o2 = validate(object({ - ox: optional(any), - ob: optional(boolean), - on: optional(number), - os: optional(string), - oa: optional(array), - oo: optional(object), -}), null) +const o2 = validate( + object({ + ox: optional(any), + ob: optional(boolean), + on: optional(number), + os: optional(string), + oa: optional(array), + oo: optional(object), + }), + null, +) expectType(o2.ox) expectType(o2.ob) @@ -61,45 +67,51 @@ expectType(o2.oa) expectType | undefined>(o2.oo) expectAssignable<{ - ox?: any | undefined, - ob?: boolean | undefined, - on?: number | undefined, - os?: string | undefined, - oa?: any[] | undefined, - oo?: Record | undefined, + ox?: any | undefined + ob?: boolean | undefined + on?: number | undefined + os?: string | undefined + oa?: any[] | undefined + oo?: Record | undefined }>(o2) // -------------------------------------------------------------------------- // // constructed validators -const o3 = validate(object({ - on: optional(number({})), - os: optional(string({})), - oa: optional(array({})), -}), null) +const o3 = validate( + object({ + on: optional(number({})), + os: optional(string({})), + oa: optional(array({})), + }), + null, +) expectType(o3.on) expectType(o3.os) expectType(o3.oa) expectAssignable<{ - ox?: any | undefined, - ob?: boolean | undefined, - on?: number | undefined, - os?: string | undefined, - oa?: any[] | undefined, + ox?: any | undefined + ob?: boolean | undefined + on?: number | undefined + os?: string | undefined + oa?: any[] | undefined }>(o3) // -------------------------------------------------------------------------- // // constants -const o4 = validate(object({ - oz: optional(constant(null)), - ot: optional(constant(true)), - of: optional(constant(false)), - on: optional(constant(12345)), - os: optional(constant('xyz')), -}), null) +const o4 = validate( + object({ + oz: optional(constant(null)), + ot: optional(constant(true)), + of: optional(constant(false)), + on: optional(constant(12345)), + os: optional(constant('xyz')), + }), + null, +) expectType(o4.oz) expectType(o4.ot) @@ -108,23 +120,26 @@ expectType<12345 | undefined>(o4.on) expectType<'xyz' | undefined>(o4.os) expectAssignable<{ - oz?: null | undefined, - ot?: true | undefined, - of?: false | undefined, - on?: 12345 | undefined, - os?: 'xyz' | undefined, + oz?: null | undefined + ot?: true | undefined + of?: false | undefined + on?: 12345 | undefined + os?: 'xyz' | undefined }>(o4) // -------------------------------------------------------------------------- // // simple constants (no need for "as const" on numbers and strings) -const o5 = validate(object({ - oz: optional(null), - ot: optional(true), - of: optional(false), - on: optional(12345), - os: optional('xyz'), -}), null) +const o5 = validate( + object({ + oz: optional(null), + ot: optional(true), + of: optional(false), + on: optional(12345), + os: optional('xyz'), + }), + null, +) expectType(o5.oz) expectType(o5.ot) @@ -133,27 +148,30 @@ expectType<12345 | undefined>(o5.on) expectType<'xyz' | undefined>(o5.os) expectAssignable<{ - oz?: null | undefined, - ot?: true | undefined, - of?: false | undefined, - on?: 12345 | undefined, - os?: 'xyz' | undefined, + oz?: null | undefined + ot?: true | undefined + of?: false | undefined + on?: 12345 | undefined + os?: 'xyz' | undefined }>(o5) // -------------------------------------------------------------------------- // // "branded" primitives -const o6 = validate(object({ - on: optional(number({})), - os: optional(string({})), -}), null) +const o6 = validate( + object({ + on: optional(number({})), + os: optional(string({})), + }), + null, +) expectType(o6.on) expectType(o6.os) expectAssignable<{ - on?: BrandedNumber | undefined, - os?: BrandedString | undefined, + on?: BrandedNumber | undefined + os?: BrandedString | undefined }>(o6) // -------------------------------------------------------------------------- // @@ -227,4 +245,4 @@ const v1 = object({ noDefault: optional(number), }) const x1 = validate(v1, null) -expectAssignable<{ hasDefault: string, noDefault?: number | undefined }>(x1) +expectAssignable<{ hasDefault: string; noDefault?: number | undefined }>(x1) diff --git a/test-d/04-addprops.test-d.ts b/test-d/04-addprops.test-d.ts index 2f8a69b..a5678c6 100644 --- a/test-d/04-addprops.test-d.ts +++ b/test-d/04-addprops.test-d.ts @@ -1,45 +1,62 @@ import { expectAssignable, expectError, expectType, printType } from 'tsd' -import { - allowAdditionalProperties, - boolean, - never, - number, - object, - string, - validate, -} from '../src' +import { allowAdditionalProperties, boolean, never, number, object, string, validate } from '../src/index.ts' printType('__file_marker__') // -------------------------------------------------------------------------- // -expectError(validate(object({ - // no ...additionalProperties -}), null).extra) - -expectType(validate(object({ - ...allowAdditionalProperties, // as a function -}), null).extra) - -expectType(validate(object({ - ...allowAdditionalProperties(), // default = true -}), null).extra) - -expectType(validate(object({ - ...allowAdditionalProperties(true), -}), null).extra) - -expectError(validate(object({ - ...allowAdditionalProperties(false), -}), null).extra) +expectError( + validate( + object({ + // no ...additionalProperties + }), + null, + ).extra, +) + +expectType( + validate( + object({ + ...allowAdditionalProperties, // as a function + }), + null, + ).extra, +) + +expectType( + validate( + object({ + ...allowAdditionalProperties(), // default = true + }), + null, + ).extra, +) + +expectType( + validate( + object({ + ...allowAdditionalProperties(true), + }), + null, + ).extra, +) + +expectError( + validate( + object({ + ...allowAdditionalProperties(false), + }), + null, + ).extra, +) // -------------------------------------------------------------------------- // -expectType(validate(object({ ...allowAdditionalProperties(null) }), null).extra) -expectType>(validate(object({ ...allowAdditionalProperties(object) }), null).extra) -expectType(validate(object({ ...allowAdditionalProperties(number) }), null).extra) -expectType<'hello'>(validate(object({ ...allowAdditionalProperties('hello') }), null).extra) +expectType(validate(object({ ...allowAdditionalProperties(null) }), null).extra) +expectType | undefined>(validate(object({ ...allowAdditionalProperties(object) }), null).extra) +expectType(validate(object({ ...allowAdditionalProperties(number) }), null).extra) +expectType<'hello' | undefined>(validate(object({ ...allowAdditionalProperties('hello') }), null).extra) // -------------------------------------------------------------------------- // // combining schemas @@ -66,7 +83,7 @@ const o1 = validate(s1, null) expectType(o1.a) expectType(o1.b) expectType(o1.c) -expectType(o1.extra) +expectType(o1.extra) const o2 = validate(s2, null) @@ -89,7 +106,7 @@ const o4 = validate(s4, null) expectType(o4.a) expectType(o4.b) expectType(o4.c) -expectAssignable<{ a: number, b?: undefined, c: string }>(o4) +expectAssignable<{ a: number; b?: undefined; c: string }>(o4) expectError(o4.extra) // no additional properties // never with "additionalProperties" @@ -106,5 +123,5 @@ const o5 = validate(s5, null) expectType(o5.a) expectType(o5.b) // forcedly removed from the resulting object expectType(o5.c) -expectAssignable<{ a: number, b?: undefined, c: string } & { [ k in string ]: boolean }>(o5) -expectType(o5.extra) // defined in additionalProperties +expectAssignable<{ a: number; b?: undefined; c: string } & { [k in string]: boolean }>(o5) +expectType(o5.extra) // defined in additionalProperties diff --git a/test-d/05-tuples.test-d.ts b/test-d/05-tuples.test-d.ts index e4e9e1c..2530225 100644 --- a/test-d/05-tuples.test-d.ts +++ b/test-d/05-tuples.test-d.ts @@ -1,124 +1,132 @@ import { expectAssignable, expectType, printType } from 'tsd' -import { boolean, number, object, string, tuple, validate } from '../src' +import { boolean, number, object, string, tuple, validate } from '../src/index.ts' printType('__file_marker__') // with "as const" -expectType<[ 1 ]>(validate(tuple([ 1 ] as const), null)) -expectType<[ 1, 'foo' ]>(validate(tuple([ 1, 'foo' ] as const), null)) +expectType<[1]>(validate(tuple([1] as const), null)) +expectType<[1, 'foo']>(validate(tuple([1, 'foo'] as const), null)) // without "as const" -expectType<[ number ]>(validate(tuple([ 1 ]), null)) -expectType<[ number, string ]>(validate(tuple([ 1, 'foo' ]), null)) +expectType<[number]>(validate(tuple([1]), null)) +expectType<[number, string]>(validate(tuple([1, 'foo']), null)) // with validators -expectType<[ number, string ]>(validate(tuple([ 1, string ]), null)) -expectType<[ 1, number ]>(validate(tuple([ 1, number ] as const), null)) +expectType<[number, string]>(validate(tuple([1, string]), null)) +expectType<[1, number]>(validate(tuple([1, number] as const), null)) // with rest arguments -expectType<[ number, ...string[] ]>(validate(tuple([ 1, ...string ]), null)) -expectType<[ 1, ...number[] ]>(validate(tuple([ 1, ...number ] as const), null)) +expectType<[number, ...string[]]>(validate(tuple([1, ...string]), null)) +expectType<[1, ...number[]]>(validate(tuple([1, ...number] as const), null)) -expectType<[ number, ...string[] ]>(validate(tuple([ 1, ...string ]), null)) -expectType<[ 1, ...number[] ]>(validate(tuple([ 1, ...number ] as const), null)) +expectType<[number, ...string[]]>(validate(tuple([1, ...string]), null)) +expectType<[1, ...number[]]>(validate(tuple([1, ...number] as const), null)) // only rest arguments -expectType(validate(tuple([ ...string ]), null)) -expectType(validate(tuple([ ...number ] as const), null)) +expectType(validate(tuple([...string]), null)) +expectType(validate(tuple([...number] as const), null)) -expectType<(string | number)[]>(validate(tuple([ ...string, ...number ]), null)) -expectType<(string | number)[]>(validate(tuple([ ...number, ...string ] as const), null)) +expectType<(string | number)[]>(validate(tuple([...string, ...number]), null)) +expectType<(string | number)[]>(validate(tuple([...number, ...string] as const), null)) // more tests -expectType<[ string, boolean, number, string ]>(validate(tuple([ string, boolean, number, string ] as const), null)) -expectType<[ ...string[], boolean, number, string ]>(validate(tuple([ ...string, boolean, number, string ] as const), null)) -expectType<[ string, ...boolean[], number, string ]>(validate(tuple([ string, ...boolean, number, string ] as const), null)) -expectType<[ string, boolean, ...number[], string ]>(validate(tuple([ string, boolean, ...number, string ] as const), null)) -expectType<[ string, boolean, number, ...string[] ]>(validate(tuple([ string, boolean, number, ...string ] as const), null)) -expectType<[ string, ...(boolean|number)[], string ]>(validate(tuple([ string, ...boolean, ...number, string ] as const), null)) -expectType<[ string, ...(boolean|string|number)[], string ]>(validate(tuple([ string, ...boolean, string, ...number, string ] as const), null)) - -expectType<[ 'foo', false, 12345, 'bar' ]>(validate(tuple([ 'foo', false, 12345, 'bar' ] as const), null)) -expectType<[ ...string[], false, 12345, 'bar' ]>(validate(tuple([ ...string, false, 12345, 'bar' ] as const), null)) -expectType<[ 'foo', ...boolean[], 12345, 'bar' ]>(validate(tuple([ 'foo', ...boolean, 12345, 'bar' ] as const), null)) -expectType<[ 'foo', false, ...number[], 'bar' ]>(validate(tuple([ 'foo', false, ...number, 'bar' ] as const), null)) -expectType<[ 'foo', false, 12345, ...string[] ]>(validate(tuple([ 'foo', false, 12345, ...string ] as const), null)) -expectType<[ 'foo', ...(boolean|number)[], 'bar' ]>(validate(tuple([ 'foo', ...boolean, ...number, 'bar' ] as const), null)) -expectType<[ 'foo', ...(boolean|'xxx'|number)[], 'bar' ]>(validate(tuple([ 'foo', ...boolean, 'xxx', ...number, 'bar' ] as const), null)) +expectType<[string, boolean, number, string]>(validate(tuple([string, boolean, number, string] as const), null)) +expectType<[...string[], boolean, number, string]>(validate(tuple([...string, boolean, number, string] as const), null)) +expectType<[string, ...boolean[], number, string]>(validate(tuple([string, ...boolean, number, string] as const), null)) +expectType<[string, boolean, ...number[], string]>(validate(tuple([string, boolean, ...number, string] as const), null)) +expectType<[string, boolean, number, ...string[]]>(validate(tuple([string, boolean, number, ...string] as const), null)) +expectType<[string, ...(boolean | number)[], string]>( + validate(tuple([string, ...boolean, ...number, string] as const), null), +) +expectType<[string, ...(boolean | string | number)[], string]>( + validate(tuple([string, ...boolean, string, ...number, string] as const), null), +) + +expectType<['foo', false, 12345, 'bar']>(validate(tuple(['foo', false, 12345, 'bar'] as const), null)) +expectType<[...string[], false, 12345, 'bar']>(validate(tuple([...string, false, 12345, 'bar'] as const), null)) +expectType<['foo', ...boolean[], 12345, 'bar']>(validate(tuple(['foo', ...boolean, 12345, 'bar'] as const), null)) +expectType<['foo', false, ...number[], 'bar']>(validate(tuple(['foo', false, ...number, 'bar'] as const), null)) +expectType<['foo', false, 12345, ...string[]]>(validate(tuple(['foo', false, 12345, ...string] as const), null)) +expectType<['foo', ...(boolean | number)[], 'bar']>( + validate(tuple(['foo', ...boolean, ...number, 'bar'] as const), null), +) +expectType<['foo', ...(boolean | 'xxx' | number)[], 'bar']>( + validate(tuple(['foo', ...boolean, 'xxx', ...number, 'bar'] as const), null), +) // tuples in objects const validator1 = object({ - tuple: [ number, string, ...boolean ], + tuple: [number, string, ...boolean], } as const) const result1 = validate(validator1, null) -expectAssignable<{ tuple: [ number, string, ...boolean[] ] }>(result1) -expectType<[ number, string, ...boolean[] ]>(result1.tuple) +expectAssignable<{ tuple: [number, string, ...boolean[]] }>(result1) +expectType<[number, string, ...boolean[]]>(result1.tuple) expectType(result1.tuple[0]) expectType(result1.tuple[1]) -expectType(result1.tuple[2]) -expectType(result1.tuple[9]) +expectType(result1.tuple[2]) +expectType(result1.tuple[9]) const validator2 = object({ - tuple: [ 12345, 'foo', ...boolean ], + tuple: [12345, 'foo', ...boolean], } as const) const result2 = validate(validator2, null) -expectAssignable<{ tuple: [ 12345, 'foo', ...boolean[] ] }>(result2) -expectType<[ 12345, 'foo', ...boolean[] ]>(result2.tuple) +expectAssignable<{ tuple: [12345, 'foo', ...boolean[]] }>(result2) +expectType<[12345, 'foo', ...boolean[]]>(result2.tuple) expectType<12345>(result2.tuple[0]) expectType<'foo'>(result2.tuple[1]) -expectType(result2.tuple[2]) -expectType(result2.tuple[9]) +expectType(result2.tuple[2]) +expectType(result2.tuple[9]) const validatorX = object({ - tuple: [ number, string, ...boolean ], + tuple: [number, string, ...boolean], }) // no as const... types are messed up! :-) const resultX = validate(validatorX, null) -expectAssignable<{ tuple: (number|string|boolean)[] }>(resultX) -expectType<(number|string|boolean)[]>(resultX.tuple) -expectType(resultX.tuple[0]) -expectType(resultX.tuple[1]) -expectType(resultX.tuple[2]) -expectType(resultX.tuple[9]) +expectAssignable<{ tuple: (number | string | boolean)[] }>(resultX) +expectType<(number | string | boolean)[]>(resultX.tuple) +expectType(resultX.tuple[0]) +expectType(resultX.tuple[1]) +expectType(resultX.tuple[2]) +expectType(resultX.tuple[9]) // tuples in tuples -const tuple1 = tuple([ string, number ] as const) -const tuple2 = tuple([ 'header', ...tuple1 ] as const) +const tuple1 = tuple([string, number] as const) +const tuple2 = tuple(['header', ...tuple1] as const) const result = validate(tuple2, null) expectType<'header'>(result[0]) -expectType<[ string, number ]>(result[1]) -expectType<[ string, number ]>(result[9]) +expectType<[string, number] | undefined>(result[1]) +expectType<[string, number] | undefined>(result[9]) -expectType(result[1][0]) -expectType(result[1][1]) +expectType(result[1]?.[0]) +expectType(result[1]?.[1]) -expectType(result[9][0]) -expectType(result[9][1]) +expectType(result[9]?.[0]) +expectType(result[9]?.[1]) // objects in tuples const testObject = object({ foo: string }) -const tuple3 = tuple([ string, testObject ] as const) +const tuple3 = tuple([string, testObject] as const) const result3 = validate(tuple3, null) -expectAssignable<[ string, { foo: string }]>(result3) +expectAssignable<[string, { foo: string }]>(result3) expectType(result3[0]) expectAssignable<{ foo: string }>(result3[1]) expectType(result3[1].foo) // objects in tuples as rest parameters -const tuple4 = tuple([ string, ...testObject ] as const) +const tuple4 = tuple([string, ...testObject] as const) const result4 = validate(tuple4, null) -expectAssignable<[ string, ...({ foo: string })[]]>(result4) +expectAssignable<[string, ...{ foo: string }[]]>(result4) expectType(result4[0]) -expectAssignable<{ foo: string }>(result4[1]) -expectType(result4[1].foo) +expectAssignable<{ foo: string } | undefined>(result4[1]) +expectType(result4[1]?.foo) -expectAssignable<{ foo: string }>(result4[999]) -expectType(result4[999].foo) +expectAssignable<{ foo: string } | undefined>(result4[999]) +expectType(result4[999]?.foo) diff --git a/test-d/06-unions.test-d.ts b/test-d/06-unions.test-d.ts index 302a357..ca7f92c 100644 --- a/test-d/06-unions.test-d.ts +++ b/test-d/06-unions.test-d.ts @@ -1,17 +1,8 @@ import { expectAssignable, expectError, expectType, printType } from 'tsd' -import { - allOf, - boolean, - number, - object, - oneOf, - optional, - string, - validate, -} from '../src' - -import type { InferValidation, Validator } from '../src' +import { allOf, boolean, number, object, oneOf, optional, string, validate } from '../src/index.ts' + +import type { InferValidation, Validator } from '../src/index.ts' printType('__file_marker__') @@ -59,7 +50,7 @@ const allOf2 = allOf(t1, t2) expectAssignable>>(allOf2) const allOfR2 = validate(allOf2, null) -expectAssignable<{ o1: string, o2: number }>(allOfR2) +expectAssignable<{ o1: string; o2: number }>(allOfR2) expectType(allOfR2.o1) expectType(allOfR2.o2) diff --git a/test-d/07-generics.test-d.ts b/test-d/07-generics.test-d.ts index eb037a4..9fffc35 100644 --- a/test-d/07-generics.test-d.ts +++ b/test-d/07-generics.test-d.ts @@ -1,8 +1,8 @@ import { expectAssignable, expectError, expectType, printType } from 'tsd' -import { arrayOf, object, validate } from '../src' +import { arrayOf, object, validate } from '../src/index.ts' -import type { InferValidation, Validation } from '../src' +import type { InferValidation, Validation } from '../src/index.ts' printType('__file_marker__') diff --git a/test-d/10-input.test-d.ts b/test-d/10-input.test-d.ts index 4256d98..e430fb9 100644 --- a/test-d/10-input.test-d.ts +++ b/test-d/10-input.test-d.ts @@ -1,5 +1,6 @@ import { expectAssignable, expectType, printType } from 'tsd' +import { url } from '../src/extra/url.ts' import { allOf, any, @@ -16,10 +17,9 @@ import { optional, string, validate, -} from '../src' -import { url } from '../src/extra/url' +} from '../src/index.ts' -import type { InferInput } from '../src' +import type { InferInput } from '../src/index.ts' printType('__file_marker__') @@ -100,7 +100,7 @@ expectType(inputType(optional(string, 'foo' as const))) expectType(inputType(optional(string, 12345 as const))) expectType(inputType(optional(arrayOf(number)))) -expectType(inputType(optional(arrayOf(number), [ 1, 2, 3 ] as const))) +expectType(inputType(optional(arrayOf(number), [1, 2, 3] as const))) expectType(inputType(optional(arrayOf(number), 12345 as const))) expectType(inputType(optional(date))) diff --git a/test-d/11-input-tuples.test-d.ts b/test-d/11-input-tuples.test-d.ts index 21f7251..b44dd21 100644 --- a/test-d/11-input-tuples.test-d.ts +++ b/test-d/11-input-tuples.test-d.ts @@ -1,9 +1,9 @@ import { expectType, printType } from 'tsd' -import { date, tuple } from '../src' -import { url } from '../src/extra/url' +import { url } from '../src/extra/url.ts' +import { date, tuple } from '../src/index.ts' -import type { InferInput } from '../src' +import type { InferInput } from '../src/index.ts' printType('__file_marker__') @@ -13,32 +13,32 @@ function inputType(param: T): InferInput { // as const -expectType<[ Date | string | number ]>(inputType(tuple([ date ] as const))) -expectType<[ Date | string | number ]>(inputType([ date ] as const)) +expectType<[Date | string | number]>(inputType(tuple([date] as const))) +expectType<[Date | string | number]>(inputType([date] as const)) -expectType<[ Date | string | number, URL | string ]>(inputType(tuple([ date, url ] as const))) -expectType<[ Date | string | number, URL | string ]>(inputType([ date, url ] as const)) +expectType<[Date | string | number, URL | string]>(inputType(tuple([date, url] as const))) +expectType<[Date | string | number, URL | string]>(inputType([date, url] as const)) // as array (not really a tuple) -expectType<[ Date | string | number ]>(inputType(tuple([ date ]))) -expectType<(Date | string | number)[]>(inputType([ date ])) // not much we can do about this... +expectType<[Date | string | number]>(inputType(tuple([date]))) +expectType<(Date | string | number)[]>(inputType([date])) // not much we can do about this... -expectType<[ Date | string | number, URL | string ]>(inputType(tuple([ date, url ]))) -expectType<[ Date | string | number, URL | string ]>(inputType([ date, url ])) // recognized as a tuple +expectType<[Date | string | number, URL | string]>(inputType(tuple([date, url]))) +expectType<[Date | string | number, URL | string]>(inputType([date, url])) // recognized as a tuple // with rest parameters at the end -expectType<[ string | number | Date, ...(string | URL)[] ]>(inputType(tuple([ date, ...url ] as const))) -expectType<[ string | number | Date, ...(string | URL)[] ]>(inputType([ date, ...url ] as const)) +expectType<[string | number | Date, ...(string | URL)[]]>(inputType(tuple([date, ...url] as const))) +expectType<[string | number | Date, ...(string | URL)[]]>(inputType([date, ...url] as const)) -expectType<[ string | number | Date, ...(string | URL)[] ]>(inputType(tuple([ date, ...url ]))) -expectType<[ string | number | Date, ...(string | URL)[] ]>(inputType([ date, ...url ])) +expectType<[string | number | Date, ...(string | URL)[]]>(inputType(tuple([date, ...url]))) +expectType<[string | number | Date, ...(string | URL)[]]>(inputType([date, ...url])) // with rest parameters at the beginning -expectType<[ ...(string | number | Date)[], (string | URL) ]>(inputType(tuple([ ...date, url ] as const))) -expectType<[ ...(string | number | Date)[], (string | URL) ]>(inputType([ ...date, url ] as const)) +expectType<[...(string | number | Date)[], string | URL]>(inputType(tuple([...date, url] as const))) +expectType<[...(string | number | Date)[], string | URL]>(inputType([...date, url] as const)) -expectType<[ ...(string | number | Date)[], (string | URL) ]>(inputType(tuple([ ...date, url ]))) -expectType<[ ...(string | number | Date)[], (string | URL) ]>(inputType([ ...date, url ])) +expectType<[...(string | number | Date)[], string | URL]>(inputType(tuple([...date, url]))) +expectType<[...(string | number | Date)[], string | URL]>(inputType([...date, url])) diff --git a/test-d/12-input-objects.test-d.ts b/test-d/12-input-objects.test-d.ts index 1515285..7f98bc5 100644 --- a/test-d/12-input-objects.test-d.ts +++ b/test-d/12-input-objects.test-d.ts @@ -1,18 +1,9 @@ import { expectError, printType } from 'tsd' -import { - allOf, - date, - never, - number, - object, - oneOf, - optional, - string, -} from '../src' -import { url } from '../src/extra/url' - -import type { InferInput, Validation } from '../src' +import { url } from '../src/extra/url.ts' +import { allOf, date, never, number, object, oneOf, optional, string } from '../src/index.ts' + +import type { InferInput, Validation } from '../src/index.ts' printType('__file_marker__') diff --git a/test-d/20-extras.test-d.ts b/test-d/20-extras.test-d.ts index af13717..d8e4a87 100644 --- a/test-d/20-extras.test-d.ts +++ b/test-d/20-extras.test-d.ts @@ -1,14 +1,14 @@ import { expectType, printType } from 'tsd' -import { validate } from '../src' -import { arn, parseArn } from '../src/extra/arn' -import { ean13 } from '../src/extra/ean13' -import { uuid } from '../src/extra/uuid' +import { arn, parseArn } from '../src/extra/arn.ts' +import { ean13 } from '../src/extra/ean13.ts' +import { uuid } from '../src/extra/uuid.ts' +import { validate } from '../src/index.ts' -import type { InferInput } from '../src' -import type { ArnString, ParsedArn } from '../src/extra/arn' -import type { EAN13String } from '../src/extra/ean13' -import type { UUIDString } from '../src/extra/uuid' +import type { ArnString, ParsedArn } from '../src/extra/arn.ts' +import type { EAN13String } from '../src/extra/ean13.ts' +import type { UUIDString } from '../src/extra/uuid.ts' +import type { InferInput } from '../src/index.ts' printType('__file_marker__') @@ -21,19 +21,12 @@ function inputType(param: T): InferInput { expectType(validate(arn, 'foo')) expectType(validate(arn, 'foo')) -expectType<( -& string -& { __arn: never } -& { __arn_service_myservice: never } -)>(validate(arn('myservice'), 'foo')) +expectType(validate(arn('myservice'), 'foo')) expectType>(validate(arn('myservice'), 'foo')) -expectType<( -& string -& { __arn: never } -& { __arn_service_myservice: never } -& { __arn_resource_myresource: never } -)>(validate(arn('myservice', 'myresource'), 'foo')) +expectType( + validate(arn('myservice', 'myresource'), 'foo'), +) expectType>(validate(arn('myservice', 'myresource'), 'foo')) expectType>(validate(parseArn, 'foo')) diff --git a/test-d/index.d.ts b/test-d/index.d.ts new file mode 100644 index 0000000..e69de29 diff --git a/test-d/package.json b/test-d/package.json new file mode 100644 index 0000000..3dbc1ca --- /dev/null +++ b/test-d/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/test-d/tsconfig.json b/test-d/tsconfig.json index c35521f..b8638b5 100644 --- a/test-d/tsconfig.json +++ b/test-d/tsconfig.json @@ -2,6 +2,7 @@ "extends": "../tsconfig.json", "compilerOptions": { "rootDir": "..", + "noPropertyAccessFromIndexSignature": false }, - "include": [ "." ], + "include": ["."] } diff --git a/test/01-errors.test.ts b/test/01-errors.test.ts index 024517d..5680bb2 100644 --- a/test/01-errors.test.ts +++ b/test/01-errors.test.ts @@ -1,58 +1,43 @@ /* eslint-disable @typescript-eslint/no-unsafe-function-type */ -import { assertSchema, assertValidation, ValidationError, ValidationErrorBuilder } from '../src' +import { assertSchema, assertValidation, ValidationError, ValidationErrorBuilder } from '../src/index.ts' describe('Errors', () => { describe('ValidationError', () => { it('should create a validation error', () => { const error = new ValidationError('This is a test') expect(error.message).toStrictlyEqual('Found 1 validation error\n This is a test') - expect(error.errors).toEqual([ - { path: [], message: 'This is a test' }, - ]) + expect(error.errors).toEqual([{ path: [], message: 'This is a test' }]) }) it('should create a validation error with a path', () => { const error1 = new ValidationError('This is a test', []) expect(error1.message).toStrictlyEqual('Found 1 validation error\n This is a test') - expect(error1.errors).toEqual([ - { path: [], message: 'This is a test' }, - ]) + expect(error1.errors).toEqual([{ path: [], message: 'This is a test' }]) - const error2 = new ValidationError('This is a test', [ 123 ]) + const error2 = new ValidationError('This is a test', [123]) expect(error2.message).toStrictlyEqual('Found 1 validation error\n [123]: This is a test') - expect(error2.errors).toEqual([ - { path: [ 123 ], message: 'This is a test' }, - ]) + expect(error2.errors).toEqual([{ path: [123], message: 'This is a test' }]) - const error3 = new ValidationError('This is a test', [ 'foo' ]) + const error3 = new ValidationError('This is a test', ['foo']) expect(error3.message).toStrictlyEqual('Found 1 validation error\n foo: This is a test') - expect(error3.errors).toEqual([ - { path: [ 'foo' ], message: 'This is a test' }, - ]) + expect(error3.errors).toEqual([{ path: ['foo'], message: 'This is a test' }]) - const error4 = new ValidationError('This is a test', [ 'foo', 'bar', 123, 456, 'baz', 789 ]) + const error4 = new ValidationError('This is a test', ['foo', 'bar', 123, 456, 'baz', 789]) expect(error4.message).toStrictlyEqual('Found 1 validation error\n foo.bar[123][456].baz[789]: This is a test') - expect(error4.errors).toEqual([ - { path: [ 'foo', 'bar', 123, 456, 'baz', 789 ], message: 'This is a test' }, - ]) + expect(error4.errors).toEqual([{ path: ['foo', 'bar', 123, 456, 'baz', 789], message: 'This is a test' }]) }) it('should wrap another ValidationError', () => { - const error0 = new ValidationError('This is a test', [ 123 ]) - const error1 = new ValidationError(error0, [ 'foo' ]) + const error0 = new ValidationError('This is a test', [123]) + const error1 = new ValidationError(error0, ['foo']) expect(error1.message).toStrictlyEqual('Found 1 validation error\n foo[123]: This is a test') - expect(error1.errors).toEqual([ - { path: [ 'foo', 123 ], message: 'This is a test' }, - ]) + expect(error1.errors).toEqual([{ path: ['foo', 123], message: 'This is a test' }]) }) it('should create a validation error ignoring certain stack trace elements', () => { - function _testCreate_( - constructorOrPath?: Function | string[], - maybeConstructor?: Function, - ): ValidationError { - return new ValidationError('This is a test', constructorOrPath, maybeConstructor) + function _testCreate_(constructorOrPath?: Function | string[], maybeConstructor?: Function): ValidationError { + return new ValidationError('This is a test', constructorOrPath, maybeConstructor) } expect(_testCreate_().stack.match(/^\s+at\s+.*_testCreate_/gm)).toBeA('array') @@ -69,53 +54,58 @@ describe('Errors', () => { }) it('should throw when a simple error have been recorded', () => { - const builder = new ValidationErrorBuilder() - .record('Hello, world!') - .record('Something else', 'myKey') + const builder = new ValidationErrorBuilder().record('Hello, world!').record('Something else', 'myKey') - expect(() => builder.assert(null)).toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ + expect(() => builder.assert(null)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ { path: [], message: 'Hello, world!' }, - { path: [ 'myKey' ], message: 'Something else' }, - ]))) + { path: ['myKey'], message: 'Something else' }, + ]), + ), + ) }) it('should properly wrap another ValidationError', () => { const error1 = new ValidationError('This has no path') - const error2 = new ValidationError('A message', [ 'myKey' ]) + const error2 = new ValidationError('A message', ['myKey']) - const builder = new ValidationErrorBuilder() - .record(error1) - .record(error2) - .record(error1, 123) - .record(error2, 456) + const builder = new ValidationErrorBuilder().record(error1).record(error2).record(error1, 123).record(error2, 456) - expect(() => builder.assert(null)).toThrow((assert) => assert - .toBeError(ValidationError, /^Found 4 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ + expect(() => builder.assert(null)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 4 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ { path: [], message: 'This has no path' }, - { path: [ 'myKey' ], message: 'A message' }, - { path: [ 123 ], message: 'This has no path' }, - { path: [ 456, 'myKey' ], message: 'A message' }, - ]))) + { path: ['myKey'], message: 'A message' }, + { path: [123], message: 'This has no path' }, + { path: [456, 'myKey'], message: 'A message' }, + ]), + ), + ) }) }) describe('Assertions', () => { it('should assert a schema error', () => { expect(() => assertSchema(true, 'This should not throw')).not.toThrow() - expect(() => assertSchema(false, 'This should throw')) - .toThrowError(TypeError, 'This should throw') + expect(() => assertSchema(false, 'This should throw')).toThrowError(TypeError, 'This should throw') }) it('should assert a validation error', () => { expect(() => assertValidation(true, 'This should not throw')).not.toThrow() - expect(() => assertValidation(false, 'This should throw')) - .toThrow((assert) => assert.toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'This should throw', - } ]))) + expect(() => assertValidation(false, 'This should throw')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'This should throw', + }, + ]), + ), + ) }) }) }) diff --git a/test/02-validators.test.ts b/test/02-validators.test.ts index 038e025..e7c0ca2 100644 --- a/test/02-validators.test.ts +++ b/test/02-validators.test.ts @@ -1,18 +1,23 @@ -import { AbstractValidator, any, ConstantValidator, getValidator, ObjectValidator, TupleValidator } from '../src' +import { + AbstractValidator, + any, + ConstantValidator, + getValidator, + ObjectValidator, + TupleValidator, +} from '../src/index.ts' -import type { Schema } from '../src' +import type { Schema } from '../src/index.ts' describe('Validators', () => { - const fakeValidator = new class extends AbstractValidator { + const fakeValidator = new (class extends AbstractValidator { validate(): never { throw new Error('Method not implemented.') } - } + })() it('null', () => { - expect(getValidator(null)) - .toBeInstanceOf(ConstantValidator) - .toHaveProperty('constant', expect.toBeNull()) + expect(getValidator(null)).toBeInstanceOf(ConstantValidator).toHaveProperty('constant', expect.toBeNull()) }) it('validators', () => { @@ -21,44 +26,42 @@ describe('Validators', () => { }) it('primitives', () => { - expect(getValidator(true)) - .toBeInstanceOf(ConstantValidator) - .toHaveProperty('constant', expect.toBeTrue()) + expect(getValidator(true)).toBeInstanceOf(ConstantValidator).toHaveProperty('constant', expect.toBeTrue()) expect(getValidator(12345)) - .toBeInstanceOf(ConstantValidator) - .toHaveProperty('constant', expect.toStrictlyEqual(12345)) + .toBeInstanceOf(ConstantValidator) + .toHaveProperty('constant', expect.toStrictlyEqual(12345)) expect(getValidator('Hello, world!')) - .toBeInstanceOf(ConstantValidator) - .toHaveProperty('constant', expect.toStrictlyEqual('Hello, world!')) + .toBeInstanceOf(ConstantValidator) + .toHaveProperty('constant', expect.toStrictlyEqual('Hello, world!')) }) it('objects', () => { const objectValidator = getValidator({ foo: 'bar' }) expect(objectValidator) - .toBeInstanceOf(ObjectValidator) - .toHaveProperty('schema', expect.toEqual({ foo: 'bar' })) + .toBeInstanceOf(ObjectValidator) + .toHaveProperty('schema', expect.toEqual({ foo: 'bar' })) - expect(getValidator({ [Symbol.justusValidator]: objectValidator } as Schema)) - .toStrictlyEqual(objectValidator) + expect(getValidator({ [Symbol.justusValidator]: objectValidator } as Schema)).toStrictlyEqual(objectValidator) }) it('tuples', () => { - expect(getValidator([ 1, 'foo' ])) - .toBeInstanceOf(TupleValidator) - .toHaveProperty('tuple', expect.toEqual([ 1, 'foo' ])) + expect(getValidator([1, 'foo'])) + .toBeInstanceOf(TupleValidator) + .toHaveProperty('tuple', expect.toEqual([1, 'foo'])) }) it('others (error)', () => { - expect(() => getValidator(Symbol('foo') as any)) - .toThrowError(TypeError, 'Invalid validation (type=symbol)') + expect(() => getValidator(Symbol('foo') as any)).toThrowError(TypeError, 'Invalid validation (type=symbol)') }) it('validator iterator (tuple rest parameters)', () => { - const array = [ ...fakeValidator ] - expect(array).toEqual([ { - [Symbol.justusRestValidator]: fakeValidator, - } ]) + const array = [...fakeValidator] + expect(array).toEqual([ + { + [Symbol.justusRestValidator]: fakeValidator, + }, + ]) }) }) diff --git a/test/10-primitives.test.ts b/test/10-primitives.test.ts index 2b2df6b..288bfab 100644 --- a/test/10-primitives.test.ts +++ b/test/10-primitives.test.ts @@ -1,4 +1,16 @@ -import { any, bigint, BigIntValidator, boolean, constant, number, NumberValidator, string, StringValidator, validate, ValidationError } from '../src' +import { + any, + bigint, + BigIntValidator, + boolean, + constant, + number, + NumberValidator, + string, + StringValidator, + validate, + ValidationError, +} from '../src/index.ts' describe('Primitive validators', () => { describe('any', () => { @@ -20,29 +32,28 @@ describe('Primitive validators', () => { expect(validate(boolean({ fromString: true }), 'false')).toBeFalse() expect(validate(boolean({ fromString: true }), 'FALSE')).toBeFalse() - expect(() => validate(boolean({ fromString: true }), 'hello')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Boolean can not be parsed from string' }, - ])), - ) + expect(() => validate(boolean({ fromString: true }), 'hello')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Boolean can not be parsed from string' }]), + ), + ) }) it('should fail validating non booleans', () => { - expect(() => validate(boolean, 'foobar')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "boolean"' }, - ]))) - - expect(() => validate(boolean, undefined)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "boolean"' }, - ]))) + expect(() => validate(boolean, 'foobar')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "boolean"' }])), + ) + + expect(() => validate(boolean, undefined)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "boolean"' }])), + ) }) }) @@ -62,40 +73,50 @@ describe('Primitive validators', () => { }) it('should fail validating the wrong constant', () => { - expect(() => validate(constant('foo'), 'bar')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "foo" (string)' }, - ]))) - - expect(() => validate(constant(123n), 123)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "123" (bigint)' }, - ]))) - - expect(() => validate(constant(123), 123n)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "123" (number)' }, - ]))) - - expect(() => validate(constant(true), false)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "true" (boolean)' }, - ]))) - - expect(() => validate(constant(null), undefined)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "null"' }, - ]))) + expect(() => validate(constant('foo'), 'bar')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "foo" (string)' }]), + ), + ) + + expect(() => validate(constant(123n), 123)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "123" (bigint)' }]), + ), + ) + + expect(() => validate(constant(123), 123n)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "123" (number)' }]), + ), + ) + + expect(() => validate(constant(true), false)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "true" (boolean)' }]), + ), + ) + + expect(() => validate(constant(null), undefined)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "null"' }]), + ), + ) }) }) @@ -106,12 +127,11 @@ describe('Primitive validators', () => { expect(validate(number, Number.NEGATIVE_INFINITY)).toStrictlyEqual(Number.NEGATIVE_INFINITY) expect(validate(number, Number.POSITIVE_INFINITY)).toStrictlyEqual(Number.POSITIVE_INFINITY) - expect(() => validate(number, 'foobar')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "number"' }, - ]))) + expect(() => validate(number, 'foobar')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "number"' }])), + ) }) it('should validate a number within a range', () => { @@ -122,22 +142,22 @@ describe('Primitive validators', () => { expect(validate(number({ minimum: 0, maximum: 0 }), 0)).toStrictlyEqual(0) - expect(() => validate(range, -10)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is less than -9' }, - ]))) - - expect(() => validate(range, 20)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is greater than 19' }, - ]))) - - expect(() => number({ minimum: 10, maximum: 9 })) - .toThrowError(TypeError, 'Constraint "minimum" (10) is greater than "maximum" (9)') + expect(() => validate(range, -10)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is less than -9' }])), + ) + + expect(() => validate(range, 20)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is greater than 19' }])), + ) + + expect(() => number({ minimum: 10, maximum: 9 })).toThrowError( + TypeError, + 'Constraint "minimum" (10) is greater than "maximum" (9)', + ) }) it('should validate a number within an exclusive range', () => { @@ -145,137 +165,162 @@ describe('Primitive validators', () => { expect(validate(range1, 0.001)).toStrictlyEqual(0.001) expect(validate(range1, 0.999)).toStrictlyEqual(0.999) - expect(() => validate(range1, 0)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is less than or equal to 0' }, - ]))) - - expect(() => validate(range1, 1)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is greater than or equal to 1' }, - ]))) + expect(() => validate(range1, 0)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is less than or equal to 0' }]), + ), + ) + + expect(() => validate(range1, 1)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is greater than or equal to 1' }]), + ), + ) const range2 = number({ exclusiveMinimum: 0, maximum: 1 }) expect(validate(range2, 0.001)).toStrictlyEqual(0.001) expect(validate(range2, 1)).toStrictlyEqual(1) - expect(() => validate(range2, 0)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is less than or equal to 0' }, - ]))) - - expect(() => validate(range2, 1.001)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is greater than 1' }, - ]))) + expect(() => validate(range2, 0)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is less than or equal to 0' }]), + ), + ) + + expect(() => validate(range2, 1.001)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is greater than 1' }])), + ) const range3 = number({ minimum: 0, exclusiveMaximum: 1 }) expect(validate(range3, 0)).toStrictlyEqual(0) expect(validate(range3, 0.999)).toStrictlyEqual(0.999) - expect(() => validate(range3, -0.001)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is less than 0' }, - ]))) - - expect(() => validate(range3, 1)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is greater than or equal to 1' }, - ]))) - - expect(() => number({ exclusiveMinimum: 2, exclusiveMaximum: 1 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (1) must be greater than "exclusiveMinimum" (2)') - expect(() => number({ exclusiveMinimum: 0, exclusiveMaximum: 0 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (0) must be greater than "exclusiveMinimum" (0)') - - expect(() => number({ exclusiveMinimum: 2, maximum: 1 })) - .toThrowError(TypeError, 'Constraint "maximum" (1) must be greater than "exclusiveMinimum" (2)') - expect(() => number({ exclusiveMinimum: 0, maximum: 0 })) - .toThrowError(TypeError, 'Constraint "maximum" (0) must be greater than "exclusiveMinimum" (0)') - - expect(() => number({ minimum: 2, exclusiveMaximum: 1 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (1) must be greater than "minimum" (2)') - expect(() => number({ minimum: 0, exclusiveMaximum: 0 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (0) must be greater than "minimum" (0)') + expect(() => validate(range3, -0.001)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is less than 0' }])), + ) + + expect(() => validate(range3, 1)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is greater than or equal to 1' }]), + ), + ) + + expect(() => number({ exclusiveMinimum: 2, exclusiveMaximum: 1 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (1) must be greater than "exclusiveMinimum" (2)', + ) + expect(() => number({ exclusiveMinimum: 0, exclusiveMaximum: 0 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (0) must be greater than "exclusiveMinimum" (0)', + ) + + expect(() => number({ exclusiveMinimum: 2, maximum: 1 })).toThrowError( + TypeError, + 'Constraint "maximum" (1) must be greater than "exclusiveMinimum" (2)', + ) + expect(() => number({ exclusiveMinimum: 0, maximum: 0 })).toThrowError( + TypeError, + 'Constraint "maximum" (0) must be greater than "exclusiveMinimum" (0)', + ) + + expect(() => number({ minimum: 2, exclusiveMaximum: 1 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (1) must be greater than "minimum" (2)', + ) + expect(() => number({ minimum: 0, exclusiveMaximum: 0 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (0) must be greater than "minimum" (0)', + ) }) it('should validate multiple ofs', () => { // integers expect(validate(number({ multipleOf: 2 }), 4)).toStrictlyEqual(4) - expect(() => validate(number({ multipleOf: 2 }), 3)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is not a multiple of 2' }, - ]))) + expect(() => validate(number({ multipleOf: 2 }), 3)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is not a multiple of 2' }])), + ) // reals expect(validate(number({ multipleOf: 0.01 }), 0.12)).toStrictlyEqual(0.12) - expect(() => validate(number({ multipleOf: 0.03 }), 0.07)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is not a multiple of 0.03' }, - ]))) + expect(() => validate(number({ multipleOf: 0.03 }), 0.07)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is not a multiple of 0.03' }]), + ), + ) expect(validate(number({ multipleOf: 0.000001 }), 0.123456)).toStrictlyEqual(0.123456) expect(validate(number({ multipleOf: 0.000001 }), 1000e100)).toStrictlyEqual(1000e100) - expect(() => validate(number({ multipleOf: 0.000001 }), 0.0000001)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is not a multiple of 0.000001' }, - ]))) + expect(() => validate(number({ multipleOf: 0.000001 }), 0.0000001)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is not a multiple of 0.000001' }]), + ), + ) // too much precision expect(() => number({ multipleOf: 0.123456 })).not.toThrow() - expect(() => number({ multipleOf: 0.1234567 })) - .toThrowError(TypeError, 'Constraint "multipleOf" (0.1234567) requires too much precision') + expect(() => number({ multipleOf: 0.1234567 })).toThrowError( + TypeError, + 'Constraint "multipleOf" (0.1234567) requires too much precision', + ) // this is a magical number that _multiplied_ by our precision (1 000 000) // result in an integer (100820000)... so we need a different way to check // for how many decimal digits a number has... - expect(() => validate(number({ multipleOf: 0.000001 }), 100.82000000000001 )) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is not a multiple of 0.000001' }, - ]))) - - expect(() => validate(number({ multipleOf: 0.000001 }), Infinity )) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Can\'t calculate digits for number "Infinity"' }, - ]))) + expect(() => validate(number({ multipleOf: 0.000001 }), 100.82000000000001)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number is not a multiple of 0.000001' }]), + ), + ) + + expect(() => validate(number({ multipleOf: 0.000001 }), Infinity)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Can\'t calculate digits for number "Infinity"' }]), + ), + ) }) it('should validate NaN', () => { - expect(() => validate(number, NaN)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is "NaN"' }, - ]))) - expect(() => validate(number({ allowNaN: false }), NaN)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number is "NaN"' }, - ]))) + expect(() => validate(number, NaN)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is "NaN"' }])), + ) + expect(() => validate(number({ allowNaN: false }), NaN)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Number is "NaN"' }])), + ) expect(validate(number({ allowNaN: true }), NaN)).toBeNaN() }) @@ -283,15 +328,17 @@ describe('Primitive validators', () => { const validator = number({ fromString: true }) expect(validate(validator, '123456'), '123456').toStrictlyEqual(123456) expect(validate(validator, '-12.34'), '-12.34').toStrictlyEqual(-12.34) - expect(validate(validator, '0xCAFE'), '0xCAFE').toStrictlyEqual(0xCAFE) + expect(validate(validator, '0xCAFE'), '0xCAFE').toStrictlyEqual(0xcafe) expect(validate(validator, '0o4321'), '0o4321').toStrictlyEqual(0o4321) expect(validate(validator, '0b1011'), '0b1011').toStrictlyEqual(0b1011) - expect(() => validate(validator, 'hello')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Number can not be parsed from string' }, - ]))) + expect(() => validate(validator, 'hello')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Number can not be parsed from string' }]), + ), + ) }) it('should validate a number using the NumberValidator class', () => { @@ -311,49 +358,60 @@ describe('Primitive validators', () => { expect(validate(string, 'foobar')).toStrictlyEqual('foobar') expect(validate(string, '')).toStrictlyEqual('') - expect(() => validate(string, 123)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "string"' }, - ]))) + expect(() => validate(string, 123)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "string"' }])), + ) }) it('should validate a string of a specified length', () => { const length = string({ minLength: 3, maxLength: 6 }) expect(validate(length, 'foo')).toStrictlyEqual('foo') expect(validate(length, 'foobar')).toStrictlyEqual('foobar') - expect(() => validate(length, 'fo')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'String must have a minimum length of 3' }, - ]))) - expect(() => validate(length, 'foobarx')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'String must have a maximum length of 6' }, - ]))) + expect(() => validate(length, 'fo')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'String must have a minimum length of 3' }]), + ), + ) + expect(() => validate(length, 'foobarx')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'String must have a maximum length of 6' }]), + ), + ) expect(validate(string({ minLength: 3, maxLength: 3 }), 'foo')).toStrictlyEqual('foo') - expect(() => string({ minLength: -1 })) - .toThrowError(TypeError, 'Constraint "minLength" (-1) must be non-negative') - expect(() => string({ maxLength: -1 })) - .toThrowError(TypeError, 'Constraint "maxLength" (-1) must be non-negative') - expect(() => string({ minLength: 4, maxLength: 3 })) - .toThrowError(TypeError, 'Constraint "minLength" (4) is greater than "maxLength" (3)') + expect(() => string({ minLength: -1 })).toThrowError( + TypeError, + 'Constraint "minLength" (-1) must be non-negative', + ) + expect(() => string({ maxLength: -1 })).toThrowError( + TypeError, + 'Constraint "maxLength" (-1) must be non-negative', + ) + expect(() => string({ minLength: 4, maxLength: 3 })).toThrowError( + TypeError, + 'Constraint "minLength" (4) is greater than "maxLength" (3)', + ) }) it('should validate a string a with a pattern', () => { expect(validate(string({ pattern: /^foobar$/ }), 'foobar')).toStrictlyEqual('foobar') - expect(() => validate(string({ pattern: /^$/ }), 'foobar')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'String does not match required pattern /^$/' }, - ]))) + expect(() => validate(string({ pattern: /^$/ }), 'foobar')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'String does not match required pattern /^$/' }]), + ), + ) }) it('should validate a string using the StringValidator class', () => { @@ -376,19 +434,20 @@ describe('Primitive validators', () => { expect(validate(bigint, 0)).toStrictlyEqual(0n) expect(validate(bigint, 123)).toStrictlyEqual(123n) - expect(() => validate(bigint, 123.456)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt can not be parsed from number' }, - ]))) - - expect(() => validate(bigint, '12345')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "bigint"' }, - ]))) + expect(() => validate(bigint, 123.456)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt can not be parsed from number' }]), + ), + ) + + expect(() => validate(bigint, '12345')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "bigint"' }])), + ) }) it('should validate a bigint within a range', () => { @@ -399,22 +458,22 @@ describe('Primitive validators', () => { expect(validate(bigint({ minimum: 0, maximum: 0 }), 0)).toStrictlyEqual(0n) - expect(() => validate(range, -10)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is less than -9' }, - ]))) - - expect(() => validate(range, 20)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is greater than 19' }, - ]))) - - expect(() => bigint({ minimum: 10, maximum: 9 })) - .toThrowError(TypeError, 'Constraint "minimum" (10) is greater than "maximum" (9)') + expect(() => validate(range, -10)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'BigInt is less than -9' }])), + ) + + expect(() => validate(range, 20)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'BigInt is greater than 19' }])), + ) + + expect(() => bigint({ minimum: 10, maximum: 9 })).toThrowError( + TypeError, + 'Constraint "minimum" (10) is greater than "maximum" (9)', + ) }) it('should validate a bigint within an exclusive range', () => { @@ -422,114 +481,134 @@ describe('Primitive validators', () => { expect(validate(range1, 1)).toStrictlyEqual(1n) expect(validate(range1, 9)).toStrictlyEqual(9n) - expect(() => validate(range1, 0)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is less than or equal to 0' }, - ]))) - - expect(() => validate(range1, 10)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is greater than or equal to 10' }, - ]))) + expect(() => validate(range1, 0)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt is less than or equal to 0' }]), + ), + ) + + expect(() => validate(range1, 10)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt is greater than or equal to 10' }]), + ), + ) const range2 = bigint({ exclusiveMinimum: 0, maximum: 10 }) expect(validate(range2, 1)).toStrictlyEqual(1n) expect(validate(range2, 10)).toStrictlyEqual(10n) - expect(() => validate(range2, 0)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is less than or equal to 0' }, - ]))) - - expect(() => validate(range2, 11)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is greater than 10' }, - ]))) + expect(() => validate(range2, 0)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt is less than or equal to 0' }]), + ), + ) + + expect(() => validate(range2, 11)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'BigInt is greater than 10' }])), + ) const range3 = bigint({ minimum: 0, exclusiveMaximum: 10 }) expect(validate(range3, 0)).toStrictlyEqual(0n) expect(validate(range3, 9)).toStrictlyEqual(9n) - expect(() => validate(range3, -1)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is less than 0' }, - ]))) - - expect(() => validate(range3, 10)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is greater than or equal to 10' }, - ]))) - - expect(() => bigint({ exclusiveMinimum: 2, exclusiveMaximum: 1 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (1) must be greater than "exclusiveMinimum" (2)') - expect(() => bigint({ exclusiveMinimum: 0, exclusiveMaximum: 0 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (0) must be greater than "exclusiveMinimum" (0)') - - expect(() => bigint({ exclusiveMinimum: 2, maximum: 1 })) - .toThrowError(TypeError, 'Constraint "maximum" (1) must be greater than "exclusiveMinimum" (2)') - expect(() => bigint({ exclusiveMinimum: 0, maximum: 0 })) - .toThrowError(TypeError, 'Constraint "maximum" (0) must be greater than "exclusiveMinimum" (0)') - - expect(() => bigint({ minimum: 2, exclusiveMaximum: 1 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (1) must be greater than "minimum" (2)') - expect(() => bigint({ minimum: 0, exclusiveMaximum: 0 })) - .toThrowError(TypeError, 'Constraint "exclusiveMaximum" (0) must be greater than "minimum" (0)') + expect(() => validate(range3, -1)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'BigInt is less than 0' }])), + ) + + expect(() => validate(range3, 10)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt is greater than or equal to 10' }]), + ), + ) + + expect(() => bigint({ exclusiveMinimum: 2, exclusiveMaximum: 1 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (1) must be greater than "exclusiveMinimum" (2)', + ) + expect(() => bigint({ exclusiveMinimum: 0, exclusiveMaximum: 0 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (0) must be greater than "exclusiveMinimum" (0)', + ) + + expect(() => bigint({ exclusiveMinimum: 2, maximum: 1 })).toThrowError( + TypeError, + 'Constraint "maximum" (1) must be greater than "exclusiveMinimum" (2)', + ) + expect(() => bigint({ exclusiveMinimum: 0, maximum: 0 })).toThrowError( + TypeError, + 'Constraint "maximum" (0) must be greater than "exclusiveMinimum" (0)', + ) + + expect(() => bigint({ minimum: 2, exclusiveMaximum: 1 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (1) must be greater than "minimum" (2)', + ) + expect(() => bigint({ minimum: 0, exclusiveMaximum: 0 })).toThrowError( + TypeError, + 'Constraint "exclusiveMaximum" (0) must be greater than "minimum" (0)', + ) }) it('should validate multiple ofs', () => { expect(validate(bigint({ multipleOf: 2 }), 4)).toStrictlyEqual(4n) - expect(() => validate(bigint({ multipleOf: 2 }), 3)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt is not a multiple of 2' }, - ]))) + expect(() => validate(bigint({ multipleOf: 2 }), 3)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'BigInt is not a multiple of 2' }])), + ) }) it('should validate a bigint parsing a string', () => { const validator = bigint({ fromString: true }) expect(validate(validator, '123456'), '123456').toStrictlyEqual(123456n) - expect(validate(validator, '0xCAFE'), '0xCAFE').toStrictlyEqual(0xCAFEn) + expect(validate(validator, '0xCAFE'), '0xCAFE').toStrictlyEqual(0xcafen) expect(validate(validator, '0o4321'), '0o4321').toStrictlyEqual(0o4321n) expect(validate(validator, '0b1011'), '0b1011').toStrictlyEqual(0b1011n) - expect(() => validate(validator, '123.456')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt can not be parsed from string' }, - ]))) + expect(() => validate(validator, '123.456')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt can not be parsed from string' }]), + ), + ) }) it('should validate a bigint parsing a number', () => { const validator = bigint({ fromNumber: true }) expect(validate(validator, 123456), '123456').toStrictlyEqual(123456n) - expect(() => validate(validator, 123.456)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'BigInt can not be parsed from number' }, - ]))) + expect(() => validate(validator, 123.456)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'BigInt can not be parsed from number' }]), + ), + ) const validator2 = bigint({ fromNumber: false }) - expect(() => validate(validator2, 123456), '123456') - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "bigint"' }, - ]))) + expect(() => validate(validator2, 123456), '123456').toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not a "bigint"' }])), + ) }) it('should validate a bigint using the BigIntValidator class', () => { diff --git a/test/11-arrays.test.ts b/test/11-arrays.test.ts index 373a84d..6eba28e 100644 --- a/test/11-arrays.test.ts +++ b/test/11-arrays.test.ts @@ -1,104 +1,117 @@ -import { array, arrayOf, ArrayValidator, string, validate, ValidationError } from '../src' +import { array, arrayOf, ArrayValidator, string, validate, ValidationError } from '../src/index.ts' describe('Array validator', () => { it('should validate an array', () => { - expect(validate(array, [ 1, true, 'foo' ])).toEqual([ 1, true, 'foo' ]) + expect(validate(array, [1, true, 'foo'])).toEqual([1, true, 'foo']) expect(validate(array, [])).toEqual([]) - expect(() => validate(array, 123)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not an "array"' }, - ]))) + expect(() => validate(array, 123)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not an "array"' }])), + ) }) it('should validate an array of a specified length', () => { const length = array({ minItems: 3, maxItems: 6 }) - expect(validate(length, [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ]) - expect(validate(length, [ 1, 2, 3, 4, 5, 6 ])).toEqual([ 1, 2, 3, 4, 5, 6 ]) - expect(() => validate(length, [ 1, 2 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Array must have a minimum length of 3' }, - ]))) - expect(() => validate(length, [ 1, 2, 3, 4, 5, 6, 7 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Array must have a maximum length of 6' }, - ]))) - - expect(validate(array({ minItems: 3, maxItems: 3 }), [ 1, 2, 3 ])).toEqual([ 1, 2, 3 ]) - - expect(() => array({ minItems: -1 })) - .toThrowError(TypeError, 'Constraint "minItems" (-1) must be non-negative') - expect(() => array({ maxItems: -1 })) - .toThrowError(TypeError, 'Constraint "maxItems" (-1) must be non-negative') - expect(() => array({ minItems: 4, maxItems: 3 })) - .toThrowError(TypeError, 'Constraint "minItems" (4) is greater than "maxItems" (3)') + expect(validate(length, [1, 2, 3])).toEqual([1, 2, 3]) + expect(validate(length, [1, 2, 3, 4, 5, 6])).toEqual([1, 2, 3, 4, 5, 6]) + expect(() => validate(length, [1, 2])).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Array must have a minimum length of 3' }]), + ), + ) + expect(() => validate(length, [1, 2, 3, 4, 5, 6, 7])).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Array must have a maximum length of 6' }]), + ), + ) + + expect(validate(array({ minItems: 3, maxItems: 3 }), [1, 2, 3])).toEqual([1, 2, 3]) + + expect(() => array({ minItems: -1 })).toThrowError(TypeError, 'Constraint "minItems" (-1) must be non-negative') + expect(() => array({ maxItems: -1 })).toThrowError(TypeError, 'Constraint "maxItems" (-1) must be non-negative') + expect(() => array({ minItems: 4, maxItems: 3 })).toThrowError( + TypeError, + 'Constraint "minItems" (4) is greater than "maxItems" (3)', + ) }) it('should validate an array with unique items', () => { - expect(validate(array, [ 1, 2, 1 ])).toEqual([ 1, 2, 1 ]) - expect(validate(array({ uniqueItems: false }), [ 1, 2, 1 ])).toEqual([ 1, 2, 1 ]) - - expect(() => validate(array({ uniqueItems: true }), [ 1, 2, 1, 2 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 2 ], message: 'Duplicate of item at index 0' }, - { path: [ 3 ], message: 'Duplicate of item at index 1' }, - ]))) + expect(validate(array, [1, 2, 1])).toEqual([1, 2, 1]) + expect(validate(array({ uniqueItems: false }), [1, 2, 1])).toEqual([1, 2, 1]) + + expect(() => validate(array({ uniqueItems: true }), [1, 2, 1, 2])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [2], message: 'Duplicate of item at index 0' }, + { path: [3], message: 'Duplicate of item at index 1' }, + ]), + ), + ) }) it('should validate an array with items of a specific type', () => { - expect(validate(arrayOf(string), [ 'a', 'b', 'c' ])).toEqual([ 'a', 'b', 'c' ]) - - expect(() => validate(arrayOf(string), [ 'a', true, 'b', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 1 ], message: 'Value is not a "string"' }, - { path: [ 3 ], message: 'Value is not a "string"' }, - ]))) - - expect(validate(arrayOf(string), [ 'a', 'b', 'c' ])).toEqual([ 'a', 'b', 'c' ]) - - expect(() => validate(arrayOf(string), [ 'a', true, 'b', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 1 ], message: 'Value is not a "string"' }, - { path: [ 3 ], message: 'Value is not a "string"' }, - ]))) - - expect(validate(arrayOf('a'), [ 'a', 'a', 'a' ])).toEqual([ 'a', 'a', 'a' ]) - - expect(() => validate(arrayOf('a'), [ 'a', true, 'b', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 3 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 1 ], message: 'Value does not match constant "a" (string)' }, - { path: [ 2 ], message: 'Value does not match constant "a" (string)' }, - { path: [ 3 ], message: 'Value does not match constant "a" (string)' }, - ]))) - - expect(validate(arrayOf('a'), [ 'a', 'a', 'a' ])).toEqual([ 'a', 'a', 'a' ]) - - expect(() => validate(array({ items: 'a', uniqueItems: true }), [ 'a', true, 'a', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 3 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 1 ], message: 'Value does not match constant "a" (string)' }, - { path: [ 2 ], message: 'Duplicate of item at index 0' }, - { path: [ 3 ], message: 'Value does not match constant "a" (string)' }, - ]))) + expect(validate(arrayOf(string), ['a', 'b', 'c'])).toEqual(['a', 'b', 'c']) + + expect(() => validate(arrayOf(string), ['a', true, 'b', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [1], message: 'Value is not a "string"' }, + { path: [3], message: 'Value is not a "string"' }, + ]), + ), + ) + + expect(validate(arrayOf(string), ['a', 'b', 'c'])).toEqual(['a', 'b', 'c']) + + expect(() => validate(arrayOf(string), ['a', true, 'b', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [1], message: 'Value is not a "string"' }, + { path: [3], message: 'Value is not a "string"' }, + ]), + ), + ) + + expect(validate(arrayOf('a'), ['a', 'a', 'a'])).toEqual(['a', 'a', 'a']) + + expect(() => validate(arrayOf('a'), ['a', true, 'b', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 3 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [1], message: 'Value does not match constant "a" (string)' }, + { path: [2], message: 'Value does not match constant "a" (string)' }, + { path: [3], message: 'Value does not match constant "a" (string)' }, + ]), + ), + ) + + expect(validate(arrayOf('a'), ['a', 'a', 'a'])).toEqual(['a', 'a', 'a']) + + expect(() => validate(array({ items: 'a', uniqueItems: true }), ['a', true, 'a', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 3 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [1], message: 'Value does not match constant "a" (string)' }, + { path: [2], message: 'Duplicate of item at index 0' }, + { path: [3], message: 'Value does not match constant "a" (string)' }, + ]), + ), + ) }) it('should validate an array using the ArrayValidator class', () => { const validator = new ArrayValidator() - expect(validate(validator, [ 1, 'foo', true ])).toEqual([ 1, 'foo', true ]) + expect(validate(validator, [1, 'foo', true])).toEqual([1, 'foo', true]) }) }) diff --git a/test/12-objects.test.ts b/test/12-objects.test.ts index 9cc6070..66eb237 100644 --- a/test/12-objects.test.ts +++ b/test/12-objects.test.ts @@ -1,23 +1,36 @@ -import { allowAdditionalProperties, any, array, boolean, never, number, object, objectOf, optional, partial, string, strip, validate, ValidationError } from '../src' +import { + allowAdditionalProperties, + any, + array, + boolean, + never, + number, + object, + objectOf, + optional, + partial, + string, + strip, + validate, + ValidationError, +} from '../src/index.ts' describe('Object validator', () => { it('should validate a generic object', () => { expect(validate(object, {})).toEqual({}) expect(validate(object, { a: 1, b: 'foo' })).toEqual({ a: 1, b: 'foo' }) - expect(() => validate(object, 123)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not an "object"' }, - ]))) - - expect(() => validate(object, null)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is "null"' }, - ]))) + expect(() => validate(object, 123)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not an "object"' }])), + ) + + expect(() => validate(object, null)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is "null"' }])), + ) }) it('should validate an object', () => { @@ -25,36 +38,38 @@ describe('Object validator', () => { expect(validate(validator, { a: 1, b: 'foo' })).toEqual({ a: 1, b: 'foo' }) - expect(() => validate(validator, 123)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not an "object"' }, - ]))) - - expect(() => validate(validator, null)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is "null"' }, - ]))) - - expect(() => validate(validator, {})) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'a' ], message: 'Required property missing' }, - { path: [ 'b' ], message: 'Required property missing' }, - ]))) - - expect(() => validate(validator, { a: 'foo', b: 1, c: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 3 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'a' ], message: 'Value is not a "number"' }, - { path: [ 'b' ], message: 'Value is not a "string"' }, - { path: [ 'c' ], message: 'Unknown property' }, - ]))) + expect(() => validate(validator, 123)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is not an "object"' }])), + ) + + expect(() => validate(validator, null)).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: [], message: 'Value is "null"' }])), + ) + + expect(() => validate(validator, {})).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['a'], message: 'Required property missing' }, + { path: ['b'], message: 'Required property missing' }, + ]), + ), + ) + + expect(() => validate(validator, { a: 'foo', b: 1, c: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 3 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['a'], message: 'Value is not a "number"' }, + { path: ['b'], message: 'Value is not a "string"' }, + { path: ['c'], message: 'Unknown property' }, + ]), + ), + ) }) it('should validate a complex object', () => { @@ -74,47 +89,59 @@ describe('Object validator', () => { contents: array({ items: contents, minItems: 2 }), } as const) - expect(validate(validator, { - version: 1, - title: 'hello, world!', - contents: [ { - description: 'foo', - value: 123.456, - }, { - description: 'bar', - value: 654.321, - } ], - })).toEqual({ + expect( + validate(validator, { + version: 1, + title: 'hello, world!', + contents: [ + { + description: 'foo', + value: 123.456, + }, + { + description: 'bar', + value: 654.321, + }, + ], + }), + ).toEqual({ version: 1, title: 'hello, world!', - contents: [ { - description: 'foo', - value: 123.456, - }, { - description: 'bar', - value: 654.321, - } ], + contents: [ + { + description: 'foo', + value: 123.456, + }, + { + description: 'bar', + value: 654.321, + }, + ], }) - expect(() => validate(validator, { version: 2, contents: [] })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 3 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'version' ], message: 'Value does not match constant "1" (number)' }, - { path: [ 'title' ], message: 'Required property missing' }, - { path: [ 'contents' ], message: 'Array must have a minimum length of 2' }, - ]))) - - expect(() => validate(validator, { version: 3, contents: [ {}, 'foo' ] })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 5 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'version' ], message: 'Value does not match constant "1" (number)' }, - { path: [ 'title' ], message: 'Required property missing' }, - { path: [ 'contents', 0, 'description' ], message: 'Required property missing' }, - { path: [ 'contents', 0, 'value' ], message: 'Required property missing' }, - { path: [ 'contents', 1 ], message: 'Value is not an "object"' }, - ]))) + expect(() => validate(validator, { version: 2, contents: [] })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 3 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['version'], message: 'Value does not match constant "1" (number)' }, + { path: ['title'], message: 'Required property missing' }, + { path: ['contents'], message: 'Array must have a minimum length of 2' }, + ]), + ), + ) + + expect(() => validate(validator, { version: 3, contents: [{}, 'foo'] })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 5 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['version'], message: 'Value does not match constant "1" (number)' }, + { path: ['title'], message: 'Required property missing' }, + { path: ['contents', 0, 'description'], message: 'Required property missing' }, + { path: ['contents', 0, 'value'], message: 'Required property missing' }, + { path: ['contents', 1], message: 'Value is not an "object"' }, + ]), + ), + ) }) it('should validate an object tree', () => { @@ -124,166 +151,218 @@ describe('Object validator', () => { validate(object3, { two: { one: { zero: 'zero' } } }) - expect(() => validate(object3, { two: { one: { zero: 0 } } } )) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'two', 'one', 'zero' ], message: 'Value is not a "string"' }, - ]))) + expect(() => validate(object3, { two: { one: { zero: 0 } } })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: ['two', 'one', 'zero'], message: 'Value is not a "string"' }]), + ), + ) }) it('should validate an object with additional properties', () => { const validator1 = object({ foo: true, ...allowAdditionalProperties, baz: never }) - expect(validate(validator1, { foo: true, bar: 'whatever' })) - .toEqual({ foo: true, bar: 'whatever' }) - expect(() => validate(validator1, { foo: false, bar: 'whatever', baz: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'foo' ], message: 'Value does not match constant "true" (boolean)' }, - { path: [ 'baz' ], message: 'Forbidden property' }, - ]))) + expect(validate(validator1, { foo: true, bar: 'whatever' })).toEqual({ foo: true, bar: 'whatever' }) + expect(() => validate(validator1, { foo: false, bar: 'whatever', baz: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['foo'], message: 'Value does not match constant "true" (boolean)' }, + { path: ['baz'], message: 'Forbidden property' }, + ]), + ), + ) const validator2 = object({ foo: true, ...allowAdditionalProperties(true), baz: never }) - expect(validate(validator2, { foo: true, bar: 'whatever' })) - .toEqual({ foo: true, bar: 'whatever' }) - expect(() => validate(validator2, { foo: false, bar: 'whatever', baz: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'foo' ], message: 'Value does not match constant "true" (boolean)' }, - { path: [ 'baz' ], message: 'Forbidden property' }, - ]))) + expect(validate(validator2, { foo: true, bar: 'whatever' })).toEqual({ foo: true, bar: 'whatever' }) + expect(() => validate(validator2, { foo: false, bar: 'whatever', baz: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['foo'], message: 'Value does not match constant "true" (boolean)' }, + { path: ['baz'], message: 'Forbidden property' }, + ]), + ), + ) const validator3 = object({ foo: true, ...allowAdditionalProperties(any), baz: never }) - expect(validate(validator3, { foo: true, bar: 'whatever' })) - .toEqual({ foo: true, bar: 'whatever' }) - expect(() => validate(validator3, { foo: false, bar: 'whatever', baz: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'foo' ], message: 'Value does not match constant "true" (boolean)' }, - { path: [ 'baz' ], message: 'Forbidden property' }, - ]))) + expect(validate(validator3, { foo: true, bar: 'whatever' })).toEqual({ foo: true, bar: 'whatever' }) + expect(() => validate(validator3, { foo: false, bar: 'whatever', baz: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['foo'], message: 'Value does not match constant "true" (boolean)' }, + { path: ['baz'], message: 'Forbidden property' }, + ]), + ), + ) const validator4 = object({ foo: true, ...allowAdditionalProperties(false), baz: never }) - expect(() => validate(validator4, { foo: true, bar: 'whatever', baz: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'baz' ], message: 'Forbidden property' }, - { path: [ 'bar' ], message: 'Unknown property' }, - ]))) + expect(() => validate(validator4, { foo: true, bar: 'whatever', baz: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['baz'], message: 'Forbidden property' }, + { path: ['bar'], message: 'Unknown property' }, + ]), + ), + ) const validator5 = object({ foo: true, ...allowAdditionalProperties(string), baz: never }) - expect(validate(validator5, { foo: true, bar: 'whatever' })) - .toEqual({ foo: true, bar: 'whatever' }) - expect(validate(validator5, { foo: true, bar: undefined, baz: undefined })) - .toEqual({ foo: true }) - expect(() => validate(validator5, { foo: true, bar: 123, baz: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'baz' ], message: 'Forbidden property' }, - { path: [ 'bar' ], message: 'Value is not a "string"' }, - ]))) + expect(validate(validator5, { foo: true, bar: 'whatever' })).toEqual({ foo: true, bar: 'whatever' }) + expect(validate(validator5, { foo: true, bar: undefined, baz: undefined })).toEqual({ foo: true }) + expect(() => validate(validator5, { foo: true, bar: 123, baz: true })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['baz'], message: 'Forbidden property' }, + { path: ['bar'], message: 'Value is not a "string"' }, + ]), + ), + ) }) it('should validate an object of specific values', () => { const validator1 = objectOf(string) - expect(validate(validator1, { foo: 'FOO', bar: 'BAR' })) - .toEqual({ foo: 'FOO', bar: 'BAR' }) + expect(validate(validator1, { foo: 'FOO', bar: 'BAR' })).toEqual({ foo: 'FOO', bar: 'BAR' }) - expect(() => validate(validator1, { foo: 'FOO', bar: true })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Value is not a "string"' }, - ]))) + expect(() => validate(validator1, { foo: 'FOO', bar: true })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['bar'], message: 'Value is not a "string"' }])), + ) const validator2 = objectOf({ test: boolean }) - expect(validate(validator2, { foo: { test: true }, bar: { test: false } })) - .toEqual({ foo: { test: true }, bar: { test: false } }) - - expect(() => validate(validator2, { foo: { test: 'hello' }, bar: { test: 123 } })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'foo', 'test' ], message: 'Value is not a "boolean"' }, - { path: [ 'bar', 'test' ], message: 'Value is not a "boolean"' }, - ]))) + expect(validate(validator2, { foo: { test: true }, bar: { test: false } })).toEqual({ + foo: { test: true }, + bar: { test: false }, + }) + + expect(() => validate(validator2, { foo: { test: 'hello' }, bar: { test: 123 } })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['foo', 'test'], message: 'Value is not a "boolean"' }, + { path: ['bar', 'test'], message: 'Value is not a "boolean"' }, + ]), + ), + ) }) it('should strip additional or forbidden properties when asked to do so', () => { const validator = object({ foo: true, baz: never }) // normal validation - expect(validate(validator, { foo: true })) - .toEqual({ foo: true }) + expect(validate(validator, { foo: true })).toEqual({ foo: true }) // validate with forbidden/unknown properties are "undefined" - expect(validate(validator, { foo: true, bar: undefined, baz: undefined })) - .toEqual({ foo: true }) + expect(validate(validator, { foo: true, bar: undefined, baz: undefined })).toEqual({ foo: true }) // validate with forbidden/unknown properties set - expect(() => validate(validator, { foo: true, bar: 'whatever', baz: 123 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'baz' ], message: 'Forbidden property' }, - { path: [ 'bar' ], message: 'Unknown property' }, - ]))) - - expect(() => strip(validator, { foo: true, bar: 'whatever', baz: 123 }, { - stripAdditionalProperties: false, - })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'baz' ], message: 'Forbidden property' }, - { path: [ 'bar' ], message: 'Unknown property' }, - ]))) + expect(() => validate(validator, { foo: true, bar: 'whatever', baz: 123 })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['baz'], message: 'Forbidden property' }, + { path: ['bar'], message: 'Unknown property' }, + ]), + ), + ) + + expect(() => + strip( + validator, + { foo: true, bar: 'whatever', baz: 123 }, + { + stripAdditionalProperties: false, + }, + ), + ).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['baz'], message: 'Forbidden property' }, + { path: ['bar'], message: 'Unknown property' }, + ]), + ), + ) // strip with unknown properties set - expect(validate(validator, { foo: true, bar: 'whatever' }, { - stripAdditionalProperties: true, - })).toEqual({ foo: true }) - - expect(strip(validator, { foo: true, bar: 'whatever' })) - .toEqual({ foo: true }) + expect( + validate( + validator, + { foo: true, bar: 'whatever' }, + { + stripAdditionalProperties: true, + }, + ), + ).toEqual({ foo: true }) + + expect(strip(validator, { foo: true, bar: 'whatever' })).toEqual({ foo: true }) // strip with forbidden properties set - expect(validate(validator, { foo: true, baz: 'whatever' }, { - stripForbiddenProperties: true, - })).toEqual({ foo: true }) - - expect(strip(validator, { foo: true, baz: 'whatever' }, { - stripForbiddenProperties: true, - })).toEqual({ foo: true }) + expect( + validate( + validator, + { foo: true, baz: 'whatever' }, + { + stripForbiddenProperties: true, + }, + ), + ).toEqual({ foo: true }) + + expect( + strip( + validator, + { foo: true, baz: 'whatever' }, + { + stripForbiddenProperties: true, + }, + ), + ).toEqual({ foo: true }) // strip with unknown/forbidden properties set - expect(validate(validator, { foo: true, bar: 'whatever', baz: 'forbidden' }, { - stripAdditionalProperties: true, - stripForbiddenProperties: true, - })).toEqual({ foo: true }) + expect( + validate( + validator, + { foo: true, bar: 'whatever', baz: 'forbidden' }, + { + stripAdditionalProperties: true, + stripForbiddenProperties: true, + }, + ), + ).toEqual({ foo: true }) // strip with forbidden properties set - expect(() => validate(validator, { foo: true, bar: 'whatever', baz: 'forbidden' }, { - stripAdditionalProperties: true, - })).toThrow((assert) => assert + expect(() => + validate( + validator, + { foo: true, bar: 'whatever', baz: 'forbidden' }, + { + stripAdditionalProperties: true, + }, + ), + ).toThrow((assert) => + assert .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'baz' ], message: 'Forbidden property' }, - ]))) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['baz'], message: 'Forbidden property' }])), + ) // strip with forbidden properties set - expect(() => validate(validator, { foo: true, bar: 'whatever', baz: 'forbidden' }, { - stripForbiddenProperties: true, - })).toThrow((assert) => assert + expect(() => + validate( + validator, + { foo: true, bar: 'whatever', baz: 'forbidden' }, + { + stripForbiddenProperties: true, + }, + ), + ).toThrow((assert) => + assert .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Unknown property' }, - ]))) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['bar'], message: 'Unknown property' }])), + ) }) it('should perform a partial validation', () => { @@ -306,26 +385,26 @@ describe('Object validator', () => { expect(partial(validation, { addition: 'bar' })).toEqual({}) expect(partial(validation, { addition: null })).toEqual({}) - expect(() => partial(validation, { required: 12345 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'required' ], message: 'Value is not a "string"' }, - ]))) - - expect(() => partial(validation, { optional: 12345 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'optional' ], message: 'Value is not a "boolean"' }, - ]))) - - expect(() => partial(validation, { defaults: 'foo' })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'defaults' ], message: 'Value is not a "number"' }, - ]))) + expect(() => partial(validation, { required: 12345 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['required'], message: 'Value is not a "string"' }])), + ) + + expect(() => partial(validation, { optional: 12345 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: ['optional'], message: 'Value is not a "boolean"' }]), + ), + ) + + expect(() => partial(validation, { defaults: 'foo' })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['defaults'], message: 'Value is not a "number"' }])), + ) }) it('should perform a partial validation with allowed additional propertiees', () => { @@ -343,50 +422,46 @@ describe('Object validator', () => { expect(partial(validation, { defaults: 12345 })).toEqual({ defaults: 12345 }) expect(partial(validation, { addition: 'bar' })).toEqual({ addition: 'bar' }) - expect(() => partial(validation, { required: 12345 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'required' ], message: 'Value is not a "string"' }, - ]))) - - expect(() => partial(validation, { optional: 12345 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'optional' ], message: 'Value is not a "boolean"' }, - ]))) - - expect(() => partial(validation, { defaults: 'foo' })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'defaults' ], message: 'Value is not a "number"' }, - ]))) - - expect(() => partial(validation, { addition: 12345 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'addition' ], message: 'Value is not a "string"' }, - ]))) + expect(() => partial(validation, { required: 12345 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['required'], message: 'Value is not a "string"' }])), + ) + + expect(() => partial(validation, { optional: 12345 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: ['optional'], message: 'Value is not a "boolean"' }]), + ), + ) + + expect(() => partial(validation, { defaults: 'foo' })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['defaults'], message: 'Value is not a "number"' }])), + ) + + expect(() => partial(validation, { addition: 12345 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['addition'], message: 'Value is not a "string"' }])), + ) }) it('should extends and allow additional properties', () => { const object1 = object({ foo: string, ...allowAdditionalProperties(number) }) const object2 = object({ ...object1, bar: boolean }) - expect(validate(object1, { foo: 'bar', bar: 321, baz: 123 })) - .toEqual({ foo: 'bar', bar: 321, baz: 123 }) - expect(validate(object2, { foo: 'bar', bar: true, baz: 123 })) - .toEqual({ foo: 'bar', bar: true, baz: 123 }) - - expect(() => validate(object1, { foo: 'bar', bar: true, baz: 123 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Value is not a "number"' }, - ]))) + expect(validate(object1, { foo: 'bar', bar: 321, baz: 123 })).toEqual({ foo: 'bar', bar: 321, baz: 123 }) + expect(validate(object2, { foo: 'bar', bar: true, baz: 123 })).toEqual({ foo: 'bar', bar: true, baz: 123 }) + + expect(() => validate(object1, { foo: 'bar', bar: true, baz: 123 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['bar'], message: 'Value is not a "number"' }])), + ) }) it('should extends and remove additional properties', () => { @@ -394,11 +469,10 @@ describe('Object validator', () => { const object2 = object({ ...object1, ...allowAdditionalProperties(false) }) expect(validate(object1, { foo: 'bar', bar: 123 })).toEqual({ foo: 'bar', bar: 123 }) - expect(() => validate(object2, { foo: 'bar', bar: 123 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Unknown property' }, - ]))) + expect(() => validate(object2, { foo: 'bar', bar: 123 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['bar'], message: 'Unknown property' }])), + ) }) }) diff --git a/test/13-optional.test.ts b/test/13-optional.test.ts index 186aa92..9f113a0 100644 --- a/test/13-optional.test.ts +++ b/test/13-optional.test.ts @@ -1,31 +1,46 @@ -import { arrayOf, number, object, oneOf, optional, string, StringValidator, strip, validate, ValidationError } from '../src' +import { + arrayOf, + number, + object, + oneOf, + optional, + string, + StringValidator, + strip, + validate, + ValidationError, +} from '../src/index.ts' describe('Object modifiers', () => { it('should validate a simple optional validation', () => { const validation = optional('foobar') expect(validate(validation, undefined)).toBeUndefined() expect(validate(validation, 'foobar')).toStrictlyEqual('foobar') - expect(() => validate(validation, 'wrong')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "foobar" (string)' }, - ]))) + expect(() => validate(validation, 'wrong')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'Value does not match constant "foobar" (string)' }]), + ), + ) }) it('should validate an array with optional elements', () => { const validation = arrayOf(optional('foobar')) - expect(validate(validation, [ undefined ])).toEqual([ undefined ]) - expect(validate(validation, [ 'foobar' ])).toEqual([ 'foobar' ]) - expect(validate(validation, [ undefined, 'foobar' ])).toEqual([ undefined, 'foobar' ]) - - expect(() => validate(validation, [ 'wrong', 12 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 0 ], message: 'Value does not match constant "foobar" (string)' }, - { path: [ 1 ], message: 'Value does not match constant "foobar" (string)' }, - ]))) + expect(validate(validation, [undefined])).toEqual([undefined]) + expect(validate(validation, ['foobar'])).toEqual(['foobar']) + expect(validate(validation, [undefined, 'foobar'])).toEqual([undefined, 'foobar']) + + expect(() => validate(validation, ['wrong', 12])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [0], message: 'Value does not match constant "foobar" (string)' }, + { path: [1], message: 'Value does not match constant "foobar" (string)' }, + ]), + ), + ) }) it('should validate an object with optional properties', () => { @@ -34,19 +49,19 @@ describe('Object modifiers', () => { bar: optional(number({ minimum: 50 })), }) - expect(validate(schema1, { foo: 'hello', bar: 50 })) - .toEqual({ foo: 'hello', bar: 50 }) + expect(validate(schema1, { foo: 'hello', bar: 50 })).toEqual({ foo: 'hello', bar: 50 }) - expect(validate(schema1, { foo: 'hello' })) - .toEqual({ foo: 'hello' }) + expect(validate(schema1, { foo: 'hello' })).toEqual({ foo: 'hello' }) - expect(() => validate(schema1, { foo: 'hello', bar: 40, baz: 60 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Number is less than 50' }, - { path: [ 'baz' ], message: 'Unknown property' }, - ]))) + expect(() => validate(schema1, { foo: 'hello', bar: 40, baz: 60 })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['bar'], message: 'Number is less than 50' }, + { path: ['baz'], message: 'Unknown property' }, + ]), + ), + ) }) it('should validate an object with optional properties and defaults', () => { @@ -56,21 +71,21 @@ describe('Object modifiers', () => { baz: optional(string, 'world'), }) - expect(validate(schema, {})) - .toEqual({ foo: 'hello', bar: 10, baz: 'world' }) - - expect(validate(schema, { foo: 'world', bar: 15, baz: 'hello' })) - .toEqual({ foo: 'world', bar: 15, baz: 'hello' }) - - expect(() => validate(schema, { foo: 'nope', bar: 0, baz: 0 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 4 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'foo' ], message: 'Value does not match constant "hello" (string)' }, - { path: [ 'foo' ], message: 'Value does not match constant "world" (string)' }, - { path: [ 'bar' ], message: 'Number is less than 5' }, - { path: [ 'baz' ], message: 'Value is not a "string"' }, - ]))) + expect(validate(schema, {})).toEqual({ foo: 'hello', bar: 10, baz: 'world' }) + + expect(validate(schema, { foo: 'world', bar: 15, baz: 'hello' })).toEqual({ foo: 'world', bar: 15, baz: 'hello' }) + + expect(() => validate(schema, { foo: 'nope', bar: 0, baz: 0 })).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 4 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['foo'], message: 'Value does not match constant "hello" (string)' }, + { path: ['foo'], message: 'Value does not match constant "world" (string)' }, + { path: ['bar'], message: 'Number is less than 5' }, + { path: ['baz'], message: 'Value is not a "string"' }, + ]), + ), + ) }) it('should validate an object when a validator is forced as "optional"', () => { @@ -81,25 +96,30 @@ describe('Object modifiers', () => { validator.optional = true expect(validate({ test: validator }, {})).toEqual({}) - expect(() => validate({ test: validator }, { test: 123 })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'test' ], message: 'Value is not a "string"' }, - ]))) + expect(() => validate({ test: validator }, { test: 123 })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['test'], message: 'Value is not a "string"' }])), + ) }) it('should fail when a default value does not match the validation', () => { - expect(() => object({ - foo: optional(oneOf('hello', 'world'), 'nope' as any), - })).toThrow((assert) => assert - .toBeError(TypeError, 'Default value does not match validator') - .toHaveProperty('cause', expect - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value does not match constant "hello" (string)' }, - { path: [], message: 'Value does not match constant "world" (string)' }, - ])))) + expect(() => + object({ + foo: optional(oneOf('hello', 'world'), 'nope' as any), + }), + ).toThrow((assert) => + assert.toBeError(TypeError, 'Default value does not match validator').toHaveProperty( + 'cause', + expect.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [], message: 'Value does not match constant "hello" (string)' }, + { path: [], message: 'Value does not match constant "world" (string)' }, + ]), + ), + ), + ) }) it('should strip an object with optional properties', () => { @@ -108,20 +128,16 @@ describe('Object modifiers', () => { bar: optional(number({ minimum: 50 })), }) - expect(strip(schema1, { foo: 'hello', bar: 50, extra: 'foo' })) - .toEqual({ foo: 'hello', bar: 50 }) + expect(strip(schema1, { foo: 'hello', bar: 50, extra: 'foo' })).toEqual({ foo: 'hello', bar: 50 }) - expect(strip(schema1, { foo: 'hello', bar: null, extra: 'foo' })) - .toEqual({ foo: 'hello' }) + expect(strip(schema1, { foo: 'hello', bar: null, extra: 'foo' })).toEqual({ foo: 'hello' }) - expect(strip(schema1, { foo: 'hello', extra: 'foo' })) - .toEqual({ foo: 'hello' }) + expect(strip(schema1, { foo: 'hello', extra: 'foo' })).toEqual({ foo: 'hello' }) - expect(() => strip(schema1, { foo: 'hello', bar: 40, baz: 60, extra: 'foo' })) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'bar' ], message: 'Number is less than 50' }, - ]))) + expect(() => strip(schema1, { foo: 'hello', bar: 40, baz: 60, extra: 'foo' })).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty('errors', expect.toMatchContents([{ path: ['bar'], message: 'Number is less than 50' }])), + ) }) }) diff --git a/test/14-unions.test.ts b/test/14-unions.test.ts index 9af1f7b..b3ed099 100644 --- a/test/14-unions.test.ts +++ b/test/14-unions.test.ts @@ -1,4 +1,4 @@ -import { allOf, number, oneOf, string, validate, ValidationError } from '../src' +import { allOf, number, oneOf, string, validate, ValidationError } from '../src/index.ts' describe('Union validators', () => { it('should validate one of the given options', () => { @@ -6,13 +6,15 @@ describe('Union validators', () => { expect(validate(validator, 'foo')).toStrictlyEqual('foo') expect(validate(validator, 12345)).toStrictlyEqual(12345) - expect(() => validate(validator, true)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'Value is not a "string"' }, - { path: [], message: 'Value is not a "number"' }, - ]))) + expect(() => validate(validator, true)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: [], message: 'Value is not a "string"' }, + { path: [], message: 'Value is not a "number"' }, + ]), + ), + ) }) it('should validate all of the given options', () => { @@ -22,18 +24,22 @@ describe('Union validators', () => { const validator = allOf(s1, s2) expect(validate(validator, 'foo')).toStrictlyEqual('foo') - expect(() => validate(validator, '')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'String must have a minimum length of 3' }, - ]))) + expect(() => validate(validator, '')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'String must have a minimum length of 3' }]), + ), + ) - expect(() => validate(validator, 'foobar')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [], message: 'String must have a maximum length of 3' }, - ]))) + expect(() => validate(validator, 'foobar')).toThrow((assert) => + assert + .toBeError(ValidationError, /^Found 1 validation error/) + .toHaveProperty( + 'errors', + expect.toMatchContents([{ path: [], message: 'String must have a maximum length of 3' }]), + ), + ) }) }) diff --git a/test/15-tuples.test.ts b/test/15-tuples.test.ts index d87309a..afbe623 100644 --- a/test/15-tuples.test.ts +++ b/test/15-tuples.test.ts @@ -1,13 +1,18 @@ -import { boolean, number, object, string, tuple, validate, ValidationError } from '../src' +import { boolean, number, object, string, tuple, validate, ValidationError } from '../src/index.ts' describe('Tuple validator', () => { it('should not validate non-arrays', () => { - expect(() => validate([], 'string')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Value is not an "array"', - } ]))) + expect(() => validate([], 'string')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Value is not an "array"', + }, + ]), + ), + ) }) it('should validate an empty tuple', () => { @@ -15,129 +20,162 @@ describe('Tuple validator', () => { expect(validate(validator, [])).toEqual([]) - expect(() => validate(validator, [ 'foo' ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Found 1 element validating empty tuple', - } ]))) - - expect(() => validate(validator, [ 'foo', 'bar' ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Found 2 elements validating empty tuple', - } ]))) + expect(() => validate(validator, ['foo'])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Found 1 element validating empty tuple', + }, + ]), + ), + ) + + expect(() => validate(validator, ['foo', 'bar'])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Found 2 elements validating empty tuple', + }, + ]), + ), + ) }) it('should validate a simple tuple', () => { - const validator = tuple([ string, number, boolean ]) - - expect(validate(validator, [ 'foo', 123, true ])) - .toEqual([ 'foo', 123, true ]) - - expect(() => validate(validator, [ 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [ 0 ], message: 'Value is not a "string"', - } ]))) - - expect(() => validate(validator, [ 'foo', 123, true, 'bar' ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Found 1 extra element in tuple', - } ]))) - - expect(() => validate(validator, [ 'foo', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Tuple defines 1 missing validation', - } ]))) - - expect(() => validate(validator, [ 'foo' ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Tuple defines 2 missing validations', - } ]))) + const validator = tuple([string, number, boolean]) + + expect(validate(validator, ['foo', 123, true])).toEqual(['foo', 123, true]) + + expect(() => validate(validator, [123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [0], + message: 'Value is not a "string"', + }, + ]), + ), + ) + + expect(() => validate(validator, ['foo', 123, true, 'bar'])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Found 1 extra element in tuple', + }, + ]), + ), + ) + + expect(() => validate(validator, ['foo', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Tuple defines 1 missing validation', + }, + ]), + ), + ) + + expect(() => validate(validator, ['foo'])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Tuple defines 2 missing validations', + }, + ]), + ), + ) }) it('should validate a tuple with rest parameters', () => { - const validator = tuple([ ...string, null, ...number ]) - - expect(validate(validator, [ 'foo', 'bar', null, 123, 456 ])) - .toEqual([ 'foo', 'bar', null, 123, 456 ]) - expect(validate(validator, [ 'foo', null, 123 ])) - .toEqual([ 'foo', null, 123 ]) - - expect(validate(validator, [ 'foo', 'bar', null ])) - .toEqual([ 'foo', 'bar', null ]) - expect(validate(validator, [ 'foo', null ])) - .toEqual([ 'foo', null ]) - - expect(validate(validator, [ null, 123, 456 ])) - .toEqual([ null, 123, 456 ]) - expect(validate(validator, [ null, 123 ])) - .toEqual([ null, 123 ]) - - expect(() => validate(validator, [ 'foo', 123 ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [ 1 ], message: 'Value does not match constant "null"', - } ]))) - - expect(() => validate(validator, [ 'foo', null, 123, true ])) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Found 1 extra element in tuple', - } ]))) + const validator = tuple([...string, null, ...number]) + + expect(validate(validator, ['foo', 'bar', null, 123, 456])).toEqual(['foo', 'bar', null, 123, 456]) + expect(validate(validator, ['foo', null, 123])).toEqual(['foo', null, 123]) + + expect(validate(validator, ['foo', 'bar', null])).toEqual(['foo', 'bar', null]) + expect(validate(validator, ['foo', null])).toEqual(['foo', null]) + + expect(validate(validator, [null, 123, 456])).toEqual([null, 123, 456]) + expect(validate(validator, [null, 123])).toEqual([null, 123]) + + expect(() => validate(validator, ['foo', 123])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [1], + message: 'Value does not match constant "null"', + }, + ]), + ), + ) + + expect(() => validate(validator, ['foo', null, 123, true])).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Found 1 extra element in tuple', + }, + ]), + ), + ) }) it('should validate a tuple with only rest parameters', () => { - const v1 = tuple([ ...string, ...number ]) - expect(validate(v1, [ 'foo', 'bar', 123, 456 ])) - .toEqual([ 'foo', 'bar', 123, 456 ]) + const v1 = tuple([...string, ...number]) + expect(validate(v1, ['foo', 'bar', 123, 456])).toEqual(['foo', 'bar', 123, 456]) - expect(validate(v1, [ 'foo', 'bar' ])) - .toEqual([ 'foo', 'bar' ]) + expect(validate(v1, ['foo', 'bar'])).toEqual(['foo', 'bar']) - expect(validate(v1, [ 123, 456 ])) - .toEqual([ 123, 456 ]) + expect(validate(v1, [123, 456])).toEqual([123, 456]) - expect(validate(v1, [])) - .toEqual([]) + expect(validate(v1, [])).toEqual([]) }) it('should validate a tuple with an object rest parameter', () => { const o1 = object({ foo: string } as const) - const v1 = tuple([ number, ...o1, boolean ]) + const v1 = tuple([number, ...o1, boolean]) - expect(validate(v1, [ 123, true ])) - .toEqual([ 123, true ]) + expect(validate(v1, [123, true])).toEqual([123, true]) - expect(validate(v1, [ 123, { foo: 'bar' }, true ])) - .toEqual([ 123, { foo: 'bar' }, true ]) + expect(validate(v1, [123, { foo: 'bar' }, true])).toEqual([123, { foo: 'bar' }, true]) - expect(validate(v1, [ 123, { foo: 'bar' }, { foo: 'baz' }, true ])) - .toEqual([ 123, { foo: 'bar' }, { foo: 'baz' }, true ]) + expect(validate(v1, [123, { foo: 'bar' }, { foo: 'baz' }, true])).toEqual([ + 123, + { foo: 'bar' }, + { foo: 'baz' }, + true, + ]) }) it('should validate a straight tuple', () => { const o1 = object({ foo: string } as const) - const v1 = [ number, ...o1, boolean ] as const + const v1 = [number, ...o1, boolean] as const - expect(validate(v1, [ 123, true ])) - .toEqual([ 123, true ]) + expect(validate(v1, [123, true])).toEqual([123, true]) - expect(validate(v1, [ 123, { foo: 'bar' }, true ])) - .toEqual([ 123, { foo: 'bar' }, true ]) + expect(validate(v1, [123, { foo: 'bar' }, true])).toEqual([123, { foo: 'bar' }, true]) - expect(validate(v1, [ 123, { foo: 'bar' }, { foo: 'baz' }, true ])) - .toEqual([ 123, { foo: 'bar' }, { foo: 'baz' }, true ]) + expect(validate(v1, [123, { foo: 'bar' }, { foo: 'baz' }, true])).toEqual([ + 123, + { foo: 'bar' }, + { foo: 'baz' }, + true, + ]) }) }) diff --git a/test/16-dates.test.ts b/test/16-dates.test.ts index f748f31..ee61dc3 100644 --- a/test/16-dates.test.ts +++ b/test/16-dates.test.ts @@ -1,4 +1,4 @@ -import { date, validate, ValidationError } from '../src' +import { date, validate, ValidationError } from '../src/index.ts' describe('Date validator', () => { it('should validate a simple date', () => { @@ -18,19 +18,29 @@ describe('Date validator', () => { expect(validate(validator, '1970-01-01T00:00:00.000Z').getTime()).toEqual(0) expect(validate(validator, new Date(0)).getTime()).toEqual(0) - expect(() => validate(validator, 0)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'ISO Date is not a "string"', - } ]))) - - expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Invalid format for ISO Date', - } ]))) + expect(() => validate(validator, 0)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'ISO Date is not a "string"', + }, + ]), + ), + ) + + expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Invalid format for ISO Date', + }, + ]), + ), + ) }) it('should validate a timestamp', () => { @@ -39,12 +49,17 @@ describe('Date validator', () => { expect(validate(validator, 123).getTime()).toEqual(123) expect(validate(validator, new Date(123)).getTime()).toEqual(123) - expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Timestamp is not a "number"', - } ]))) + expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Timestamp is not a "number"', + }, + ]), + ), + ) }) it('should validate a timestamp', () => { @@ -53,71 +68,106 @@ describe('Date validator', () => { expect(validate(validator, 123).getTime()).toEqual(123_000) expect(validate(validator, new Date(123)).getTime()).toEqual(123) - expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Unix Timestamp is not a "number"', - } ]))) + expect(() => validate(validator, 'Thu, 01 Jan 1970 00:00:00 GMT')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Unix Timestamp is not a "number"', + }, + ]), + ), + ) }) - it('should validate a date within a range', () => { const v1 = date({ from: new Date(2000), until: new Date(3000) }) expect(validate(v1, 2000).getTime()).toEqual(2000) expect(validate(v1, 3000).getTime()).toEqual(3000) - expect(() => validate(v1, 1999)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Date is before 1970-01-01T00:00:02.000Z', - } ]))) - - expect(() => validate(v1, 3001)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Date is after 1970-01-01T00:00:03.000Z', - } ]))) - + expect(() => validate(v1, 1999)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Date is before 1970-01-01T00:00:02.000Z', + }, + ]), + ), + ) + + expect(() => validate(v1, 3001)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Date is after 1970-01-01T00:00:03.000Z', + }, + ]), + ), + ) const v2 = date({ from: new Date(2000), until: new Date(2000) }) expect(validate(v2, 2000).getTime()).toEqual(2000) - expect(() => validate(v2, 1999)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Date is before 1970-01-01T00:00:02.000Z', - } ]))) - - expect(() => validate(v2, 2001)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Date is after 1970-01-01T00:00:02.000Z', - } ]))) - - expect(() => date({ from: new Date(100), until: new Date(99) })) - .toThrowError(TypeError, 'Constraint "until" (1970-01-01T00:00:00.099Z) must not be before "from" (1970-01-01T00:00:00.100Z)') + expect(() => validate(v2, 1999)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Date is before 1970-01-01T00:00:02.000Z', + }, + ]), + ), + ) + + expect(() => validate(v2, 2001)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Date is after 1970-01-01T00:00:02.000Z', + }, + ]), + ), + ) + + expect(() => date({ from: new Date(100), until: new Date(99) })).toThrowError( + TypeError, + 'Constraint "until" (1970-01-01T00:00:00.099Z) must not be before "from" (1970-01-01T00:00:00.100Z)', + ) }) it('should consider edge cases', () => { - expect(() => validate(date, Symbol())) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Value could not be converted to a "Date"', - } ]))) - - expect(() => validate(date, Number.POSITIVE_INFINITY)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error/) - .toHaveProperty('errors', expect.toMatchContents([ { - path: [], message: 'Invalid date', - } ]))) + expect(() => validate(date, Symbol())).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Value could not be converted to a "Date"', + }, + ]), + ), + ) + + expect(() => validate(date, Number.POSITIVE_INFINITY)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { + path: [], + message: 'Invalid date', + }, + ]), + ), + ) }) }) diff --git a/test/20-conversion.test.ts b/test/20-conversion.test.ts index d5907e7..b75aa99 100644 --- a/test/20-conversion.test.ts +++ b/test/20-conversion.test.ts @@ -1,24 +1,24 @@ -import { arrayOf, date, object, tuple, validate } from '../src' +import { arrayOf, date, object, tuple, validate } from '../src/index.ts' describe('Type conversion', () => { it('should convert types in arrays', () => { - const src = [ 0 ] + const src = [0] const tgt = validate(arrayOf(date), src) expect(src).not.toStrictlyEqual(tgt) - expect(src).toEqual([ 0 ]) + expect(src).toEqual([0]) expect(tgt).toBeA('array').toHaveLength(1) expect(tgt[0]).toBeInstanceOf(Date) - expect(tgt[0].getTime()).toStrictlyEqual(0) + expect(tgt[0]!.getTime()).toStrictlyEqual(0) }) it('should convert types in tuples', () => { - const src = [ 0 ] - const tgt = validate(tuple([ date ]), src) + const src = [0] + const tgt = validate(tuple([date]), src) expect(src).not.toStrictlyEqual(tgt) - expect(src).toEqual([ 0 ]) + expect(src).toEqual([0]) expect(tgt).toBeA('array').toHaveLength(1) expect(tgt[0]).toBeInstanceOf(Date) diff --git a/test/50-extra-arn.test.ts b/test/50-extra-arn.test.ts index 2038cac..a21132f 100644 --- a/test/50-extra-arn.test.ts +++ b/test/50-extra-arn.test.ts @@ -1,202 +1,242 @@ -import { ValidationError, validate } from '../src' -import { arn, parseArn } from '../src/extra/arn' +import { arn, parseArn } from '../src/extra/arn.ts' +import { ValidationError, validate } from '../src/index.ts' describe('Extra UUID validator', () => { describe('Parsed ARNs', () => { it('should parse an IAM Role ARN', () => { // resources separated by `/` - expect(validate(parseArn, 'arn:aws:iam::123456789012:role/my-role')) - .toEqual({ - Arn: 'arn:aws:iam::123456789012:role/my-role', - Partition: 'aws', - Service: 'iam', - Region: '', - Account: '123456789012', - Resource: [ - 'role', - 'my-role', - ], - }) + expect(validate(parseArn, 'arn:aws:iam::123456789012:role/my-role')).toEqual({ + Arn: 'arn:aws:iam::123456789012:role/my-role', + Partition: 'aws', + Service: 'iam', + Region: '', + Account: '123456789012', + Resource: ['role', 'my-role'], + }) }) it('should parse a Lambda Function ARN', () => { // resources separated by `:` - expect(validate(parseArn, 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name')) - .toEqual({ - Arn: 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name', - Partition: 'aws', - Service: 'lambda', - Region: 'xx-somewhere-0', - Account: '123456789012', - Resource: [ - 'function', - 'my-function-name', - ] }) + expect(validate(parseArn, 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name')).toEqual({ + Arn: 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name', + Partition: 'aws', + Service: 'lambda', + Region: 'xx-somewhere-0', + Account: '123456789012', + Resource: ['function', 'my-function-name'], + }) }) it('should parse a SQS Queue ARN', () => { // only one resource - expect(validate(parseArn, 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue')) - .toEqual({ - Arn: 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue', - Partition: 'aws', - Service: 'sqs', - Region: 'xx-somewhere-0', - Account: '123456789012', - Resource: [ 'my-queue' ], - }) + expect(validate(parseArn, 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue')).toEqual({ + Arn: 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue', + Partition: 'aws', + Service: 'sqs', + Region: 'xx-somewhere-0', + Account: '123456789012', + Resource: ['my-queue'], + }) }) it('should parse an ARN matching the service', () => { - expect(validate(parseArn('service'), 'arn:partition:service:region:account:resource')) - .toEqual({ - Arn: 'arn:partition:service:region:account:resource', - Partition: 'partition', - Service: 'service', - Region: 'region', - Account: 'account', - Resource: [ 'resource' ], - }) + expect(validate(parseArn('service'), 'arn:partition:service:region:account:resource')).toEqual({ + Arn: 'arn:partition:service:region:account:resource', + Partition: 'partition', + Service: 'service', + Region: 'region', + Account: 'account', + Resource: ['resource'], + }) }) it('should accept a slightly malformed ARN', () => { - expect(validate(parseArn('service'), 'arn:partition:service:region:account:resource/foo:bar')) - .toEqual({ - Arn: 'arn:partition:service:region:account:resource/foo', // no "bar" - Partition: 'partition', - Service: 'service', - Region: 'region', - Account: 'account', - Resource: [ 'resource', 'foo' ], // no "bar" - }) + expect(validate(parseArn('service'), 'arn:partition:service:region:account:resource/foo:bar')).toEqual({ + Arn: 'arn:partition:service:region:account:resource/foo', // no "bar" + Partition: 'partition', + Service: 'service', + Region: 'region', + Account: 'account', + Resource: ['resource', 'foo'], // no "bar" + }) }) }) describe('String ARNs', () => { it('should parse an IAM Role ARN', () => { // resources separated by `/` - expect(validate(arn, 'arn:aws:iam::123456789012:role/my-role')) - .toStrictlyEqual('arn:aws:iam::123456789012:role/my-role') + expect(validate(arn, 'arn:aws:iam::123456789012:role/my-role')).toStrictlyEqual( + 'arn:aws:iam::123456789012:role/my-role', + ) }) it('should parse a Lambda Function ARN', () => { // resources separated by `:` - expect(validate(arn, 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name')) - .toStrictlyEqual('arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name') + expect(validate(arn, 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name')).toStrictlyEqual( + 'arn:aws:lambda:xx-somewhere-0:123456789012:function:my-function-name', + ) }) it('should parse a SQS Queue ARN', () => { // only one resource - expect(validate(arn, 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue')) - .toStrictlyEqual('arn:aws:sqs:xx-somewhere-0:123456789012:my-queue') + expect(validate(arn, 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue')).toStrictlyEqual( + 'arn:aws:sqs:xx-somewhere-0:123456789012:my-queue', + ) }) it('should parse an ARN matching the service', () => { - expect(validate(arn('service'), 'arn:partition:service:region:account:resource')) - .toStrictlyEqual('arn:partition:service:region:account:resource') + expect(validate(arn('service'), 'arn:partition:service:region:account:resource')).toStrictlyEqual( + 'arn:partition:service:region:account:resource', + ) }) it('should accept a slightly malformed ARN', () => { - expect(validate(arn('service'), 'arn:partition:service:region:account:resource/foo:bar')) - .toStrictlyEqual('arn:partition:service:region:account:resource/foo') + expect(validate(arn('service'), 'arn:partition:service:region:account:resource/foo:bar')).toStrictlyEqual( + 'arn:partition:service:region:account:resource/foo', + ) }) }) describe('Invalid ARNs', () => { it('should fail when the prefix is not "arn:"', () => { - expect(() => validate(arn, 'xxx:aws:sqs:xx-somewhere-0:123456789012:my-queue')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'ARN must start with "arn:"', - } ]))) + expect(() => validate(arn, 'xxx:aws:sqs:xx-somewhere-0:123456789012:my-queue')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'ARN must start with "arn:"', + }, + ]), + ), + ) }) it('should fail when a required component is missing', () => { - expect(() => validate(arn, 'arn::service:region:account:resource')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Missing partition in ARN', - } ]))) - - expect(() => validate(arn, 'arn:aws::region:account:resource')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Missing service in ARN', - } ]))) - - expect(() => validate(arn, 'arn:aws:service:region::resource')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Missing account ID in ARN', - } ]))) - - expect(() => validate(arn, 'arn:aws:service:region:account')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Invalid components in ARN', - } ]))) - - expect(() => validate(arn, 'arn:aws:service:region:account:')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Missing resource ID in ARN', - } ]))) - - expect(() => validate(arn, 'arn:aws:service:region:account:/')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'Invalid resource ID in ARN', - } ]))) + expect(() => validate(arn, 'arn::service:region:account:resource')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Missing partition in ARN', + }, + ]), + ), + ) + + expect(() => validate(arn, 'arn:aws::region:account:resource')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Missing service in ARN', + }, + ]), + ), + ) + + expect(() => validate(arn, 'arn:aws:service:region::resource')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Missing account ID in ARN', + }, + ]), + ), + ) + + expect(() => validate(arn, 'arn:aws:service:region:account')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Invalid components in ARN', + }, + ]), + ), + ) + + expect(() => validate(arn, 'arn:aws:service:region:account:')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Missing resource ID in ARN', + }, + ]), + ), + ) + + expect(() => validate(arn, 'arn:aws:service:region:account:/')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'Invalid resource ID in ARN', + }, + ]), + ), + ) }) it('should fail when the service is mismatched', () => { - expect(() => validate(arn('correct'), 'arn:aws:wrong:region:account:resource')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'ARN Service "wrong" mismatch (expected "correct")', - } ]))) - - expect(() => validate(parseArn('correct'), 'arn:aws:wrong:region:account:resource')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'ARN Service "wrong" mismatch (expected "correct")', - } ]))) + expect(() => validate(arn('correct'), 'arn:aws:wrong:region:account:resource')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'ARN Service "wrong" mismatch (expected "correct")', + }, + ]), + ), + ) + + expect(() => validate(parseArn('correct'), 'arn:aws:wrong:region:account:resource')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'ARN Service "wrong" mismatch (expected "correct")', + }, + ]), + ), + ) }) it('should fail when the resource type is mismatched', () => { - expect(() => validate(arn('service', 'correct'), 'arn:aws:service:region:account:wrong/foo')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { - path: [], - message: 'ARN Resource Type "wrong" mismatch (expected "correct")', - } ]))) - - expect(() => validate(parseArn('service', 'correct'), 'arn:aws:service:region:account:wrong/foo')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', expect.toEqual([ { + expect(() => validate(arn('service', 'correct'), 'arn:aws:service:region:account:wrong/foo')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { + path: [], + message: 'ARN Resource Type "wrong" mismatch (expected "correct")', + }, + ]), + ), + ) + + expect(() => validate(parseArn('service', 'correct'), 'arn:aws:service:region:account:wrong/foo')).toThrow( + (assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty( + 'errors', + expect.toEqual([ + { path: [], message: 'ARN Resource Type "wrong" mismatch (expected "correct")', - } ]))) + }, + ]), + ), + ) }) }) }) diff --git a/test/50-extra-ean13.test.ts b/test/50-extra-ean13.test.ts index 547a30f..1540c50 100644 --- a/test/50-extra-ean13.test.ts +++ b/test/50-extra-ean13.test.ts @@ -1,5 +1,5 @@ -import { ValidationError, validate } from '../src' -import { ean13 } from '../src/extra/ean13' +import { ean13 } from '../src/extra/ean13.ts' +import { ValidationError, validate } from '../src/index.ts' describe('Extra EAN-13 Validator', () => { it('should validate all our EAN-13 codes', async () => { @@ -13,190 +13,767 @@ describe('Extra EAN-13 Validator', () => { }) it('should reject a short EAN-13', () => { - expect(() => validate(ean13, '123456789012')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a minimum length of 13', - path: [], - } ])), - ) + expect(() => validate(ean13, '123456789012')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a minimum length of 13', + path: [], + }, + ]), + ), + ) }) it('should reject a long EAN-13', () => { - expect(() => validate(ean13, '12345678901234')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a maximum length of 13', - path: [], - } ])), - ) + expect(() => validate(ean13, '12345678901234')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a maximum length of 13', + path: [], + }, + ]), + ), + ) }) it('should reject an invalid EAN-13', () => { - expect(() => validate(ean13, 'aaaaaaaaaaaaa')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: expect.toMatch(/^String does not match required pattern /), - path: [], - } ])), - ) + expect(() => validate(ean13, 'aaaaaaaaaaaaa')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: expect.toMatch(/^String does not match required pattern /), + path: [], + }, + ]), + ), + ) }) it('should reject an EAN-13 with the wrong checksum', () => { - expect(() => validate(ean13, '9780802409431')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'Invalid checksum in EAN-13 "9780802409431"', - path: [], - } ])), - ) + expect(() => validate(ean13, '9780802409431')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'Invalid checksum in EAN-13 "9780802409431"', + path: [], + }, + ]), + ), + ) }) }) const correct = [ - '9780802409430', '9781891595240', '9780897876254', '9780300091892', '9785887021454', - '9789879960165', '9780764422799', '9780534264956', '9780517568439', '9782865377923', - '9783110175752', '9780732274689', '9789682978739', '9781420102765', '9780914336556', - '9780538140201', '9781557666291', '9780439897518', '9780310607106', '9788484566052', - '9780471614470', '9780548573617', '9780716789017', '9780548693711', '9783540784395', - '9781592964727', '9780606028479', '9780559649769', '9780451129567', '9780295956190', - '9780252014628', '9780548879740', '9781420878844', '9780882293820', '9781580330060', - '9781434304155', '9781605975993', '9780884964087', '9780976425625', '9781424151523', - '9780756400071', '9781604537871', '9780573691980', '9789871081073', '9781412094054', - '9780720472288', '9788480181129', '9789683644237', '9780941451765', '9781591607663', - '9780911307764', '9780376042989', '9781556551529', '9780891168607', '9788301027599', - '9780141316093', '9788430021772', '9780859676908', '9783854206934', '9780976096702', - '9785808400788', '9781421977287', '9780811842174', '9780892060795', '9780687300303', - '9780521676380', '9780883183885', '9781604743531', '9780877596462', '9780516204420', - '9780613753890', '9780153402876', '9781883717278', '9780965916455', '9780030746673', - '9783718603107', '9780078820908', '9781877059162', '9781841210131', '9780805724059', - '9780387074283', '9781597711227', '9781600142703', '9789290221944', '9781558963672', - '9781933662039', '9789709022612', '9780870658426', '9781401876623', '9789793285030', - '9788991331990', '9783453059085', '9780774814430', '9781559144636', '9780886461911', - '9783880201996', '9780850668513', '9780387978390', '9780340977743', '9780325006840', - '9780320054495', '9783889852700', '9780801057144', '9780824059378', '9780449446331', - '9780307110541', '9780671744779', '9780520227675', '9780671554811', '9780700706464', - '9781420853483', '9781553675570', '9783902053053', '9789759546502', '9789715502948', - '9783810722683', '9780977637126', '9789660213586', '9781427074997', '9789684116467', - '9780809118908', '9780802794512', '9780787661502', '9789632085289', '9788420448169', - '9780803945456', '9780976728306', '9789179003081', '9781883884253', '9783876270166', - '9780781710138', '9780952000402', '9780554714370', '9780686178101', '9784770015341', - '9788435504300', '9780966245417', '9780688164997', '9782708700871', '9780787669928', - '9781875943258', '9780824076757', '9788834812433', '9780852700594', '9783908450320', - '9780123875600', '9780528860669', '9780451522481', '9789022308752', '9780345018793', - '9784582841961', '9780548887455', '9780920576830', '9787536717725', '9780801982811', - '9780064405102', '9780881955101', '9789781421662', '9780333150986', '9782717816976', - '9780521056779', '9781441907165', '9789507100451', '9781873410240', '9780844659442', - '9780160450488', '9780768835977', '9781557731302', '9780793827626', '9780143001355', - '9780590448901', '9781930455504', '9780814471982', '9780933979154', '9781894020831', - '9788439349754', '9780662265955', '9780822201991', '9781103984282', '9788481746433', - '9780712621533', '9780160526589', '9780812108231', '9783923120000', '9780786137565', - '9788813261849', '9781841151380', '9780884020646', '9780865680616', '9780761471714', - '9788496515024', '9780471079965', '9783639114201', '9781585790272', '9780898700459', - '9788750347583', '9781891438011', '9781563052477', '9780805080230', '9780870001154', - '9783475520976', '9780559253904', '9780030000645', '9789872060404', '9780061012099', - '9781110304035', '9781556709838', '9780522840179', '9780809302192', '9781581742442', - '9780536609137', '9783878763123', '9780553542264', '9780899709406', '9781555036928', - '9780862644512', '9781559391443', '9780895245229', '9781602833043', '9783351011703', - '9780613210959', '9789879395325', '9780812575620', '9780230602250', '9783060061204', - '9781880399330', '9781401084653', '9788301105396', '9788487641282', '9785767100804', - '9780590333221', '9780958190534', '9781426452000', '9780899256351', '9781413711271', - '9780837368054', '9780340734865', '9780763114428', '9781428007642', '9781593110574', - '9788474967333', '9781740593687', '9780006380436', '9780967989600', '9781428624559', - '9780764319334', '9780896086296', '9788475660158', '9788431502669', '9780458961009', - '9780595281824', '9780825416057', '9780921057635', '9780606005043', '9780892364671', - '9780825422973', '9781592133659', '9781426430367', '9788846407504', '9781598699906', - '9780716304173', '9781581979459', '9789745971547', '9780913153031', '9781556422928', - '9781905042289', '9788466754460', '9780768206340', '9780195423235', '9788486047238', - '9780706370089', '9781854751768', '9785835403011', '9780060469030', '9780554904191', - '9781600610936', '9780768602876', '9781564320889', '9780792396574', '9789994282951', - '9788446007371', '9780896361485', '9780764507847', '9780813123752', '9780528276316', - '9780451602206', '9780704401808', '9781404104242', '9780521391177', '9780415485067', - '9780668023368', '9780905118352', '9780853340515', '9781104403539', '9780314988126', - '9780030131363', '9780738501925', '9788822237064', '9780688138073', '9781555231361', - '9780691024318', '9781560440260', '9780520251151', '9781561592708', '9789794594704', - '9781847611130', '9780446768894', '9788460487609', '9780853621164', '9780818904615', - '9781104405106', '9780915869008', '9780950097510', '9781425909376', '9781419665851', - '9781877967078', '9780817264352', '9780321537119', '9782051015752', '9780690016956', - '9780697345356', '9780941845083', '9788450048582', '9780803733459', '9780201586336', - '9780812042191', '9780697168092', '9785288019807', '9780756746124', '9780192111937', - '9780823217755', '9780307038074', '9780470150566', '9780787228002', '9780397504039', - '9784476072235', '9781426914591', '9780471487067', '9780849303982', '9781420834574', - '9780123695352', '9782879390079', '9780760108802', '9780380975662', '9780966480634', - '9780852342701', '9780446342445', '9782864182269', '9780852312100', '9788588787018', - '9780521833912', '9780972402255', '9780738515632', '9780681417106', '9782902402892', - '9780435901554', '9780021642700', '9783642053276', '9788186030615', '9781558501027', - '9780887294228', '9781560114048', '9781583880425', '9781852916008', '9780816517732', - '9780716500537', '9780936388939', '9780375946769', '9783540897835', '9780821772133', - '9781853715495', '9788427304819', '9780939513437', '9783814401713', '9780486437385', - '9789264137790', '9781401025663', '9781933087368', '9783865219121', '9780892871322', - '9782760513099', '9780917734243', '9788440092762', '9781558686410', '9780811208352', - '9780934385824', '9783428072149', '9780521215947', '9780441049127', '9789173840149', - '9780606054690', '9780415033848', '9789053565766', '9780780339132', '9780256069266', - '9783201013109', '9780761471899', '9780140223248', '9780939314362', '9781551642123', - '9780548577066', '9789211262322', '9788430621903', '9780312874889', '9780753196557', - '9780641577833', '9781439505847', '9781413789362', '9780304936151', '9780398018207', - '9788484564850', '9780671739829', '9780495130390', '9788885148444', '9789544452230', - '9781417737826', '9789654932981', '9780199230273', '9780951375723', '9780833540430', - '9781591912439', '9780689102523', '9780613441728', '9782921556729', '9780822339571', - '9788171431892', '9780313255298', '9780471549895', '9781421967271', '9781103825097', - '9780898839784', '9780766179417', '9780026655903', '9780801825408', '9780153049910', - '9780825410383', '9780951214039', '9780787947897', '9789630932028', '9781594538728', - '9780554494005', '9781902588001', '9780903729956', '9780060972707', '9780194315852', - '9781558701298', '9780963425713', '9780844731971', '9780752859774', '9780471172178', - '9781901414103', '9780750529488', '9780817616434', '9780827384729', '9780724102556', - '9780007170562', '9781404366909', '9788820488284', '9789688054130', '9780559104237', - '9780774027779', '9781877295812', '9783150096413', '9780517650103', '9781432673635', - '9781566392143', '9781564962652', '9781878327024', '9782060034713', '9780345277022', - '9780553207958', '9781904303558', '9780387193823', '9780314934505', '9780947183127', - '9783883756097', '9780134528311', '9780812817577', '9780804809726', '9781556224188', - '9780440219910', '9780607920833', '9780275982249', '9781425055158', '9781608762910', - '9787306000323', '9781565545502', '9780871011909', '9789062651979', '9781595434715', - '9780735526495', '9783404920587', '9788450022056', '9780323016117', '9780312170080', - '9780914019589', '9781439231074', '9780873064910', '9781403917386', '9781104410193', - '9780226104454', '9780810101616', '9788427002012', '9789290446828', '9780963416001', - '9782738473288', '9789848684351', '9781437079364', '9780762000418', '9780754818571', - '9780586037300', '9782718801100', '9781857110142', '9780811867610', '9789060007808', - '9780252061035', '9788473988803', '9780559233210', '9783499143915', '9780852244975', - '9780160376443', '9780837310329', '9780306377259', '9788450565645', '9780394405483', - '9781432566234', '9780300125832', '9783905455199', '9780737300277', '9781553662440', - '9780415953344', '9783701172047', '9783260050084', '9788487583285', '9780894558689', - '9780078262401', '9780910110372', '9782729112738', '9788493052447', '9789681212483', - '9780938922049', '9780373672868', '9780136416050', '9780851704043', '9789549090444', - '9780963884923', '9789771331209', '9780817982225', '9780803214279', '9780030369339', - '9780968153055', '9783597101091', '9789590804113', '9781891859564', '9780756717612', - '9780769516370', '9780559304620', '9781408009222', '9780452263215', '9780883290361', - '9788870147711', '9780396004691', '9788485354085', '9780763700867', '9780936384368', - '9780854404216', '9789514423239', '9780849215377', '9781587798443', '9789681674120', - '9785340012425', '9780751531626', '9788520301470', '9780198249078', '9780345364708', - '9780525246657', '9788474908008', '9788798677208', '9781550411980', '9780737725650', - '9781103726714', '9788817014717', '9780872911659', '9780801855252', '9781432566647', - '9789711000288', '9787800709630', '9782729887377', '9783406346217', '9788436809503', - '9781417699926', '9781567589603', '9789210612739', '9782844660565', '9780471502845', - '9780806134390', '9781404335417', '9781561563067', '9780803923379', '9782911606700', - '9780713446258', '9780061814341', '9788477400660', '9780716717515', '9780963968500', - '9782873170349', '9780451179371', '9782907150224', '9789781328336', '9783540625551', - '9780691116952', '9780140770339', '9780713721683', '9789155023560', '9781103796014', - '9780714843803', '9780669909777', '9789974779303', '9780198610755', '9785270006044', - '9780907305392', '9789291180707', '9780497260637', '9789715013253', '9780070221574', - '9780159290200', '9780836891133', '9783506767820', '9788186385432', '9781878569677', - '9788871230870', '9780807822562', '9780897110099', '9780613437974', '9789684092099', - '9780974407807', '9780439782487', '9789879749883', '9780126407402', '9780373766468', - '9781932472691', '9789264044494', '9783608910148', '9788431501051', '9780613172011', - '9780824776466', '9780395264287', '9789559570103', '9789687155111', '9781557045447', - '9781581804355', '9780772610577', '9780590206013', '9781421824215', '9780720407013', - '9780896861817', '9781602190078', '9781566919227', '9780471899631', '9781559636001', - '9780873648226', '9780759243996', '9780613165297', '9780533134908', '9788586611278', - '9780387564760', '9785713304027', '9781853675003', '9780521589871', '9780719070464', - '9780300105292', '9780312493189', '9780911378900', '9781437813005', '9780573605741', - '9788487146596', '9788420457062', '9789138049488', '9789686154061', '9780028605722', - '9781552750230', '9781891643026', '9781874105596', '9780613060950', '9780030555749', - '9780160840876', '9780439429825', '9781928893028', '9780854563647', '9780373752454', - '9780965850889', '9780747586128', '9789507823572', '9780133319422', '9781606991466', - '9781595250001', '9780521085199', '9781437522587', '9780065010374', '9788486072049', - '9780415763844', '9780871319999', '9780788302565', '9782070406951', '9780160799976', - '9780822937791', '9780684106021', '9780521095068', '9789517352918', '9789138066843' ] + '9780802409430', + '9781891595240', + '9780897876254', + '9780300091892', + '9785887021454', + '9789879960165', + '9780764422799', + '9780534264956', + '9780517568439', + '9782865377923', + '9783110175752', + '9780732274689', + '9789682978739', + '9781420102765', + '9780914336556', + '9780538140201', + '9781557666291', + '9780439897518', + '9780310607106', + '9788484566052', + '9780471614470', + '9780548573617', + '9780716789017', + '9780548693711', + '9783540784395', + '9781592964727', + '9780606028479', + '9780559649769', + '9780451129567', + '9780295956190', + '9780252014628', + '9780548879740', + '9781420878844', + '9780882293820', + '9781580330060', + '9781434304155', + '9781605975993', + '9780884964087', + '9780976425625', + '9781424151523', + '9780756400071', + '9781604537871', + '9780573691980', + '9789871081073', + '9781412094054', + '9780720472288', + '9788480181129', + '9789683644237', + '9780941451765', + '9781591607663', + '9780911307764', + '9780376042989', + '9781556551529', + '9780891168607', + '9788301027599', + '9780141316093', + '9788430021772', + '9780859676908', + '9783854206934', + '9780976096702', + '9785808400788', + '9781421977287', + '9780811842174', + '9780892060795', + '9780687300303', + '9780521676380', + '9780883183885', + '9781604743531', + '9780877596462', + '9780516204420', + '9780613753890', + '9780153402876', + '9781883717278', + '9780965916455', + '9780030746673', + '9783718603107', + '9780078820908', + '9781877059162', + '9781841210131', + '9780805724059', + '9780387074283', + '9781597711227', + '9781600142703', + '9789290221944', + '9781558963672', + '9781933662039', + '9789709022612', + '9780870658426', + '9781401876623', + '9789793285030', + '9788991331990', + '9783453059085', + '9780774814430', + '9781559144636', + '9780886461911', + '9783880201996', + '9780850668513', + '9780387978390', + '9780340977743', + '9780325006840', + '9780320054495', + '9783889852700', + '9780801057144', + '9780824059378', + '9780449446331', + '9780307110541', + '9780671744779', + '9780520227675', + '9780671554811', + '9780700706464', + '9781420853483', + '9781553675570', + '9783902053053', + '9789759546502', + '9789715502948', + '9783810722683', + '9780977637126', + '9789660213586', + '9781427074997', + '9789684116467', + '9780809118908', + '9780802794512', + '9780787661502', + '9789632085289', + '9788420448169', + '9780803945456', + '9780976728306', + '9789179003081', + '9781883884253', + '9783876270166', + '9780781710138', + '9780952000402', + '9780554714370', + '9780686178101', + '9784770015341', + '9788435504300', + '9780966245417', + '9780688164997', + '9782708700871', + '9780787669928', + '9781875943258', + '9780824076757', + '9788834812433', + '9780852700594', + '9783908450320', + '9780123875600', + '9780528860669', + '9780451522481', + '9789022308752', + '9780345018793', + '9784582841961', + '9780548887455', + '9780920576830', + '9787536717725', + '9780801982811', + '9780064405102', + '9780881955101', + '9789781421662', + '9780333150986', + '9782717816976', + '9780521056779', + '9781441907165', + '9789507100451', + '9781873410240', + '9780844659442', + '9780160450488', + '9780768835977', + '9781557731302', + '9780793827626', + '9780143001355', + '9780590448901', + '9781930455504', + '9780814471982', + '9780933979154', + '9781894020831', + '9788439349754', + '9780662265955', + '9780822201991', + '9781103984282', + '9788481746433', + '9780712621533', + '9780160526589', + '9780812108231', + '9783923120000', + '9780786137565', + '9788813261849', + '9781841151380', + '9780884020646', + '9780865680616', + '9780761471714', + '9788496515024', + '9780471079965', + '9783639114201', + '9781585790272', + '9780898700459', + '9788750347583', + '9781891438011', + '9781563052477', + '9780805080230', + '9780870001154', + '9783475520976', + '9780559253904', + '9780030000645', + '9789872060404', + '9780061012099', + '9781110304035', + '9781556709838', + '9780522840179', + '9780809302192', + '9781581742442', + '9780536609137', + '9783878763123', + '9780553542264', + '9780899709406', + '9781555036928', + '9780862644512', + '9781559391443', + '9780895245229', + '9781602833043', + '9783351011703', + '9780613210959', + '9789879395325', + '9780812575620', + '9780230602250', + '9783060061204', + '9781880399330', + '9781401084653', + '9788301105396', + '9788487641282', + '9785767100804', + '9780590333221', + '9780958190534', + '9781426452000', + '9780899256351', + '9781413711271', + '9780837368054', + '9780340734865', + '9780763114428', + '9781428007642', + '9781593110574', + '9788474967333', + '9781740593687', + '9780006380436', + '9780967989600', + '9781428624559', + '9780764319334', + '9780896086296', + '9788475660158', + '9788431502669', + '9780458961009', + '9780595281824', + '9780825416057', + '9780921057635', + '9780606005043', + '9780892364671', + '9780825422973', + '9781592133659', + '9781426430367', + '9788846407504', + '9781598699906', + '9780716304173', + '9781581979459', + '9789745971547', + '9780913153031', + '9781556422928', + '9781905042289', + '9788466754460', + '9780768206340', + '9780195423235', + '9788486047238', + '9780706370089', + '9781854751768', + '9785835403011', + '9780060469030', + '9780554904191', + '9781600610936', + '9780768602876', + '9781564320889', + '9780792396574', + '9789994282951', + '9788446007371', + '9780896361485', + '9780764507847', + '9780813123752', + '9780528276316', + '9780451602206', + '9780704401808', + '9781404104242', + '9780521391177', + '9780415485067', + '9780668023368', + '9780905118352', + '9780853340515', + '9781104403539', + '9780314988126', + '9780030131363', + '9780738501925', + '9788822237064', + '9780688138073', + '9781555231361', + '9780691024318', + '9781560440260', + '9780520251151', + '9781561592708', + '9789794594704', + '9781847611130', + '9780446768894', + '9788460487609', + '9780853621164', + '9780818904615', + '9781104405106', + '9780915869008', + '9780950097510', + '9781425909376', + '9781419665851', + '9781877967078', + '9780817264352', + '9780321537119', + '9782051015752', + '9780690016956', + '9780697345356', + '9780941845083', + '9788450048582', + '9780803733459', + '9780201586336', + '9780812042191', + '9780697168092', + '9785288019807', + '9780756746124', + '9780192111937', + '9780823217755', + '9780307038074', + '9780470150566', + '9780787228002', + '9780397504039', + '9784476072235', + '9781426914591', + '9780471487067', + '9780849303982', + '9781420834574', + '9780123695352', + '9782879390079', + '9780760108802', + '9780380975662', + '9780966480634', + '9780852342701', + '9780446342445', + '9782864182269', + '9780852312100', + '9788588787018', + '9780521833912', + '9780972402255', + '9780738515632', + '9780681417106', + '9782902402892', + '9780435901554', + '9780021642700', + '9783642053276', + '9788186030615', + '9781558501027', + '9780887294228', + '9781560114048', + '9781583880425', + '9781852916008', + '9780816517732', + '9780716500537', + '9780936388939', + '9780375946769', + '9783540897835', + '9780821772133', + '9781853715495', + '9788427304819', + '9780939513437', + '9783814401713', + '9780486437385', + '9789264137790', + '9781401025663', + '9781933087368', + '9783865219121', + '9780892871322', + '9782760513099', + '9780917734243', + '9788440092762', + '9781558686410', + '9780811208352', + '9780934385824', + '9783428072149', + '9780521215947', + '9780441049127', + '9789173840149', + '9780606054690', + '9780415033848', + '9789053565766', + '9780780339132', + '9780256069266', + '9783201013109', + '9780761471899', + '9780140223248', + '9780939314362', + '9781551642123', + '9780548577066', + '9789211262322', + '9788430621903', + '9780312874889', + '9780753196557', + '9780641577833', + '9781439505847', + '9781413789362', + '9780304936151', + '9780398018207', + '9788484564850', + '9780671739829', + '9780495130390', + '9788885148444', + '9789544452230', + '9781417737826', + '9789654932981', + '9780199230273', + '9780951375723', + '9780833540430', + '9781591912439', + '9780689102523', + '9780613441728', + '9782921556729', + '9780822339571', + '9788171431892', + '9780313255298', + '9780471549895', + '9781421967271', + '9781103825097', + '9780898839784', + '9780766179417', + '9780026655903', + '9780801825408', + '9780153049910', + '9780825410383', + '9780951214039', + '9780787947897', + '9789630932028', + '9781594538728', + '9780554494005', + '9781902588001', + '9780903729956', + '9780060972707', + '9780194315852', + '9781558701298', + '9780963425713', + '9780844731971', + '9780752859774', + '9780471172178', + '9781901414103', + '9780750529488', + '9780817616434', + '9780827384729', + '9780724102556', + '9780007170562', + '9781404366909', + '9788820488284', + '9789688054130', + '9780559104237', + '9780774027779', + '9781877295812', + '9783150096413', + '9780517650103', + '9781432673635', + '9781566392143', + '9781564962652', + '9781878327024', + '9782060034713', + '9780345277022', + '9780553207958', + '9781904303558', + '9780387193823', + '9780314934505', + '9780947183127', + '9783883756097', + '9780134528311', + '9780812817577', + '9780804809726', + '9781556224188', + '9780440219910', + '9780607920833', + '9780275982249', + '9781425055158', + '9781608762910', + '9787306000323', + '9781565545502', + '9780871011909', + '9789062651979', + '9781595434715', + '9780735526495', + '9783404920587', + '9788450022056', + '9780323016117', + '9780312170080', + '9780914019589', + '9781439231074', + '9780873064910', + '9781403917386', + '9781104410193', + '9780226104454', + '9780810101616', + '9788427002012', + '9789290446828', + '9780963416001', + '9782738473288', + '9789848684351', + '9781437079364', + '9780762000418', + '9780754818571', + '9780586037300', + '9782718801100', + '9781857110142', + '9780811867610', + '9789060007808', + '9780252061035', + '9788473988803', + '9780559233210', + '9783499143915', + '9780852244975', + '9780160376443', + '9780837310329', + '9780306377259', + '9788450565645', + '9780394405483', + '9781432566234', + '9780300125832', + '9783905455199', + '9780737300277', + '9781553662440', + '9780415953344', + '9783701172047', + '9783260050084', + '9788487583285', + '9780894558689', + '9780078262401', + '9780910110372', + '9782729112738', + '9788493052447', + '9789681212483', + '9780938922049', + '9780373672868', + '9780136416050', + '9780851704043', + '9789549090444', + '9780963884923', + '9789771331209', + '9780817982225', + '9780803214279', + '9780030369339', + '9780968153055', + '9783597101091', + '9789590804113', + '9781891859564', + '9780756717612', + '9780769516370', + '9780559304620', + '9781408009222', + '9780452263215', + '9780883290361', + '9788870147711', + '9780396004691', + '9788485354085', + '9780763700867', + '9780936384368', + '9780854404216', + '9789514423239', + '9780849215377', + '9781587798443', + '9789681674120', + '9785340012425', + '9780751531626', + '9788520301470', + '9780198249078', + '9780345364708', + '9780525246657', + '9788474908008', + '9788798677208', + '9781550411980', + '9780737725650', + '9781103726714', + '9788817014717', + '9780872911659', + '9780801855252', + '9781432566647', + '9789711000288', + '9787800709630', + '9782729887377', + '9783406346217', + '9788436809503', + '9781417699926', + '9781567589603', + '9789210612739', + '9782844660565', + '9780471502845', + '9780806134390', + '9781404335417', + '9781561563067', + '9780803923379', + '9782911606700', + '9780713446258', + '9780061814341', + '9788477400660', + '9780716717515', + '9780963968500', + '9782873170349', + '9780451179371', + '9782907150224', + '9789781328336', + '9783540625551', + '9780691116952', + '9780140770339', + '9780713721683', + '9789155023560', + '9781103796014', + '9780714843803', + '9780669909777', + '9789974779303', + '9780198610755', + '9785270006044', + '9780907305392', + '9789291180707', + '9780497260637', + '9789715013253', + '9780070221574', + '9780159290200', + '9780836891133', + '9783506767820', + '9788186385432', + '9781878569677', + '9788871230870', + '9780807822562', + '9780897110099', + '9780613437974', + '9789684092099', + '9780974407807', + '9780439782487', + '9789879749883', + '9780126407402', + '9780373766468', + '9781932472691', + '9789264044494', + '9783608910148', + '9788431501051', + '9780613172011', + '9780824776466', + '9780395264287', + '9789559570103', + '9789687155111', + '9781557045447', + '9781581804355', + '9780772610577', + '9780590206013', + '9781421824215', + '9780720407013', + '9780896861817', + '9781602190078', + '9781566919227', + '9780471899631', + '9781559636001', + '9780873648226', + '9780759243996', + '9780613165297', + '9780533134908', + '9788586611278', + '9780387564760', + '9785713304027', + '9781853675003', + '9780521589871', + '9780719070464', + '9780300105292', + '9780312493189', + '9780911378900', + '9781437813005', + '9780573605741', + '9788487146596', + '9788420457062', + '9789138049488', + '9789686154061', + '9780028605722', + '9781552750230', + '9781891643026', + '9781874105596', + '9780613060950', + '9780030555749', + '9780160840876', + '9780439429825', + '9781928893028', + '9780854563647', + '9780373752454', + '9780965850889', + '9780747586128', + '9789507823572', + '9780133319422', + '9781606991466', + '9781595250001', + '9780521085199', + '9781437522587', + '9780065010374', + '9788486072049', + '9780415763844', + '9780871319999', + '9780788302565', + '9782070406951', + '9780160799976', + '9780822937791', + '9780684106021', + '9780521095068', + '9789517352918', + '9789138066843', +] diff --git a/test/50-extra-email.test.ts b/test/50-extra-email.test.ts index b6c01ec..0558a7d 100644 --- a/test/50-extra-email.test.ts +++ b/test/50-extra-email.test.ts @@ -1,43 +1,48 @@ -import { ValidationError, validate } from '../src' -import { email } from '../src/extra/email' +import { email } from '../src/extra/email.ts' +import { ValidationError, validate } from '../src/index.ts' describe('Extra Email validator', () => { it('should validate and normalize an email', () => { - expect(validate(email, 'Test@Example.ORG')) - .toStrictlyEqual('test@example.org') + expect(validate(email, 'Test@Example.ORG')).toStrictlyEqual('test@example.org') }) it('should reject a short email', () => { - expect(() => validate(email, 'a@b')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a minimum length of 5', - path: [], - } ])), - ) + expect(() => validate(email, 'a@b')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a minimum length of 5', + path: [], + }, + ]), + ), + ) }) it('should reject a long email', () => { const localPart = 'a'.repeat(120) - expect(() => validate(email, `${localPart}@example.com`)) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a maximum length of 128', - path: [], - } ])), - ) + expect(() => validate(email, `${localPart}@example.com`)).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a maximum length of 128', + path: [], + }, + ]), + ), + ) }) it('should reject an invalid email', () => { - expect(() => validate(email, 'This is not an email')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: expect.toMatch(/^String does not match required pattern /), - path: [], - } ])), - ) + expect(() => validate(email, 'This is not an email')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: expect.toMatch(/^String does not match required pattern /), + path: [], + }, + ]), + ), + ) }) }) diff --git a/test/50-extra-url.test.ts b/test/50-extra-url.test.ts index 055fabc..f4a8930 100644 --- a/test/50-extra-url.test.ts +++ b/test/50-extra-url.test.ts @@ -1,5 +1,5 @@ -import { constant, optional, string, validate, ValidationError } from '../src' -import { url } from '../src/extra/url' +import { url } from '../src/extra/url.ts' +import { constant, optional, string, validate, ValidationError } from '../src/index.ts' describe('URL validator', () => { it('should validate a simple URL', () => { @@ -9,8 +9,7 @@ describe('URL validator', () => { }) it('should not validate a wrong URL', () => { - expect(() => validate(url, '/foo/bar')) - .toThrowError(ValidationError, /Value could not be converted to a "URL"/) + expect(() => validate(url, '/foo/bar')).toThrowError(ValidationError, /Value could not be converted to a "URL"/) }) it('should validate an URL with some basic constraints', () => { @@ -23,14 +22,16 @@ describe('URL validator', () => { expect(validator.validate('http://www/a/b/c#foo').href).toStrictlyEqual('http://www/a/b/c#foo') - expect(() => validator.validate('ftp://funet/fi')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 3 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'protocol' ], message: 'String does not match required pattern /^https?:$/' }, - { path: [ 'hostname' ], message: 'Value does not match constant "www" (string)' }, - { path: [ 'pathname' ], message: 'Value does not match constant "/a/b/c" (string)' }, - ]))) + expect(() => validator.validate('ftp://funet/fi')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 3 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['protocol'], message: 'String does not match required pattern /^https?:$/' }, + { path: ['hostname'], message: 'Value does not match constant "www" (string)' }, + { path: ['pathname'], message: 'Value does not match constant "/a/b/c" (string)' }, + ]), + ), + ) }) it('should validate an URL with some search parameters constraints', () => { @@ -42,12 +43,14 @@ describe('URL validator', () => { }) expect(validator.validate('http://www/?foo=bar&baz=xyz').href).toEqual('http://www/?foo=bar&baz=xyz') - expect(() => validator.validate('http://www/?baz=abc').href) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 2 validation errors/) - .toHaveProperty('errors', expect.toMatchContents([ - { path: [ 'searchParams', 'foo' ], message: 'Required property missing' }, - { path: [ 'searchParams', 'baz' ], message: 'Value does not match constant "xyz" (string)' }, - ]))) + expect(() => validator.validate('http://www/?baz=abc').href).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 2 validation errors/).toHaveProperty( + 'errors', + expect.toMatchContents([ + { path: ['searchParams', 'foo'], message: 'Required property missing' }, + { path: ['searchParams', 'baz'], message: 'Value does not match constant "xyz" (string)' }, + ]), + ), + ) }) }) diff --git a/test/50-extra-uuid.test.ts b/test/50-extra-uuid.test.ts index a39613a..196a665 100644 --- a/test/50-extra-uuid.test.ts +++ b/test/50-extra-uuid.test.ts @@ -1,42 +1,49 @@ -import { ValidationError, validate } from '../src' -import { uuid } from '../src/extra/uuid' +import { uuid } from '../src/extra/uuid.ts' +import { ValidationError, validate } from '../src/index.ts' describe('Extra UUID validator', () => { it('should validate and normalize an UUID', () => { - expect(validate(uuid, 'BD075D99-1114-45B4-8B71-45C0EB89589C')) - .toStrictlyEqual('bd075d99-1114-45b4-8b71-45c0eb89589c') + expect(validate(uuid, 'BD075D99-1114-45B4-8B71-45C0EB89589C')).toStrictlyEqual( + 'bd075d99-1114-45b4-8b71-45c0eb89589c', + ) }) it('should reject a short UUID', () => { - expect(() => validate(uuid, '')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a minimum length of 36', - path: [], - } ])), - ) + expect(() => validate(uuid, '')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a minimum length of 36', + path: [], + }, + ]), + ), + ) }) it('should reject a long UUID', () => { - expect(() => validate(uuid, '00000000000000000000000000000000000000000000')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: 'String must have a maximum length of 36', - path: [], - } ])), - ) + expect(() => validate(uuid, '00000000000000000000000000000000000000000000')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: 'String must have a maximum length of 36', + path: [], + }, + ]), + ), + ) }) it('should reject an invalid UUID', () => { - expect(() => validate(uuid, 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX')) - .toThrow((assert) => assert - .toBeError(ValidationError, /^Found 1 validation error$/m) - .toHaveProperty('errors', (assert) => assert.toEqual([ { - message: expect.toMatch(/^String does not match required pattern /), - path: [], - } ])), - ) + expect(() => validate(uuid, 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX')).toThrow((assert) => + assert.toBeError(ValidationError, /^Found 1 validation error$/m).toHaveProperty('errors', (assert) => + assert.toEqual([ + { + message: expect.toMatch(/^String does not match required pattern /), + path: [], + }, + ]), + ), + ) }) }) diff --git a/test/99-dts.test.ts b/test/99-dts.test.ts index 83957bd..fc1d166 100644 --- a/test/99-dts.test.ts +++ b/test/99-dts.test.ts @@ -1,3 +1,8 @@ +import { generateDeclarations, generateTypes } from '../src/dts-generator.ts' +import { ean13, EAN13Validator } from '../src/extra/ean13.ts' +import { email, EmailValidator } from '../src/extra/email.ts' +import { url, URLValidator } from '../src/extra/url.ts' +import { uuid, UUIDValidator } from '../src/extra/uuid.ts' import { allOf, allowAdditionalProperties, @@ -25,481 +30,718 @@ import { optional, string, tuple, -} from '../src' -import { generateDeclarations, generateTypes } from '../src/dts-generator' -import { ean13, EAN13Validator } from '../src/extra/ean13' -import { email, EmailValidator } from '../src/extra/email' -import { url, URLValidator } from '../src/extra/url' -import { uuid, UUIDValidator } from '../src/extra/uuid' +} from '../src/index.ts' describe('DTS Generation', () => { describe('Validated types', () => { it('should generate the validated type for some basic types', () => { - expect(generateTypes({ - test: any, - })).toStrictlyEqual('export type test = any;') + expect( + generateTypes({ + test: any, + }), + ).toStrictlyEqual('export type test = any;') - expect(generateTypes({ - test: array, - })).toStrictlyEqual('export type test = any[];') + expect( + generateTypes({ + test: array, + }), + ).toStrictlyEqual('export type test = any[];') - expect(generateTypes({ - test: number, - })).toStrictlyEqual('export type test = number;') + expect( + generateTypes({ + test: number, + }), + ).toStrictlyEqual('export type test = number;') - expect(generateTypes({ - test: object, - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { [key in string]: any; };') + expect( + generateTypes({ + test: object, + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { [key in string]: any; };') - expect(generateTypes({ - test: string, - })).toStrictlyEqual('export type test = string;') + expect( + generateTypes({ + test: string, + }), + ).toStrictlyEqual('export type test = string;') - expect(generateTypes({ - test: boolean, - })).toStrictlyEqual('export type test = boolean;') + expect( + generateTypes({ + test: boolean, + }), + ).toStrictlyEqual('export type test = boolean;') - expect(generateTypes({ - test: bigint, - })).toStrictlyEqual('export type test = bigint;') + expect( + generateTypes({ + test: bigint, + }), + ).toStrictlyEqual('export type test = bigint;') - expect(generateTypes({ - test: date, - })).toStrictlyEqual('export type test = Date;') + expect( + generateTypes({ + test: date, + }), + ).toStrictlyEqual('export type test = Date;') - expect(generateTypes({ - test: never, - })).toStrictlyEqual('export type test = undefined;') + expect( + generateTypes({ + test: never, + }), + ).toStrictlyEqual('export type test = undefined;') }) it('should generate the validated type for some basic validators', () => { - expect(generateTypes({ - test: new AnyValidator(), - })).toStrictlyEqual('export type test = any;') + expect( + generateTypes({ + test: new AnyValidator(), + }), + ).toStrictlyEqual('export type test = any;') - expect(generateTypes({ - test: new AnyArrayValidator(), - })).toStrictlyEqual('export type test = any[];') + expect( + generateTypes({ + test: new AnyArrayValidator(), + }), + ).toStrictlyEqual('export type test = any[];') - expect(generateTypes({ - test: new AnyBigIntValidator(), - })).toStrictlyEqual('export type test = bigint;') + expect( + generateTypes({ + test: new AnyBigIntValidator(), + }), + ).toStrictlyEqual('export type test = bigint;') - expect(generateTypes({ - test: new AnyNumberValidator(), - })).toStrictlyEqual('export type test = number;') + expect( + generateTypes({ + test: new AnyNumberValidator(), + }), + ).toStrictlyEqual('export type test = number;') - expect(generateTypes({ - test: new AnyObjectValidator(), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { [key in string]: any; };') + expect( + generateTypes({ + test: new AnyObjectValidator(), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { [key in string]: any; };') - expect(generateTypes({ - test: new AnyStringValidator(), - })).toStrictlyEqual('export type test = string;') + expect( + generateTypes({ + test: new AnyStringValidator(), + }), + ).toStrictlyEqual('export type test = string;') - expect(generateTypes({ - test: new BooleanValidator(), - })).toStrictlyEqual('export type test = boolean;') + expect( + generateTypes({ + test: new BooleanValidator(), + }), + ).toStrictlyEqual('export type test = boolean;') - expect(generateTypes({ - test: new BigIntValidator(), - })).toStrictlyEqual('export type test = bigint;') + expect( + generateTypes({ + test: new BigIntValidator(), + }), + ).toStrictlyEqual('export type test = bigint;') - expect(generateTypes({ - test: new DateValidator(), - })).toStrictlyEqual('export type test = Date;') + expect( + generateTypes({ + test: new DateValidator(), + }), + ).toStrictlyEqual('export type test = Date;') - expect(generateTypes({ - test: new NeverValidator(), - })).toStrictlyEqual('export type test = undefined;') + expect( + generateTypes({ + test: new NeverValidator(), + }), + ).toStrictlyEqual('export type test = undefined;') }) it('should generate the validated type for arrays', () => { - expect(generateTypes({ - test: array, - })).toStrictlyEqual('export type test = any[];') + expect( + generateTypes({ + test: array, + }), + ).toStrictlyEqual('export type test = any[];') - expect(generateTypes({ - test: arrayOf(string), - })).toStrictlyEqual('export type test = string[];') + expect( + generateTypes({ + test: arrayOf(string), + }), + ).toStrictlyEqual('export type test = string[];') - expect(generateTypes({ - test: arrayOf(url), - })).toStrictlyEqual('export type test = URL[];') + expect( + generateTypes({ + test: arrayOf(url), + }), + ).toStrictlyEqual('export type test = URL[];') }) it('should generate the validated type for constants', () => { - expect(generateTypes({ - test: 'a string', - })).toStrictlyEqual('export type test = "a string";') + expect( + generateTypes({ + test: 'a string', + }), + ).toStrictlyEqual('export type test = "a string";') - expect(generateTypes({ - test: 12345, - })).toStrictlyEqual('export type test = 12345;') + expect( + generateTypes({ + test: 12345, + }), + ).toStrictlyEqual('export type test = 12345;') - expect(generateTypes({ - test: 1234n, - })).toStrictlyEqual('export type test = 1234n;') + expect( + generateTypes({ + test: 1234n, + }), + ).toStrictlyEqual('export type test = 1234n;') - expect(generateTypes({ - test: false, - })).toStrictlyEqual('export type test = false;') + expect( + generateTypes({ + test: false, + }), + ).toStrictlyEqual('export type test = false;') - expect(generateTypes({ - test: true, - })).toStrictlyEqual('export type test = true;') + expect( + generateTypes({ + test: true, + }), + ).toStrictlyEqual('export type test = true;') - expect(generateTypes({ - test: null, - })).toStrictlyEqual('export type test = null;') + expect( + generateTypes({ + test: null, + }), + ).toStrictlyEqual('export type test = null;') - expect(() => generateTypes({ - test: constant( { toString: () => 'foo' }), - })).toThrowError(TypeError, 'Invalid constant "foo"') + expect(() => + generateTypes({ + test: constant({ toString: () => 'foo' }), + }), + ).toThrowError(TypeError, 'Invalid constant "foo"') }) it('should generate the validated type for (branded) bigints', () => { - expect(generateTypes({ - test: bigint({}), - })).toStrictlyEqual('export type test = bigint;') + expect( + generateTypes({ + test: bigint({}), + }), + ).toStrictlyEqual('export type test = bigint;') - expect(generateTypes({ - test: bigint({ brand: 'foo' }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = bigint & { __brand_foo: never; };') + expect( + generateTypes({ + test: bigint({ brand: 'foo' }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = bigint & { __brand_foo: never; };') }) it('should generate the validated type for (branded) numbers', () => { - expect(generateTypes({ - test: number({}), - })).toStrictlyEqual('export type test = number;') + expect( + generateTypes({ + test: number({}), + }), + ).toStrictlyEqual('export type test = number;') - expect(generateTypes({ - test: number({ brand: 'foo' }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = number & { __brand_foo: never; };') + expect( + generateTypes({ + test: number({ brand: 'foo' }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = number & { __brand_foo: never; };') }) it('should generate the validated type for (branded) strings', () => { - expect(generateTypes({ - test: string({}), - })).toStrictlyEqual('export type test = string;') + expect( + generateTypes({ + test: string({}), + }), + ).toStrictlyEqual('export type test = string;') - expect(generateTypes({ - test: string({ brand: 'foo' }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = string & { __brand_foo: never; };') + expect( + generateTypes({ + test: string({ brand: 'foo' }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = string & { __brand_foo: never; };') }) it('should generate the validated type for tuples', () => { - expect(generateTypes({ - test: [], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ ];') - - expect(generateTypes({ - test: [ number, string, boolean ], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ number, string, boolean ];') - - expect(generateTypes({ - test: [ 12345, 'foo', null ], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ 12345, "foo", null ];') - - expect(generateTypes({ - test: [ number, ...string, boolean ], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ number, ...string[], boolean ];') + expect( + generateTypes({ + test: [], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ ];') + + expect( + generateTypes({ + test: [number, string, boolean], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ number, string, boolean ];') + + expect( + generateTypes({ + test: [12345, 'foo', null], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ 12345, "foo", null ];') + + expect( + generateTypes({ + test: [number, ...string, boolean], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ number, ...string[], boolean ];') // combine types in unions when multiple rest parameters exist.. - expect(generateTypes({ - test: [ ...number, string, ...boolean ], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ ...(number | string | boolean)[] ];') - - expect(generateTypes({ - test: [ 'foo', ...number, string, ...boolean, 'bar' ], - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = [ "foo", ...(number | string | boolean)[], "bar" ];') + expect( + generateTypes({ + test: [...number, string, ...boolean], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ ...(number | string | boolean)[] ];') + + expect( + generateTypes({ + test: ['foo', ...number, string, ...boolean, 'bar'], + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = [ "foo", ...(number | string | boolean)[], "bar" ];') }) it('should generate the validated type for unions', () => { - expect(generateTypes({ - test: allOf(string, number, boolean), - })).toStrictlyEqual('export type test = string & number & boolean;') + expect( + generateTypes({ + test: allOf(string, number, boolean), + }), + ).toStrictlyEqual('export type test = string & number & boolean;') - expect(generateTypes({ - test: oneOf(string, number, boolean), - })).toStrictlyEqual('export type test = string | number | boolean;') + expect( + generateTypes({ + test: oneOf(string, number, boolean), + }), + ).toStrictlyEqual('export type test = string | number | boolean;') }) it('should generate the validated type for optionals', () => { - expect(generateTypes({ - hasDefault: optional(string, 'foobar'), - noDefault: optional(number), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type hasDefault = string; export type noDefault = number | undefined;') - - expect(generateTypes({ - test: { - hasDefault: optional(oneOf('foo', 'bar'), 'foo'), - noDefault: optional(oneOf('foo', 'bar')), - }, - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { hasDefault: "foo" | "bar"; noDefault?: "foo" | "bar" | undefined; };') + expect( + generateTypes({ + hasDefault: optional(string, 'foobar'), + noDefault: optional(number), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type hasDefault = string; export type noDefault = number | undefined;') + + expect( + generateTypes({ + test: { + hasDefault: optional(oneOf('foo', 'bar'), 'foo'), + noDefault: optional(oneOf('foo', 'bar')), + }, + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { hasDefault: "foo" | "bar"; noDefault?: "foo" | "bar" | undefined; };') }) it('should generate the validated type for optionals in input mode', () => { - expect(generateTypes({ - hasDefault: optional(string, 'foobar'), - noDefault: optional(number), - }, true).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type hasDefault = string | undefined; export type noDefault = number | undefined;') - - expect(generateTypes({ - test: { - hasDefault: optional(oneOf('foo', 'bar'), 'foo'), - noDefault: optional(oneOf('foo', 'bar')), - }, - }, true).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { hasDefault?: "foo" | "bar" | undefined; noDefault?: "foo" | "bar" | undefined; };') + expect( + generateTypes( + { + hasDefault: optional(string, 'foobar'), + noDefault: optional(number), + }, + true, + ).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type hasDefault = string | undefined; export type noDefault = number | undefined;') + + expect( + generateTypes( + { + test: { + hasDefault: optional(oneOf('foo', 'bar'), 'foo'), + noDefault: optional(oneOf('foo', 'bar')), + }, + }, + true, + ).replace(/\s+/gm, ' '), + ).toStrictlyEqual( + 'export type test = { hasDefault?: "foo" | "bar" | undefined; noDefault?: "foo" | "bar" | undefined; };', + ) }) it('should generate the validated type for objects', () => { - expect(generateTypes({ - test: object, - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { [key in string]: any; };') - - expect(generateTypes({ - test: object({}), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = {};') - - expect(generateTypes({ - test: object({ - s: string, - n: number, - b: boolean, - x: null, - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { s: string; n: number; b: boolean; x: null; };') - - expect(generateTypes({ - test: object({ - n: optional(number), - x: never, - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { n?: number | undefined; x?: undefined; };') - - expect(generateTypes({ - test: object({ - s: string, - ...allowAdditionalProperties, - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { s: string; } & { [key in string]: any; };') - - expect(generateTypes({ - test: object({ - s: string, - ...allowAdditionalProperties(), - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { s: string; } & { [key in string]: any; };') - - expect(generateTypes({ - test: object({ - s: string, - ...allowAdditionalProperties(number), - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { s: string; } & { [key in string]: number; };') - - expect(generateTypes({ - test: object({ - ...allowAdditionalProperties(number), - }), - }).replace(/\s+/gm, ' ')) - .toStrictlyEqual('export type test = { [key in string]: number; };') + expect( + generateTypes({ + test: object, + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { [key in string]: any; };') + + expect( + generateTypes({ + test: object({}), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = {};') + + expect( + generateTypes({ + test: object({ + s: string, + n: number, + b: boolean, + x: null, + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { s: string; n: number; b: boolean; x: null; };') + + expect( + generateTypes({ + test: object({ + n: optional(number), + x: never, + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { n?: number | undefined; x?: undefined; };') + + expect( + generateTypes({ + test: object({ + s: string, + ...allowAdditionalProperties, + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { s: string; } & { [key in string]: any; };') + + expect( + generateTypes({ + test: object({ + s: string, + ...allowAdditionalProperties(), + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { s: string; } & { [key in string]: any; };') + + expect( + generateTypes({ + test: object({ + s: string, + ...allowAdditionalProperties(number), + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { s: string; } & { [key in string]: number; };') + + expect( + generateTypes({ + test: object({ + ...allowAdditionalProperties(number), + }), + }).replace(/\s+/gm, ' '), + ).toStrictlyEqual('export type test = { [key in string]: number; };') }) }) describe('Input types', () => { it('should generate the input type for booleans', () => { - expect(generateTypes({ - test: boolean, - }, true)).toStrictlyEqual('export type test = boolean;') - - expect(generateTypes({ - test: boolean({ fromString: true }), - }, true)).toStrictlyEqual('export type test = boolean | "true" | "false";') + expect( + generateTypes( + { + test: boolean, + }, + true, + ), + ).toStrictlyEqual('export type test = boolean;') + + expect( + generateTypes( + { + test: boolean({ fromString: true }), + }, + true, + ), + ).toStrictlyEqual('export type test = boolean | "true" | "false";') }) it('should generate the input type for arrays', () => { - expect(generateTypes({ - test: array, - }, true)).toStrictlyEqual('export type test = any[];') - - expect(generateTypes({ - test: arrayOf(string), - }, true)).toStrictlyEqual('export type test = string[];') - - expect(generateTypes({ - test: arrayOf(url), - }, true)).toStrictlyEqual('export type test = (URL | string)[];') + expect( + generateTypes( + { + test: array, + }, + true, + ), + ).toStrictlyEqual('export type test = any[];') + + expect( + generateTypes( + { + test: arrayOf(string), + }, + true, + ), + ).toStrictlyEqual('export type test = string[];') + + expect( + generateTypes( + { + test: arrayOf(url), + }, + true, + ), + ).toStrictlyEqual('export type test = (URL | string)[];') }) it('should generate the input type for (branded) bigints', () => { - expect(generateTypes({ - test: bigint({}), - }, true)).toStrictlyEqual('export type test = bigint | number;') - - expect(generateTypes({ - test: bigint({ fromString: true }), - }, true)).toStrictlyEqual('export type test = bigint | number | string;') - - expect(generateTypes({ - test: bigint({ fromNumber: false }), - }, true)).toStrictlyEqual('export type test = bigint;') - - expect(generateTypes({ - test: bigint({ brand: 'foo' }), - }, true)).toStrictlyEqual('export type test = bigint | number;') + expect( + generateTypes( + { + test: bigint({}), + }, + true, + ), + ).toStrictlyEqual('export type test = bigint | number;') + + expect( + generateTypes( + { + test: bigint({ fromString: true }), + }, + true, + ), + ).toStrictlyEqual('export type test = bigint | number | string;') + + expect( + generateTypes( + { + test: bigint({ fromNumber: false }), + }, + true, + ), + ).toStrictlyEqual('export type test = bigint;') + + expect( + generateTypes( + { + test: bigint({ brand: 'foo' }), + }, + true, + ), + ).toStrictlyEqual('export type test = bigint | number;') }) it('should generate the input type for (branded) numbers', () => { - expect(generateTypes({ - test: number({}), - }, true)).toStrictlyEqual('export type test = number;') - - expect(generateTypes({ - test: number({ fromString: true }), - }, true)).toStrictlyEqual('export type test = number | string;') - - expect(generateTypes({ - test: number({ brand: 'foo' }), - }, true)).toStrictlyEqual('export type test = number;') + expect( + generateTypes( + { + test: number({}), + }, + true, + ), + ).toStrictlyEqual('export type test = number;') + + expect( + generateTypes( + { + test: number({ fromString: true }), + }, + true, + ), + ).toStrictlyEqual('export type test = number | string;') + + expect( + generateTypes( + { + test: number({ brand: 'foo' }), + }, + true, + ), + ).toStrictlyEqual('export type test = number;') }) it('should generate the input type for (branded) strings', () => { - expect(generateTypes({ - test: string({}), - }, true)).toStrictlyEqual('export type test = string;') - - expect(generateTypes({ - test: string({ brand: 'foo' }), - }, true)).toStrictlyEqual('export type test = string;') + expect( + generateTypes( + { + test: string({}), + }, + true, + ), + ).toStrictlyEqual('export type test = string;') + + expect( + generateTypes( + { + test: string({ brand: 'foo' }), + }, + true, + ), + ).toStrictlyEqual('export type test = string;') }) it('should generate the input type for dates', () => { - expect(generateTypes({ - test: date, - }, true)).toStrictlyEqual('export type test = Date | number | string;') - - expect(generateTypes({ - test: date({ format: 'iso' }), - }, true)).toStrictlyEqual('export type test = string;') - - expect(generateTypes({ - test: date({ format: 'timestamp' }), - }, true)).toStrictlyEqual('export type test = number;') + expect( + generateTypes( + { + test: date, + }, + true, + ), + ).toStrictlyEqual('export type test = Date | number | string;') + + expect( + generateTypes( + { + test: date({ format: 'iso' }), + }, + true, + ), + ).toStrictlyEqual('export type test = string;') + + expect( + generateTypes( + { + test: date({ format: 'timestamp' }), + }, + true, + ), + ).toStrictlyEqual('export type test = number;') }) }) describe('Extra validators', () => { it('ean 13', () => { - expect(generateTypes({ - test: ean13, - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __ean_13: never; };') - - expect(generateTypes({ - test: new EAN13Validator(), - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __ean_13: never; };') + expect( + generateTypes({ + test: ean13, + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __ean_13: never; };') + + expect( + generateTypes({ + test: new EAN13Validator(), + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __ean_13: never; };') }) it('email', () => { - expect(generateTypes({ - test: email, - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __email: never; };') - - expect(generateTypes({ - test: new EmailValidator(), - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __email: never; };') + expect( + generateTypes({ + test: email, + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __email: never; };') + + expect( + generateTypes({ + test: new EmailValidator(), + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __email: never; };') }) it('url', () => { - expect(generateTypes({ - test: url, - })).toStrictlyEqual('export type test = URL;') + expect( + generateTypes({ + test: url, + }), + ).toStrictlyEqual('export type test = URL;') - expect(generateTypes({ - test: new URLValidator(), - })).toStrictlyEqual('export type test = URL;') + expect( + generateTypes({ + test: new URLValidator(), + }), + ).toStrictlyEqual('export type test = URL;') }) it('uuid', () => { - expect(generateTypes({ - test: uuid, - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __uuid: never; };') - - expect(generateTypes({ - test: new UUIDValidator(), - }).replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual('export type test = string & { __uuid: never; };') + expect( + generateTypes({ + test: uuid, + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __uuid: never; };') + + expect( + generateTypes({ + test: new UUIDValidator(), + }) + .replace(/\s+/gm, ' ') + .trim(), + ).toStrictlyEqual('export type test = string & { __uuid: never; };') }) }) describe('Extra validators input types', () => { it('ean 13', () => { - expect(generateTypes({ - test: ean13, - }, true)).toStrictlyEqual('export type test = number | string;') - - expect(generateTypes({ - test: new EAN13Validator(), - }, true)).toStrictlyEqual('export type test = number | string;') + expect( + generateTypes( + { + test: ean13, + }, + true, + ), + ).toStrictlyEqual('export type test = number | string;') + + expect( + generateTypes( + { + test: new EAN13Validator(), + }, + true, + ), + ).toStrictlyEqual('export type test = number | string;') }) it('email', () => { - expect(generateTypes({ - test: email, - }, true)).toStrictlyEqual('export type test = string;') - - expect(generateTypes({ - test: new EmailValidator(), - }, true)).toStrictlyEqual('export type test = string;') + expect( + generateTypes( + { + test: email, + }, + true, + ), + ).toStrictlyEqual('export type test = string;') + + expect( + generateTypes( + { + test: new EmailValidator(), + }, + true, + ), + ).toStrictlyEqual('export type test = string;') }) it('url', () => { - expect(generateTypes({ - test: url, - }, true)).toStrictlyEqual('export type test = URL | string;') - - expect(generateTypes({ - test: new URLValidator(), - }, true)).toStrictlyEqual('export type test = URL | string;') + expect( + generateTypes( + { + test: url, + }, + true, + ), + ).toStrictlyEqual('export type test = URL | string;') + + expect( + generateTypes( + { + test: new URLValidator(), + }, + true, + ), + ).toStrictlyEqual('export type test = URL | string;') }) it('uuid', () => { - expect(generateTypes({ - test: uuid, - }, true)).toStrictlyEqual('export type test = string;') - - expect(generateTypes({ - test: new UUIDValidator(), - }, true)).toStrictlyEqual('export type test = string;') + expect( + generateTypes( + { + test: uuid, + }, + true, + ), + ).toStrictlyEqual('export type test = string;') + + expect( + generateTypes( + { + test: new UUIDValidator(), + }, + true, + ), + ).toStrictlyEqual('export type test = string;') }) }) @@ -523,15 +765,13 @@ describe('DTS Generation', () => { description: description; }; export type description = string;` - .replace(/\s+/gm, ' ').trim() + .replace(/\s+/gm, ' ') + .trim() // run our little test... - expect(generateTypes({ ean, product, description }) - .replace(/\s+/gm, ' ').trim()) - .toStrictlyEqual(expected) + expect(generateTypes({ ean, product, description }).replace(/\s+/gm, ' ').trim()).toStrictlyEqual(expected) }) - it('should generate a full type declaration', () => { // this will be exported... const ean = ean13 @@ -553,7 +793,8 @@ describe('DTS Generation', () => { log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- ean ---------------------------------------------------------------- */ /** Validated type for {@link ean} */ export type Ean = string & { @@ -600,7 +841,10 @@ describe('DTS Generation', () => { export type TestInput = EanInput; /** The \`testValidator\` validator */ export const testValidator: import("justus").Validator;` - .split('\n').slice(1).map((s) => s.trim())) + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration for constants', () => { @@ -614,7 +858,8 @@ describe('DTS Generation', () => { log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- nullValidator ------------------------------------------------------ */ /** Validated type for {@link nullValidator} */ export type Null = null; @@ -650,7 +895,10 @@ describe('DTS Generation', () => { export type FalseInput = False; /** The \`falseValidator\` validator */ export const falseValidator: False;` - .split('\n').slice(1).map((s) => s.trim())) + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration a schema with additional properties', () => { @@ -663,7 +911,8 @@ describe('DTS Generation', () => { log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myObjectValidator -------------------------------------------------- */ /** Validated type for {@link myObjectValidator} */ export type MyObject = { @@ -677,7 +926,11 @@ describe('DTS Generation', () => { export const myObjectValidator: { readonly foo: import("justus").Validator; readonly [Symbol.justusAdditionalValidator]: import("justus").Validator; - };`.split('\n').slice(1).map((s) => s.trim())) + };` + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration a schema with no additional properties', () => { @@ -690,7 +943,8 @@ describe('DTS Generation', () => { log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myObjectValidator -------------------------------------------------- */ /** Validated type for {@link myObjectValidator} */ export type MyObject = { @@ -701,7 +955,11 @@ describe('DTS Generation', () => { /** The \`myObjectValidator\` validator */ export const myObjectValidator: { readonly foo: import("justus").Validator; - };`.split('\n').slice(1).map((s) => s.trim())) + };` + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration a schema with explicit additional properties', () => { @@ -714,7 +972,8 @@ describe('DTS Generation', () => { log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myObjectValidator -------------------------------------------------- */ /** Validated type for {@link myObjectValidator} */ export type MyObject = { @@ -728,15 +987,20 @@ describe('DTS Generation', () => { export const myObjectValidator: { readonly foo: import("justus").Validator; readonly [Symbol.justusAdditionalValidator]: import("justus").Validator; - };`.split('\n').slice(1).map((s) => s.trim())) + };` + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration for wrapped tuples', () => { - const result = generateDeclarations({ myTuple: tuple([ string, number ]) }) + const result = generateDeclarations({ myTuple: tuple([string, number]) }) log.info(result) - expect(result.split('\n').map((s) => s.trim())).toEqual(` + expect(result.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myTuple ------------------------------------------------------------ */ /** Validated type for {@link myTuple} */ export type MyTuple = [ @@ -747,14 +1011,18 @@ describe('DTS Generation', () => { export type MyTupleInput = MyTuple; /** The \`myTuple\` validator */ export const myTuple: import("justus").Validator;` - .split('\n').slice(1).map((s) => s.trim())) + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) it('should generate a full type declaration for straight tuples', () => { - const result1 = generateDeclarations({ myTuple: [ string ] }) + const result1 = generateDeclarations({ myTuple: [string] }) log.info(result1) - expect(result1.split('\n').map((s) => s.trim())).toEqual(` + expect(result1.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myTuple ------------------------------------------------------------ */ /** Validated type for {@link myTuple} */ export type MyTuple = [ @@ -764,14 +1032,17 @@ describe('DTS Generation', () => { export type MyTupleInput = MyTuple; /** The \`myTuple\` validator */ export const myTuple: import("justus").Validator;` - .split('\n').slice(1).map((s) => s.trim())) - + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) const o = object({ foo: string } as const) - const result2 = generateDeclarations({ myTuple: [ number, ...o, boolean ] }) + const result2 = generateDeclarations({ myTuple: [number, ...o, boolean] }) log.info(result2) - expect(result2.split('\n').map((s) => s.trim())).toEqual(` + expect(result2.split('\n').map((s) => s.trim())).toEqual( + ` /* ----- myTuple ------------------------------------------------------------ */ /** Validated type for {@link myTuple} */ export type MyTuple = [ @@ -785,7 +1056,10 @@ describe('DTS Generation', () => { export type MyTupleInput = MyTuple; /** The \`myTuple\` validator */ export const myTuple: import("justus").Validator;` - .split('\n').slice(1).map((s) => s.trim())) + .split('\n') + .slice(1) + .map((s) => s.trim()), + ) }) }) }) diff --git a/test/sources/testme.ts b/test/sources/testme.ts index 7761d43..3b2ec79 100644 --- a/test/sources/testme.ts +++ b/test/sources/testme.ts @@ -1,14 +1,4 @@ -import { - allowAdditionalProperties, - any, - array, - boolean, - date, - never, - number, - object, - string, -} from 'justus' +import { allowAdditionalProperties, any, array, boolean, date, never, number, object, string } from 'justus' import { url } from 'justus/extra/url' export const testKeywords = object({ diff --git a/test/sources/tsconfig.json b/test/sources/tsconfig.json index b13d14e..7c8a6cb 100644 --- a/test/sources/tsconfig.json +++ b/test/sources/tsconfig.json @@ -1,10 +1,10 @@ { "compilerOptions": { - "lib": [ "esnext", "webworker" ], + "lib": ["esnext", "webworker"], "target": "esnext", "module": "esnext", "moduleResolution": "bundler", - "types": [ ], + "types": [], "esModuleInterop": true, "noEmit": false, @@ -21,9 +21,9 @@ "verbatimModuleSyntax": true, "paths": { - "justus": [ "../.." ] + "justus": ["../.."] } }, - "include": [ "*.ts", ], - "exclude": [ ] + "include": ["*.ts"], + "exclude": [] } diff --git a/test/tsconfig.json b/test/tsconfig.json index c56f7e5..c4f8a6b 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,8 +1,11 @@ { + // Inherit options from the root configuration file "extends": "../tsconfig.json", + // Add Expect5's own globals and make sure we can reference "../src" "compilerOptions": { - "types": [ "@plugjs/expect5/globals", "node" ], - "rootDir": "..", + "types": ["@plugjs/expect5/globals", "node"], + "rootDir": ".." }, - "include": [ "." ], + // Include only tests, but exclude resources (intentionally broken) + "include": ["."] } diff --git a/tsconfig.json b/tsconfig.json index 2063c47..a40e2c9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,49 @@ +// ===== BASE CONFIGURATION ==================================================== +// This is the base configuration for the TypeScript compiler. It declares our +// overall preferences for the TypeScript compiler, and is extended by the two +// specific configurations for sources and tests. { "compilerOptions": { - "lib": [ "esnext", "webworker" ], + // This project is a "very modern" NodeJS project + "lib": ["esnext"], "target": "esnext", - "module": "esnext", - "moduleResolution": "bundler", - "types": [ ], - "esModuleInterop": true, + "module": "nodenext", + "moduleResolution": "nodenext", + "types": ["node"], + // Do not emit any files (we only want to type-check) "noEmit": true, + // ES modules interoperability and preserve import/export statements + "esModuleInterop": true, + "verbatimModuleSyntax": true, + + // Import relative files as "file.ts" and rewrite them in the output + "allowImportingTsExtensions": true, + "rewriteRelativeImportExtensions": true, + + // Ultra strict "strict": true, + // Implies: + // - alwaysStrict + // - noImplicitAny + // - noImplicitThis + // - strictBindCallApply + // - strictBuiltinIteratorReturn + // - strictFunctionTypes + // - strictNullChecks + // - strictPropertyInitialization + // - useUnknownInCatchVariables + "allowUnreachableCode": false, + "allowUnusedLabels": false, + "noFallthroughCasesInSwitch": true, + "noImplicitOverride": true, "noImplicitReturns": true, + "noPropertyAccessFromIndexSignature": true, + "noUncheckedIndexedAccess": true, "noUnusedLocals": true, - "noUnusedParameters": true, - "verbatimModuleSyntax": true, + "noUnusedParameters": true }, - "include": [ - "./src", - "./build.ts", - ], + // Include only the local (config and build) files... + "include": ["*.ts"] }