diff --git a/.npmignore b/.npmignore index ba2c37e..645d251 100644 --- a/.npmignore +++ b/.npmignore @@ -2,19 +2,21 @@ .husky .idea coverage -/node_modules +node_modules src tests .commitlintrc.json -.eslintrc.js .gitignore .npmrc .versionrc.json +codecov.yml docker-compose.yml -jest.config.ts -rollup.config.ts +eslint.config.mjs tsconfig.json +vite.config.basic.ts +vite.config.ts +vitest.config.ts yarn.lock Makefile diff --git a/Makefile b/Makefile index 5f3fa9b..8e20545 100644 --- a/Makefile +++ b/Makefile @@ -29,11 +29,7 @@ test: node_modules ## Runs autotests .PHONY: test-coverage test-coverage: node_modules ## Runs autotests with --coverage $(TARGET_HEADER) -ifdef reporter - $(YARN) test --coverage --coverageReporters=$(reporter) -else - $(YARN) test --coverage --coverageReporters=text -endif + $(YARN) test:coverage .PHONY: release release: ## Bumps version and creates tag diff --git a/README.md b/README.md index 61c6804..29be9ed 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ [![Tests Status](https://github.com/modulify/validator/actions/workflows/tests.yml/badge.svg)](https://github.com/modulify/validator/actions) [![npm version](https://badge.fury.io/js/%40modulify%2Fvalidator.svg)](https://www.npmjs.com/package/@modulify/validator) -This library provides a declarative validation util. +This library provides a declarative validation utility. -The util does not provide any text messages in the constraints produced and gives only metadata that can +The utility does not include text messages in the generated violations but instead provides metadata that can be used to create a custom view for them. ## Installation @@ -27,35 +27,34 @@ npm install @modulify/validator --save ```typescript import { - Collection, - Exists, - Length, - createValidator, + HasLength, + HasProperties, + IsDefined, + IsString, + validate, } from '@modulify/validator' -const validator = createValidator() - -const violations = validator.validate({ +const violations = await validate({ form: { nickname: '', password: '', }, -}, new Collection({ +}, HasProperties({ form: [ - new Exists(), - new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), + IsDefined(), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), }), ], -}), /* do not set or set to true for async validation */ false) /* [{ - by: '@modulify/validator/Length', +})) /* [{ + by: '@modulify/validator/IsString', value: '', path: ['form', 'nickname'], reason: 'min', meta: 4, }, { - by: '@modulify/validator/Length', + by: '@modulify/validator/IsString', value: '', path: ['form', 'password'], reason: 'min', @@ -63,124 +62,90 @@ const violations = validator.validate({ }] */ ``` -### Constraints - -Constraints provide information of how the value should be validated. - -Available from the box: - -* `Collection` – used for validating objects' structure; -* `Each` – used for validating arrays' elements; applies specified constraints to each element of an array; -* `Exists` – used for checking if a value is defined; useful for finding missing keys; -* `Length` – used for checking arrays' and string's length, available settings (all optional) are: - * `exact` – `number`, array or string should have exactly specified count of elements or characters; - * `max` – `number`, maximum elements in array or maximum characters in string; - * `min` – `number`, minimum elements in array or minimum characters in string; -* `OneOf` – used for restricting which values can be used. - -There is no any basic constraint class to extend, but they should follow signature -described in `types/index.d.ts` – `Constraint`. - -### Validators - -Validators provide validation logic that relies on information provided by constraints. - -There is no any basic validator class to extend, but they should follow signature -described in `types/index.d.ts` – `ConstraintValidator`. - -### Provider - -Provider is used to bind constraints with their validators, provides a validator for a constraint. - -All providers should follow signature described in `types/index.d.ts` – `Provider`. - -This feature is responsible for extending validation capabilities. Custom provider can be passed into -`createValidator` function or `override` method of `Validator` instance. - -There is a built-in provider – `ProviderChain`. It allows to "chain" providers – if -suitable validator was not found in currently used provider, it will try to find it in previous provider that was -overridden by `override` method. +or (for synchronous validation): ```typescript -import type { - Constraint, - ConstraintValidator, - ConstraintViolation, - Key, - Provider, -} from '@modulify/validator' - -import { - ProviderChain, - createValidator, -} from '@modulify/validator' - -class Email implements Constraint { - public readonly name = '@app/validator/Email' - - toViolation (value: unknown, path: Key[]): ConstraintViolation { - return { - by: this.name, - value, - path, - } - } -} - -class EmailValidator implements ConstraintValidator { - private readonly _constraint: Email - - constructor (constraint: Email) { - this._constraint = constraint - } - - validate (value: unknown, path?: Key[]): ConstraintViolation | null { - if (!(typeof value === 'string') || !/\S+@\S+\.\S+/.test(value)) { - return this._constraint.toViolation(value, path) - } - - return null - } -} -``` - -then - -```typescript -const provider = new ProviderChain(new class implements Provider { - get (constraint: Constraint) { - return constraint instanceof Email ? new EmailValidator(constraint) : null - } - - override (provider: Provider): Provider { - return new ProviderChain(provider, this) - } -}) -``` - -or - -```typescript -const provider = new class implements Provider { - get (constraint: Constraint) { - return constraint instanceof Email ? new EmailValidator(constraint) : null - } - - override (provider: Provider): Provider { - return new ProviderChain(provider, this) - } -} -``` - -and then - -```typescript -const validator = createValidator(provider) +const violations = validate.sync({ + form: { + nickname: '', + password: '', + }, +}, HasProperties({ + form: [ + IsDefined(), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], +})) ``` -or - -```typescript -const validator = createValidator() -const overridden = validator.override(provider) // it creates new validator instance, so validator !== overridden -``` \ No newline at end of file +## Exported types + +* `Violation` – an object that contains information about a value – why it violates one or more constraints; + includes following fields: + * `value` – value that violates something; + * `path` – path to the value, an empty array for scalar values and represents full path to the value in a complex + object; + * `violates` – indicator of the violated constraint; + * `reason` – indicator of the reason why the constraint is violated; + * `meta` – some data to describe the reason – what exactly the boundaries were not met; + ```typescript + import type { Violation } from '@modulify/validator/types' + ``` +* `Predicate` – function that accepts a value and returns `true` or `false`; logical unit that is used for checking + multiple things: type or if the value satisfies certain criteria; accepts generic argument `T` to specify + the type of the value, if predicate returns `true`; + ```typescript + import type { Predicate } from '@modulify/validator/types' + ``` +* `Assertion` – extension of the `Predicate` type that includes: + * `fqn` – field – some predefined name that will be used as a value for the `violates` field of `Violation`; + * `bail` – field – flag that interrupts further validation if the assertion fails; + * `reason` – field, optional – string or symbol that is used to indicate, why assertion has failed; + always added to a violation object, if present; + * `meta` – field, optional – some metadata to use in further analysis; always added to a violation object, if present; + * `That` – method – used to extend assertion with other assertions; + * `also` – field – readonly array of other assertions that was attached by `That` method; + ```typescript + import type { Assertion } from '@modulify/validator/types' + ``` + +## Exported members + +* `validate` – function that accepts a value for validation as the first argument, constraints as the second, + and path to a value as the third (that is optional and used mostly for internal purposes, as validation is recursive); + includes method `sync` that has the same arguments set but performs validation synchronously and throws error when + finds an asynchronous constraint; + +* `Assert` – creates assertion from logical predicate: + ```typescript + const IsSomething = Assert(isSomething, { + fqn: 'Some fqn', + bail: true, + }) + ``` + Arguments: + * Logical predicate + * Options, that includes `fqn`, `bail`, `reason` (optional), and `meta` (optional); +* `HasLength` – checks length property of the specified string or array; can be configured with options: + * `exact` – if the length should be exactly equal the specified value; + * `max` – if the length should be equal or less than the specified value; + * `min` – if the length should be equal or greater than the specified value; + * `bail` – set this to true if you need to interrupt further validation if the assertion fails; +* `IsBoolean` – checks if the value is **boolean**; interrupts further validation if fails; +* `IsDate` – checks if the value is Date **object**; interrupts further validation if fails; +* `IsDefined` – checks if the value is **not undefined**; interrupts further validation if fails; +* `IsEmail` – checks if the value is a **valid email**; interrupts further validation if fails; +* `IsNull` – checks if the value is **null**; interrupts further validation if fails; +* `IsNumber` – checks if the value is **number**; interrupts further validation if fails; +* `IsString` – checks if the value is **string**; interrupts further validation if fails; +* `IsSymbol` – checks if the value is a **symbol**; interrupts further validation if fails; +* `OneOf` – checks if the value equal to one of the specified values; can be configured with: + * `equalTo` – predicate f(a, b) that checks if two values are equal or not; + by default the strict `===` comparison is used + * `bail` – set this to true if you need to interrupt further validation if the assertion fails; + +* `Each` – a runner that runs validation for each element in array; +* `HasProperties` – a runner that runs object's structure check. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a5abf49..871297f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: node: image: node:20 diff --git a/package.json b/package.json index 417c29d..1de4c3d 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,51 @@ { "name": "@modulify/validator", + "type": "module", "description": "Declarative validation util for JavaScript", "license": "MIT", "version": "0.0.2", - "main": "dist/index.cjs", - "module": "dist/index.mjs", - "types": "types/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "default": "./dist/index.mjs" + }, + "./assertions": { + "types": "./dist/assertions.d.ts", + "import": "./dist/assertions.mjs", + "require": "./dist/assertions.cjs", + "default": "./dist/assertions.mjs" + }, + "./predicates": { + "types": "./dist/predicates.d.ts", + "import": "./dist/predicates.mjs", + "require": "./dist/predicates.cjs", + "default": "./dist/predicates.mjs" + }, + "./runners": { + "types": "./dist/runners.d.ts", + "import": "./dist/runners.mjs", + "require": "./dist/runners.cjs", + "default": "./dist/runners.mjs" + } + }, + "types": "dist/index.d.ts", + "typesVersions": { + "*": { + "assertions": [ + "./dist/assertions.d.ts" + ], + "predicates": [ + "./dist/predicates.d.ts" + ], + "runners": [ + "./dist/runners.d.ts" + ] + } + }, "scripts": { - "build": "rollup --config rollup.config.ts --configPlugin typescript", + "build": "vite build", "lint": "eslint src tests types", "prepare": "husky", "release": "standard-version", @@ -22,32 +60,29 @@ "devDependencies": { "@commitlint/cli": "^17.7.1", "@commitlint/config-conventional": "^17.7.0", - "@eslint/js": "^9.13.0", - "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-typescript": "^11.1.6", + "@eslint/js": "^9.17.0", "@types/node": "^18.15 || ^20.11", - "@vitest/coverage-istanbul": "2.1.3", - "@vitest/ui": "2.1.3", - "eslint": "^9.13.0", - "globals": "^15.11.0", - "husky": "^9.0.10", - "rollup": "^4.9.6", - "rollup-plugin-delete": "^2.0.0", + "@vitest/coverage-istanbul": "2.1.8", + "@vitest/ui": "2.1.8", + "eslint": "^9.17.0", + "globals": "^15.14.0", + "husky": "^9.1.7", "standard-version": "^9.5.0", "ts-node": "^10.9.2", - "tslib": "^2.6.2", - "typescript": "^5.3.3", - "typescript-eslint": "^8.10.0", - "vite": "^5.4.9", - "vite-plugin-dts": "^4.2.4", - "vitest": "^2.1.3" + "tslib": "^2.8.1", + "typescript": "^5.5.4", + "typescript-eslint": "^8.18.1", + "vite": "^5.4.11", + "vite-plugin-dts": "^4.4.0", + "vitest": "^2.1.8" }, "publishConfig": { "access": "public" }, "keywords": [ "validate", - "validator" + "validator", + "ES2017" ], "contributors": [ "Zaitsev Kirill " diff --git a/rollup.config.ts b/rollup.config.ts deleted file mode 100644 index 98e7e51..0000000 --- a/rollup.config.ts +++ /dev/null @@ -1,48 +0,0 @@ -import type { - InputPluginOption, - OutputOptions, - RollupOptions, -} from 'rollup' - -import path from 'node:path' -import url from 'node:url' - -import clean from 'rollup-plugin-delete' -import typescript from '@rollup/plugin-typescript' - -const __dirname = path.dirname(url.fileURLToPath(import.meta.url)) - -const input = path.join(__dirname, '/src/index.ts') - -const output: OutputOptions = { - exports: 'named', - dir: path.join(__dirname, '/dist'), - globals: { - vue: 'Vue', - }, -} - -const plugins: InputPluginOption = [ - typescript(), -] - -export default [{ - input, - output: { - ...output, - format: 'cjs', - entryFileNames: 'index.cjs', - }, - plugins: [ - clean({ targets: 'dist/*' }), - ...plugins, - ], -}, { - input, - output: { - ...output, - format: 'esm', - entryFileNames: 'index.mjs', - }, - plugins, -}] as RollupOptions[] \ No newline at end of file diff --git a/src/assertions/Assert.ts b/src/assertions/Assert.ts new file mode 100644 index 0000000..d099a33 --- /dev/null +++ b/src/assertions/Assert.ts @@ -0,0 +1,28 @@ +import type { + Assertion, + Meta, + Predicate, +} from '~types' + +const delegate = (p: Predicate): Predicate => { + return (value: unknown): value is T => p(value) +} + +export const Assert = < + T = unknown, + M = unknown +>(predicate: Predicate, options: Meta): Assertion => { + const extender = (asserts: Assertion[] = []): Pick, 'That' | 'also'> => { + return { + That (...asserts: Assertion[]) { + return Object.assign(delegate(predicate), options, extender(asserts)) as Assertion + }, + + get also (): Assertion[] { + return asserts + }, + } as Assertion + } + + return Object.assign(delegate(predicate), options, extender()) +} diff --git a/src/assertions/HasLength.ts b/src/assertions/HasLength.ts new file mode 100644 index 0000000..3307ec9 --- /dev/null +++ b/src/assertions/HasLength.ts @@ -0,0 +1,53 @@ +import { Assert } from '@/assertions/Assert' + +import { + isArray, + isExact, + isNumber, + isString, + Or, +} from '@/predicates' + +const isGTE = (min: number) => (x: unknown): x is number => isNumber(x) && x >= min +const isLTE = (max: number) => (x: unknown): x is number => isNumber(x) && x <= max + +const IsEqual = (exact: number) => Assert((x: string | unknown[]): x is string | unknown[] => isExact(exact)(x.length), { + fqn: '@modulify/validator/HasLength[exact]', + bail: false, + reason: 'exact', + meta: exact, +}) + +const IsGTE = (min: number) => Assert((x: string | unknown[]): x is string | unknown[] => isGTE(min)(x.length), { + fqn: '@modulify/validator/HasLength[min]', + bail: false, + reason: 'min', + meta: min, +}) + +const IsLTE = (max: number) => Assert((x: string | unknown[]): x is string | unknown[] => isLTE(max)(x.length), { + fqn: '@modulify/validator/HasLength[max]', + bail: false, + reason: 'max', + meta: max, +}) + +export const HasLength = ({ + exact = null, + max = null, + min = null, + bail = false, +}: { + exact?: number | null + max?: number | null + min?: number | null + bail?: boolean +}) => Assert(Or(isString, isArray), { + fqn: '@modulify/validator/HasLength', + bail, + reason: 'unsupported', +}).That( + ...(exact !== null ? [IsEqual(exact)] : []), + ...(max !== null ? [IsLTE(max)] : []), + ...(min !== null ? [IsGTE(min)] : []) +) diff --git a/src/assertions/check.ts b/src/assertions/check.ts new file mode 100644 index 0000000..51ebbe3 --- /dev/null +++ b/src/assertions/check.ts @@ -0,0 +1,33 @@ +import { + Assertion, + Violation, +} from '~types' + +const check = < + T = unknown, + M = unknown +>(assert: Assertion, value: unknown, path: PropertyKey[] = []): null | Violation => { + if (assert(value)) { + for (const a of assert.also) { + const violation = check(a, value, path) + if (violation) { + return { + ...violation, + violates: assert.fqn, + } as Violation + } + } + + return null + } + + return { + value, + path, + violates: assert.fqn, + ...('reason' in assert ? { reason: assert.reason } : {}), + ...('meta' in assert ? { meta: assert.meta } : {}), + } as Violation +} + +export default check diff --git a/src/assertions/index.ts b/src/assertions/index.ts new file mode 100644 index 0000000..985ff6b --- /dev/null +++ b/src/assertions/index.ts @@ -0,0 +1,80 @@ +import { Assert } from './Assert' + +import { + isArray, + isBoolean, + isDate, + isEmail, + isNull, + isNumber, + isString, + isSymbol, + isUndefined, + Not, +} from '@/predicates' + +export { Assert } + +export { HasLength } from './HasLength' + +export const IsBoolean = Assert(isBoolean, { + fqn: '@modulify/validator/IsBoolean', + bail: true, +}) + +export const IsDate = Assert(isDate, { + fqn: '@modulify/validator/IsDate', + bail: true, +}) + +export const IsDefined = Assert(Not(isUndefined), { + fqn: '@modulify/validator/IsDefined', + bail: true, + reason: 'undefined', +}) + +export const IsEmail = Assert(isEmail, { + fqn: '@modulify/validator/IsEmail', + bail: true, +}) + +export const IsNull = Assert(isNull, { + fqn: '@modulify/validator/IsNull', + bail: true, +}) + +export const IsNumber = Assert(isNumber, { + fqn: '@modulify/validator/IsNumber', + bail: true, +}) + +export const IsString = Assert(isString, { + fqn: '@modulify/validator/IsString', + bail: true, +}) + +export const IsSymbol = Assert(isSymbol, { + fqn: '@modulify/validator/IsSymbol', + bail: true, +}) + +export const OneOf = ( + values: Actual[] | Record, + { + equalTo = (a: Actual, b: unknown) => a === b, + bail = false, + }: { + equalTo?: (a: Actual, b: unknown) => boolean; + bail?: boolean; + } = {} +) => { + const haystack = isArray(values) ? values : Object.values(values) + + const oneOf = (value: unknown): value is Actual => haystack.some(allowed => equalTo(allowed, value)) + + return Assert(oneOf, { + fqn: '@modulify/validator/OneOf', + bail, + meta: haystack, + }) +} diff --git a/src/constraints/Collection.ts b/src/constraints/Collection.ts deleted file mode 100644 index 9ab16c6..0000000 --- a/src/constraints/Collection.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type { - Constraint, - ConstraintCollection, - ConstraintViolation, - Key, -} from '../../types' - -export default class Collection> implements Constraint { - public readonly name = '@modulify/validator/Collection' - public readonly constraints: ConstraintCollection - - constructor (constraints: ConstraintCollection) { - this.constraints = constraints - } - - reduce > ( - reducer: (accumulator: U, constraint: ConstraintCollection[P], property: P) => U, - initial: U - ): U { - return (Object.keys(this.constraints) as P[]).reduce((accumulator, key) => { - return reducer(accumulator, this.constraints[key], key) - }, initial) - } - - toViolation (value: T, path: Key[], reason: string): ConstraintViolation { - return { - by: this.name, - value, - path, - reason, - } - } -} \ No newline at end of file diff --git a/src/constraints/Each.ts b/src/constraints/Each.ts deleted file mode 100644 index de6d6c8..0000000 --- a/src/constraints/Each.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { - Constraint, - ConstraintViolation, - Key, -} from '../../types' - -import { arraify } from '@/utils' - -export default class Each implements Constraint { - public readonly name = '@modulify/validator/Each' - public readonly constraints: Constraint[] - - constructor (constraints: Constraint | Constraint[]) { - this.constraints = arraify(constraints) - } - - toViolation (value: unknown, path: Key[], reason?: string): ConstraintViolation { - return { - by: this.name, - value, - path, - reason, - } - } -} \ No newline at end of file diff --git a/src/constraints/Exists.ts b/src/constraints/Exists.ts deleted file mode 100644 index 177c644..0000000 --- a/src/constraints/Exists.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { - Constraint, - ConstraintViolation, - Key, -} from '../../types' - -export default class Exists implements Constraint { - public readonly name = '@modulify/validator/Exists' - - toViolation (value: unknown, path: Key[]): ConstraintViolation { - return { - by: this.name, - value, - path, - reason: 'undefined', - } - } -} \ No newline at end of file diff --git a/src/constraints/Length.ts b/src/constraints/Length.ts deleted file mode 100644 index 14faf0d..0000000 --- a/src/constraints/Length.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { - Constraint, - ConstraintViolation, - Key, -} from '../../types' - -export default class Length implements Constraint { - public readonly name = '@modulify/validator/Length' - - public readonly exact: number | null - public readonly max: number | null - public readonly min: number | null - - constructor (options: { - exact?: number - max?: number - min?: number - }) { - this.exact = options.exact ?? null - this.max = options.max ?? null - this.min = options.min ?? null - } - - toViolation ( - value: Value, - path: Key[], - reason: 'exact' | 'max' | 'min' | 'unsupported' - ): ConstraintViolation { - return { - by: this.name, - value, - path, - reason, - meta: { - exact: this.exact, - max: this.max, - min: this.min, - }[reason], - } - } -} \ No newline at end of file diff --git a/src/constraints/OneOf.ts b/src/constraints/OneOf.ts deleted file mode 100644 index 85c1b2d..0000000 --- a/src/constraints/OneOf.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { - Constraint, - ConstraintViolation, - Key, -} from '../../types' - -type EqualPredicate = (a: Expected, b: unknown) => boolean - -export default class OneOf implements Constraint { - public readonly name = '@modulify/validator/OneOf' - public readonly values: Expected[] - public readonly equalTo: EqualPredicate - - constructor ( - values: Expected[] | Record, - equalTo: EqualPredicate = (a: Expected, b: unknown) => a === b - ) { - this.values = Array.isArray(values) ? values : Object.values(values) - this.equalTo = equalTo - } - - toViolation (value: Actual, path: Key[]): ConstraintViolation { - return { - by: this.name, - value, - path, - meta: this.values, - } - } -} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index cb1c3a8..1557ca2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,200 +1,129 @@ import type { Constraint, - ConstraintViolation, - Provider, + ValidationRunner, + MaybeMany, Recursive, - Validator, -} from '../types' + Violation, +} from '~types' -import Collection from '@/constraints/Collection' -import Each from '@/constraints/Each' -import Exists from '@/constraints/Exists' -import Length from '@/constraints/Length' -import OneOf from '@/constraints/OneOf' +import check from '@/assertions/check' -import ProviderChain from '@/provider' +export * from '@/assertions' +export * from '@/runners' -import { - arraify, - flatten, -} from '@/utils' - -import isArray from '@/predicates/isArray' -import isRecord from '@/predicates/isRecord' +const isBatch = (c: Constraint): c is ValidationRunner => { + return 'run' in c +} -const validateAsynchronously = async ( - provider: Provider, - value: Value, - constraints: Constraint | Constraint[], +const _validate = async ( + value: T, + constraints: MaybeMany, path: PropertyKey[] = [] -): Promise => { - const validations: Promise[] = [] +): Promise => { + const validations: Promise[] = [] for (const c of arraify(constraints)) { - if (c instanceof Collection) { - if (isRecord(value as object)) { - validations.push(...c.reduce((validations, constraints, key) => { - return [...validations, validateAsynchronously(provider, value[key], constraints, [...path, key])] - }, [] as Promise[])) - } else { - validations.push(Promise.resolve([c.toViolation(value, path, 'unsupported')])) - } + if (isBatch(c)) { + validations.push(...c.run(_validate, value, path).map(v => v instanceof Promise ? v : Promise.resolve(v))) continue } - if (c instanceof Each) { - if (isArray(value)) { - value.forEach((value, index) => { - validations.push(validateAsynchronously(provider, value, c.constraints, [...path, index])) - }) + const v = 'That' in c ? check(c, value, [...path]) : c(value, [...path]) + + if (v instanceof Promise) { + if (c.bail) { + const awaited = await v + if (awaited) { + validations.push(Promise.resolve([awaited])) + break + } } else { - validations.push(validateAsynchronously(provider, value, c.constraints, [...path])) + validations.push(v.then(v => v ? [v] : [])) } - continue - } + } else if (v) { + validations.push(Promise.resolve([v])) - if (c instanceof Exists) { - if (typeof value === 'undefined') { - validations.push(Promise.resolve([c.toViolation(value, [...path])])) + if (c.bail) { break } - continue - } - - const validator = provider.get(c) - if (!validator) { - throw new Error('No validator for constraint ' + c.name) - } - - const v = validator.validate(value, [...path]) - if (v) { - if (v instanceof Promise) { - validations.push(v.then(v => v ? [v] : [])) - } else { - validations.push(Promise.resolve([v])) - } } } - const results = await Promise.allSettled(validations) - const violations: ConstraintViolation[] = [] - - results.forEach(result => { - if (result.status === 'fulfilled') { - violations.push(...result.value) - } - }) - - return violations + return settle(value, path, validations) } -const validateSynchronously = ( - provider: Provider, - value: Value, - constraints: Constraint | Constraint[], +const _sync = ( + value: T, + constraints: MaybeMany, path: PropertyKey[] = [] -): ConstraintViolation[] => { - const violations: Recursive[] = [] +): Violation[] => { + const violations: Recursive[] = [] for (const c of arraify(constraints)) { - if (c instanceof Collection) { - if (isRecord(value as object)) { - violations.push(c.reduce((violations, constraints, key) => { - return [...violations, ...validateSynchronously(provider, value[key], constraints, [...path, key])] - }, [] as ConstraintViolation[])) - } else { - violations.push(c.toViolation(value, path, 'unsupported')) - } - continue - } - - if (c instanceof Each) { - if (isArray(value)) { - value.forEach((value, index) => { - violations.push(...validateSynchronously(provider, value, c.constraints, [...path, index])) - }) - } else { - violations.push(...validateSynchronously(provider, value, c.constraints, [...path])) - } + if (isBatch(c)) { + violations.push(...c.run(_sync, value, path)) continue } - if (c instanceof Exists) { - if (typeof value === 'undefined') { - violations.push(c.toViolation(value, [...path])) - break - } - continue - } + const v = 'That' in c ? check(c, value, [...path]) : c(value, [...path]) - const validator = provider.get(c) - if (!validator) { - throw new Error('No validator for constraint ' + c.name) - } + if (v instanceof Promise) { + throw new Error('Found asynchronous constraint validator ' + String(c.fqn)) + } else if (v) { + violations.push(v) - const v = validator.validate(value, [...path]) - if (v) { - if (v instanceof Promise) { - throw new Error('Found asynchronous validator for constraint ' + c.name) + if (c.bail) { + break } - violations.push(v) } } - return flatten(violations) as ConstraintViolation[] + return flatten(violations) as Violation[] } -type MaybePromise = Asynchronously extends true ? Promise : Value - -const validate = ( - provider: Provider, - value: Value, - constraints: Constraint | Constraint[], - path: PropertyKey[] = [], - asynchronously: Asynchronously = true as Asynchronously -): MaybePromise => { - return asynchronously - ? validateAsynchronously(provider, value, constraints, path) as MaybePromise - : validateSynchronously(provider, value, constraints, path) as MaybePromise -} +export const validate = Object.assign(_validate, { + sync: _sync, +}) -class V implements Validator { - private readonly _provider: Provider +type A = T extends unknown[] ? T : T[] - constructor (provider: Provider | null = null) { - this._provider = provider ?? new ProviderChain() - } +function arraify (value: T): A { + return Array.isArray(value) + ? [...value] as A + : [value] as A +} - override (provider: Provider) { - return new V(this._provider.override(provider)) - } +function flatten(recursive: Recursive[]): T[] { + const flattened: T[] = [] + recursive.forEach(element => { + flattened.push(...( + Array.isArray(element) + ? flatten(element) + : [element] + )) + }) - validate( - value: Value, - constraints: Constraint | Constraint[], - asynchronously: Asynchronously = true as Asynchronously - ): MaybePromise { - return validate( - this._provider, - value, - constraints, - [], - asynchronously - ) - } + return flattened } -const createValidator = ( - provider: Provider | null = null -): Validator => new V(provider) - -export { - Collection, - Each, - Exists, - Length, - OneOf, - ProviderChain, - createValidator, - validate, +async function settle (value: unknown, path: PropertyKey[], validations: Promise[]) { + const violations: Violation[] = [] + + const settled = await Promise.allSettled(validations) + + settled.forEach(result => { + if (result.status === 'fulfilled') { + violations.push(...result.value) + } else { + violations.push({ + value, + path, + violates: '@modulify/validator', + reason: 'reject', + meta: result.reason, + }) + } + }) + + return violations } \ No newline at end of file diff --git a/src/predicates.ts b/src/predicates.ts new file mode 100644 index 0000000..6a6e700 --- /dev/null +++ b/src/predicates.ts @@ -0,0 +1,103 @@ +import type { + Intersect, + Predicate, +} from '~types' + +/** Checks if a value has a property */ +export function hasProperty (key: K){ + return (value: unknown): value is { [k in K]: unknown } => { + return isObject(value) && !isNull(value) && Object.prototype.hasOwnProperty.call(value, key) + } +} + +/** Checks if a value is an array */ +export function isArray (value: unknown): value is unknown[] { + return Array.isArray(value) +} + +/** Checks if a value is a boolean */ +export function isBoolean (value: unknown): value is boolean { + return typeof value === 'boolean' +} + +/** Checks if value is Date */ +export function isDate (value: unknown): value is Date { + return value instanceof Date +} + +/** Checks if a value is an email */ +export function isEmail (value: unknown): value is string { + const pattern = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i + + return isString(value) && pattern.test(value) +} + +/** Creates a predicate that checks if a value is equal to specified */ +export function isExact (exact: T){ + return (value: unknown): value is T => value === exact +} + +/** Checks if value is null */ +export function isNull (value: unknown): value is null { + return value === null +} + +/** Checks if a value is a number */ +export function isNumber (value: unknown): value is number { + return typeof value === 'number' && !isNaN(value) +} + +/** Checks if a value is an object */ +export function isObject (value: unknown): value is object { + return typeof value === 'object' +} + +/** Check if a value is a record like Record */ +export function isRecord (value: unknown): value is Record { + return isObject(value) && !isNull(value) && constructorOf(value) === Object && Object.keys(prototypeOf(value)).length === 0 +} + +/** Checks if a value is a string */ +export function isString (value: unknown): value is string { + return typeof value === 'string' +} + +/** Checks if a value is a symbol */ +export function isSymbol (value: unknown): value is symbol { + return typeof value === 'symbol' +} + +/** Checks if value is undefined */ +export function isUndefined (value: unknown): value is undefined { + return typeof value === 'undefined' +} + +function constructorOf(value: object): unknown { + return prototypeOf(value).constructor +} + +function prototypeOf (value: object) { + return Object.getPrototypeOf(value) +} + +export function And( + ...predicates: [...{ [K in keyof T]: Predicate }] +): Predicate> { + return (value: unknown): value is Intersect => { + return predicates.every(predicate => predicate(value)) + } +} + +export function Or( + ...predicates: [...{ [K in keyof T]: Predicate }] +): Predicate { + return (value: unknown): value is T[number] => { + return predicates.some(predicate => predicate(value)) + } +} + +export function Not (predicate: Predicate): Predicate { + return (value: unknown): value is unknown => { + return !predicate(value) + } +} diff --git a/src/predicates/hasProperty.ts b/src/predicates/hasProperty.ts deleted file mode 100644 index 5acfd07..0000000 --- a/src/predicates/hasProperty.ts +++ /dev/null @@ -1,7 +0,0 @@ -import isNull from './isNull' -import isObject from './isObject' - -/** Checks if a value has a property */ -export default (value: unknown, key: PropertyKey): boolean => { - return isObject(value) && !isNull(value) && Object.prototype.hasOwnProperty.call(value, key) -} diff --git a/src/predicates/isArray.ts b/src/predicates/isArray.ts deleted file mode 100644 index f8d62e6..0000000 --- a/src/predicates/isArray.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if a value is an array */ -export default (value: unknown): value is unknown[] => Array.isArray(value) diff --git a/src/predicates/isEmail.ts b/src/predicates/isEmail.ts deleted file mode 100644 index 163b208..0000000 --- a/src/predicates/isEmail.ts +++ /dev/null @@ -1,6 +0,0 @@ -import isString from '@/predicates/isString' - -const pattern = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i - -/** Checks if a value is an email */ -export default (value: unknown): value is string => isString(value) && pattern.test(value) diff --git a/src/predicates/isNull.ts b/src/predicates/isNull.ts deleted file mode 100644 index 82ac64b..0000000 --- a/src/predicates/isNull.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if value is null */ -export default (value: unknown): value is null => value === null diff --git a/src/predicates/isNumber.ts b/src/predicates/isNumber.ts deleted file mode 100644 index ab4ec2f..0000000 --- a/src/predicates/isNumber.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if a value is a number */ -export default (value: unknown): value is number => typeof value === 'number' && !isNaN(value) diff --git a/src/predicates/isNumeric.ts b/src/predicates/isNumeric.ts deleted file mode 100644 index 07c1853..0000000 --- a/src/predicates/isNumeric.ts +++ /dev/null @@ -1,11 +0,0 @@ -import isNumber from '@/predicates/isNumber' -import isString from '@/predicates/isString' - -/** Checks if a value is a number or a numeric string */ -export default (value: unknown, integer = false): value is number | string => { - const valid = (value: number) => { - return !isNaN(value) && (!integer || Number.isInteger(value)) - } - - return (isNumber(value) || isString(value)) && valid(Number(value)) -} diff --git a/src/predicates/isObject.ts b/src/predicates/isObject.ts deleted file mode 100644 index 685b850..0000000 --- a/src/predicates/isObject.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if a value is an object */ -export default (value: unknown): value is object => typeof value === 'object' diff --git a/src/predicates/isRecord.ts b/src/predicates/isRecord.ts deleted file mode 100644 index 54f32b0..0000000 --- a/src/predicates/isRecord.ts +++ /dev/null @@ -1,12 +0,0 @@ -import isNull from './isNull' -import isObject from './isObject' - -const prototypeOf = (value: object) => Object.getPrototypeOf(value) -const constructorOf = (value: object): unknown => { - return prototypeOf(value).constructor -} - -/** Check if a value is a record like Record */ -export default (value: unknown): value is Record => { - return isObject(value) && !isNull(value) && constructorOf(value) === Object && Object.keys(prototypeOf(value)).length === 0 -} diff --git a/src/predicates/isString.ts b/src/predicates/isString.ts deleted file mode 100644 index fdfebbe..0000000 --- a/src/predicates/isString.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if a value is a string */ -export default (value: unknown): value is string => typeof value === 'string' diff --git a/src/predicates/isUndefined.ts b/src/predicates/isUndefined.ts deleted file mode 100644 index 7d36f33..0000000 --- a/src/predicates/isUndefined.ts +++ /dev/null @@ -1,2 +0,0 @@ -/** Checks if value is undefined */ -export default (value: unknown): value is undefined => value === undefined diff --git a/src/provider.ts b/src/provider.ts deleted file mode 100644 index c22f167..0000000 --- a/src/provider.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type { - Constraint, - ConstraintValidator, - Provider, -} from '../types' - -import Length from '@/constraints/Length' -import LengthValidator from '@/validators/LengthValidator' - -import OneOf from '@/constraints/OneOf' -import OneOfValidator from '@/validators/OneOfValidator' - -export default class ProviderChain implements Provider { - private _current: Provider | null - private _previous: Provider | null - - constructor ( - current: Provider | null = null, - previous: Provider | null = null - ) { - this._current = current - this._previous = previous - } - - get (constraint: Constraint): ConstraintValidator | null { - switch (true) { - case constraint instanceof Length: - return new LengthValidator(constraint) - case constraint instanceof OneOf: - return new OneOfValidator(constraint) - default: - return this._current?.get(constraint) - ?? this._previous?.get(constraint) - ?? null - } - } - - override (provider: Provider): Provider { - return new ProviderChain(provider, this) - } -} \ No newline at end of file diff --git a/src/runners/Each.ts b/src/runners/Each.ts new file mode 100644 index 0000000..567ab77 --- /dev/null +++ b/src/runners/Each.ts @@ -0,0 +1,24 @@ +import type { + Constraint, + MaybeMany, + Validate, + ValidateSync, + Validation, + ValidationRunner, +} from '~types' + +import { isArray } from '@/predicates' + +export default (constraints: MaybeMany) => { + return { + run ( + validate: F, + value: unknown, + path: PropertyKey[] + ): Validation[] { + return isArray(value) + ? value.map((v, i) => validate(v, constraints, [...path, i])) as Validation[] + : [validate(value, constraints, [...path])] as Validation[] + }, + } as ValidationRunner +} \ No newline at end of file diff --git a/src/runners/HasProperties.ts b/src/runners/HasProperties.ts new file mode 100644 index 0000000..2318b3c --- /dev/null +++ b/src/runners/HasProperties.ts @@ -0,0 +1,40 @@ +import { + Constraint, + MaybeMany, + Validate, + ValidateSync, + Validation, + ValidationRunner, +} from '~types' + +import { isRecord } from '@/predicates' + +export type Descriptor = { + [P in keyof T]: MaybeMany +} + +export default (descriptor: Descriptor) => ({ + run ( + validate: F, + value: unknown, + path: PropertyKey[] + ): Validation[] { + if (isRecord(value)) { + const fields = Object.keys(descriptor) as Array> + + return fields.reduce((accumulator, key) => [ + ...accumulator, + validate(value[key], descriptor[key], [...path, key]) as Validation, + ], [] as Validation[]) + } else { + return [ + [{ + value, + path, + violates: '@modulify/validator/HasProperties', + reason: 'unsupported', + }], + ] as Validation[] + } + }, +} as ValidationRunner) diff --git a/src/runners/index.ts b/src/runners/index.ts new file mode 100644 index 0000000..73e99fe --- /dev/null +++ b/src/runners/index.ts @@ -0,0 +1,2 @@ +export { default as Each } from './Each' +export { default as HasProperties } from './HasProperties' diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 5c1b9e7..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Recursive } from '../types' - -export type A = T extends unknown[] ? T : T[] - -export const arraify = (value: T): A => Array.isArray(value) - ? [...value] as A - : [value] as A - -export const flatten = (recursive: Recursive[]): T[] => { - const flattened: T[] = [] - recursive.forEach(element => { - flattened.push(...( - Array.isArray(element) - ? flatten(element) - : [element] - )) - }) - - return flattened -} \ No newline at end of file diff --git a/src/validators/LengthValidator.ts b/src/validators/LengthValidator.ts deleted file mode 100644 index 99d687f..0000000 --- a/src/validators/LengthValidator.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { - ConstraintValidator, - Key, -} from '../../types' - -import type Length from '@/constraints/Length' - -export default class LengthValidator implements ConstraintValidator { - public readonly constraint: Length - - constructor (constraint: Length) { - this.constraint = constraint - } - - validate (value: V, path: Key[] = []) { - const constraint = this.constraint - const { exact, max, min } = constraint - - if (!(typeof value === 'string' || Array.isArray(value))) { - return constraint.toViolation(value, path, 'unsupported') - } - - if (exact !== null && exact !== value.length) { - return constraint.toViolation(value, path, 'exact') - } - - if (max !== null && value.length > max) { - return constraint.toViolation(value, path, 'max') - } - - if (min !== null && value.length < min) { - return constraint.toViolation(value, path, 'min') - } - - return null - } -} \ No newline at end of file diff --git a/src/validators/OneOfValidator.ts b/src/validators/OneOfValidator.ts deleted file mode 100644 index 5c718bc..0000000 --- a/src/validators/OneOfValidator.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { - ConstraintValidator, - Key, -} from '../../types' - -import type OneOf from '@/constraints/OneOf' - -export default class OneOfValidator< - Allowed = unknown, - Actual = unknown -> implements ConstraintValidator { - public readonly constraint: OneOf - - constructor (constraint: OneOf) { - this.constraint = constraint - } - - validate (value: Actual, path: Key[] = []) { - const equalTo = this.constraint.equalTo - - if (!this.constraint.values.some(allowed => equalTo(allowed, value))) { - return this.constraint.toViolation(value, path) - } - - return null - } -} \ No newline at end of file diff --git a/tests/assertions/HasLength.test.ts b/tests/assertions/HasLength.test.ts new file mode 100644 index 0000000..8972783 --- /dev/null +++ b/tests/assertions/HasLength.test.ts @@ -0,0 +1,78 @@ +import { expect, test } from 'vitest' + +import check from '@/assertions/check' + +import { HasLength } from '@/assertions/HasLength' + +test.each([ + // arrays + { options: { exact: 3 }, value: [1, 2, 3] }, + { options: { max: 5 }, value: [] }, + { options: { max: 5 }, value: [1, 2, 3, 4] }, + { options: { max: 5 }, value: [1, 2, 3, 4, 5] }, + { options: { min: 4 }, value: [1, 2, 3, 4] }, + { options: { min: 4 }, value: [1, 2, 3, 4, 5] }, + { options: { max: 5, min: 3 }, value: [1, 2, 3] }, + { options: { max: 5, min: 3 }, value: [1, 2, 3, 4, 5] }, + // strings + { options: { exact: 3 }, value: '123' }, + { options: { exact: 5 }, value: '12345' }, + { options: { max: 5 }, value: '' }, + { options: { max: 5 }, value: '1234' }, + { options: { max: 5 }, value: '12345' }, + { options: { min: 3 }, value: '123' }, + { options: { min: 3 }, value: '1234' }, + { options: { max: 5, min: 3 }, value: '123' }, + { options: { max: 5, min: 3 }, value: '1234' }, + { options: { max: 5, min: 3 }, value: '12345' }, +])('valid #%#', ({ options, value }) => { + expect(HasLength(options)(value)).toBe(true) +}) + +test.each([ + { options: { exact: 3 }, value: '12', reason: 'exact', meta: 3 }, + { options: { exact: 3 }, value: '1234', reason: 'exact', meta: 3 }, + { options: { max: 5 }, value: '123456', reason: 'max', meta: 5 }, + { options: { min: 3 }, value: '12', reason: 'min', meta: 3 }, + { options: { max: 5, min: 3 }, value: '123456', reason: 'max', meta: 5 }, +])('invalid arrays #%#', ({ options, value, reason, meta }) => { + expect(check(HasLength(options), value)).toEqual({ + value, + path: [], + violates: '@modulify/validator/HasLength', + reason, + meta, + }) +}) + +test.each([ + { options: { exact: 3 }, value: '12', reason: 'exact', meta: 3 }, + { options: { exact: 3 }, value: '1234', reason: 'exact', meta: 3 }, + { options: { max: 5 }, value: '123456', reason: 'max', meta: 5 }, + { options: { min: 3 }, value: '12', reason: 'min', meta: 3 }, + { options: { max: 5, min: 3 }, value: '123456', reason: 'max', meta: 5 }, +])('invalid strings #%#', ({ options, value, reason, meta }) => { + expect(check(HasLength(options), value)).toEqual({ + value, + path: [], + violates: '@modulify/validator/HasLength', + reason, + meta, + }) +}) + +test.each([ + { options: { exact: 3 }, value: {}, reason: 'unsupported', meta: undefined }, + { options: { exact: 3 }, value: null, reason: 'unsupported', meta: undefined }, + { options: { max: 5 }, value: undefined, reason: 'unsupported', meta: undefined }, + { options: { min: 3 }, value: new Date(), reason: 'unsupported', meta: undefined }, + { options: { max: 5, min: 3 }, value: new Blob(), reason: 'unsupported', meta: undefined }, +])('unsupported #%#', ({ options, value, reason, meta }) => { + expect(check(HasLength(options), value)).toEqual({ + value, + path: [], + violates: '@modulify/validator/HasLength', + reason, + meta, + }) +}) \ No newline at end of file diff --git a/tests/assertions/OneOf.test.ts b/tests/assertions/OneOf.test.ts new file mode 100644 index 0000000..c4d66d2 --- /dev/null +++ b/tests/assertions/OneOf.test.ts @@ -0,0 +1,73 @@ +import { + expect, + test, +} from 'vitest' + +import { OneOf } from '@/assertions' + +test('array', () => { + const isCorrect = OneOf([1, 2, 3]) + + expect(isCorrect(1)).toBe(true) + expect(isCorrect(2)).toBe(true) + expect(isCorrect(3)).toBe(true) + expect(isCorrect(4)).toBe(false) +}) + +test('enum', () => { + enum Appearance { + Filled = 'filled', + Outline = 'outline', + Tonal = 'tonal' + } + + const isCorrect = OneOf(Appearance) + + expect(isCorrect.meta).toEqual([ + Appearance.Filled, + Appearance.Outline, + Appearance.Tonal, + ]) + + expect(isCorrect('filled')).toBe(true) + expect(isCorrect('outline')).toBe(true) + expect(isCorrect('tonal')).toBe(true) + expect(isCorrect(Appearance.Filled)).toBe(true) + expect(isCorrect(Appearance.Outline)).toBe(true) + expect(isCorrect(Appearance.Tonal)).toBe(true) + expect(isCorrect('')).toBe(false) +}) + +test('equalTo option', () => { + const isCorrect = OneOf([ + { value: 1 }, + { value: 2 }, + { value: 3 }, + ], { equalTo: (a, b) => typeof b === 'object' && 'value' in b && a.value === b.value }) + + expect(isCorrect.meta).toEqual([ + { value: 1 }, + { value: 2 }, + { value: 3 }, + ]) + + expect(isCorrect({ value: 1 })).toBe(true) + expect(isCorrect({ value: 2 })).toBe(true) + expect(isCorrect({ value: 3 })).toBe(true) + expect(isCorrect({ value: 3, label: 'Third' })).toBe(true) + expect(isCorrect({ value: 4 })).toBe(false) + expect(isCorrect(1)).toBe(false) + expect(isCorrect(2)).toBe(false) + expect(isCorrect(3)).toBe(false) +}) + +test.each([ + { accept: ['1', 2, 3], value: 4 }, + { accept: [1, 2, 3], value: 4 }, + { accept: [1, 2, 3, '4'], value: 4 }, +])('invalid#%#', ({ accept, value }) => { + const isCorrect = OneOf(accept) + + expect(isCorrect.meta).toEqual(accept) + expect(isCorrect(value)).toBe(false) +}) \ No newline at end of file diff --git a/tests/index.test.ts b/tests/index.test.ts index bcd9ba3..3a6e5c5 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -1,358 +1,386 @@ -import { - Constraint, - ConstraintValidator, - ConstraintViolation, - Key, - Provider, -} from '../types' - import { describe, expect, test, } from 'vitest' -import Collection from '@/constraints/Collection' -import Each from '@/constraints/Each' -import Exists from '@/constraints/Exists' -import Length from '@/constraints/Length' -import OneOf from '@/constraints/OneOf' +import { + Each, + HasProperties, +} from '@/runners' import { - ProviderChain, - createValidator, -} from '@/index' + HasLength, + IsDefined, + IsString, + OneOf, +} from '@/assertions' -import isEmail from '@/predicates/isEmail' +import { validate } from '@/index' -describe('validates synchronously', () => { - const validator = createValidator() +describe('validate', () => { + describe('HasProperties', () => { + test('checks object\'s structure', async () => { + const constraint = HasProperties({ + form: [ + IsDefined, + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], + }) - describe('Collection', () => { - test('checks object\'s structure', () => { - expect(validator.validate({ + expect(await validate({ + form: { + nickname: 'none', + password: 'qwerty', + }, + }, constraint)).toEqual([]) + + expect(await validate({}, constraint)).toEqual([{ + value: undefined, + path: ['form'], + violates: '@modulify/validator/IsDefined', + reason: 'undefined', + }]) + + expect(await validate({ form: { nickname: '', password: '', }, - }, new Collection({ - form: [ - new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), - }), - ], - }), false)).toEqual([{ - by: '@modulify/validator/Length', + }, constraint)).toEqual([{ value: '', path: ['form', 'nickname'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 4, }, { - by: '@modulify/validator/Length', value: '', path: ['form', 'password'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 6, }]) + + expect(await validate({ + nickname: 'none', + password: 'qwerty', + }, [ + Object.assign(async (value: unknown, path: PropertyKey[] = []) => { + if (IsDefined(value)) return null + + return { value, path, violates: IsDefined.fqn } + }, { + fqn: IsDefined.fqn, + bail: false, + }), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ])).toEqual([]) }) - test('doesn\'t check non-object values', () => { - expect(validator.validate('', new Collection({ - form: new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), + test('doesn\'t check non-object values', async () => { + expect(await validate('', HasProperties({ + form: HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), }), - }), false)).toEqual([{ - by: '@modulify/validator/Collection', + }))).toEqual([{ value: '', path: [], + violates: '@modulify/validator/HasProperties', reason: 'unsupported', }]) }) }) - describe('Collection & Exists', () => { - test('checks object\'s structure', () => { - expect(validator.validate({}, new Collection({ + describe('HasProperties & IsDefined', () => { + test('checks object\'s structure', async () => { + expect(await validate({}, HasProperties({ form: [ - new Exists(), - new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), + IsDefined, + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), }), ], - }), false)).toEqual([{ - by: '@modulify/validator/Exists', + }))).toEqual([{ value: undefined, path: ['form'], + violates: '@modulify/validator/IsDefined', reason: 'undefined', }]) }) }) describe('Each', () => { - test('checks elements in array', () => { - expect(validator.validate([ + test('checks elements in array', async () => { + expect(await validate([ { name: '' }, - { name: 'longEnough' }, - ], new Each([ - new Collection({ - name: new Length({ min: 4, max: 6 }), + { name: 'tooLong' }, + ], Each([ + HasProperties({ + name: IsString.That(HasLength({ min: 4, max: 6 })), }), - ]), false)).toEqual([{ - by: '@modulify/validator/Length', + ]))).toEqual([{ value: '', path: [0, 'name'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 4, }, { - by: '@modulify/validator/Length', - value: 'longEnough', + value: 'tooLong', path: [1, 'name'], + violates: '@modulify/validator/IsString', reason: 'max', meta: 6, }]) }) - test('checks single value', () => { - expect(validator.validate({ name: 'longEnough' }, new Each([ - new Collection({ - name: new Length({ min: 4, max: 6 }), + test('checks single value', async () => { + expect(await validate({ name: 'tooLong' }, Each([ + HasProperties({ + name: IsString.That(HasLength({ min: 4, max: 6 })), }), - ]), false)).toEqual([{ - by: '@modulify/validator/Length', - value: 'longEnough', + ]))).toEqual([{ + value: 'tooLong', path: ['name'], + violates: '@modulify/validator/IsString', reason: 'max', meta: 6, }]) }) }) - test('OneOf', () => { - expect(validator.validate('', new OneOf(['filled', 'outline', 'tonal']), false)).toEqual([{ - by: '@modulify/validator/OneOf', + test('OneOf', async () => { + expect(await validate('', OneOf(['filled', 'outline', 'tonal']))).toEqual([{ value: '', path: [], + violates: '@modulify/validator/OneOf', meta: ['filled', 'outline', 'tonal'], }]) }) + + test('skips the rest constraints if the current one with bail flag fails', async () => { + const _IsDefined = ({ bail }: { bail: boolean }) => { + const fqn = '_IsDefined.bail=' + JSON.stringify(bail) + + return Object.assign(async (value: unknown, path: PropertyKey[] = []) => { + if (IsDefined(value)) return null + + return { value, path, violates: fqn } + }, { fqn, bail }) + } + + expect(await validate({ + form: { + nickname: 'none', + password: 'qwerty', + }, + }, HasProperties({ + form: [ + _IsDefined({ bail: true }), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], + }))).toEqual([]) + + expect(await validate({}, HasProperties({ + form: [ + _IsDefined({ bail: true }), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], + }))).toEqual([{ + value: undefined, + path: ['form'], + violates: '_IsDefined.bail=true', + }]) + + expect(await validate({}, HasProperties({ + form: [ + _IsDefined({ bail: false }), + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], + }))).toEqual([{ + value: undefined, + path: ['form'], + violates: '_IsDefined.bail=false', + }, { + value: undefined, + path: ['form'], + violates: '@modulify/validator/HasProperties', + reason: 'unsupported', + }]) + }) + + test('returns special violation for rejected async validator', async () => { + expect(await validate('', Object.assign(async () => Promise.reject('test rejection'), { + fqn: 'This should not appear in the result', + bail: false, + }))).toEqual([{ + value: '', + path: [], + violates: '@modulify/validator', + reason: 'reject', + meta: 'test rejection', + }]) + }) }) -describe('validates asynchronously', () => { - const validator = createValidator() +describe('validate.sync', () => { + describe('HasProperties', () => { + test('checks object\'s structure', () => { + const constraint = HasProperties({ + form: [ + IsDefined, + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), + }), + ], + }) - describe('Collection', () => { - test('checks object\'s structure', async () => { - expect(await validator.validate({ + expect(validate.sync({ + form: { + nickname: 'none', + password: 'qwerty', + }, + }, constraint)).toEqual([]) + + expect(validate.sync({}, constraint)).toEqual([{ + value: undefined, + path: ['form'], + violates: '@modulify/validator/IsDefined', + reason: 'undefined', + }]) + + expect(validate.sync({ form: { nickname: '', password: '', }, - }, new Collection({ - form: [ - new Exists(), - new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), - }), - ], - }))).toEqual([{ - by: '@modulify/validator/Length', + }, constraint)).toEqual([{ value: '', path: ['form', 'nickname'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 4, }, { - by: '@modulify/validator/Length', value: '', path: ['form', 'password'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 6, }]) }) - test('doesn\'t check non-object values', async () => { - expect(await validator.validate('', new Collection({ - form: new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), + test('doesn\'t check non-object values', () => { + expect(validate.sync('', HasProperties({ + form: HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), }), }))).toEqual([{ - by: '@modulify/validator/Collection', value: '', path: [], + violates: '@modulify/validator/HasProperties', reason: 'unsupported', }]) }) }) - describe('Collection & Exists', () => { - test('checks object\'s structure', async () => { - expect(await validator.validate({}, new Collection({ + describe('HasProperties & IsDefined', () => { + test('checks object\'s structure', () => { + expect(validate.sync({}, HasProperties({ form: [ - new Exists(), - new Collection({ - nickname: new Length({ min: 4 }), - password: new Length({ min: 6 }), + IsDefined, + HasProperties({ + nickname: IsString.That(HasLength({ min: 4 })), + password: IsString.That(HasLength({ min: 6 })), }), ], }))).toEqual([{ - by: '@modulify/validator/Exists', value: undefined, path: ['form'], + violates: '@modulify/validator/IsDefined', reason: 'undefined', }]) }) }) describe('Each', () => { - test('checks elements in array', async () => { - expect(await validator.validate([ + test('checks elements in array', () => { + expect(validate.sync([ { name: '' }, - { name: 'longEnough' }, - ], new Each([ - new Collection({ - name: new Length({ min: 4, max: 6 }), + { name: 'tooLong' }, + ], Each([ + HasProperties({ + name: IsString.That(HasLength({ min: 4, max: 6 })), }), ]))).toEqual([{ - by: '@modulify/validator/Length', value: '', path: [0, 'name'], + violates: '@modulify/validator/IsString', reason: 'min', meta: 4, }, { - by: '@modulify/validator/Length', - value: 'longEnough', + value: 'tooLong', path: [1, 'name'], + violates: '@modulify/validator/IsString', reason: 'max', meta: 6, }]) }) - test('checks single value', async () => { - expect(await validator.validate({ name: 'longEnough' }, new Each([ - new Collection({ - name: new Length({ min: 4, max: 6 }), + test('checks single value', () => { + expect(validate.sync({ name: 'tooLong' }, Each([ + HasProperties({ + name: IsString.That(HasLength({ min: 4, max: 6 })), }), ]))).toEqual([{ - by: '@modulify/validator/Length', - value: 'longEnough', + value: 'tooLong', path: ['name'], + violates: '@modulify/validator/IsString', reason: 'max', meta: 6, }]) }) }) - test('OneOf', async () => { - expect(await validator.validate('', new OneOf(['filled', 'outline', 'tonal']))).toEqual([{ - by: '@modulify/validator/OneOf', + test('OneOf', () => { + expect(validate.sync('', OneOf(['filled', 'outline', 'tonal']))).toEqual([{ value: '', path: [], + violates: '@modulify/validator/OneOf', meta: ['filled', 'outline', 'tonal'], }]) }) -}) - -describe('override', () => { - const validator = createValidator() - class Email implements Constraint { - public readonly name = '@app/validator/Email' - - toViolation (value: unknown, path: Key[]): ConstraintViolation { + test('throws error if found async validator', () => { + const validator = Object.assign(async (value: unknown) => { return { - by: this.name, value, - path, - } - } - } - - class EmailValidator implements ConstraintValidator { - private readonly _constraint: Email - - constructor (constraint: Email) { - this._constraint = constraint - } - - validate (value: unknown, path?: Key[]): ConstraintViolation | null { - if (!isEmail(value)) { - return this._constraint.toViolation(value, path) - } - - return null - } - } - - class AsyncEmailValidator implements ConstraintValidator { - private readonly _constraint: Email - - constructor (constraint: Email) { - this._constraint = constraint - } - - validate (value: unknown, path?: Key[]): Promise { - if (!isEmail(value)) { - return Promise.resolve(this._constraint.toViolation(value, path)) - } - - return Promise.resolve(null) - } - } - - test('fails if some rules are unknown', () => { - expect(() => { - validator.validate('my@test.test', new Email(), false) - }).toThrow('No validator for constraint @app/validator/Email') - }) - - test('uses new rules', () => { - const overridden = validator.override(new class implements Provider { - get (constraint: Constraint) { - return constraint instanceof Email ? new EmailValidator(constraint) : null - } - - override (provider: Provider): Provider { - return new ProviderChain(provider, this) - } - }) - - expect(overridden.validate('my@test.test', new Email(), false)).toEqual([]) - - expect(overridden.validate( - { email: 'not-email' }, - new Collection({ email: new Email() }), - false - )).toEqual([{ - by: '@app/validator/Email', - value: 'not-email', - path: ['email'], - }]) - }) - - test('uses new asynchronous rules', async () => { - const overridden = validator.override(new class implements Provider { - get (constraint: Constraint) { - return constraint instanceof Email ? new AsyncEmailValidator(constraint) : null - } - - override (provider: Provider): Provider { - return new ProviderChain(provider, this) + violates: '__async__', } + }, { + fqn: '__async__', + bail: false, }) - expect(await overridden.validate('my@test.test', new Email())).toEqual([]) - - expect(await overridden.validate( - { email: 'not-email' }, - new Collection({ email: new Email() }) - )).toEqual([{ - by: '@app/validator/Email', - value: 'not-email', - path: ['email'], - }]) + expect(() => { + validate.sync('', validator) + }).toThrowError('Found asynchronous constraint validator __async__') }) -}) \ No newline at end of file +}) diff --git a/tests/predicates.test.ts b/tests/predicates.test.ts new file mode 100644 index 0000000..53b3f7b --- /dev/null +++ b/tests/predicates.test.ts @@ -0,0 +1,320 @@ +import { describe, expect, test } from 'vitest' + +import { + hasProperty, + isArray, + isBoolean, + isDate, + isEmail, + isExact, + isNull, + isNumber, + isObject, + isRecord, + isString, + isSymbol, + isUndefined, + And, + Or, + Not, +} from '@/predicates' + +describe('hasProperty', () => { + const property = Symbol('property') + + test('returns true when property exists', () => { + expect(hasProperty('a')({ a: 1 })).toBe(true) + expect(hasProperty(0)({ 0: 1 })).toBe(true) + expect(hasProperty(property)({ [property]: 1 })).toBe(true) + expect(hasProperty('length')([])).toBe(true) + }) + + test('returns false when property does not exist', () => { + expect(hasProperty('a')({})).toBe(false) + expect(hasProperty(0)({})).toBe(false) + expect(hasProperty(property)({})).toBe(false) + expect(hasProperty(property)(null)).toBe(false) + expect(hasProperty('does_not_exists')([])).toBe(false) + }) +}) + +describe('isArray', () => { + test('returns true when a value is an array', () => { + expect(isArray([])).toBe(true) + expect(isArray([1, 2, 3])).toBe(true) + expect(isArray(['a', 'b', 'c'])).toBe(true) + expect(isArray([null, undefined, 3])).toBe(true) + }) + + test('returns false when a value is not an array', () => { + expect(isArray({})).toBe(false) + expect(isArray(1)).toBe(false) + expect(isArray('string')).toBe(false) + expect(isArray(null)).toBe(false) + expect(isArray(undefined)).toBe(false) + expect(isArray(Symbol('array'))).toBe(false) + }) +}) + +describe('isBoolean', () => { + test('returns true when a value\'s type is a boolean', () => { + expect(isBoolean(true)).toBe(true) + expect(isBoolean(false)).toBe(true) + }) + + test('returns false when a value\'s type is not a boolean', () => { + expect(isBoolean({})).toBe(false) + expect(isBoolean(1)).toBe(false) + expect(isBoolean('true')).toBe(false) + expect(isBoolean(null)).toBe(false) + expect(isBoolean(undefined)).toBe(false) + expect(isBoolean(Symbol('boolean'))).toBe(false) + }) +}) + +describe('isDate', () => { + test('returns true when a value is a valid Date object', () => { + expect(isDate(new Date())).toBe(true) + expect(isDate(new Date('2023-01-01'))).toBe(true) + }) + + test('returns false when a value is not a valid Date object', () => { + expect(isDate({})).toBe(false) + expect(isDate(12345)).toBe(false) + expect(isDate('2023-01-01')).toBe(false) + expect(isDate(null)).toBe(false) + expect(isDate(undefined)).toBe(false) + expect(isDate(Symbol('date'))).toBe(false) + }) +}) + +describe('isEmail', () => { + test('returns true when a value is email', () => { + expect(isEmail('my@test.test')).toBe(true) + expect(isEmail('user@example.com')).toBe(true) + expect(isEmail('test123@domain.co')).toBe(true) + expect(isEmail('name.surname@sub.domain.org')).toBe(true) + expect(isEmail('email+alias@domain.com')).toBe(true) + }) + + test('returns false when a value is not email', () => { + expect(isEmail({})).toBe(false) + expect(isEmail(2)).toBe(false) + expect(isEmail(Symbol('2'))).toBe(false) + expect(isEmail('not-email')).toBe(false) + }) +}) + +describe('isExact', () => { + test('returns true when a value is equal exactly to the specified one', () => { + expect(isExact(1)(1)).toBe(true) + expect(isExact('string')('string')).toBe(true) + expect(isExact(true)(true)).toBe(true) + expect(isExact(null)(null)).toBe(true) + expect(isExact(undefined)(undefined)).toBe(true) + + const s1 = Symbol('s1') + + expect(isExact(s1)(s1)).toBe(true) + expect(isExact(Symbol.for('s2'))(Symbol.for('s2'))).toBe(true) + }) + + test('returns false when a value is not equal exactly to the specified one', () => { + expect(isExact(1)(2)).toBe(false) + expect(isExact('string')('different')).toBe(false) + expect(isExact(true)(false)).toBe(false) + expect(isExact(null)(undefined)).toBe(false) + expect(isExact(undefined)(null)).toBe(false) + expect(isExact(Symbol('s1'))(Symbol('s1'))).toBe(false) + }) +}) + +describe('isNull', () => { + test('returns true when a value is equal to null', () => { + expect(isNull(null)).toBe(true) + }) + + test('returns false when a value is not equal to null', () => { + expect(isNull({})).toBe(false) + expect(isNull(2)).toBe(false) + expect(isNull(Symbol('2'))).toBe(false) + }) +}) + +describe('isNumber', () => { + test('returns true when a value\'s type is a number', () => { + expect(isNumber(1)).toBe(true) + expect(isNumber(1.5)).toBe(true) + }) + + test('returns false when a value\'s type is not a number', () => { + expect(isNumber({})).toBe(false) + expect(isNumber('1')).toBe(false) + expect(isNumber('1.5')).toBe(false) + }) +}) + +describe('isObject', () => { + test('returns true when a value is an object', () => { + expect(isObject(null)).toBe(true) + expect(isObject({})).toBe(true) + expect(isObject({ a: 1 })).toBe(true) + expect(isObject(Object.create(null))).toBe(true) + expect(isObject([])).toBe(true) + + class A {} + + expect(isObject(new A())).toBe(true) + }) + + test('returns false when a value is not an object', () => { + expect(isObject(undefined)).toBe(false) + expect(isObject(1)).toBe(false) + expect(isObject('string')).toBe(false) + expect(isObject(true)).toBe(false) + expect(isObject(Symbol('key'))).toBe(false) + }) +}) + +describe('isRecord', () => { + const a = Symbol('property') + const b = Symbol('property') + + test('returns true when a value is a Record<*, *>', () => { + expect(isRecord({})).toBe(true) + expect(isRecord({ 'a': 1, 'b': 2 })).toBe(true) + expect(isRecord({ [a]: 1, [b]: 2 })).toBe(true) + }) + + test('returns false when a value is not a Record<*, *>', () => { + expect(isRecord(1)).toBe(false) + expect(isRecord('1')).toBe(false) + expect(isRecord(null)).toBe(false) + + class A {} + + expect(isRecord(new A())).toBe(false) + }) +}) + +describe('isString', () => { + test('returns true when a value\'s type is a string', () => { + expect(isString('1')).toBe(true) + expect(isString('1.5')).toBe(true) + expect(isString('Some text')).toBe(true) + }) + + test('returns false when a value\'s type is not a string', () => { + expect(isString({})).toBe(false) + expect(isString(1)).toBe(false) + expect(isString(1.5)).toBe(false) + expect(isString(true)).toBe(false) + expect(isString(false)).toBe(false) + }) +}) + +describe('isSymbol', () => { + test('returns true when a value is a symbol', () => { + expect(isSymbol(Symbol('key'))).toBe(true) + expect(isSymbol(Symbol.for('key'))).toBe(true) + }) + + test('returns false when a value is not a symbol', () => { + expect(isSymbol({})).toBe(false) + expect(isSymbol(123)).toBe(false) + expect(isSymbol('string')).toBe(false) + expect(isSymbol(true)).toBe(false) + expect(isSymbol(null)).toBe(false) + expect(isSymbol(undefined)).toBe(false) + }) +}) + +describe('isUndefined', () => { + test('returns true when a value is equal to undefined', () => { + expect(isUndefined(undefined)).toBe(true) + }) + + test('returns false when a value is not equal to undefined', () => { + expect(isUndefined({})).toBe(false) + expect(isUndefined(2)).toBe(false) + expect(isUndefined(Symbol('2'))).toBe(false) + }) +}) + +describe('And', () => { + test('returns true when a value satisfies all of the predicates', () => { + expect(And(isNumber, (value: number): value is number => isFinite(value))(1)).toBe(true) + expect(And( + isString, + (value: string): value is string => value.length > 3, + (value: string): value is string => value.length < 10 + )('NickName')).toBe(true) + }) + + test('returns false when a value does not satisfy at least one of the predicates', () => { + expect(And(isNumber, (value: number): value is number => value > 10)(5)).toBe(false) + expect(And(isString, (value: string): value is string => value.length > 0)('')).toBe(false) + }) +}) + +describe('Or', () => { + test('returns true when a value satisfies to any of the predicates', () => { + expect(Or(isArray, isNumber)(1)).toBe(true) + expect(Or(isArray, isNumber)([])).toBe(true) + expect(Or(isArray, isNumber)([1, 2])).toBe(true) + expect(Or(isArray, isString)([])).toBe(true) + expect(Or(isArray, isString)([1, 2])).toBe(true) + expect(Or(isArray, isString)('')).toBe(true) + expect(Or(isArray, isString)('String')).toBe(true) + + expect(Or(isNumber, isString)(1)).toBe(true) + + expect(Or(isArray, isNumber, isString)(1)).toBe(true) + expect(Or(isArray, isNumber, isString)('1')).toBe(true) + expect(Or(isArray, isNumber, isString)('String')).toBe(true) + }) + + test('returns false when a value does not satisfy to all the predicates', () => { + expect(Or(isArray, isNumber)({})).toBe(false) + expect(Or(isArray, isNumber)(null)).toBe(false) + expect(Or(isArray, isNumber)('String')).toBe(false) + expect(Or(isArray, isString)({})).toBe(false) + expect(Or(isArray, isString)(null)).toBe(false) + expect(Or(isArray, isString)(1)).toBe(false) + expect(Or(isArray, isString)(Symbol('Symbol'))).toBe(false) + + expect(Or(isNumber, isString)([])).toBe(false) + expect(Or(isNumber, isString)(null)).toBe(false) + expect(Or(isNumber, isString)({})).toBe(false) + + expect(Or(isArray, isNumber, isString)({})).toBe(false) + expect(Or(isArray, isNumber, isString)(null)).toBe(false) + expect(Or(isArray, isNumber, isString)(Symbol('Symbol'))).toBe(false) + }) +}) + +describe('Not', () => { + test('returns true when a value does not satisfy the predicate', () => { + expect(Not(isArray)({})).toBe(true) + expect(Not(isArray)(2)).toBe(true) + expect(Not(isArray)('2')).toBe(true) + expect(Not(isNull)(undefined)).toBe(true) + expect(Not(isNull)(2)).toBe(true) + expect(Not(isNumber)('string')).toBe(true) + expect(Not(isNumber)(null)).toBe(true) + expect(Not(isObject)('abc')).toBe(true) + expect(Not(isString)(123)).toBe(true) + expect(Not(isSymbol)(123)).toBe(true) + expect(Not(isUndefined)(null)).toBe(true) + }) + + test('returns false when a value satisfies the predicate', () => { + expect(Not(isArray)([])).toBe(false) + expect(Not(isNull)(null)).toBe(false) + expect(Not(isNumber)(123)).toBe(false) + expect(Not(isObject)({})).toBe(false) + expect(Not(isString)('string')).toBe(false) + expect(Not(isSymbol)(Symbol('key'))).toBe(false) + expect(Not(isUndefined)(undefined)).toBe(false) + }) +}) diff --git a/tests/predicates/hasProperty.test.ts b/tests/predicates/hasProperty.test.ts deleted file mode 100644 index 98f4339..0000000 --- a/tests/predicates/hasProperty.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import hasProperty from '@/predicates/hasProperty' - -const property = Symbol('property') - -describe('predicates/hasProperty', () => { - test('returns true when property exists', () => { - expect(hasProperty({ a: 1 }, 'a')).toBe(true) - expect(hasProperty({ 0: 1 }, 0)).toBe(true) - expect(hasProperty({ [property]: 1 }, property)).toBe(true) - expect(hasProperty([], 'length')).toBe(true) - }) - - test('returns false when property does not exist', () => { - expect(hasProperty({}, 'a')).toBe(false) - expect(hasProperty({}, 0)).toBe(false) - expect(hasProperty({}, property)).toBe(false) - expect(hasProperty(null, property)).toBe(false) - expect(hasProperty([], 'does_not_exists')).toBe(false) - }) -}) diff --git a/tests/predicates/isNull.test.ts b/tests/predicates/isNull.test.ts deleted file mode 100644 index 83a3e04..0000000 --- a/tests/predicates/isNull.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import isNull from '@/predicates/isNull' - -describe('predicates/isNull', () => { - test('returns true when a value is equal to undefined', () => { - expect(isNull(null)).toBe(true) - }) - - test('returns false when a value is not equal to undefined', () => { - expect(isNull({})).toBe(false) - expect(isNull(2)).toBe(false) - expect(isNull(Symbol('2'))).toBe(false) - }) -}) diff --git a/tests/predicates/isNumber.test.ts b/tests/predicates/isNumber.test.ts deleted file mode 100644 index af56e5a..0000000 --- a/tests/predicates/isNumber.test.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import isNumber from '@/predicates/isNumber' - -describe('predicates/isNumber', () => { - test('returns true when a value\'s type is a number', () => { - expect(isNumber(1)).toBe(true) - expect(isNumber(1.5)).toBe(true) - }) - - test('returns false when a value\'s type is not a number', () => { - expect(isNumber({})).toBe(false) - expect(isNumber('1')).toBe(false) - expect(isNumber('1.5')).toBe(false) - }) -}) diff --git a/tests/predicates/isNumeric.test.ts b/tests/predicates/isNumeric.test.ts deleted file mode 100644 index 260e9be..0000000 --- a/tests/predicates/isNumeric.test.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import isNumeric from '@/predicates/isNumeric' - -describe('predicates/isNumeric', () => { - test('returns true when a value is a number or a numeric string', () => { - expect(isNumeric(1)).toBe(true) - expect(isNumeric(1.5)).toBe(true) - expect(isNumeric('1')).toBe(true) - expect(isNumeric('1.5')).toBe(true) - }) - - test('returns false when a value is not a number or a numeric string', () => { - expect(isNumeric({})).toBe(false) - expect(isNumeric('a1')).toBe(false) - expect(isNumeric('1.3y5')).toBe(false) - expect(isNumeric('1.3y5', true)).toBe(false) - expect(isNumeric(null)).toBe(false) - expect(isNumeric(undefined)).toBe(false) - expect(isNumeric(Symbol('2'))).toBe(false) - }) - - test('returns false when a value is a number or a numeric string, but not integer when flag is set to true', () => { - expect(isNumeric(1.5, true)).toBe(false) - expect(isNumeric('1.5', true)).toBe(false) - }) -}) diff --git a/tests/predicates/isUndefined.test.ts b/tests/predicates/isUndefined.test.ts deleted file mode 100644 index 20a2839..0000000 --- a/tests/predicates/isUndefined.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import isUndefined from '@/predicates/isUndefined' - -describe('predicates/isUndefined', () => { - test('returns true when a value is equal to undefined', () => { - expect(isUndefined(undefined)).toBe(true) - }) - - test('returns false when a value is not equal to undefined', () => { - expect(isUndefined({})).toBe(false) - expect(isUndefined(2)).toBe(false) - expect(isUndefined(Symbol('2'))).toBe(false) - }) -}) diff --git a/tests/validators/LengthValidator.test.ts b/tests/validators/LengthValidator.test.ts deleted file mode 100644 index a3ddf00..0000000 --- a/tests/validators/LengthValidator.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import Length from '@/constraints/Length' -import LengthValidator from '@/validators/LengthValidator' - -describe('LengthValidator', () => { - test.each([ - // arrays - { options: { exact: 3 }, value: [1, 2, 3] }, - { options: { max: 5 }, value: [] }, - { options: { max: 5 }, value: [1, 2, 3, 4] }, - { options: { max: 5 }, value: [1, 2, 3, 4, 5] }, - { options: { min: 4 }, value: [1, 2, 3, 4] }, - { options: { min: 4 }, value: [1, 2, 3, 4, 5] }, - { options: { max: 5, min: 3 }, value: [1, 2, 3] }, - { options: { max: 5, min: 3 }, value: [1, 2, 3, 4, 5] }, - // strings - { options: { exact: 3 }, value: '123' }, - { options: { exact: 5 }, value: '12345' }, - { options: { max: 5 }, value: '' }, - { options: { max: 5 }, value: '1234' }, - { options: { max: 5 }, value: '12345' }, - { options: { min: 3 }, value: '123' }, - { options: { min: 3 }, value: '1234' }, - { options: { max: 5, min: 3 }, value: '123' }, - { options: { max: 5, min: 3 }, value: '1234' }, - { options: { max: 5, min: 3 }, value: '12345' }, - ])('valid#%#', ({ options, value }) => { - const validator = new LengthValidator(new Length(options)) - - expect(validator.validate(value)).toBeNull() - }) - - test.each([ - // arrays - { options: { exact: 3 }, value: [1, 2], reason: 'exact', meta: 3 }, - { options: { exact: 3 }, value: [1, 2, 3, 4], reason: 'exact', meta: 3 }, - { options: { max: 5 }, value: [1, 2, 3, 4, 5, 6], reason: 'max', meta: 5 }, - { options: { min: 3 }, value: [1, 2], reason: 'min', meta: 3 }, - { options: { max: 5, min: 3 }, value: [1, 2, 3, 4, 5, 6], reason: 'max', meta: 5 }, - { options: { exact: 3, max: 5, min: 3 }, value: [1, 2, 3, 4, 5, 6], reason: 'exact', meta: 3 }, - { options: { exact: 3, max: 5, min: 4 }, value: [1, 2, 3], reason: 'min', meta: 4 }, - // strings - { options: { exact: 3 }, value: '12', reason: 'exact', meta: 3 }, - { options: { exact: 3 }, value: '1234', reason: 'exact', meta: 3 }, - { options: { max: 5 }, value: '123456', reason: 'max', meta: 5 }, - { options: { min: 3 }, value: '12', reason: 'min', meta: 3 }, - { options: { max: 5, min: 3 }, value: '123456', reason: 'max', meta: 5 }, - // unsupported - { options: { exact: 3 }, value: {}, reason: 'unsupported', meta: undefined }, - { options: { exact: 3 }, value: null, reason: 'unsupported', meta: undefined }, - { options: { max: 5 }, value: undefined, reason: 'unsupported', meta: undefined }, - { options: { min: 3 }, value: new Date(), reason: 'unsupported', meta: undefined }, - { options: { max: 5, min: 3 }, value: new Blob(), reason: 'unsupported', meta: undefined }, - ])('invalid#%#', ({ options, value, reason, meta }) => { - const validator = new LengthValidator(new Length(options)) - - expect(validator.validate(value)).toEqual({ - by: '@modulify/validator/Length', - value, - path: [], - reason, - meta, - }) - }) -}) \ No newline at end of file diff --git a/tests/validators/OneOfValidator.test.ts b/tests/validators/OneOfValidator.test.ts deleted file mode 100644 index 02e0851..0000000 --- a/tests/validators/OneOfValidator.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - describe, - expect, - test, -} from 'vitest' - -import OneOf from '@/constraints/OneOf' -import OneOfValidator from '@/validators/OneOfValidator' - -describe('OneOfValidator', () => { - test('valid', () => { - const validator = new OneOfValidator(new OneOf([ - 1, 2, 3, - ])) - - expect(validator.validate(1)).toBeNull() - }) - - test('enum', () => { - enum Appearance { - Filled = 'filled', - Outline = 'outline', - Tonal = 'tonal' - } - - const validator = new OneOfValidator(new OneOf(Appearance)) - - expect(validator.validate('')).toEqual({ - by: '@modulify/validator/OneOf', - value: '', - path: [], - meta: ['filled', 'outline', 'tonal'], - }) - }) - - test.each([ - { accept: ['1', 2, 3], value: 4 }, - { accept: [1, 2, 3], value: 4 }, - { accept: [1, 2, 3, '4'], value: 4 }, - ])('invalid#%#', ({ accept, value }) => { - const validator = new OneOfValidator(new OneOf(accept)) - - expect(validator.validate(value)).toEqual({ - by: '@modulify/validator/OneOf', - value, - path: [], - meta: accept, - }) - }) -}) \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 4433d49..7e807b7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,15 @@ { "compilerOptions": { "esModuleInterop": true, - "module": "esnext", - "moduleResolution": "node", + "module": "ESNext", + "moduleResolution": "Node", "paths": { - "@/*": ["./src/*"] + "@/*": ["./src/*"], + "~types": ["./types/index.d.ts"], + "~types/*": ["./types"] }, - "target": "es6" + "resolveJsonModule": true, + "target": "ES2017" }, "include": [ "src/**/*.ts", diff --git a/types/index.d.ts b/types/index.d.ts index 536f692..3b6f951 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,130 +1,65 @@ -export type Key = PropertyKey -export type Recursive = T | Recursive[] - -export interface ConstraintViolation { - by: string | symbol; - value: Value; - /** Path to a property, if a constraint is used as part of a `Collection` for checking some object's structure */ - path?: PropertyKey[]; - reason?: string | symbol; - meta?: Meta; -} - -export interface Constraint { - name: string; - toViolation (value: Value, path: PropertyKey[], reason?: string): ConstraintViolation -} - -export type ConstraintCollection = { - [P in keyof T]: Constraint | Constraint[] -} - -/** - * Works only with a specific constraint - */ -export interface ConstraintValidator { - validate (value: Value, path?: PropertyKey[]): ConstraintViolation | null | Promise | null>; -} - -/** - * Used by Validator|FunctionalValidator to determine, how a specific constraint should be validated. - */ -export interface Provider { - get (constraint: Constraint): ConstraintValidator | null; - override (provider: Provider): Provider; -} +export type Intersect = + T extends [infer First, ...infer Rest extends unknown[]] + ? First & Intersect + : unknown; -type MaybePromise< - Value, - Asynchronously extends boolean = true -> = Asynchronously extends true ? Promise : Value - -export type FunctionalValidator = ( - provider: Provider, - value: Value, - constraints: Constraint | Constraint[], - path?: PropertyKey[], - asynchronously?: Asynchronously -) => MaybePromise - -export interface Validator { - override (provider: Provider): Validator; - - validate( - value: Value, - constraints: Constraint | Constraint[], - asynchronously?: Asynchronously - ): MaybePromise -} - -export declare class Collection> implements Constraint { - public readonly name = '@modulify/validator/Collection' - public readonly constraints: ConstraintCollection +export type Recursive = T | Recursive[] - constructor (constraints: ConstraintCollection); +export type MaybeMany = V | V[] +export type MaybePromise = V | Promise - toViolation (value: T, path: PropertyKey[], reason: string): ConstraintViolation; +export type Predicate = (value: unknown) => value is T +export type Meta = { + fqn: string | symbol, + bail: boolean; + reason?: string | symbol; + meta?: T; } -/** - * If the value should be defined. Interrupts validation of a value, if it produces a violation - */ -export declare class Exists implements Constraint { - public readonly name = '@modulify/validator/Exists' - - toViolation (value: unknown, path: PropertyKey[]): ConstraintViolation; +export type Assertion = Predicate & Meta & { + readonly also: Assertion[] + That(...asserts: Assertion[]): Assertion; } -export declare class Length implements Constraint { - public readonly name = '@modulify/validator/Length' - - public readonly exact: number | null - public readonly max: number | null - public readonly min: number | null - - constructor (options: { - exact?: number - max?: number - min?: number - }); - - toViolation ( - value: Value, - path: PropertyKey[], - reason: 'exact' | 'max' | 'min' | 'unsupported' - ): ConstraintViolation; +export type Violation = { + value: unknown; + /** Path to a property, if a constraint is used as part of a `Collection` for checking some object's structure */ + path?: PropertyKey[]; + violates: string | symbol; + reason?: string | symbol; + meta?: M; } -type EqualPredicate = (a: Expected, b: unknown) => boolean - -export declare class OneOf implements Constraint { - public readonly name = '@modulify/validator/OneOf' - public readonly values: Expected[] - public readonly equalTo: EqualPredicate - - /** - * @param values Array of allowed values - * @param equalTo Defaults to strict comparison via `===` - */ - constructor ( - values: Expected[] | Record, - equalTo?: EqualPredicate - ); - - toViolation (value: Actual, path: PropertyKey[]): ConstraintViolation; +export type Validator = (( + value: unknown, + path?: PropertyKey[] +) => MaybePromise | null>) & { + fqn: string; + bail: boolean; } -export declare class ProviderChain implements Provider { - constructor ( - current?: Provider | null, - previous?: Provider | null - ); - - get (constraint: Constraint): ConstraintValidator | null; - - override (provider: Provider): Provider; +export type Constraint = Assertion | Validator | ValidationRunner + +export type Validate = ( + value: T, + constraints: MaybeMany, + path?: PropertyKey[] +) => Promise + +export type ValidateSync = ( + value: T, + constraints: MaybeMany, + path?: PropertyKey[] +) => Violation[] + +export type Validation = Validate extends F + ? MaybePromise + : Violation[] + +export interface ValidationRunner { + run ( + validate: F, + value: unknown, + path: PropertyKey[] + ): Validation[]; } - -export declare const createValidator: (provider?: Provider | null) => Validator - -export declare const validate: FunctionalValidator \ No newline at end of file diff --git a/vite.config.basic.ts b/vite.config.basic.ts new file mode 100644 index 0000000..978c0c2 --- /dev/null +++ b/vite.config.basic.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite' +import { resolve } from 'node:path' + +export default defineConfig({ + plugins: [], + + resolve: { + alias: { + '@': resolve(__dirname, './src'), + '~types': resolve(__dirname, './types/'), + }, + }, +}) \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..5433550 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,52 @@ +import { + defineConfig, + mergeConfig, +} from 'vite' + +import dts from 'vite-plugin-dts' + +import { + join, + resolve, +} from 'node:path' + +import { name } from './package.json' + +import basic from './vite.config.basic' + +export default mergeConfig(basic, defineConfig({ + build: { + lib: { + name, + formats: ['es', 'cjs'], + entry: { + 'index': resolve(__dirname, './src/index.ts'), + 'assertions': resolve(__dirname, './src/assertions/index.ts'), + 'predicates': resolve(__dirname, './src/predicates.ts'), + 'runners': resolve(__dirname, './src/runners/index.ts'), + }, + fileName: (format, name) => `${name}.${{ + cjs: 'cjs', + es: 'mjs', + }[format as 'es' | 'cjs']}`, + }, + minify: false, + rollupOptions: { + output: { + exports: 'named', + dir: join(__dirname, '/dist'), + chunkFileNames: '[name].[format].js', + }, + }, + }, + + plugins: [dts({ + entryRoot: './src', + exclude: [ + 'scripts/**/*.*', + 'tests/**/*.*', + ], + insertTypesEntry: true, + staticImport: true, + })], +})) diff --git a/vitest.config.mts b/vitest.config.mts deleted file mode 100644 index 5b806e7..0000000 --- a/vitest.config.mts +++ /dev/null @@ -1,17 +0,0 @@ -import * as path from 'node:path' - -import { defineConfig } from 'vitest/config' - -export default defineConfig({ - resolve: { - alias: { - '@': path.join(__dirname, './src/'), - }, - }, - test: { - coverage: { - provider: 'istanbul', - include: ['src/**'], - }, - }, -}) diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..2fccb9d --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,15 @@ +import { + defineConfig, + mergeConfig, +} from 'vitest/config' + +import basic from './vite.config.basic' + +export default mergeConfig(basic, defineConfig({ + test: { + coverage: { + provider: 'istanbul', + include: ['src/**'], + }, + }, +})) diff --git a/yarn.lock b/yarn.lock index 9175f7c..2098690 100644 --- a/yarn.lock +++ b/yarn.lock @@ -479,29 +479,36 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.11.0": +"@eslint-community/regexpp@^4.10.0": version "4.11.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== -"@eslint/config-array@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.18.0.tgz#37d8fe656e0d5e3dbaea7758ea56540867fd074d" - integrity sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw== +"@eslint-community/regexpp@^4.12.1": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + +"@eslint/config-array@^0.19.0": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.1.tgz#734aaea2c40be22bbb1f2a9dac687c57a6a4c984" + integrity sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA== dependencies: - "@eslint/object-schema" "^2.1.4" + "@eslint/object-schema" "^2.1.5" debug "^4.3.1" minimatch "^3.1.2" -"@eslint/core@^0.7.0": - version "0.7.0" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.7.0.tgz#a1bb4b6a4e742a5ff1894b7ee76fbf884ec72bd3" - integrity sha512-xp5Jirz5DyPYlPiKat8jaq0EmYvDXKKpzTbxXMpT9eqlRJkRKIz9AGMdlvYjih+im+QlhWrpvVjl8IPC/lHlUw== +"@eslint/core@^0.9.0": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.9.1.tgz#31763847308ef6b7084a4505573ac9402c51f9d1" + integrity sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q== + dependencies: + "@types/json-schema" "^7.0.15" -"@eslint/eslintrc@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.1.0.tgz#dbd3482bfd91efa663cbe7aa1f506839868207b6" - integrity sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ== +"@eslint/eslintrc@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c" + integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -513,34 +520,34 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.13.0", "@eslint/js@^9.13.0": - version "9.13.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.13.0.tgz#c5f89bcd57eb54d5d4fa8b77693e9c28dc97e547" - integrity sha512-IFLyoY4d72Z5y/6o/BazFBezupzI/taV8sGumxTAVw3lXG9A6md1Dc34T9s1FoD/an9pJH8RHbAxsaEbBed9lA== +"@eslint/js@9.17.0", "@eslint/js@^9.17.0": + version "9.17.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.17.0.tgz#1523e586791f80376a6f8398a3964455ecc651ec" + integrity sha512-Sxc4hqcs1kTu0iID3kcZDW3JHq2a77HO9P8CP6YEA/FpH3Ll8UXE2r/86Rz9YJLKme39S9vU5OWNjC6Xl0Cr3w== -"@eslint/object-schema@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843" - integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ== +"@eslint/object-schema@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.5.tgz#8670a8f6258a2be5b2c620ff314a1d984c23eb2e" + integrity sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ== -"@eslint/plugin-kit@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.1.tgz#cd14fe2db79fa639839dfef4105e83bad1814482" - integrity sha512-HFZ4Mp26nbWk9d/BpvP0YNL6W4UoZF0VFcTw/aPPA8RpOxeFQgK+ClABGgAUXs9Y/RGX/l1vOmrqz1MQt9MNuw== +"@eslint/plugin-kit@^0.2.3": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.4.tgz#2b78e7bb3755784bb13faa8932a1d994d6537792" + integrity sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg== dependencies: levn "^0.4.1" -"@humanfs/core@^0.19.0": - version "0.19.0" - resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.0.tgz#08db7a8c73bb07673d9ebd925f2dad746411fcec" - integrity sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw== +"@humanfs/core@^0.19.1": + version "0.19.1" + resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77" + integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA== -"@humanfs/node@^0.16.5": - version "0.16.5" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.5.tgz#a9febb7e7ad2aff65890fdc630938f8d20aa84ba" - integrity sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg== +"@humanfs/node@^0.16.6": + version "0.16.6" + resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e" + integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw== dependencies: - "@humanfs/core" "^0.19.0" + "@humanfs/core" "^0.19.1" "@humanwhocodes/retry" "^0.3.0" "@humanwhocodes/module-importer@^1.0.1": @@ -548,11 +555,16 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/retry@^0.3.0", "@humanwhocodes/retry@^0.3.1": +"@humanwhocodes/retry@^0.3.0": version "0.3.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a" integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA== +"@humanwhocodes/retry@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b" + integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA== + "@hutson/parse-repository-url@^3.0.0": version "3.0.2" resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" @@ -625,27 +637,27 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@microsoft/api-extractor-model@7.29.6": - version "7.29.6" - resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.29.6.tgz#e5941514502049b06ca9af21e2096f8f1ad5a01b" - integrity sha512-gC0KGtrZvxzf/Rt9oMYD2dHvtN/1KPEYsrQPyMKhLHnlVuO/f4AFN3E4toqZzD2pt4LhkKoYmL2H9tX3yCOyRw== +"@microsoft/api-extractor-model@7.30.1": + version "7.30.1" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor-model/-/api-extractor-model-7.30.1.tgz#719e2ab8afe8fe3a5dd65aaa8783dbba90f7c802" + integrity sha512-CTS2PlASJHxVY8hqHORVb1HdECWOEMcMnM6/kDkPr0RZapAFSIHhg9D4jxuE8g+OWYHtPc10LCpmde5pylTRlA== dependencies: - "@microsoft/tsdoc" "~0.15.0" - "@microsoft/tsdoc-config" "~0.17.0" - "@rushstack/node-core-library" "5.7.0" + "@microsoft/tsdoc" "~0.15.1" + "@microsoft/tsdoc-config" "~0.17.1" + "@rushstack/node-core-library" "5.10.1" -"@microsoft/api-extractor@7.47.7": - version "7.47.7" - resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.47.7.tgz#3bc4450fe46c265bef857ab938aa15b9fc7a85de" - integrity sha512-fNiD3G55ZJGhPOBPMKD/enozj8yxJSYyVJWxRWdcUtw842rvthDHJgUWq9gXQTensFlMHv2wGuCjjivPv53j0A== +"@microsoft/api-extractor@^7.48.1": + version "7.48.1" + resolved "https://registry.yarnpkg.com/@microsoft/api-extractor/-/api-extractor-7.48.1.tgz#792197cfc5113cd2efc04524c065d682ef58d2ba" + integrity sha512-HN9Osa1WxqLM66RaqB5nPAadx+nTIQmY/XtkFdaJvusjG8Tus++QqZtD7KPZDSkhEMGHsYeSyeU8qUzCDUXPjg== dependencies: - "@microsoft/api-extractor-model" "7.29.6" - "@microsoft/tsdoc" "~0.15.0" - "@microsoft/tsdoc-config" "~0.17.0" - "@rushstack/node-core-library" "5.7.0" + "@microsoft/api-extractor-model" "7.30.1" + "@microsoft/tsdoc" "~0.15.1" + "@microsoft/tsdoc-config" "~0.17.1" + "@rushstack/node-core-library" "5.10.1" "@rushstack/rig-package" "0.5.3" - "@rushstack/terminal" "0.14.0" - "@rushstack/ts-command-line" "4.22.6" + "@rushstack/terminal" "0.14.4" + "@rushstack/ts-command-line" "4.23.2" lodash "~4.17.15" minimatch "~3.0.3" resolve "~1.22.1" @@ -653,20 +665,20 @@ source-map "~0.6.1" typescript "5.4.2" -"@microsoft/tsdoc-config@~0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.17.0.tgz#82605152b3c1d3f5cd4a11697bc298437484d55d" - integrity sha512-v/EYRXnCAIHxOHW+Plb6OWuUoMotxTN0GLatnpOb1xq0KuTNw/WI3pamJx/UbsoJP5k9MCw1QxvvhPcF9pH3Zg== +"@microsoft/tsdoc-config@~0.17.1": + version "0.17.1" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz#e0f0b50628f4ad7fe121ca616beacfe6a25b9335" + integrity sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw== dependencies: - "@microsoft/tsdoc" "0.15.0" + "@microsoft/tsdoc" "0.15.1" ajv "~8.12.0" jju "~1.4.0" resolve "~1.22.2" -"@microsoft/tsdoc@0.15.0", "@microsoft/tsdoc@~0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.0.tgz#f29a55df17cb6e87cfbabce33ff6a14a9f85076d" - integrity sha512-HZpPoABogPvjeJOdzCOSJsXeL/SMCBgBZMVC3X3d7YYp2gf31MfxhUoYUNwf1ERPJOnQc0wkFn9trqI6ZEdZuA== +"@microsoft/tsdoc@0.15.1", "@microsoft/tsdoc@~0.15.1": + version "0.15.1" + resolved "https://registry.yarnpkg.com/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz#d4f6937353bc4568292654efb0a0e0532adbcba2" + integrity sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -699,80 +711,40 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.28.tgz#d45e01c4a56f143ee69c54dd6b12eade9e270a73" integrity sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw== -"@rollup/plugin-alias@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz#99a94accc4ff9a3483be5baeedd5d7da3b597e93" - integrity sha512-lpA3RZ9PdIG7qqhEfv79tBffNaoDuukFDrmhLqg9ifv99u/ehn+lOg30x2zmhf8AQqQUZaMk/B9fZraQ6/acDQ== - dependencies: - slash "^4.0.0" - -"@rollup/plugin-typescript@^11.1.6": - version "11.1.6" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz#724237d5ec12609ec01429f619d2a3e7d4d1b22b" - integrity sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA== - dependencies: - "@rollup/pluginutils" "^5.1.0" - resolve "^1.22.1" - -"@rollup/pluginutils@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" - integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== +"@rollup/pluginutils@^5.1.4": + version "5.1.4" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.4.tgz#bb94f1f9eaaac944da237767cdfee6c5b2262d4a" + integrity sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" - picomatch "^2.3.1" + picomatch "^4.0.2" "@rollup/rollup-android-arm-eabi@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54" integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA== -"@rollup/rollup-android-arm-eabi@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.6.tgz#66b8d9cb2b3a474d115500f9ebaf43e2126fe496" - integrity sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg== - "@rollup/rollup-android-arm64@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e" integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA== -"@rollup/rollup-android-arm64@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.6.tgz#46327d5b86420d2307946bec1535fdf00356e47d" - integrity sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw== - "@rollup/rollup-darwin-arm64@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f" integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA== -"@rollup/rollup-darwin-arm64@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.6.tgz#166987224d2f8b1e2fd28ee90c447d52271d5e90" - integrity sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw== - "@rollup/rollup-darwin-x64@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724" integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ== -"@rollup/rollup-darwin-x64@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.6.tgz#a2e6e096f74ccea6e2f174454c26aef6bcdd1274" - integrity sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog== - "@rollup/rollup-linux-arm-gnueabihf@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb" integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA== -"@rollup/rollup-linux-arm-gnueabihf@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.6.tgz#09fcd4c55a2d6160c5865fec708a8e5287f30515" - integrity sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ== - "@rollup/rollup-linux-arm-musleabihf@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3" @@ -783,21 +755,11 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496" integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA== -"@rollup/rollup-linux-arm64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.6.tgz#19a3c0b6315c747ca9acf86e9b710cc2440f83c9" - integrity sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ== - "@rollup/rollup-linux-arm64-musl@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065" integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw== -"@rollup/rollup-linux-arm64-musl@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.6.tgz#94aaf95fdaf2ad9335983a4552759f98e6b2e850" - integrity sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ== - "@rollup/rollup-linux-powerpc64le-gnu@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d" @@ -808,11 +770,6 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983" integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg== -"@rollup/rollup-linux-riscv64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.6.tgz#160510e63f4b12618af4013bddf1761cf9fc9880" - integrity sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA== - "@rollup/rollup-linux-s390x-gnu@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58" @@ -823,55 +780,30 @@ resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b" integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== -"@rollup/rollup-linux-x64-gnu@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.6.tgz#5ac5d068ce0726bd0a96ca260d5bd93721c0cb98" - integrity sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw== - "@rollup/rollup-linux-x64-musl@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127" integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== -"@rollup/rollup-linux-x64-musl@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.6.tgz#bafa759ab43e8eab9edf242a8259ffb4f2a57a5d" - integrity sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ== - "@rollup/rollup-win32-arm64-msvc@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5" integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ== -"@rollup/rollup-win32-arm64-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.6.tgz#1cc3416682e5a20d8f088f26657e6e47f8db468e" - integrity sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA== - "@rollup/rollup-win32-ia32-msvc@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2" integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ== -"@rollup/rollup-win32-ia32-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.6.tgz#7d2251e1aa5e8a1e47c86891fe4547a939503461" - integrity sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ== - "@rollup/rollup-win32-x64-msvc@4.24.0": version "4.24.0" resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818" integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== -"@rollup/rollup-win32-x64-msvc@4.9.6": - version "4.9.6" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.6.tgz#2c1fb69e02a3f1506f52698cfdc3a8b6386df9a6" - integrity sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ== - -"@rushstack/node-core-library@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-5.7.0.tgz#f28699c7d0b3de0120a207f8b9d5bd7c69806e18" - integrity sha512-Ff9Cz/YlWu9ce4dmqNBZpA45AEya04XaBFIjV7xTVeEf+y/kTjEasmozqFELXlNG4ROdevss75JrrZ5WgufDkQ== +"@rushstack/node-core-library@5.10.1": + version "5.10.1" + resolved "https://registry.yarnpkg.com/@rushstack/node-core-library/-/node-core-library-5.10.1.tgz#14c10c918ed12da003c21af9d5bf0e76633215d2" + integrity sha512-BSb/KcyBHmUQwINrgtzo6jiH0HlGFmrUy33vO6unmceuVKTEyL2q+P0fQq2oB5hvXVWOEUhxB2QvlkZluvUEmg== dependencies: ajv "~8.13.0" ajv-draft-04 "~1.0.0" @@ -890,20 +822,20 @@ resolve "~1.22.1" strip-json-comments "~3.1.1" -"@rushstack/terminal@0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@rushstack/terminal/-/terminal-0.14.0.tgz#967ecc586d7172204353059f8fdb1760666e9381" - integrity sha512-juTKMAMpTIJKudeFkG5slD8Z/LHwNwGZLtU441l/u82XdTBfsP+LbGKJLCNwP5se+DMCT55GB8x9p6+C4UL7jw== +"@rushstack/terminal@0.14.4": + version "0.14.4" + resolved "https://registry.yarnpkg.com/@rushstack/terminal/-/terminal-0.14.4.tgz#37e160b0878a324cf3e0fecab25fe48a030e29ed" + integrity sha512-NxACqERW0PHq8Rpq1V6v5iTHEwkRGxenjEW+VWqRYQ8T9puUzgmGHmEZUaUEDHAe9Qyvp0/Ew04sAiQw9XjhJg== dependencies: - "@rushstack/node-core-library" "5.7.0" + "@rushstack/node-core-library" "5.10.1" supports-color "~8.1.1" -"@rushstack/ts-command-line@4.22.6": - version "4.22.6" - resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.22.6.tgz#2aee4fc98c6043c026ce278880fbffb5227de5ca" - integrity sha512-QSRqHT/IfoC5nk9zn6+fgyqOPXHME0BfchII9EUPR19pocsNp/xSbeBCbD3PIR2Lg+Q5qk7OFqk1VhWPMdKHJg== +"@rushstack/ts-command-line@4.23.2": + version "4.23.2" + resolved "https://registry.yarnpkg.com/@rushstack/ts-command-line/-/ts-command-line-4.23.2.tgz#37b28a418db84d04f6a1c787390dd02ad8dfadf0" + integrity sha512-JJ7XZX5K3ThBBva38aomgsPv1L7FV6XmSOcR6HtM7HDFZJkepqT65imw26h9ggGqMjsY0R9jcl30tzKcVj9aOQ== dependencies: - "@rushstack/terminal" "0.14.0" + "@rushstack/terminal" "0.14.4" "@types/argparse" "1.0.38" argparse "~1.0.9" string-argv "~0.3.1" @@ -933,46 +865,26 @@ resolved "https://registry.yarnpkg.com/@types/argparse/-/argparse-1.0.38.tgz#a81fd8606d481f873a3800c6ebae4f1d768a56a9" integrity sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA== -"@types/estree@1.0.5", "@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - "@types/estree@1.0.6", "@types/estree@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" +"@types/estree@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - "@types/minimist@^1.2.0": version "1.2.5" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== -"@types/node@*": - version "20.11.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.6.tgz#6adf4241460e28be53836529c033a41985f85b6e" - integrity sha512-+EOokTnksGVgip2PbYbr3xnR7kZigh4LbybAfBAw5BpnQ+FqBYUsvCEjYd70IXKlbohQ64mzEYmMtlWUY8q//Q== - dependencies: - undici-types "~5.26.4" - "@types/node@20.5.1": version "20.5.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.1.tgz#178d58ee7e4834152b0e8b4d30cbfab578b9bb30" @@ -990,62 +902,62 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== -"@typescript-eslint/eslint-plugin@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.10.0.tgz#9c8218ed62f9a322df10ded7c34990f014df44f2" - integrity sha512-phuB3hoP7FFKbRXxjl+DRlQDuJqhpOnm5MmtROXyWi3uS/Xg2ZXqiQfcG2BJHiN4QKyzdOJi3NEn/qTnjUlkmQ== +"@typescript-eslint/eslint-plugin@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz#992e5ac1553ce20d0d46aa6eccd79dc36dedc805" + integrity sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ== dependencies: "@eslint-community/regexpp" "^4.10.0" - "@typescript-eslint/scope-manager" "8.10.0" - "@typescript-eslint/type-utils" "8.10.0" - "@typescript-eslint/utils" "8.10.0" - "@typescript-eslint/visitor-keys" "8.10.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/type-utils" "8.18.1" + "@typescript-eslint/utils" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" graphemer "^1.4.0" ignore "^5.3.1" natural-compare "^1.4.0" ts-api-utils "^1.3.0" -"@typescript-eslint/parser@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.10.0.tgz#3cbe7206f5e42835878a74a76da533549f977662" - integrity sha512-E24l90SxuJhytWJ0pTQydFT46Nk0Z+bsLKo/L8rtQSL93rQ6byd1V/QbDpHUTdLPOMsBCcYXZweADNCfOCmOAg== +"@typescript-eslint/parser@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.18.1.tgz#c258bae062778b7696793bc492249027a39dfb95" + integrity sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA== dependencies: - "@typescript-eslint/scope-manager" "8.10.0" - "@typescript-eslint/types" "8.10.0" - "@typescript-eslint/typescript-estree" "8.10.0" - "@typescript-eslint/visitor-keys" "8.10.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.10.0.tgz#606ffe18314d7b5c2f118f2f02aaa2958107a19c" - integrity sha512-AgCaEjhfql9MDKjMUxWvH7HjLeBqMCBfIaBbzzIcBbQPZE7CPh1m6FF+L75NUMJFMLYhCywJXIDEMa3//1A0dw== +"@typescript-eslint/scope-manager@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.18.1.tgz#52cedc3a8178d7464a70beffed3203678648e55b" + integrity sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ== dependencies: - "@typescript-eslint/types" "8.10.0" - "@typescript-eslint/visitor-keys" "8.10.0" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" -"@typescript-eslint/type-utils@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.10.0.tgz#99f1d2e21f8c74703e7d9c4a67a87271eaf57597" - integrity sha512-PCpUOpyQSpxBn230yIcK+LeCQaXuxrgCm2Zk1S+PTIRJsEfU6nJ0TtwyH8pIwPK/vJoA+7TZtzyAJSGBz+s/dg== +"@typescript-eslint/type-utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.18.1.tgz#10f41285475c0bdee452b79ff7223f0e43a7781e" + integrity sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ== dependencies: - "@typescript-eslint/typescript-estree" "8.10.0" - "@typescript-eslint/utils" "8.10.0" + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/utils" "8.18.1" debug "^4.3.4" ts-api-utils "^1.3.0" -"@typescript-eslint/types@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.10.0.tgz#eb29c4bc2ed23489348c297469c76d28c38fb618" - integrity sha512-k/E48uzsfJCRRbGLapdZgrX52csmWJ2rcowwPvOZ8lwPUv3xW6CcFeJAXgx4uJm+Ge4+a4tFOkdYvSpxhRhg1w== +"@typescript-eslint/types@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.18.1.tgz#d7f4f94d0bba9ebd088de840266fcd45408a8fff" + integrity sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw== -"@typescript-eslint/typescript-estree@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.10.0.tgz#36cc66e06c5f44d6781f95cb03b132e985273a33" - integrity sha512-3OE0nlcOHaMvQ8Xu5gAfME3/tWVDpb/HxtpUZ1WeOAksZ/h/gwrBzCklaGzwZT97/lBbbxJ16dMA98JMEngW4w== +"@typescript-eslint/typescript-estree@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.1.tgz#2a86cd64b211a742f78dfa7e6f4860413475367e" + integrity sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg== dependencies: - "@typescript-eslint/types" "8.10.0" - "@typescript-eslint/visitor-keys" "8.10.0" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" debug "^4.3.4" fast-glob "^3.3.2" is-glob "^4.0.3" @@ -1053,151 +965,151 @@ semver "^7.6.0" ts-api-utils "^1.3.0" -"@typescript-eslint/utils@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.10.0.tgz#d78d1ce3ea3d2a88a2593ebfb1c98490131d00bf" - integrity sha512-Oq4uZ7JFr9d1ZunE/QKy5egcDRXT/FrS2z/nlxzPua2VHFtmMvFNDvpq1m/hq0ra+T52aUezfcjGRIB7vNJF9w== +"@typescript-eslint/utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.18.1.tgz#c4199ea23fc823c736e2c96fd07b1f7235fa92d5" + integrity sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@typescript-eslint/scope-manager" "8.10.0" - "@typescript-eslint/types" "8.10.0" - "@typescript-eslint/typescript-estree" "8.10.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" -"@typescript-eslint/visitor-keys@8.10.0": - version "8.10.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.10.0.tgz#7ce4c0c3b82140415c9cd9babe09e0000b4e9979" - integrity sha512-k8nekgqwr7FadWk548Lfph6V3r9OVqjzAIVskE7orMZR23cGJjAOVazsZSJW+ElyjfTM4wx/1g88Mi70DDtG9A== +"@typescript-eslint/visitor-keys@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.1.tgz#344b4f6bc83f104f514676facf3129260df7610a" + integrity sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ== dependencies: - "@typescript-eslint/types" "8.10.0" - eslint-visitor-keys "^3.4.3" + "@typescript-eslint/types" "8.18.1" + eslint-visitor-keys "^4.2.0" -"@vitest/coverage-istanbul@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.3.tgz#0709be35e9fbb5acc58b1bd75fb67e990ce61d6f" - integrity sha512-FByj6ni54EzA4SXl5X3ugSeeBSI6MSEQBbvPefF6x6GCajePLeZSNYt7u0NOKUQbWpQpAdHHstrqR9ALEpnAxA== +"@vitest/coverage-istanbul@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/coverage-istanbul/-/coverage-istanbul-2.1.8.tgz#72fed37ad79d256209a8fc8678039422a94eadc3" + integrity sha512-cSaCd8KcWWvgDwEJSXm0NEWZ1YTiJzjicKHy+zOEbUm0gjbbkz+qJf1p8q71uBzSlS7vdnZA8wRLeiwVE3fFTA== dependencies: "@istanbuljs/schema" "^0.1.3" - debug "^4.3.6" + debug "^4.3.7" istanbul-lib-coverage "^3.2.2" istanbul-lib-instrument "^6.0.3" istanbul-lib-report "^3.0.1" istanbul-lib-source-maps "^5.0.6" istanbul-reports "^3.1.7" - magicast "^0.3.4" + magicast "^0.3.5" test-exclude "^7.0.1" tinyrainbow "^1.2.0" -"@vitest/expect@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.3.tgz#4b9a6fff22be4c4cd5d57e687cfda611b514b0ad" - integrity sha512-SNBoPubeCJhZ48agjXruCI57DvxcsivVDdWz+SSsmjTT4QN/DfHk3zB/xKsJqMs26bLZ/pNRLnCf0j679i0uWQ== +"@vitest/expect@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-2.1.8.tgz#13fad0e8d5a0bf0feb675dcf1d1f1a36a1773bc1" + integrity sha512-8ytZ/fFHq2g4PJVAtDX57mayemKgDR6X3Oa2Foro+EygiOJHUXhCqBAAKQYYajZpFoIfvBCF1j6R6IYRSIUFuw== dependencies: - "@vitest/spy" "2.1.3" - "@vitest/utils" "2.1.3" - chai "^5.1.1" + "@vitest/spy" "2.1.8" + "@vitest/utils" "2.1.8" + chai "^5.1.2" tinyrainbow "^1.2.0" -"@vitest/mocker@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.3.tgz#a3593b426551be5715fa108faf04f8a9ddb0a9cc" - integrity sha512-eSpdY/eJDuOvuTA3ASzCjdithHa+GIF1L4PqtEELl6Qa3XafdMLBpBlZCIUCX2J+Q6sNmjmxtosAG62fK4BlqQ== +"@vitest/mocker@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-2.1.8.tgz#51dec42ac244e949d20009249e033e274e323f73" + integrity sha512-7guJ/47I6uqfttp33mgo6ga5Gr1VnL58rcqYKyShoRK9ebu8T5Rs6HN3s1NABiBeVTdWNrwUMcHH54uXZBN4zA== dependencies: - "@vitest/spy" "2.1.3" + "@vitest/spy" "2.1.8" estree-walker "^3.0.3" - magic-string "^0.30.11" + magic-string "^0.30.12" -"@vitest/pretty-format@2.1.3", "@vitest/pretty-format@^2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.3.tgz#48b9b03de75507d1d493df7beb48dc39a1946a3e" - integrity sha512-XH1XdtoLZCpqV59KRbPrIhFCOO0hErxrQCMcvnQete3Vibb9UeIOX02uFPfVn3Z9ZXsq78etlfyhnkmIZSzIwQ== +"@vitest/pretty-format@2.1.8", "@vitest/pretty-format@^2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.8.tgz#88f47726e5d0cf4ba873d50c135b02e4395e2bca" + integrity sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ== dependencies: tinyrainbow "^1.2.0" -"@vitest/runner@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.3.tgz#20a6da112007dfd92969951df189c6da66c9dac4" - integrity sha512-JGzpWqmFJ4fq5ZKHtVO3Xuy1iF2rHGV4d/pdzgkYHm1+gOzNZtqjvyiaDGJytRyMU54qkxpNzCx+PErzJ1/JqQ== +"@vitest/runner@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-2.1.8.tgz#b0e2dd29ca49c25e9323ea2a45a5125d8729759f" + integrity sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg== dependencies: - "@vitest/utils" "2.1.3" + "@vitest/utils" "2.1.8" pathe "^1.1.2" -"@vitest/snapshot@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.3.tgz#1b405a9c40a82563605b13fdc045217751069e58" - integrity sha512-qWC2mWc7VAXmjAkEKxrScWHWFyCQx/cmiZtuGqMi+WwqQJ2iURsVY4ZfAK6dVo6K2smKRU6l3BPwqEBvhnpQGg== +"@vitest/snapshot@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-2.1.8.tgz#d5dc204f4b95dc8b5e468b455dfc99000047d2de" + integrity sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg== dependencies: - "@vitest/pretty-format" "2.1.3" - magic-string "^0.30.11" + "@vitest/pretty-format" "2.1.8" + magic-string "^0.30.12" pathe "^1.1.2" -"@vitest/spy@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.3.tgz#2c8a457673094ec4c1ab7c50cb11c58e3624ada2" - integrity sha512-Nb2UzbcUswzeSP7JksMDaqsI43Sj5+Kry6ry6jQJT4b5gAK+NS9NED6mDb8FlMRCX8m5guaHCDZmqYMMWRy5nQ== +"@vitest/spy@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-2.1.8.tgz#bc41af3e1e6a41ae3b67e51f09724136b88fa447" + integrity sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg== dependencies: - tinyspy "^3.0.0" + tinyspy "^3.0.2" -"@vitest/ui@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-2.1.3.tgz#2c191e55fd169d4aea853dfbc74a0790e8d5bf87" - integrity sha512-2XwTrHVJw3t9NYES26LQUYy51ZB8W4bRPgqUH2Eyda3kIuOlYw1ZdPNU22qcVlUVx4WKgECFQOSXuopsczuVjQ== +"@vitest/ui@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-2.1.8.tgz#4a4d88e20bcced4c8710826cd4e2795f5ec1f0a1" + integrity sha512-5zPJ1fs0ixSVSs5+5V2XJjXLmNzjugHRyV11RqxYVR+oMcogZ9qTuSfKW+OcTV0JeFNznI83BNylzH6SSNJ1+w== dependencies: - "@vitest/utils" "2.1.3" + "@vitest/utils" "2.1.8" fflate "^0.8.2" flatted "^3.3.1" pathe "^1.1.2" - sirv "^2.0.4" - tinyglobby "^0.2.6" + sirv "^3.0.0" + tinyglobby "^0.2.10" tinyrainbow "^1.2.0" -"@vitest/utils@2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.3.tgz#e52aa5745384091b151cbdf79bb5a3ad2bea88d2" - integrity sha512-xpiVfDSg1RrYT0tX6czgerkpcKFmFOF/gCr30+Mve5V2kewCy4Prn1/NDMSRwaSmT7PRaOF83wu+bEtsY1wrvA== +"@vitest/utils@2.1.8": + version "2.1.8" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.8.tgz#f8ef85525f3362ebd37fd25d268745108d6ae388" + integrity sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA== dependencies: - "@vitest/pretty-format" "2.1.3" - loupe "^3.1.1" + "@vitest/pretty-format" "2.1.8" + loupe "^3.1.2" tinyrainbow "^1.2.0" -"@volar/language-core@2.4.6", "@volar/language-core@~2.4.1": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.6.tgz#159625a6e1263fe68d1afad524ae2bd40c4ee0dd" - integrity sha512-FxUfxaB8sCqvY46YjyAAV6c3mMIq/NWQMVvJ+uS4yxr1KzOvyg61gAuOnNvgCvO4TZ7HcLExBEsWcDu4+K4E8A== +"@volar/language-core@2.4.11", "@volar/language-core@~2.4.8": + version "2.4.11" + resolved "https://registry.yarnpkg.com/@volar/language-core/-/language-core-2.4.11.tgz#d95a9ec4f14fbdb41a6a64f9f321d11d23a5291c" + integrity sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg== dependencies: - "@volar/source-map" "2.4.6" + "@volar/source-map" "2.4.11" -"@volar/source-map@2.4.6": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.6.tgz#b71ad241216f646812639f359262e6a84b46b6ed" - integrity sha512-Nsh7UW2ruK+uURIPzjJgF0YRGP5CX9nQHypA2OMqdM2FKy7rh+uv3XgPnWPw30JADbKvZ5HuBzG4gSbVDYVtiw== +"@volar/source-map@2.4.11": + version "2.4.11" + resolved "https://registry.yarnpkg.com/@volar/source-map/-/source-map-2.4.11.tgz#5876d4531508129724c2755e295db1df98bd5895" + integrity sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ== -"@volar/typescript@^2.4.4": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.6.tgz#6a4611b9fae793ad0d4c66d11d765f2731d93a12" - integrity sha512-NMIrA7y5OOqddL9VtngPWYmdQU03htNKFtAYidbYfWA0TOhyGVd9tfcP4TsLWQ+RBWDZCbBqsr8xzU0ZOxYTCQ== +"@volar/typescript@^2.4.11": + version "2.4.11" + resolved "https://registry.yarnpkg.com/@volar/typescript/-/typescript-2.4.11.tgz#aafbfa413337654db211bf4d8fb6670c89f6fa57" + integrity sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw== dependencies: - "@volar/language-core" "2.4.6" + "@volar/language-core" "2.4.11" path-browserify "^1.0.1" vscode-uri "^3.0.8" -"@vue/compiler-core@3.5.12": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.12.tgz#bd70b7dabd12b0b6f31bc53418ba3da77994c437" - integrity sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw== +"@vue/compiler-core@3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz#b0ae6c4347f60c03e849a05d34e5bf747c9bda05" + integrity sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q== dependencies: "@babel/parser" "^7.25.3" - "@vue/shared" "3.5.12" + "@vue/shared" "3.5.13" entities "^4.5.0" estree-walker "^2.0.2" source-map-js "^1.2.0" -"@vue/compiler-dom@^3.4.0": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.12.tgz#456d631d11102535b7ee6fd954cf2c93158d0354" - integrity sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg== +"@vue/compiler-dom@^3.5.0": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz#bb1b8758dbc542b3658dda973b98a1c9311a8a58" + integrity sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA== dependencies: - "@vue/compiler-core" "3.5.12" - "@vue/shared" "3.5.12" + "@vue/compiler-core" "3.5.13" + "@vue/shared" "3.5.13" "@vue/compiler-vue2@^2.7.16": version "2.7.16" @@ -1207,24 +1119,24 @@ de-indent "^1.0.2" he "^1.2.0" -"@vue/language-core@2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.1.6.tgz#b48186bdb9b3ef2b83e1f76d5b1ac357b3a7ed94" - integrity sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg== +"@vue/language-core@2.1.10": + version "2.1.10" + resolved "https://registry.yarnpkg.com/@vue/language-core/-/language-core-2.1.10.tgz#5988e9ea155f3e09ccbbb3b2a0ddd530dad912e6" + integrity sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ== dependencies: - "@volar/language-core" "~2.4.1" - "@vue/compiler-dom" "^3.4.0" + "@volar/language-core" "~2.4.8" + "@vue/compiler-dom" "^3.5.0" "@vue/compiler-vue2" "^2.7.16" - "@vue/shared" "^3.4.0" - computeds "^0.0.1" + "@vue/shared" "^3.5.0" + alien-signals "^0.2.0" minimatch "^9.0.3" muggle-string "^0.4.1" path-browserify "^1.0.1" -"@vue/shared@3.5.12", "@vue/shared@^3.4.0": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.12.tgz#f9e45b7f63f2c3f40d84237b1194b7f67de192e3" - integrity sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg== +"@vue/shared@3.5.13", "@vue/shared@^3.5.0": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.13.tgz#87b309a6379c22b926e696893237826f64339b6f" + integrity sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ== JSONStream@^1.0.4, JSONStream@^1.3.5: version "1.3.5" @@ -1249,6 +1161,11 @@ acorn@^8.12.0, acorn@^8.12.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3" integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w== +acorn@^8.14.0: + version "8.14.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0" + integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA== + acorn@^8.4.1: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" @@ -1259,14 +1176,6 @@ add-stream@^1.0.0: resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - ajv-draft-04@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz#3b64761b268ba0b9e668f0b41ba53fce0ad77fc8" @@ -1319,6 +1228,11 @@ ajv@~8.13.0: require-from-string "^2.0.2" uri-js "^4.4.1" +alien-signals@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/alien-signals/-/alien-signals-0.2.2.tgz#439d09b363dc4d609c0f6ce69362dce068d23197" + integrity sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -1370,11 +1284,6 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1456,10 +1365,10 @@ caniuse-lite@^1.0.30001663: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001669.tgz#fda8f1d29a8bfdc42de0c170d7f34a9cf19ed7a3" integrity sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w== -chai@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.1.tgz#f035d9792a22b481ead1c65908d14bb62ec1c82c" - integrity sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA== +chai@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/chai/-/chai-5.1.2.tgz#3afbc340b994ae3610ca519a6c70ace77ad4378d" + integrity sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw== dependencies: assertion-error "^2.0.1" check-error "^2.1.1" @@ -1489,11 +1398,6 @@ check-error@^2.1.1: resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc" integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw== -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -1549,11 +1453,6 @@ compare-versions@^6.1.1: resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9" integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg== -computeds@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/computeds/-/computeds-0.0.1.tgz#215b08a4ba3e08a11ff6eee5d6d8d7166a97ce2e" - integrity sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q== - concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -1791,7 +1690,7 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -1800,6 +1699,15 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + dargs@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" @@ -1815,7 +1723,7 @@ de-indent@^1.0.2: resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== -debug@^4.1.0, debug@^4.1.1, debug@^4.3.6: +debug@^4.1.0, debug@^4.1.1: version "4.3.7" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== @@ -1829,6 +1737,13 @@ debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" +debug@^4.3.7, debug@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" + integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + dependencies: + ms "^2.1.3" + decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -1852,20 +1767,6 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -del@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/del/-/del-5.1.0.tgz#d9487c94e367410e6eff2925ee58c0c84a75b3a7" - integrity sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA== - dependencies: - globby "^10.0.1" - graceful-fs "^4.2.2" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.1" - p-map "^3.0.0" - rimraf "^3.0.0" - slash "^3.0.0" - detect-indent@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" @@ -1881,13 +1782,6 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - dot-prop@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -1935,6 +1829,11 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +es-module-lexer@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.4.tgz#a8efec3a3da991e60efa6b633a7cad6ab8d26b78" + integrity sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw== + esbuild@^0.21.3: version "0.21.5" resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.5.tgz#9ca301b120922959b766360d8ac830da0d02997d" @@ -1984,15 +1883,15 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== -eslint-scope@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.1.0.tgz#70214a174d4cbffbc3e8a26911d8bf51b9ae9d30" - integrity sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw== +eslint-scope@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.2.0.tgz#377aa6f1cb5dc7592cfd0b7f892fd0cf352ce442" + integrity sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -2002,31 +1901,36 @@ eslint-visitor-keys@^4.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c" integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg== -eslint@^9.13.0: - version "9.13.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.13.0.tgz#7659014b7dda1ff876ecbd990f726e11c61596e6" - integrity sha512-EYZK6SX6zjFHST/HRytOdA/zE72Cq/bfw45LSyuwrdvcclb/gqV8RRQxywOBEWO2+WDpva6UZa4CcDeJKzUCFA== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + +eslint@^9.17.0: + version "9.17.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.17.0.tgz#faa1facb5dd042172fdc520106984b5c2421bb0c" + integrity sha512-evtlNcpJg+cZLcnVKwsai8fExnqjGPicK7gnUtlNuzu+Fv9bI0aLpND5T44VLQtoMEnI57LoXO9XAkIXwohKrA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.11.0" - "@eslint/config-array" "^0.18.0" - "@eslint/core" "^0.7.0" - "@eslint/eslintrc" "^3.1.0" - "@eslint/js" "9.13.0" - "@eslint/plugin-kit" "^0.2.0" - "@humanfs/node" "^0.16.5" + "@eslint-community/regexpp" "^4.12.1" + "@eslint/config-array" "^0.19.0" + "@eslint/core" "^0.9.0" + "@eslint/eslintrc" "^3.2.0" + "@eslint/js" "9.17.0" + "@eslint/plugin-kit" "^0.2.3" + "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" - "@humanwhocodes/retry" "^0.3.1" + "@humanwhocodes/retry" "^0.4.1" "@types/estree" "^1.0.6" "@types/json-schema" "^7.0.15" ajv "^6.12.4" chalk "^4.0.0" - cross-spawn "^7.0.2" + cross-spawn "^7.0.6" debug "^4.3.2" escape-string-regexp "^4.0.0" - eslint-scope "^8.1.0" - eslint-visitor-keys "^4.1.0" - espree "^10.2.0" + eslint-scope "^8.2.0" + eslint-visitor-keys "^4.2.0" + espree "^10.3.0" esquery "^1.5.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -2041,9 +1945,8 @@ eslint@^9.13.0: minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" - text-table "^0.2.0" -espree@^10.0.1, espree@^10.2.0: +espree@^10.0.1: version "10.2.0" resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6" integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g== @@ -2052,6 +1955,15 @@ espree@^10.0.1, espree@^10.2.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.1.0" +espree@^10.3.0: + version "10.3.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a" + integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg== + dependencies: + acorn "^8.14.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^4.2.0" + esquery@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" @@ -2103,12 +2015,17 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +expect-type@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.1.0.tgz#a146e414250d13dfc49eafcfd1344a4060fa4c75" + integrity sha512-bFi65yM+xZgk+u/KRIpekdSYkTB5W1pEf0Lt8Q8Msh7b+eQ7LXVtIB1Bkm4fvclDEL1b2CZkMhv2mOeF8tMdkA== + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.0.3, fast-glob@^3.3.2: +fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -2141,7 +2058,7 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -fdir@^6.4.0: +fdir@^6.4.2: version "6.4.2" resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689" integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ== @@ -2246,11 +2163,6 @@ fs-extra@~7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" @@ -2346,18 +2258,6 @@ glob@^10.4.1: package-json-from-dist "^1.0.0" path-scurry "^1.11.1" -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" @@ -2375,26 +2275,12 @@ globals@^14.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== -globals@^15.11.0: - version "15.11.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-15.11.0.tgz#b96ed4c6998540c6fb824b24b5499216d2438d6e" - integrity sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw== - -globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2: +globals@^15.14.0: + version "15.14.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.14.0.tgz#b8fd3a8941ff3b4d38f3319d433b61bbb482e73f" + integrity sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig== + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -2465,12 +2351,12 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -husky@^9.0.10: - version "9.0.10" - resolved "https://registry.yarnpkg.com/husky/-/husky-9.0.10.tgz#ddca8908deb5f244e9286865ebc80b54387672c2" - integrity sha512-TQGNknoiy6bURzIO77pPRu+XHi6zI7T93rX+QnJsoYFf3xdjKOur+IlfqzJGMHIK/wXrLg+GsvMs8Op7vI2jVA== +husky@^9.1.7: + version "9.1.7" + resolved "https://registry.yarnpkg.com/husky/-/husky-9.1.7.tgz#d46a38035d101b46a70456a850ff4201344c0b2d" + integrity sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA== -ignore@^5.1.1, ignore@^5.2.0: +ignore@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== @@ -2503,15 +2389,7 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3, inherits@~2.0.3: +inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2560,16 +2438,6 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-inside@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -2771,13 +2639,13 @@ load-json-file@^4.0.0: pify "^3.0.0" strip-bom "^3.0.0" -local-pkg@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.0.tgz#093d25a346bae59a99f80e75f6e9d36d7e8c925c" - integrity sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg== +local-pkg@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/local-pkg/-/local-pkg-0.5.1.tgz#69658638d2a95287534d4c2fff757980100dbb6d" + integrity sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ== dependencies: - mlly "^1.4.2" - pkg-types "^1.0.3" + mlly "^1.7.3" + pkg-types "^1.2.1" locate-path@^2.0.0: version "2.0.0" @@ -2869,7 +2737,7 @@ lodash@^4.17.15, lodash@~4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loupe@^3.1.0, loupe@^3.1.1: +loupe@^3.1.0, loupe@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.2.tgz#c86e0696804a02218f2206124c45d8b15291a240" integrity sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg== @@ -2893,14 +2761,14 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -magic-string@^0.30.11: - version "0.30.12" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" - integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== +magic-string@^0.30.12, magic-string@^0.30.17: + version "0.30.17" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.17.tgz#450a449673d2460e5bbcfba9a61916a1714c7453" + integrity sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA== dependencies: "@jridgewell/sourcemap-codec" "^1.5.0" -magicast@^0.3.4: +magicast@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/magicast/-/magicast-0.3.5.tgz#8301c3c7d66704a0771eb1bad74274f0ec036739" integrity sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ== @@ -2953,7 +2821,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0: +merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -2976,7 +2844,7 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -3016,7 +2884,7 @@ minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -mlly@^1.4.2, mlly@^1.7.2: +mlly@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.2.tgz#21c0d04543207495b8d867eff0ac29fac9a023c0" integrity sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA== @@ -3026,6 +2894,16 @@ mlly@^1.4.2, mlly@^1.7.2: pkg-types "^1.2.0" ufo "^1.5.4" +mlly@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.3.tgz#d86c0fcd8ad8e16395eb764a5f4b831590cee48c" + integrity sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A== + dependencies: + acorn "^8.14.0" + pathe "^1.1.2" + pkg-types "^1.2.1" + ufo "^1.5.4" + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -3098,13 +2976,6 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -3173,13 +3044,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -3235,11 +3099,6 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -3305,7 +3164,7 @@ pify@^3.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== -pkg-types@^1.0.3, pkg-types@^1.2.0: +pkg-types@^1.2.0, pkg-types@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.2.1.tgz#6ac4e455a5bb4b9a6185c1c79abd544c901db2e5" integrity sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw== @@ -3446,7 +3305,7 @@ resolve-global@1.0.0, resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" -resolve@^1.10.0, resolve@^1.22.1, resolve@~1.22.1, resolve@~1.22.2: +resolve@^1.10.0, resolve@~1.22.1, resolve@~1.22.2: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -3460,20 +3319,6 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rollup-plugin-delete@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-delete/-/rollup-plugin-delete-2.0.0.tgz#262acf80660d48c3b167fb0baabd0c3ab985c153" - integrity sha512-/VpLMtDy+8wwRlDANuYmDa9ss/knGsAgrDhM+tEwB1npHwNu4DYNmDfUL55csse/GHs9Q+SMT/rw9uiaZ3pnzA== - dependencies: - del "^5.1.0" - rollup@^4.20.0: version "4.24.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05" @@ -3499,28 +3344,6 @@ rollup@^4.20.0: "@rollup/rollup-win32-x64-msvc" "4.24.0" fsevents "~2.3.2" -rollup@^4.9.6: - version "4.9.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.9.6.tgz#4515facb0318ecca254a2ee1315e22e09efc50a0" - integrity sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg== - dependencies: - "@types/estree" "1.0.5" - optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.9.6" - "@rollup/rollup-android-arm64" "4.9.6" - "@rollup/rollup-darwin-arm64" "4.9.6" - "@rollup/rollup-darwin-x64" "4.9.6" - "@rollup/rollup-linux-arm-gnueabihf" "4.9.6" - "@rollup/rollup-linux-arm64-gnu" "4.9.6" - "@rollup/rollup-linux-arm64-musl" "4.9.6" - "@rollup/rollup-linux-riscv64-gnu" "4.9.6" - "@rollup/rollup-linux-x64-gnu" "4.9.6" - "@rollup/rollup-linux-x64-musl" "4.9.6" - "@rollup/rollup-win32-arm64-msvc" "4.9.6" - "@rollup/rollup-win32-ia32-msvc" "4.9.6" - "@rollup/rollup-win32-x64-msvc" "4.9.6" - fsevents "~2.3.2" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -3587,25 +3410,15 @@ signal-exit@^4.0.1: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -sirv@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" - integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== +sirv@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.0.tgz#f8d90fc528f65dff04cb597a88609d4e8a4361ce" + integrity sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg== dependencies: "@polka/url" "^1.0.0-next.24" mrmime "^2.0.0" totalist "^3.0.0" -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" @@ -3686,26 +3499,17 @@ standard-version@^9.5.0: stringify-package "^1.0.1" yargs "^16.0.0" -std-env@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" - integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== +std-env@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.8.0.tgz#b56ffc1baf1a29dcc80a3bdf11d7fca7c315e7d5" + integrity sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w== string-argv@~0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3742,14 +3546,7 @@ stringify-package@^1.0.1: resolved "https://registry.yarnpkg.com/stringify-package/-/stringify-package-1.0.1.tgz#e5aa3643e7f74d0f28628b72f3dad5cecfc3ba85" integrity sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg== -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -3825,11 +3622,6 @@ text-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - through2@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" @@ -3855,30 +3647,30 @@ tinybench@^2.9.0: resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b" integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg== -tinyexec@^0.3.0: +tinyexec@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98" integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ== -tinyglobby@^0.2.6: - version "0.2.9" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.9.tgz#6baddd1b0fe416403efb0dd40442c7d7c03c1c66" - integrity sha512-8or1+BGEdk1Zkkw2ii16qSS7uVrQJPre5A9o/XkWPATkk23FZh/15BKFxPnlTy6vkljZxLqYCzzBMj30ZrSvjw== +tinyglobby@^0.2.10: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== dependencies: - fdir "^6.4.0" + fdir "^6.4.2" picomatch "^4.0.2" -tinypool@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.1.tgz#c64233c4fac4304e109a64340178760116dbe1fe" - integrity sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA== +tinypool@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.2.tgz#706193cc532f4c100f66aa00b01c42173d9051b2" + integrity sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA== tinyrainbow@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== -tinyspy@^3.0.0: +tinyspy@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a" integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q== @@ -3929,10 +3721,10 @@ ts-node@^10.8.1, ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -3961,25 +3753,30 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript-eslint@^8.10.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.10.0.tgz#7f7d51577e9b93538cc8801f2cbfdd66098a00e7" - integrity sha512-YIu230PeN7z9zpu/EtqCIuRVHPs4iSlqW6TEvjbyDAE3MZsSl2RXBo+5ag+lbABCG8sFM1WVKEXhlQ8Ml8A3Fw== +typescript-eslint@^8.18.1: + version "8.18.1" + resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.18.1.tgz#197b284b6769678ed77d9868df180eeaf61108eb" + integrity sha512-Mlaw6yxuaDEPQvb/2Qwu3/TfgeBHy9iTJ3mTwe7OvpPmF6KPQjVOfGyEJpPv6Ez2C34OODChhXrzYw/9phI0MQ== dependencies: - "@typescript-eslint/eslint-plugin" "8.10.0" - "@typescript-eslint/parser" "8.10.0" - "@typescript-eslint/utils" "8.10.0" + "@typescript-eslint/eslint-plugin" "8.18.1" + "@typescript-eslint/parser" "8.18.1" + "@typescript-eslint/utils" "8.18.1" typescript@5.4.2: version "5.4.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== -"typescript@^4.6.4 || ^5.2.2", typescript@^5.3.3: +"typescript@^4.6.4 || ^5.2.2": version "5.3.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@^5.5.4: + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== + ufo@^1.5.4: version "1.5.4" resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.4.tgz#16d6949674ca0c9e0fbbae1fa20a71d7b1ded754" @@ -4038,32 +3835,33 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -vite-node@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.3.tgz#8291d31f91c69dc22fea7909f4394c2b3cc2e2d9" - integrity sha512-I1JadzO+xYX887S39Do+paRePCKoiDrWRRjp9kkG5he0t7RXNvPAJPCQSJqbGN4uCrFFeS3Kj3sLqY8NMYBEdA== +vite-node@2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-2.1.8.tgz#9495ca17652f6f7f95ca7c4b568a235e0c8dbac5" + integrity sha512-uPAwSr57kYjAUux+8E2j0q0Fxpn8M9VoyfGiRI8Kfktz9NcYMCenwY5RnZxnF1WTu3TGiYipirIzacLL3VVGFg== dependencies: cac "^6.7.14" - debug "^4.3.6" + debug "^4.3.7" + es-module-lexer "^1.5.4" pathe "^1.1.2" vite "^5.0.0" -vite-plugin-dts@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-4.2.4.tgz#5b8697e6abe9004e6d134a59a9bc08f2eacb9288" - integrity sha512-REcYoxO90Pi8c0P1J7XAa/nVwNVGkX2eYkBEIfFSfcKE4g1W8sB0R23a7SU3aLEMfdOdb0SVHq3JlJ+Qb6gjgA== +vite-plugin-dts@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/vite-plugin-dts/-/vite-plugin-dts-4.4.0.tgz#ef79b5ceaa39a70aa69b619b249b6b49be911257" + integrity sha512-CJ6phvnnPLF+aFk8Jz2ZcMBLleJ4gKJOXb9We5Kzmsp5bPuD+uMDeVefjFNYSXZ+wdcqnf+Yp2P7oA5hBKQTlQ== dependencies: - "@microsoft/api-extractor" "7.47.7" - "@rollup/pluginutils" "^5.1.0" - "@volar/typescript" "^2.4.4" - "@vue/language-core" "2.1.6" + "@microsoft/api-extractor" "^7.48.1" + "@rollup/pluginutils" "^5.1.4" + "@volar/typescript" "^2.4.11" + "@vue/language-core" "2.1.10" compare-versions "^6.1.1" - debug "^4.3.6" + debug "^4.4.0" kolorist "^1.8.0" - local-pkg "^0.5.0" - magic-string "^0.30.11" + local-pkg "^0.5.1" + magic-string "^0.30.17" -vite@^5.0.0, vite@^5.4.9: +vite@^5.0.0: version "5.4.9" resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.9.tgz#215c80cbebfd09ccbb9ceb8c0621391c9abdc19c" integrity sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg== @@ -4074,29 +3872,41 @@ vite@^5.0.0, vite@^5.4.9: optionalDependencies: fsevents "~2.3.3" -vitest@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.3.tgz#dae1055dd328621b59fc6e594fd988fbf2e5370e" - integrity sha512-Zrxbg/WiIvUP2uEzelDNTXmEMJXuzJ1kCpbDvaKByFA9MNeO95V+7r/3ti0qzJzrxdyuUw5VduN7k+D3VmVOSA== - dependencies: - "@vitest/expect" "2.1.3" - "@vitest/mocker" "2.1.3" - "@vitest/pretty-format" "^2.1.3" - "@vitest/runner" "2.1.3" - "@vitest/snapshot" "2.1.3" - "@vitest/spy" "2.1.3" - "@vitest/utils" "2.1.3" - chai "^5.1.1" - debug "^4.3.6" - magic-string "^0.30.11" +vite@^5.4.11: + version "5.4.11" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.11.tgz#3b415cd4aed781a356c1de5a9ebafb837715f6e5" + integrity sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +vitest@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-2.1.8.tgz#2e6a00bc24833574d535c96d6602fb64163092fa" + integrity sha512-1vBKTZskHw/aosXqQUlVWWlGUxSJR8YtiyZDJAFeW2kPAeX6S3Sool0mjspO+kXLuxVWlEDDowBAeqeAQefqLQ== + dependencies: + "@vitest/expect" "2.1.8" + "@vitest/mocker" "2.1.8" + "@vitest/pretty-format" "^2.1.8" + "@vitest/runner" "2.1.8" + "@vitest/snapshot" "2.1.8" + "@vitest/spy" "2.1.8" + "@vitest/utils" "2.1.8" + chai "^5.1.2" + debug "^4.3.7" + expect-type "^1.1.0" + magic-string "^0.30.12" pathe "^1.1.2" - std-env "^3.7.0" + std-env "^3.8.0" tinybench "^2.9.0" - tinyexec "^0.3.0" - tinypool "^1.0.0" + tinyexec "^0.3.1" + tinypool "^1.0.1" tinyrainbow "^1.2.0" vite "^5.0.0" - vite-node "2.1.3" + vite-node "2.1.8" why-is-node-running "^2.3.0" vscode-uri@^3.0.8: @@ -4124,16 +3934,7 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -4151,11 +3952,6 @@ wrap-ansi@^8.1.0: string-width "^5.0.1" strip-ansi "^7.0.1" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"