diff --git a/hammer.mjs b/hammer.mjs index d990dab21..98a7bb660 100644 --- a/hammer.mjs +++ b/hammer.mjs @@ -52,8 +52,12 @@ export async function test(filter = '') { // ------------------------------------------------------------------------------- // Build // ------------------------------------------------------------------------------- +export async function check_build(target = 'target/build') { + const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) + await shell(`cd ${target} && attw sinclair-typebox-${version}.tgz`) +} export async function build(target = 'target/build') { - // await test() + await test() await clean() await Promise.all([ Build.buildRequire(target), @@ -64,6 +68,7 @@ export async function build(target = 'target/build') { await folder(target).add('readme.md') await folder(target).add('license') await shell(`cd ${target} && npm pack`) + await check_build(target) } // ------------------------------------------------------------------------------- // Install diff --git a/license b/license index 08641fd64..88c042df0 100644 --- a/license +++ b/license @@ -1,4 +1,4 @@ -TypeBox: JSON Schema Type Builder with Static Type Resolution for TypeScript +TypeBox: Json Schema Type Builder with Static Type Resolution for TypeScript The MIT License (MIT) diff --git a/package-lock.json b/package-lock.json index f221f0031..e4e92a0cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,15 @@ { "name": "@sinclair/typebox", - "version": "0.32.0-dev-8", + "version": "0.32.0-dev-9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox", - "version": "0.32.0-dev-8", + "version": "0.32.0-dev-9", "license": "MIT", "devDependencies": { + "@arethetypeswrong/cli": "^0.13.2", "@sinclair/hammer": "^0.18.0", "@types/mocha": "^9.1.1", "@types/node": "^20.10.1", @@ -19,6 +20,59 @@ "typescript": "^5.3.2" } }, + "node_modules/@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "node_modules/@arethetypeswrong/cli": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.13.2.tgz", + "integrity": "sha512-eqRWeFFiI58xwsiUfZSdZsmNCaqqtxmSPP9554ajiCDrB/aNzq5VktVK7dNiT9PamunNeoej4KbDBnkNwVacvg==", + "dev": true, + "dependencies": { + "@arethetypeswrong/core": "0.13.2", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^6.0.0", + "semver": "^7.5.4" + }, + "bin": { + "attw": "dist/index.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@arethetypeswrong/core": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.13.2.tgz", + "integrity": "sha512-1l6ygar+6TH4o1JipWWGCEZlOhAwEShm1yKx+CgIByNjCzufbu6k9DNbDmBjdouusNRhBIOYQe1UHnJig+GtAw==", + "dev": true, + "dependencies": { + "@andrewbranch/untar.js": "^1.0.3", + "fflate": "^0.7.4", + "semver": "^7.5.4", + "typescript": "5.3.2", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@esbuild/linux-loong64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", @@ -47,6 +101,18 @@ "hammer": "hammer" } }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", @@ -110,6 +176,21 @@ "node": ">=6" } }, + "node_modules/ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "dependencies": { + "type-fest": "^3.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -134,6 +215,12 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -196,6 +283,15 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -208,6 +304,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -236,6 +345,15 @@ "node": ">=8" } }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -263,6 +381,21 @@ "fsevents": "~2.3.2" } }, + "node_modules/cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -292,6 +425,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -348,6 +490,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, "node_modules/esbuild": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", @@ -725,12 +873,31 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "node_modules/fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "dev": true + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1011,6 +1178,62 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, + "node_modules/marked-terminal": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", + "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", + "dev": true, + "dependencies": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.0", + "supports-hyperlinks": "^3.0.0" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "marked": ">=1 <11" + } + }, + "node_modules/marked-terminal/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -1084,6 +1307,21 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1207,6 +1445,15 @@ "node": ">=8.10.0" } }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "dependencies": { + "esprima": "~4.0.0" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -1245,6 +1492,21 @@ } ] }, + "node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -1254,6 +1516,18 @@ "randombytes": "^2.1.0" } }, + "node_modules/skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "dependencies": { + "unicode-emoji-modifier-base": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -1307,6 +1581,31 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1319,6 +1618,18 @@ "node": ">=8.0" } }, + "node_modules/type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", @@ -1338,6 +1649,15 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "node_modules/unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1347,6 +1667,18 @@ "punycode": "^2.1.0" } }, + "node_modules/validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "dependencies": { + "builtins": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -1400,6 +1732,12 @@ "node": ">=10" } }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -1456,6 +1794,47 @@ } }, "dependencies": { + "@andrewbranch/untar.js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz", + "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==", + "dev": true + }, + "@arethetypeswrong/cli": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.13.2.tgz", + "integrity": "sha512-eqRWeFFiI58xwsiUfZSdZsmNCaqqtxmSPP9554ajiCDrB/aNzq5VktVK7dNiT9PamunNeoej4KbDBnkNwVacvg==", + "dev": true, + "requires": { + "@arethetypeswrong/core": "0.13.2", + "chalk": "^4.1.2", + "cli-table3": "^0.6.3", + "commander": "^10.0.1", + "marked": "^9.1.2", + "marked-terminal": "^6.0.0", + "semver": "^7.5.4" + } + }, + "@arethetypeswrong/core": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.13.2.tgz", + "integrity": "sha512-1l6ygar+6TH4o1JipWWGCEZlOhAwEShm1yKx+CgIByNjCzufbu6k9DNbDmBjdouusNRhBIOYQe1UHnJig+GtAw==", + "dev": true, + "requires": { + "@andrewbranch/untar.js": "^1.0.3", + "fflate": "^0.7.4", + "semver": "^7.5.4", + "typescript": "5.3.2", + "validate-npm-package-name": "^5.0.0" + } + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true + }, "@esbuild/linux-loong64": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.15.7.tgz", @@ -1472,6 +1851,12 @@ "esbuild": "0.15.7" } }, + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true + }, "@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", @@ -1520,6 +1905,15 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, + "ansi-escapes": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz", + "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==", + "dev": true, + "requires": { + "type-fest": "^3.0.0" + } + }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1535,6 +1929,12 @@ "color-convert": "^2.0.1" } }, + "ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true + }, "anymatch": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", @@ -1588,12 +1988,31 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, "camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, + "cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "requires": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1615,6 +2034,12 @@ } } }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -1631,6 +2056,16 @@ "readdirp": "~3.6.0" } }, + "cli-table3": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", + "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "dev": true, + "requires": { + "@colors/colors": "1.5.0", + "string-width": "^4.2.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1657,6 +2092,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1698,6 +2139,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "emojilib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", + "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", + "dev": true + }, "esbuild": { "version": "0.15.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.15.7.tgz", @@ -1879,12 +2326,24 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "fflate": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", + "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "dev": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -2085,6 +2544,43 @@ "is-unicode-supported": "^0.1.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "marked": { + "version": "9.1.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz", + "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==", + "dev": true + }, + "marked-terminal": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.1.0.tgz", + "integrity": "sha512-QaCSF6NV82oo6K0szEnmc65ooDeW0T/Adcyf0fcW+Hto2GT1VADFg8dn1zaeHqzj65fqDH1hMNChGNRaC/lbkA==", + "dev": true, + "requires": { + "ansi-escapes": "^6.2.0", + "cardinal": "^2.1.1", + "chalk": "^5.3.0", + "cli-table3": "^0.6.3", + "node-emoji": "^2.1.0", + "supports-hyperlinks": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true + } + } + }, "minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -2138,6 +2634,18 @@ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", "dev": true }, + "node-emoji": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", + "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.6.0", + "char-regex": "^1.0.2", + "emojilib": "^2.4.0", + "skin-tone": "^2.0.0" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -2219,6 +2727,15 @@ "picomatch": "^2.2.1" } }, + "redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "requires": { + "esprima": "~4.0.0" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2237,6 +2754,15 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, "serialize-javascript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", @@ -2246,6 +2772,15 @@ "randombytes": "^2.1.0" } }, + "skin-tone": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", + "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "dev": true, + "requires": { + "unicode-emoji-modifier-base": "^1.0.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -2281,6 +2816,27 @@ "has-flag": "^4.0.0" } }, + "supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -2290,6 +2846,12 @@ "is-number": "^7.0.0" } }, + "type-fest": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz", + "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==", + "dev": true + }, "typescript": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.2.tgz", @@ -2302,6 +2864,12 @@ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true }, + "unicode-emoji-modifier-base": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", + "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "dev": true + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -2311,6 +2879,15 @@ "punycode": "^2.1.0" } }, + "validate-npm-package-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz", + "integrity": "sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==", + "dev": true, + "requires": { + "builtins": "^5.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2349,6 +2926,12 @@ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", diff --git a/package.json b/package.json index 1c4139d13..45140182e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sinclair/typebox", - "version": "0.32.0-dev-8", + "version": "0.32.0-dev-9", "description": "Json Schema Type Builder with Static Type Resolution for TypeScript", "keywords": [ "typescript", @@ -29,6 +29,7 @@ "publish:dev": "hammer task publish_dev" }, "devDependencies": { + "@arethetypeswrong/cli": "^0.13.2", "@sinclair/hammer": "^0.18.0", "@types/mocha": "^9.1.1", "@types/node": "^20.10.1", diff --git a/readme.md b/readme.md index 803c72408..0e2f6bcfc 100644 --- a/readme.md +++ b/readme.md @@ -103,8 +103,8 @@ License MIT - [Ajv](#typecheck-ajv) - [TypeCompiler](#typecheck-typecompiler) - [TypeSystem](#typesystem) - - [Errors](#typesystem-errors) - [Policies](#typesystem-policies) +- [ErrorFunction](#error-function) - [Workbench](#workbench) - [Codegen](#codegen) - [Ecosystem](#ecosystem) @@ -1527,49 +1527,6 @@ const C = TypeCompiler.Code(Type.String()) // const C = `return functi The TypeBox TypeSystem module provides functionality to define types above and beyond the built-in Json and JavaScript type sets. They also manage TypeBox's localization options (i18n) for error message generation and can control various assertion policies used when type checking. Configurations made to the TypeSystem module are observed by the TypeCompiler, Value and Error modules. - - -### Errors - -Use the TypeSystemErrorFunction to override validation error messages. This can be used to localize errors or create error messages for user defined types. - -```typescript -import { TypeSystemErrorFunction, ValueErrorType, DefaultErrorFunction } from '@sinclair/typebox/system' - -TypeSystemErrorFunction.Set((schema, errorType) => { // i18n override - switch(errorType) { - /* en-US */ case ValueErrorType.String: return 'Expected string' - /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu' - /* ko-KR */ case ValueErrorType.Boolean: return '예상 부울' - /* en-US */ default: return DefaultErrorFunction(schema, errorType) - } -}) -const T = Type.Object({ // const T = { ... } - x: Type.String(), - y: Type.Number(), - z: Type.Boolean() -}) -const E = [...Value.Errors(T, { // const E = [{ - x: null, // type: 48, - y: null, // schema: { ... }, - z: null // path: '/x', -})] // value: null, - // message: 'Expected string' - // }, { - // type: 34, - // schema: { ... }, - // path: '/y', - // value: null, - // message: 'Nombre attendu' - // }, { - // type: 14, - // schema: { ... }, - // path: '/z', - // value: null, - // message: '예상 부울' - // }] -``` - ### Policies @@ -1606,6 +1563,52 @@ TypeSystemPolicy.AllowNaN = true TypeSystemPolicy.AllowNullVoid = true ``` + + +## Error Function + +TypeBox error messages can be overridden by setting a custom error function. This function can be used to both localize errors as well as generate custom errors for custom types. TypeBox internally implements a DefaultErrorFunction that creates error messages using the `en-US` locale. Additional locales can be added by replicating translating the messages found in [DefaultErrorFunction](./errors/function.ts#L34). + +The following example intercepts errors for String, Number and Boolean and returns locale specific messages. The DefaultErrorFunction is used to return a default error message. + +```typescript +import { SetErrorFunction, DefaultErrorFunction, ValueErrorType } from '@sinclair/typebox/errors' + +SetErrorFunction((schema, errorType) => { // i18n override + switch(errorType) { + /* en-US */ case ValueErrorType.String: return 'Expected string' + /* fr-FR */ case ValueErrorType.Number: return 'Nombre attendu' + /* ko-KR */ case ValueErrorType.Boolean: return '예상 부울' + /* en-US */ default: return DefaultErrorFunction(schema, errorType) + } +}) +const T = Type.Object({ // const T: TObject<{ + x: Type.String(), // TString, + y: Type.Number(), // TNumber, + z: Type.Boolean() // TBoolean +}) // }> + +const E = [...Value.Errors(T, { // const E = [{ + x: null, // type: 48, + y: null, // schema: { ... }, + z: null // path: '/x', +})] // value: null, + // message: 'Expected string' + // }, { + // type: 34, + // schema: { ... }, + // path: '/y', + // value: null, + // message: 'Nombre attendu' + // }, { + // type: 14, + // schema: { ... }, + // path: '/z', + // value: null, + // message: '예상 부울' + // }] +``` + ## TypeBox Workbench diff --git a/src/compiler/index.ts b/src/compiler/index.ts index cc91cb40b..48b4c10e8 100644 --- a/src/compiler/index.ts +++ b/src/compiler/index.ts @@ -27,4 +27,4 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ export { ValueError, ValueErrorType, ValueErrorIterator } from '../errors/index' -export * from './compiler' +export { TypeCompiler, TypeCheck, type TypeCompilerCodegenOptions, type TypeCompilerLanguageOption, TypeCompilerTypeGuardError, TypeCompilerUnknownTypeError } from './compiler' diff --git a/src/errors/errors.ts b/src/errors/errors.ts index 20198717e..c7aca837c 100644 --- a/src/errors/errors.ts +++ b/src/errors/errors.ts @@ -27,10 +27,11 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ import { IsArray, IsUint8Array, IsDate, IsPromise, IsFunction, IsAsyncIterator, IsIterator, IsBoolean, IsNumber, IsBigInt, IsString, IsSymbol, IsInteger, IsNull, IsUndefined } from '../value/guard/index' -import { TypeSystemPolicy, TypeSystemErrorFunction } from '../system/index' +import { TypeSystemPolicy } from '../system/index' import { KeyOfStringResolvePattern } from '../type/keyof/index' import { TypeRegistry, FormatRegistry } from '../type/registry/index' import { ExtendsUndefinedCheck } from '../type/extends/extends-undefined' +import { GetErrorFunction } from './function' import { Deref } from '../value/deref/index' import { Hash } from '../value/hash/index' import { Kind } from '../type/symbols/index' @@ -156,7 +157,7 @@ export class ValueErrorsUnknownTypeError extends Error { // -------------------------------------------------------------------------- // EscapeKey // -------------------------------------------------------------------------- -export function EscapeKey(key: string): string { +function EscapeKey(key: string): string { return key.replace(/~/g, '~0').replace(/\//g, '~1') // RFC6901 Path } // -------------------------------------------------------------------------- @@ -183,7 +184,7 @@ export class ValueErrorIterator { // Create // -------------------------------------------------------------------------- function Create(type: ValueErrorType, schema: TSchema, path: string, value: unknown): ValueError { - return { type, schema, path, value, message: TypeSystemErrorFunction.Get()(schema, type) } + return { type, schema, path, value, message: GetErrorFunction()(schema, type) } } // -------------------------------------------------------------------------- // Types diff --git a/src/system/errors.ts b/src/errors/function.ts similarity index 90% rename from src/system/errors.ts rename to src/errors/function.ts index ab8439906..30e3c2f18 100644 --- a/src/system/errors.ts +++ b/src/errors/function.ts @@ -26,36 +26,10 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { ValueErrorType } from '../errors/errors' import { TSchema } from '../type/schema/index' import { Kind } from '../type/symbols/index' +import { ValueErrorType } from './errors' -// ------------------------------------------------------------------ -// ErrorFunction -// ------------------------------------------------------------------ -export type ErrorFunction = (schema: TSchema, type: ValueErrorType) => string -// ------------------------------------------------------------------ -// TypeSystemErrorFunction -// ------------------------------------------------------------------ -/** Manages error message providers */ -export namespace TypeSystemErrorFunction { - let errorMessageFunction: ErrorFunction = DefaultErrorFunction - /** Resets the error message function to en-us */ - export function Reset() { - errorMessageFunction = DefaultErrorFunction - } - /** Sets the error message function used to generate error messages */ - export function Set(callback: ErrorFunction) { - errorMessageFunction = callback - } - /** Gets the error message function */ - export function Get(): ErrorFunction { - return errorMessageFunction - } -} -// ------------------------------------------------------------------ -// DefaultErrorFunction -// ------------------------------------------------------------------ /** Creates an error message using en-US as the default locale */ export function DefaultErrorFunction(schema: TSchema, errorType: ValueErrorType) { switch (errorType) { @@ -189,3 +163,19 @@ export function DefaultErrorFunction(schema: TSchema, errorType: ValueErrorType) return 'Unknown error type' } } + +// ------------------------------------------------------------------ +// ErrorFunction +// ------------------------------------------------------------------ +export type ErrorFunction = (schema: TSchema, type: ValueErrorType) => string +/** Manages error message providers */ +let errorFunction: ErrorFunction = DefaultErrorFunction + +/** Sets the error function used to generate error messages */ +export function SetErrorFunction(callback: ErrorFunction) { + errorFunction = callback +} +/** Gets the error function used to generate error messages */ +export function GetErrorFunction(): ErrorFunction { + return errorFunction +} diff --git a/src/errors/index.ts b/src/errors/index.ts index 71cdce9af..b5a10ef10 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -26,4 +26,5 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -export * from './errors' +export { Errors, ValueError, ValueErrorIterator, ValueErrorType, ValueErrorsUnknownTypeError } from './errors' +export { DefaultErrorFunction, GetErrorFunction, SetErrorFunction, type ErrorFunction } from './function' diff --git a/src/index.ts b/src/index.ts index 3acbcde69..981f605cc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,7 +34,6 @@ export { PatternBoolean, PatternBooleanExact, PatternNumber, PatternNumberExact, export { TypeRegistry, FormatRegistry } from './type/registry/index' export { TypeGuard, ValueGuard } from './type/guard/index' export { CloneType, CloneRest } from './type/clone/type' -export { Clone } from './type/clone/value' // ------------------------------------------------------------------ // Type diff --git a/src/system/index.ts b/src/system/index.ts index ead7f9713..fe79f6d08 100644 --- a/src/system/index.ts +++ b/src/system/index.ts @@ -26,7 +26,5 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -export { ValueErrorType } from '../errors/errors' -export { DefaultErrorFunction, ErrorFunction, TypeSystemErrorFunction } from './errors' export { TypeSystemPolicy } from './policy' export { TypeSystem, TypeSystemDuplicateFormat, TypeSystemDuplicateTypeKind } from './system' diff --git a/src/system/policy.ts b/src/system/policy.ts index ffb7ba772..04c4a4ec2 100644 --- a/src/system/policy.ts +++ b/src/system/policy.ts @@ -28,11 +28,11 @@ THE SOFTWARE. import { IsObject, IsArray, IsNumber, IsUndefined } from '../value/guard/index' -// ------------------------------------------------------------------ -// TypeSystemPolicy -// ------------------------------------------------------------------ -/** Shared assertion routines used by the value and errors modules */ export namespace TypeSystemPolicy { + // ------------------------------------------------------------------ + // TypeSystemPolicy + // ------------------------------------------------------------------ + /** Shared assertion routines used by the value and errors modules */ /** Sets whether TypeBox should assert optional properties using the TypeScript `exactOptionalPropertyTypes` assertion policy. The default is `false` */ export let ExactOptionalPropertyTypes: boolean = false /** Sets whether arrays should be treated as a kind of objects. The default is `false` */ diff --git a/src/value/cast/cast.ts b/src/value/cast/cast.ts index d75ca1b62..8381a6ce9 100644 --- a/src/value/cast/cast.ts +++ b/src/value/cast/cast.ts @@ -77,43 +77,42 @@ export class ValueCastUnknownTypeError extends Error { // literal values are maximally awarded as literals are typically // used as union discriminator fields. // ------------------------------------------------------------------ -namespace UnionCastCreate { - function Score(schema: TSchema, references: TSchema[], value: any): number { - if (schema[Kind] === 'Object' && typeof value === 'object' && !IsNull(value)) { - const object = schema as TObject - const keys = Object.getOwnPropertyNames(value) - const entries = Object.entries(object.properties) - const [point, max] = [1 / entries.length, entries.length] - return entries.reduce((acc, [key, schema]) => { - const literal = schema[Kind] === 'Literal' && schema.const === value[key] ? max : 0 - const checks = Check(schema, references, value[key]) ? point : 0 - const exists = keys.includes(key) ? point : 0 - return acc + (literal + checks + exists) - }, 0) - } else { - return Check(schema, references, value) ? 1 : 0 - } +function ScoreUnion(schema: TSchema, references: TSchema[], value: any): number { + if (schema[Kind] === 'Object' && typeof value === 'object' && !IsNull(value)) { + const object = schema as TObject + const keys = Object.getOwnPropertyNames(value) + const entries = Object.entries(object.properties) + const [point, max] = [1 / entries.length, entries.length] + return entries.reduce((acc, [key, schema]) => { + const literal = schema[Kind] === 'Literal' && schema.const === value[key] ? max : 0 + const checks = Check(schema, references, value[key]) ? point : 0 + const exists = keys.includes(key) ? point : 0 + return acc + (literal + checks + exists) + }, 0) + } else { + return Check(schema, references, value) ? 1 : 0 } - function Select(union: TUnion, references: TSchema[], value: any): TSchema { - let [select, best] = [union.anyOf[0], 0] - for (const schema of union.anyOf) { - const score = Score(schema, references, value) - if (score > best) { - select = schema - best = score - } +} +function SelectUnion(union: TUnion, references: TSchema[], value: any): TSchema { + let [select, best] = [union.anyOf[0], 0] + for (const schema of union.anyOf) { + const score = ScoreUnion(schema, references, value) + if (score > best) { + select = schema + best = score } - return select } - export function Create(union: TUnion, references: TSchema[], value: any) { - if ('default' in union) { - return union.default - } else { - const schema = Select(union, references, value) - return Cast(schema, references, value) - } + return select +} +function CastUnion(union: TUnion, references: TSchema[], value: any) { + if ('default' in union) { + return union.default + } else { + const schema = SelectUnion(union, references, value) + return Cast(schema, references, value) } } + // ------------------------------------------------------------------ // Default // ------------------------------------------------------------------ @@ -198,7 +197,7 @@ function TTuple(schema: TTuple, references: TSchema[], value: any): any { return schema.items.map((schema, index) => Visit(schema, references, value[index])) } function TUnion(schema: TUnion, references: TSchema[], value: any): any { - return Check(schema, references, value) ? Clone(value) : UnionCastCreate.Create(schema, references, value) + return Check(schema, references, value) ? Clone(value) : CastUnion(schema, references, value) } function Visit(schema: TSchema, references: TSchema[], value: any): any { const references_ = IsString(schema.$id) ? [...references, schema] : references