From 817b7d6774cea5e715948b9288902e0c669b9d90 Mon Sep 17 00:00:00 2001 From: Avior Date: Tue, 25 Mar 2025 13:54:46 +0100 Subject: [PATCH] 0.0.2 Signed-off-by: Avior --- .gitignore | 1 + Schema.ts | 165 -- bun.lockb | Bin 80956 -> 0 bytes eslint.config.mjs | 25 +- index.ts | 18 +- package-lock.json | 2805 ++++++++++++++++++++++++++++ package.json | 54 +- src/Schema.ts | 241 +++ SchemaItem.ts => src/SchemaItem.ts | 121 +- src/helpers.ts | 60 + {items => src/items}/array.ts | 58 +- {items => src/items}/boolean.ts | 4 +- src/items/date.ts | 8 + {items => src/items}/enum.ts | 4 +- {items => src/items}/literal.ts | 6 +- {items => src/items}/nullable.ts | 12 +- {items => src/items}/number.ts | 16 +- {items => src/items}/object.ts | 32 +- src/items/record.ts | 55 + {items => src/items}/string.ts | 20 +- {items => src/items}/union.ts | 6 +- src/types.d.ts | 57 + tests/Schema.test.ts | 9 +- tsconfig.json | 30 +- types.d.ts | 29 - 25 files changed, 3490 insertions(+), 346 deletions(-) delete mode 100644 Schema.ts delete mode 100755 bun.lockb create mode 100644 package-lock.json create mode 100644 src/Schema.ts rename SchemaItem.ts => src/SchemaItem.ts (75%) create mode 100644 src/helpers.ts rename {items => src/items}/array.ts (60%) rename {items => src/items}/boolean.ts (88%) create mode 100644 src/items/date.ts rename {items => src/items}/enum.ts (89%) rename {items => src/items}/literal.ts (65%) rename {items => src/items}/nullable.ts (57%) rename {items => src/items}/number.ts (100%) rename {items => src/items}/object.ts (59%) create mode 100644 src/items/record.ts rename {items => src/items}/string.ts (95%) rename {items => src/items}/union.ts (81%) create mode 100644 src/types.d.ts delete mode 100644 types.d.ts diff --git a/.gitignore b/.gitignore index c2658d7..940d56a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules/ +dist diff --git a/Schema.ts b/Schema.ts deleted file mode 100644 index 96a308c..0000000 --- a/Schema.ts +++ /dev/null @@ -1,165 +0,0 @@ -import SchemaArray from "./items/array" -import SchemaBoolean from "./items/boolean" -import SchemaEnum, { EnumLike } from "./items/enum" -import SchemaLiteral from "./items/literal" -import SchemaNullable from "./items/nullable" -import SchemaNumber from "./items/number" -import SchemaObject from "./items/object" -import SchemaString from "./items/string" -import { SchemaUnion } from "./items/union" -import SchemaItem from "./SchemaItem" -import { SchemaJSON } from "./types" - -export function parceable() { - - return (target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => { - if (!(target instanceof SchemaItem)) { - throw new Error('the decorator is only usable on Schema') - } - - - const original = target[propertyKey] - - const t = function () { } - - descriptor.value = function (this: SchemaItem, ...args: Array) { - this.savedCalls.push({ name: propertyKey as string, args: args }) - const res = original.call(this, ...args) - return res - } - - return descriptor - } -} - -interface SchemaItemStatic { - new(...args: Array): SchemaItem -} - -type ExtractGeneric = T extends SchemaItem ? U : never - -export default class Schema { - private static registeredModules: Array = [ - SchemaArray, - SchemaBoolean, - SchemaEnum, - SchemaLiteral, - SchemaNullable, - SchemaObject, - SchemaString, - SchemaUnion - ] - - public static register(module: SchemaItemStatic) { - this.registeredModules.push(module) - } - - public static getModule(name: string) { - return this.registeredModules.find((it) => it.name === name) - } - - public static array( - ...inputs: ConstructorParameters> - ): SchemaArray { - return new SchemaArray(...inputs) - } - - public static boolean( - ...inputs: ConstructorParameters - ): SchemaBoolean { - return new SchemaBoolean(...inputs) - } - - public static enum( - ...inputs: ConstructorParameters> - ): SchemaEnum { - return new SchemaEnum(...inputs) - } - - /** - * - * @param input the literal value (note: append `as const` else the typing won't work correctly) - * @returns - */ - public static literal( - input: Type - ): SchemaLiteral { - return new SchemaLiteral(input) - } - - public static nullable( - ...inputs: ConstructorParameters> - ): SchemaNullable { - return new SchemaNullable(...inputs) - } - - public static number( - ...inputs: ConstructorParameters - ): SchemaNumber { - return new SchemaNumber(...inputs) - } - - public static object>>( - ...inputs: ConstructorParameters> - ): SchemaObject { - return new SchemaObject(...inputs) - } - - /** - * See {@link SchemaString} - */ - public static string( - ...inputs: ConstructorParameters - ): SchemaString { - return new SchemaString(...inputs) - } - - public static union>>( - ...inputs: ConstructorParameters> - ): SchemaUnion { - return new SchemaUnion(...inputs) - } - - public static fromJSON(json: SchemaJSON): SchemaItem { - - // get the module - const fn = this.getModule(json.i) - - // handle module not detected - if (!fn) { - throw new Error(`Schema cannot parse ${json.i}`) - } - - // init the module - const item = new fn(...(json.c?.map((it) => this.isSchemaJSON(it) ? Schema.fromJSON(it) : it) ?? [])) - - // handle validations - for (const validation of (json.f ?? [])) { - // validation not found in item :( - if (!(validation.n in item)) { - throw new Error('validation not available in Schema Item') - } - - // init the validation - (item[validation.n] as (...params: Array) => void)(...validation.a.map((it) => Schema.isSchemaJSON(it) ? Schema.fromJSON(it) : it)) - } - - // add the attributes - item.attrs(...json.a ?? []) - - - return item - } - - public static isSchemaJSON(data: unknown): data is SchemaJSON { - if (typeof data !== 'object' || data === null) { - return false - } - - if (!('i' in data)) { - return false - } - - return true - } -} diff --git a/bun.lockb b/bun.lockb deleted file mode 100755 index 93ab718873837006560e27334d52318927b90a56..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 80956 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 -/* -buffer -date -file -record -*/ +type Test = Infered['a']['p'] + +console.log(res.parse("{ hello: 'world' }")) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..196e46e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,2805 @@ +{ + "name": "@dzeio/schema", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@dzeio/schema", + "version": "1.0.0", + "dependencies": { + "@dzeio/object-util": "^1.8.3", + "@standard-schema/spec": "^1.0.0", + "zod": "^3.24.2" + }, + "devDependencies": { + "@eslint/js": "^9.18.0", + "@stylistic/eslint-plugin": "^2.13.0", + "@types/bun": "^1.1.18", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "globals": "^15.14.0", + "tsup": "^8.3.6", + "typescript": "^5.7.3", + "typescript-eslint": "^8.21.0", + "vitest": "^3.0.4" + } + }, + "node_modules/@dzeio/object-util": { + "version": "1.8.3", + "license": "MIT" + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.19.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/object-schema": "^2.1.5", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.10.0", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.18.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.5", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.5", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@eslint/core": "^0.10.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.1", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.31.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.31.0", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.13.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@types/bun": { + "version": "1.1.18", + "dev": true, + "license": "MIT", + "dependencies": { + "bun-types": "1.1.44" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/node": { + "version": "20.12.14", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/ws": { + "version": "8.5.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/type-utils": "8.21.0", + "@typescript-eslint/utils": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.21.0", + "@typescript-eslint/utils": "8.21.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/visitor-keys": "8.21.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.21.0", + "@typescript-eslint/types": "8.21.0", + "@typescript-eslint/typescript-estree": "8.21.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.21.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/expect": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.4", + "@vitest/utils": "3.0.4", + "chai": "^5.1.2", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "3.0.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "3.0.4", + "pathe": "^2.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "3.0.4", + "loupe": "^3.1.2", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/acorn": { + "version": "8.14.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0", + "peer": true + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/bun-types": { + "version": "1.1.44", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "~20.12.8", + "@types/ws": "~8.5.10" + } + }, + "node_modules/bundle-require": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/consola": { + "version": "3.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.18.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.0", + "@eslint/core": "^0.10.0", + "@eslint/eslintrc": "^3.2.0", + "@eslint/js": "9.18.0", + "@eslint/plugin-kit": "^0.2.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.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.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.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", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "8.2.0", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.14.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expect-type": { + "version": "1.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fastq": { + "version": "1.18.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fdir": { + "version": "6.4.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.2", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob": { + "version": "10.4.5", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob/node_modules/minimatch/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/globals": { + "version": "15.14.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/joycon": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/load-tsconfig": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/loupe": { + "version": "3.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/magic-string": { + "version": "0.30.17", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/mz": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.8", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/pathe": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss": { + "version": "8.5.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rollup": { + "version": "4.31.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.31.0", + "@rollup/rollup-android-arm64": "4.31.0", + "@rollup/rollup-darwin-arm64": "4.31.0", + "@rollup/rollup-darwin-x64": "4.31.0", + "@rollup/rollup-freebsd-arm64": "4.31.0", + "@rollup/rollup-freebsd-x64": "4.31.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.31.0", + "@rollup/rollup-linux-arm-musleabihf": "4.31.0", + "@rollup/rollup-linux-arm64-gnu": "4.31.0", + "@rollup/rollup-linux-arm64-musl": "4.31.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.31.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.31.0", + "@rollup/rollup-linux-riscv64-gnu": "4.31.0", + "@rollup/rollup-linux-s390x-gnu": "4.31.0", + "@rollup/rollup-linux-x64-gnu": "4.31.0", + "@rollup/rollup-linux-x64-musl": "4.31.0", + "@rollup/rollup-win32-arm64-msvc": "4.31.0", + "@rollup/rollup-win32-ia32-msvc": "4.31.0", + "@rollup/rollup-win32-x64-msvc": "4.31.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/semver": { + "version": "7.6.3", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/siginfo": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/source-map": { + "version": "0.8.0-beta.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "whatwg-url": "^7.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/std-env": { + "version": "3.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sucrase": { + "version": "3.35.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "glob": "^10.3.10", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinypool": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tr46": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/ts-api-utils": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/tsup": { + "version": "8.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.0.0", + "cac": "^6.7.14", + "chokidar": "^4.0.1", + "consola": "^3.2.3", + "debug": "^4.3.7", + "esbuild": "^0.24.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.24.0", + "source-map": "0.8.0-beta.0", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.1", + "tinyglobby": "^0.2.9", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.7.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.21.0", + "@typescript-eslint/parser": "8.21.0", + "@typescript-eslint/utils": "8.21.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/vite": { + "version": "6.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.0", + "es-module-lexer": "^1.6.0", + "pathe": "^2.0.2", + "vite": "^5.0.0 || ^6.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "3.0.4", + "@vitest/mocker": "3.0.4", + "@vitest/pretty-format": "^3.0.4", + "@vitest/runner": "3.0.4", + "@vitest/snapshot": "3.0.4", + "@vitest/spy": "3.0.4", + "@vitest/utils": "3.0.4", + "chai": "^5.1.2", + "debug": "^4.4.0", + "expect-type": "^1.1.0", + "magic-string": "^0.30.17", + "pathe": "^2.0.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinypool": "^1.0.2", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0", + "vite-node": "3.0.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/debug": "^4.1.12", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "@vitest/browser": "3.0.4", + "@vitest/ui": "3.0.4", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/debug": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "node_modules/webidl-conversions": { + "version": "4.0.2", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.24.2", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", + "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json index a9b9b89..c0cf828 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,43 @@ { - "dependencies": { - "@dzeio/object-util": "^1.8.3", - "@eslint/js": "^9.18.0", - "@stylistic/eslint-plugin": "^2.13.0", - "@types/bun": "^1.1.18", - "@typescript-eslint/eslint-plugin": "^8.21.0", - "globals": "^15.14.0", - "typescript": "^5.7.3", - "typescript-eslint": "^8.21.0", - "vitest": "^3.0.4" - } -} \ No newline at end of file + "name": "@dzeio/schema", + "version": "0.0.2", + "dependencies": { + "@dzeio/object-util": "^1.8.3" + }, + "main": "./dist/Schema.js", + "module": "./dist/Schema.mjs", + "types": "./dist/Schema.d.ts", + "files": [ + "dist" + ], + "exports": { + ".": { + "require": { + "types": "./dist/Schema.d.ts", + "default": "./dist/Schema.js" + }, + "import": { + "types": "./dist/Schema.d.mts", + "default": "./dist/Schema.mjs" + } + } + }, + "devDependencies": { + "@eslint/js": "^9.18.0", + "@standard-schema/spec": "^1.0.0", + "@stylistic/eslint-plugin": "^2.13.0", + "@types/bun": "^1.1.18", + "@typescript-eslint/eslint-plugin": "^8.21.0", + "globals": "^15.14.0", + "tsup": "^8.3.6", + "typescript": "^5.7.3", + "typescript-eslint": "^8.21.0", + "vitest": "^3.0.4" + }, + "scripts": { + "test": "bun test", + "lint": "eslint", + "build": "rm -rf dist && tsup ./src/Schema.ts --format cjs,esm --dts --clean", + "prepublishOnly": "rm -rf dist && tsup ./src/Schema.ts --format cjs,esm --dts --clean" + } +} diff --git a/src/Schema.ts b/src/Schema.ts new file mode 100644 index 0000000..086b52c --- /dev/null +++ b/src/Schema.ts @@ -0,0 +1,241 @@ +/* eslint-disable id-blacklist */ +import { parseForm, parseFormData, parseQuery } from 'helpers' +import SchemaDate from 'items/date' +import SchemaRecord from 'items/record' +import SchemaArray from './items/array' +import SchemaBoolean from './items/boolean' +import SchemaEnum, { EnumLike } from './items/enum' +import SchemaLiteral from './items/literal' +import SchemaNullable from './items/nullable' +import SchemaNumber from './items/number' +import SchemaObject from './items/object' +import SchemaString from './items/string' +import SchemaUnion from './items/union' +import SchemaItem from './SchemaItem' +import { SchemaJSON } from './types' + +export function parceable() { + + return (target: object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor) => { + // make sure the target is of SchemaItem + if (!(target instanceof SchemaItem)) { + throw new Error('the decorator is only usable on Schema') + } + + // make sur the property exists in the target + if (!(propertyKey in target)) { + throw new Error('property not set in object') + } + + // @ts-expect-error call a function defined from calls of collable + const original = target[propertyKey] as (...args: Array) => unknown + + // replace original function with modified one + descriptor.value = function(this: SchemaItem, ...args: Array) { + this.savedCalls.push({ name: propertyKey as string, args: args as Array }) + const res: unknown = original.call(this, ...args) + return res + } + + // return the modified descriptor + return descriptor + } +} + +type SchemaItemStatic = new (...args: Array) => SchemaItem + +export const Types = { + Array: SchemaArray, + Boolean: SchemaBoolean, + Date: SchemaDate, + Enum: SchemaEnum, + Literal: SchemaLiteral, + Nullable: SchemaNullable, + Object: SchemaObject, + Record: SchemaRecord, + String: SchemaString, + Union: SchemaUnion +} as const + +export default class Schema = Record> extends SchemaObject { + private static registeredModules: Array = [ + SchemaArray, + SchemaBoolean, + SchemaDate, + SchemaEnum, + SchemaLiteral, + SchemaNullable, + SchemaObject, + SchemaRecord, + SchemaString, + SchemaUnion + ] + + public static register(module: SchemaItemStatic) { + this.registeredModules.push(module) + } + + public static getModule(name: string) { + return this.registeredModules.find((it) => it.name === name) + } + + public static array( + ...inputs: ConstructorParameters> + ): SchemaArray { + return new SchemaArray(...inputs) + } + + public static boolean( + ...inputs: ConstructorParameters + ): SchemaBoolean { + return new SchemaBoolean(...inputs) + } + + public static date( + ...inputs: ConstructorParameters + ): SchemaDate { + return new SchemaDate(...inputs) + } + + public static enum( + ...inputs: ConstructorParameters> + ): SchemaEnum { + return new SchemaEnum(...inputs) + } + + /** + * + * @param input the literal value (note: append `as const` else the typing won't work correctly) + * @returns + */ + public static literal( + input: Type + ): SchemaLiteral { + return new SchemaLiteral(input) + } + + public static nullable( + ...inputs: ConstructorParameters> + ): SchemaNullable { + return new SchemaNullable(...inputs) + } + + public static number( + ...inputs: ConstructorParameters + ): SchemaNumber { + return new SchemaNumber(...inputs) + } + + public static object>( + ...inputs: ConstructorParameters> + ): SchemaObject { + return new SchemaObject(...inputs) + } + + public static record( + ...inputs: ConstructorParameters> + ): SchemaRecord { + return new SchemaRecord(...inputs) + } + + /** + * See {@link SchemaString} + */ + public static string( + ...inputs: ConstructorParameters + ): SchemaString { + return new SchemaString(...inputs) + } + + public static union>( + ...inputs: ConstructorParameters> + ): SchemaUnion { + return new SchemaUnion(...inputs) + } + + public static fromJSON(json: SchemaJSON): SchemaItem { + + // get the module + const fn = this.getModule(json.i) + + // handle module not detected + if (!fn) { + throw new Error(`Schema cannot parse ${json.i}`) + } + + // init the module + const item = new fn(...(json.c?.map((it) => this.isSchemaJSON(it) ? Schema.fromJSON(it) : it) ?? [])) + + // handle validations + for (const validation of (json.f ?? [])) { + // validation not found in item :( + if (!(validation.n in item)) { + throw new Error('validation not available in Schema Item') + } + + // init the validation + // @ts-expect-error call a function defined from calls of collable + (item[validation.n] as (...params: Array) => void)(...validation.a?.map((it) => Schema.isSchemaJSON(it) ? Schema.fromJSON(it) : it) ?? []) + } + + // add the attributes + item.attrs(...json.a ?? []) + + + return item + } + + public static isSchemaJSON(data: unknown): data is SchemaJSON { + if (typeof data !== 'object' || data === null) { + return false + } + + if (!('i' in data)) { + return false + } + + return true + } + + /** + * @deprecated use helper `parseQuery` + */ + public validateQuery(query: URLSearchParams, fast = false) { + return parseQuery(this, query, { fast }) + } + + /** + * @deprecated use `parse` + */ + public validate(input: unknown, fast = false) { + return this.parse(input, { fast }) + } + + /** + * @deprecated use helper `parseForm` + */ + public validateForm(form: HTMLFormElement, fast = false) { + return parseForm(this, form, { fast }) + } + + /** + * @deprecated use helper `parseFormData` + */ + public validateFormData(data: FormData, fast = false) { + return parseFormData(this, data, { fast }) + } +} + +export const s = Schema + +export * from './helpers' +export type * from './types.d.ts' + +export { + SchemaArray, + SchemaBoolean, SchemaDate, SchemaEnum, SchemaItem, SchemaLiteral, + SchemaNullable, + SchemaNumber, + SchemaObject, SchemaRecord, SchemaString, + SchemaUnion +} diff --git a/SchemaItem.ts b/src/SchemaItem.ts similarity index 75% rename from SchemaItem.ts rename to src/SchemaItem.ts index 5512d51..bdfb303 100644 --- a/SchemaItem.ts +++ b/src/SchemaItem.ts @@ -1,37 +1,41 @@ -import Schema from "./Schema" -import { SchemaJSON, ValidationError, ValidationResult } from "./types" +/* eslint-disable id-length */ +import { objectClean } from '@dzeio/object-util' +import { StandardSchemaV1 } from '@standard-schema/spec' +import Schema, { SchemaNullable } from './Schema' +import { SchemaJSON, ValidationError, ValidationResult } from './types' +export default abstract class SchemaItem implements StandardSchemaV1 { -export default abstract class SchemaItem { - - private invalidError = 'the field is invalid' - - /** - * list of attributes for custom works - */ - public readonly attributes: Array = [] - - public attrs(...attributes: Array) { - this.attributes.concat(attributes) - return this - } - - public setInvalidError(err: string): this { - this.invalidError = err - return this - } - - public clone(): this { - return Schema.fromJSON(this.toJSON()) as this + // standard Schema V1 spec + public '~standard': StandardSchemaV1.Props = { + vendor: 'aptatio', + version: 1, + validate: (value: unknown) => { + const res = this.parse(value) + if (!res.valid) { + return { + issues: res.errors + } + } + return { + value: res.object, + issues: res.errors, + } + } } /** - * schemas implementing unwrap can return their child component (mostly the value) - * - * ex: s.record(s.number(), s.string()) returns s.string() - * - * es2: s.nullable(s.string()) returns s.string() + * keep public ? */ - public unwrap?(): SchemaItem + public validations: Array<{ + fn: (input: Type) => boolean + error?: string | undefined + }> = [] + + /** + * Function calls saved for serialization + */ + public savedCalls: Array<{ name: string, args: Array | IArguments | undefined }> = [] + /** * Pre process the variable for various reasons @@ -53,23 +57,51 @@ export default abstract class SchemaItem { public postProcess: Array<(input: Type) => Type> = [] /** - * keep public ? + * list of attributes for custom works */ - public validations: Array<{ - fn: (input: Type) => boolean - error?: string | undefined - }> = [] - - public savedCalls: Array<{ name: string, args: Array | IArguments | undefined }> = [] + public readonly attributes: Array = [] private readonly items?: Array + private invalidError = 'the field is invalid' + public constructor(items?: Array | IArguments) { if (items && items.length > 0) { this.items = Array.isArray(items) ? items : Array.from(items) } } + public attrs(...attributes: Array) { + this.attributes.concat(attributes) + return this + } + + public attr(...attributes: Array) { + return this.attrs(...attributes) + } + + public setInvalidError(err: string): this { + this.invalidError = err + return this + } + + public clone(): this { + return Schema.fromJSON(this.toJSON()) as this + } + + public nullable(): SchemaNullable { + return new SchemaNullable(this) + } + + /** + * schemas implementing unwrap can return their child component (mostly the value) + * + * ex: s.record(s.number(), s.string()) returns s.string() + * + * es2: s.nullable(s.string()) returns s.string() + */ + public unwrap?(): SchemaItem + public parse(input: unknown, options?: { fast?: boolean }): ValidationResult { // pre process the variable for (const preProcess of this.preProcess) { @@ -95,6 +127,7 @@ export default abstract class SchemaItem { }) // if the system should be fast, stop checking for other errors + // eslint-disable-next-line max-depth if (options?.fast) { return { valid: false, @@ -119,26 +152,27 @@ export default abstract class SchemaItem { input = postProcess(input as Type) } - // validate that the pre process handled correctly the variable - if (!this.isOfType(input)) { - throw new Error('Post process error occured :(') - } - return { valid: true, - object: input + object: input as Type } } public toJSON(): SchemaJSON { - return { + // build the JSON + const res = { i: this.constructor.name, a: this.attributes.length > 0 ? this.attributes : undefined, c: this.items?.map((it) => it instanceof SchemaItem ? it.toJSON() : it), f: this.savedCalls .map((it) => (it.args ? { n: it.name, a: Array.from(it.args) } : { n: it.name })) } + + // cleanup the object from undefined to make it smaller + objectClean(res, { deep: false }) + + return res } protected addValidation(fn: ((input: Type) => boolean) | { fn: (input: Type) => boolean, error?: string }, error?: string) { @@ -148,6 +182,7 @@ export default abstract class SchemaItem { return this } + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents protected addPreProcess(fn: (input: unknown) => Type | unknown) { this.preProcess.push(fn) diff --git a/src/helpers.ts b/src/helpers.ts new file mode 100644 index 0000000..657bac1 --- /dev/null +++ b/src/helpers.ts @@ -0,0 +1,60 @@ +import { objectGet, objectLoop, objectSet } from '@dzeio/object-util' +import SchemaArray from 'items/array' +import SchemaBoolean from 'items/boolean' +import SchemaNullable from 'items/nullable' +import SchemaObject from 'items/object' +import type SchemaItem from 'SchemaItem' + +export function parseQuery(model: T, query: URLSearchParams, opts?: Parameters[1]): ReturnType { + const record: Record = {} + for (const [key, value] of query) { + record[key] = value + } + + return model.parse(record, opts) as ReturnType +} + +export function parseFormData(model: T, data: FormData, opts?: Parameters[1]): ReturnType { + const record: Record = {} + // console.log('VALIDATE FORM DATA data', data) + for (const [key, value] of data) { + // console.log('parse', key, value) + const isArray = model.model[key].isOfType([]) ?? false + // record[key] = isArray ? data.getAll(key) : value + objectSet(record, key.split('.').map((it) => /^\d+$/g.test(it) ? parseInt(it, 10) : it), isArray ? data.getAll(key) : value) + } + + // quick hack to handle FormData not returning Checkboxes + const handleBoolean = (value: SchemaItem, keys: Array) => { + if (value instanceof SchemaNullable) { + handleBoolean(value.unwrap(), keys) + } + + if (value instanceof SchemaArray) { + const elements: Array | undefined = objectGet(record, keys) + for (let it = 0; it < (elements?.length ?? 0); it++) { + handleBoolean(value.unwrap(), [...keys, it]) + } + } + + if (value instanceof SchemaObject) { + handleSchemaForBoolean(value.model as Record, keys) + } + + if (value instanceof SchemaBoolean) { + objectSet(record, keys, !!data.get(keys.join('.'))) + } + } + const handleSchemaForBoolean = (modl: Record, keys: Array = []) => { + objectLoop(modl, (value, key) => { + handleBoolean(value as unknown as SchemaItem, [...keys, key]) + }) + } + handleSchemaForBoolean(model.model) + // console.log(JSON.stringify(record, undefined, 2)) + return model.parse(record, opts) as ReturnType +} + +export function parseForm(model: T, form: HTMLFormElement, opts?: Parameters[1]): ReturnType { + return parseFormData(model, new FormData(form), opts) +} diff --git a/items/array.ts b/src/items/array.ts similarity index 60% rename from items/array.ts rename to src/items/array.ts index 7d00d19..e15afd6 100644 --- a/items/array.ts +++ b/src/items/array.ts @@ -1,13 +1,9 @@ -import { parceable } from "../Schema" -import SchemaItem from "../SchemaItem" -import { SchemaInfer, ValidationError, ValidationResult } from "../types" +import { parceable } from '../Schema' +import SchemaItem from '../SchemaItem' +import { SchemaInfer, ValidationError, ValidationResult } from '../types' export default class SchemaArray extends SchemaItem>> { - public constructor(public readonly values: Type) { super(arguments) } - - public unwrap() { - return this.values - } + public constructor(public readonly values: Type) { super([values]) } /** * transform the array so it only contains one of each elements @@ -22,7 +18,7 @@ export default class SchemaArray extends SchemaItem>> { // check errors from itself - let { valid, object, errors = [] } = super.parse(input, options) + const { valid, object, errors = [] } = super.parse(input, options) // skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?) if (!valid) { @@ -37,39 +33,49 @@ export default class SchemaArray extends SchemaItem = [] for (let idx = 0; idx < (object as Array).length; idx++) { const item = (object as Array)[idx] - const res = this.values.parse(item) - if (res.errors && res.errors.length > 0) { - const errors = res.errors.map((it) => ({ - ...it, - field: it.field ? `${idx}.${it.field}` : idx.toString() - })) - if (options?.fast) { - return { - valid: false, - object: clone as any, - errors: errors - } - } - errs.push(...errors) - } else { + const res: ValidationResult> = this.values.parse(item) + + // handle valid child schema + if (res.valid) { clone.push(res.object) + continue } + + // handle child errors + const errss = res.errors.map((it) => ({ + ...it, + field: it.field ? `${idx}.${it.field}` : idx.toString() + })) + + if (options?.fast) { + return { + valid: false, + object: clone, + errors: errss + } + } + errs.push(...errss) } if (errs.length > 0) { return { valid: false, - object: clone as any, + object: clone, errors: errs } } return { valid: true, - object: clone as any + object: clone } } + + public override unwrap(): Type { + return this.values + } + public override isOfType(input: unknown): input is Array> { return Array.isArray(input) } diff --git a/items/boolean.ts b/src/items/boolean.ts similarity index 88% rename from items/boolean.ts rename to src/items/boolean.ts index 0f992ea..6cfc40b 100644 --- a/items/boolean.ts +++ b/src/items/boolean.ts @@ -1,5 +1,5 @@ -import { parceable } from "../Schema" -import SchemaItem from "../SchemaItem" +import { parceable } from '../Schema' +import SchemaItem from '../SchemaItem' export default class SchemaBoolean extends SchemaItem { diff --git a/src/items/date.ts b/src/items/date.ts new file mode 100644 index 0000000..81812bd --- /dev/null +++ b/src/items/date.ts @@ -0,0 +1,8 @@ +import SchemaItem from '../SchemaItem' + +export default class SchemaDate extends SchemaItem { + + public override isOfType(input: unknown): input is Date { + return input instanceof Date + } +} diff --git a/items/enum.ts b/src/items/enum.ts similarity index 89% rename from items/enum.ts rename to src/items/enum.ts index ebea38f..ad1adc0 100644 --- a/items/enum.ts +++ b/src/items/enum.ts @@ -1,6 +1,6 @@ import SchemaItem from '../SchemaItem' -export type EnumLike = { +export interface EnumLike { [k: string]: string | number [n: number]: string } @@ -21,7 +21,7 @@ export default class SchemaEnum extends SchemaItem Object.values(this.templateEnum).includes(input), - message: `Input is not part of ${templateEnum.constructor.name}` + error: `Input is not part of ${templateEnum.constructor.name}` }) } diff --git a/items/literal.ts b/src/items/literal.ts similarity index 65% rename from items/literal.ts rename to src/items/literal.ts index c7cff1c..97cd6ff 100644 --- a/items/literal.ts +++ b/src/items/literal.ts @@ -1,10 +1,10 @@ -import SchemaItem from "../SchemaItem" +import SchemaItem from '../SchemaItem' export default class SchemaLiteral extends SchemaItem { public constructor(private readonly value: Type) { - super(arguments) + super([value]) - this.validations.push({ fn: (value) => value === this.value }) + this.validations.push({ fn: (it) => it === this.value }) } public override isOfType(input: unknown): input is Type { diff --git a/items/nullable.ts b/src/items/nullable.ts similarity index 57% rename from items/nullable.ts rename to src/items/nullable.ts index 39bb05f..4a7b732 100644 --- a/items/nullable.ts +++ b/src/items/nullable.ts @@ -1,14 +1,14 @@ -import SchemaItem from "../SchemaItem" -import { SchemaInfer, ValidationResult } from "../types" +import SchemaItem from '../SchemaItem' +import { SchemaInfer, ValidationResult } from '../types' export default class SchemaNullable extends SchemaItem | undefined> { - public constructor(public readonly child: Type) { super(arguments) } + public constructor(public readonly child: Type) { super([child]) } - public unwrap() { + public unwrap(): Type { return this.child } - public parse(input: unknown, options?: { fast?: boolean }): ValidationResult> { + public override parse(input: unknown, options?: { fast?: boolean }): ValidationResult | undefined> { if (this.isNull(input)) { return { valid: true, @@ -16,7 +16,7 @@ export default class SchemaNullable extends SchemaItem< } } - return this.child.parse(input) + return this.child.parse(input, options) } public override isOfType(input: unknown): input is SchemaInfer | undefined { diff --git a/items/number.ts b/src/items/number.ts similarity index 100% rename from items/number.ts rename to src/items/number.ts index 2748092..2741c1a 100644 --- a/items/number.ts +++ b/src/items/number.ts @@ -3,14 +3,6 @@ import SchemaItem from '../SchemaItem' export default class SchemaNumber extends SchemaItem { - public min(...params: Parameters): this { - return this.gte(...params) - } - - public max(...params: Parameters): this { - return this.lte(...params) - } - /** * validate that the number is less or equal than {@link value} * @param value the maxumum value (inclusive) @@ -92,4 +84,12 @@ export default class SchemaNumber extends SchemaItem { public override isOfType(input: unknown): input is number { return typeof input === 'number' && !Number.isNaN(input) } + + public min(...params: Parameters): this { + return this.gte(...params) + } + + public max(...params: Parameters): this { + return this.lte(...params) + } } diff --git a/items/object.ts b/src/items/object.ts similarity index 59% rename from items/object.ts rename to src/items/object.ts index edeb67b..d769948 100644 --- a/items/object.ts +++ b/src/items/object.ts @@ -1,21 +1,21 @@ -import { isObject, objectLoop, objectClone } from '@dzeio/object-util' -import SchemaItem from "../SchemaItem" -import { SchemaInfer, ValidationResult } from "../types" +import { isObject, objectClone, objectLoop } from '@dzeio/object-util' +import SchemaItem from '../SchemaItem' +import { SchemaInfer, ValidationResult } from '../types' -type ModelInfer>> = { +type ModelInfer> = { [key in keyof M]: SchemaInfer } -export default class SchemaObject>> extends SchemaItem> { - public id: string = 'object' +export default class SchemaObject = Record> extends SchemaItem> { + public id = 'object' public constructor(public readonly model: T) { - super(arguments) + super([model]) } public override parse(input: unknown, options?: { fast?: boolean }): ValidationResult> { // check errors from itself - let { valid, object, errors = [] } = super.parse(objectClone(input), options) + const { valid, object, errors = [] } = super.parse(input, options) // skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?) if (!valid) { @@ -26,20 +26,26 @@ export default class SchemaObject>> ext } as ValidationResult> } + const clone = objectClone(object) + // loop through the childs objectLoop(this.model, (childSchema, key) => { - const childValue = object![key] + const childValue = clone[key] // parse the child const child = childSchema.parse(childValue) // add errors - if ((child.errors?.length ?? 0) > 0) { - errors.push(...child.errors!) + if (!child.valid) { + errors.push(...child.errors.map((it) => ({ + ...it, + field: it.field ? `${key}.${it.field}` : key + }))) } // @ts-expect-error while it's a generic we know by proof above that it's valid ! - object![key] = child.object + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + clone[key] = child.object // skip rest of items if current one is invalid return child.valid || !options?.fast @@ -49,7 +55,7 @@ export default class SchemaObject>> ext return { valid: errors.length === 0, errors: errors, - object: object + object: clone } as ValidationResult> } diff --git a/src/items/record.ts b/src/items/record.ts new file mode 100644 index 0000000..3303810 --- /dev/null +++ b/src/items/record.ts @@ -0,0 +1,55 @@ +import { isObject, objectLoop } from '@dzeio/object-util' +import SchemaItem from '../SchemaItem' +import { SchemaInfer, ValidationResult } from '../types' + +export default class SchemaRecord extends SchemaItem, SchemaInfer>> { + + public constructor(private readonly keys: Keys, private readonly values: Values) { + super([keys, values]) + } + + public parse(input: unknown, options?: { fast?: boolean }): ValidationResult, SchemaInfer>> { + + // check errors from itself + const { valid, object, errors = [] } = super.parse(input, options) + + // skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?) + if (!valid) { + return { + valid, + object, + errors + } as ValidationResult> + } + + const clone: Partial> = {} + objectLoop(object, (value, key: string | number) => { + const res1 = this.keys.parse(key) + const res2 = this.values.parse(value) + if (!res1.valid || !res2.valid) { + errors.push(...((res1.errors ?? []).concat(...(res2.errors ?? []))).map((it) => ({ + message: it.message, + field: it.field ? `${key as string}.${it.field}` : key.toString() + }))) + } else { + // @ts-expect-error normal behavior + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access + clone[res1.object] = res2.object + } + + // skip completion if fast is enabled + return errors.length === 0 || !options?.fast + }) + + // answer ! + return { + valid: errors.length === 0, + errors: errors, + object: clone + } as ValidationResult> + } + + public override isOfType(input: unknown): input is Record, SchemaInfer> { + return isObject(input) && Object.prototype.toString.call(input) === '[object Object]' + } +} diff --git a/items/string.ts b/src/items/string.ts similarity index 95% rename from items/string.ts rename to src/items/string.ts index e4518e1..974195b 100644 --- a/items/string.ts +++ b/src/items/string.ts @@ -1,16 +1,7 @@ -import { parceable } from "../Schema" -import SchemaItem from "../SchemaItem" +import { parceable } from '../Schema' +import SchemaItem from '../SchemaItem' export default class SchemaString extends SchemaItem { - public id = 'string' - - public minLength(value: number, message?: string) { - return this.min(value, message) - } - - public maxLength(value: number, message?: string) { - return this.max(value, message) - } /** * force the input text to be a minimum of `value` size @@ -89,6 +80,13 @@ export default class SchemaString extends SchemaItem { return this } + public minLength(value: number, message?: string) { + return this.min(value, message) + } + + public maxLength(value: number, message?: string) { + return this.max(value, message) + } public override isOfType(input: unknown): input is string { return typeof input === 'string' diff --git a/items/union.ts b/src/items/union.ts similarity index 81% rename from items/union.ts rename to src/items/union.ts index 544c196..860f26e 100644 --- a/items/union.ts +++ b/src/items/union.ts @@ -1,8 +1,8 @@ import SchemaItem from '../SchemaItem' import { SchemaInfer, ValidationResult } from '../types' -type ItemType>> = SchemaInfer -export class SchemaUnion>> extends SchemaItem> { +type ItemType> = SchemaInfer +export default class SchemaUnion> extends SchemaItem> { private schemas: T @@ -14,7 +14,7 @@ export class SchemaUnion>> extends SchemaItem> { // check errors from itself - let { valid, object, errors = [] } = super.parse(input, options) + const { valid, object, errors = [] } = super.parse(input, options) // skip checking childs if self is not valid (maybe still try to check childs whan fast is false ?) if (!valid) { diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..e328deb --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,57 @@ +import SchemaItem from './SchemaItem' + +export type SchemaInfer = Type extends SchemaItem ? X : never +export type Infer = SchemaInfer + +export interface ValidationError { + message: string + field?: string + value?: unknown +} + +export type ValidationResult = { + object: T + valid: true + errors?: undefined +} | { + valid: false + object?: (T extends object ? Partial : T) | undefined + errors: Array +} + +export type ValidationResultOld = { + object: T + valid: true + error?: undefined +} | { + valid: false + object?: (T extends object ? Partial : T) | undefined + error: Array +} + +export interface SchemaJSON { + i: string + a?: Array | undefined + c?: Array | undefined + f?: Array<{ + n: string + a?: Array | undefined + }> | undefined +} + +/** +* @deprecated use `SchemaJSON` +*/ +export type SchemaItemJSON = SchemaJSON + +/** +* @deprecated use `Record` +*/ +export type Model = Record + +/** +* @deprecated +*/ +export type ModelInfer = { + [key in keyof M]: SchemaInfer +} diff --git a/tests/Schema.test.ts b/tests/Schema.test.ts index e8984de..7da8717 100644 --- a/tests/Schema.test.ts +++ b/tests/Schema.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'bun:test' -import s from '../Schema' +import s from '../src/Schema' test('number enum', () => { enum Test { @@ -74,6 +74,13 @@ test('object', () => { expect(schema.parse({ a: 'a', b: '1' }).valid).toBe(false) }) + +test('record', () => { + const schema = s.record(s.string(), s.number()) + expect(schema.parse({ a: 1, b: 2 }).valid).toBe(true) + expect(schema.parse({ a: 1, b: '1' }).valid).toBe(false) +}) + test('string', () => { const schema = s.string() expect(schema.parse('1').valid).toBe(true) diff --git a/tsconfig.json b/tsconfig.json index 4a78121..391af21 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,34 @@ { - "exclude": [ - "cypress" + "include": [ + "src", ], "compilerOptions": { + // Compilation "baseUrl": "src", + "target": "ES2019", // Follow NodeJS oldest supported LTS and use version from https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping + "module": "commonjs", + "resolveJsonModule": true, + "moduleResolution": "node", + "esModuleInterop": true, "experimentalDecorators": true, - "emitDecoratorMetadata": true + "emitDecoratorMetadata": true, + "skipLibCheck": true, + "allowJs": true, + "pretty": true, + "allowSyntheticDefaultImports": true, + // Type Checking + "forceConsistentCasingInFileNames": true, + "alwaysStrict": true, + "strict": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true } } diff --git a/types.d.ts b/types.d.ts deleted file mode 100644 index a862733..0000000 --- a/types.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import SchemaItem from "./SchemaItem" - -export type SchemaInfer = Type extends SchemaItem ? X : never - -export interface ValidationError { - message: string - field?: string - value?: unknown -} - -export type ValidationResult = { - object: T - valid: true - errors?: undefined -} | { - valid: false - object?: (T extends object ? Partial : T) | undefined - errors: Array -} - -export interface SchemaJSON { - i: string - a?: Array | undefined - c?: Array | undefined - f?: Array<{ - n: string - a?: Array | undefined - }> | undefined -}