diff --git a/hammer.mjs b/hammer.mjs index 67517cf..d61ea01 100644 --- a/hammer.mjs +++ b/hammer.mjs @@ -1,10 +1,11 @@ +import * as Build from './task/build' import * as Fs from 'node:fs' // ------------------------------------------------------------------ // Benchmark // ------------------------------------------------------------------ export async function benchmark(target = 'target/benchmark') { - await shell(`hammer run benchmark/index.ts --dist ${target}`) + await shell(`hammer run task/benchmark/index.ts --dist ${target}`) } // ------------------------------------------------------------------ // Clean @@ -23,7 +24,7 @@ export async function start() { // Format // ------------------------------------------------------------------------------- export async function format() { - await shell('prettier --no-semi --single-quote --print-width 240 --trailing-comma all --write test src benchmark example/index.ts') + await shell('prettier --no-semi --single-quote --print-width 240 --trailing-comma all --write test src example/index.ts') } // ------------------------------------------------------------------ @@ -38,13 +39,16 @@ export async function test(filter = '') { // ------------------------------------------------------------------ export async function build_check(target = 'target/build') { const { version } = JSON.parse(Fs.readFileSync('package.json', 'utf8')) - await shell(`cd ${target} && attw sinclair-typebox-adapter-${version}.tgz --ignore-rules unexpected-module-syntax`) + await shell(`cd ${target} && attw sinclair-typebox-adapter-${version}.tgz`) } export async function build(target = 'target/build') { await test() await clean() - await shell(`tsc -p src/tsconfig.json --outDir ${target} --declaration`) - await folder(target).add('package.json') + await Promise.all([ + Build.Package.build(target), + Build.Esm.build(target), + Build.Cjs.build(target), + ]) await folder(target).add('readme.md') await folder(target).add('license') await shell(`cd ${target} && npm pack`) diff --git a/package-lock.json b/package-lock.json index 53a82d8..e23753d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sinclair/typebox-adapter", - "version": "0.8.2", + "version": "0.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox-adapter", - "version": "0.8.2", + "version": "0.9.0", "license": "MIT", "devDependencies": { "@arethetypeswrong/cli": "^0.17.2", @@ -18,11 +18,11 @@ "typescript": "^5.7.2" }, "optionalDependencies": { - "valibot": ">=1.0.0-beta.9", - "zod": ">=3.24.1" + "valibot": "^1.0.0-beta.11", + "zod": "^3.24.1" }, "peerDependencies": { - "@sinclair/typebox": ">=0.34.13" + "@sinclair/typebox": "^0.34.13" } }, "node_modules/@andrewbranch/untar.js": { @@ -32,12 +32,12 @@ "dev": true }, "node_modules/@arethetypeswrong/cli": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.2.tgz", - "integrity": "sha512-/u2VcQJ8PKc4hcao/vXnHrYLEI/sQqKarbHi+NEIfvdymaW5o62XOCXy2yvalQa/vR+AAD/QNEgAUzHo5f7hrw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.3.tgz", + "integrity": "sha512-wI9ZSTweunmzHboSyYtWRFpba9fM9mpX1g7EUoRr+86zHSd7NR7svb6EmJD2hv1V+SoisB2fERu6EQGGEfQ8oQ==", "dev": true, "dependencies": { - "@arethetypeswrong/core": "0.17.2", + "@arethetypeswrong/core": "0.17.3", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", @@ -53,9 +53,9 @@ } }, "node_modules/@arethetypeswrong/core": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.2.tgz", - "integrity": "sha512-JYeLgS4rQ2l3gHCabaka3atsEyskfpx+WqUbo+6l8LApILJgr0/XDb7KNC9Ovevp4iPVF2Q73oshpgOKJ3uDRQ==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.3.tgz", + "integrity": "sha512-2TB7O5JmC7UX7QHRGGftxRVQjV4Ce6oOIDGIDDERyT9dQ8lK/tRGfFubzO80rWeXm/gSrA8jirlXSWSE1i5ynQ==", "dev": true, "dependencies": { "@andrewbranch/untar.js": "^1.0.3", @@ -126,18 +126,6 @@ "node": ">=12" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/@isaacs/cliui/node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -161,38 +149,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "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/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -240,9 +196,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "version": "22.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz", + "integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==", "dev": true, "dependencies": { "undici-types": "~6.20.0" @@ -483,6 +439,44 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "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/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1696,7 +1690,16 @@ "node": ">=8" } }, - "node_modules/strip-ansi": { + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -1708,6 +1711,42 @@ "node": ">=8" } }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "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", @@ -1730,15 +1769,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1813,9 +1843,9 @@ } }, "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "devOptional": true, "bin": { "tsc": "bin/tsc", @@ -1841,9 +1871,9 @@ } }, "node_modules/valibot": { - "version": "1.0.0-beta.9", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.9.tgz", - "integrity": "sha512-yEX8gMAZ2R1yI2uwOO4NCtVnJQx36zn3vD0omzzj9FhcoblvPukENIiRZXKZwCnqSeV80bMm8wNiGhQ0S8fiww==", + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.11.tgz", + "integrity": "sha512-Ztl5Iks1Ql7Z6CwkS5oyqguN3G8tmUiNlsHpqbDt6DLMpm+eu+n8Q7f921gI3uHvNZ8xDVkd4cEJP5t+lELOfw==", "optional": true, "peerDependencies": { "typescript": ">=5" @@ -1885,17 +1915,17 @@ "dev": true }, "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/chalk/wrap-ansi?sponsor=1" @@ -1919,6 +1949,62 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "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/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -2000,12 +2086,12 @@ "dev": true }, "@arethetypeswrong/cli": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.2.tgz", - "integrity": "sha512-/u2VcQJ8PKc4hcao/vXnHrYLEI/sQqKarbHi+NEIfvdymaW5o62XOCXy2yvalQa/vR+AAD/QNEgAUzHo5f7hrw==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.3.tgz", + "integrity": "sha512-wI9ZSTweunmzHboSyYtWRFpba9fM9mpX1g7EUoRr+86zHSd7NR7svb6EmJD2hv1V+SoisB2fERu6EQGGEfQ8oQ==", "dev": true, "requires": { - "@arethetypeswrong/core": "0.17.2", + "@arethetypeswrong/core": "0.17.3", "chalk": "^4.1.2", "cli-table3": "^0.6.3", "commander": "^10.0.1", @@ -2015,9 +2101,9 @@ } }, "@arethetypeswrong/core": { - "version": "0.17.2", - "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.2.tgz", - "integrity": "sha512-JYeLgS4rQ2l3gHCabaka3atsEyskfpx+WqUbo+6l8LApILJgr0/XDb7KNC9Ovevp4iPVF2Q73oshpgOKJ3uDRQ==", + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.3.tgz", + "integrity": "sha512-2TB7O5JmC7UX7QHRGGftxRVQjV4Ce6oOIDGIDDERyT9dQ8lK/tRGfFubzO80rWeXm/gSrA8jirlXSWSE1i5ynQ==", "dev": true, "requires": { "@andrewbranch/untar.js": "^1.0.3", @@ -2065,12 +2151,6 @@ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "dependencies": { - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, "emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", @@ -2087,26 +2167,6 @@ "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } } } }, @@ -2145,9 +2205,9 @@ "dev": true }, "@types/node": { - "version": "22.10.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", - "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "version": "22.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz", + "integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==", "dev": true, "requires": { "undici-types": "~6.20.0" @@ -2318,6 +2378,34 @@ "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } } }, "color-convert": { @@ -3071,6 +3159,23 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "string-width-cjs": { @@ -3082,15 +3187,6 @@ "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" }, "dependencies": { "ansi-regex": { @@ -3098,9 +3194,27 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } } } }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, "strip-ansi-cjs": { "version": "npm:strip-ansi@6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3171,9 +3285,9 @@ } }, "typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", "devOptional": true }, "undici-types": { @@ -3189,9 +3303,9 @@ "dev": true }, "valibot": { - "version": "1.0.0-beta.9", - "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.9.tgz", - "integrity": "sha512-yEX8gMAZ2R1yI2uwOO4NCtVnJQx36zn3vD0omzzj9FhcoblvPukENIiRZXKZwCnqSeV80bMm8wNiGhQ0S8fiww==", + "version": "1.0.0-beta.11", + "resolved": "https://registry.npmjs.org/valibot/-/valibot-1.0.0-beta.11.tgz", + "integrity": "sha512-Ztl5Iks1Ql7Z6CwkS5oyqguN3G8tmUiNlsHpqbDt6DLMpm+eu+n8Q7f921gI3uHvNZ8xDVkd4cEJP5t+lELOfw==", "optional": true, "requires": {} }, @@ -3217,14 +3331,39 @@ "dev": true }, "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", "dev": true, "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + } } }, "wrap-ansi-cjs": { @@ -3236,6 +3375,23 @@ "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "y18n": { diff --git a/package.json b/package.json index 9eff098..342149a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sinclair/typebox-adapter", - "version": "0.8.2", + "version": "0.9.0", "description": "Integrate Valibot and Zod with TypeBox", "author": "sinclairzx81", "license": "MIT", @@ -17,32 +17,12 @@ "build": "hammer task build", "publish": "hammer task publish" }, - "main": "index.js", - "module": "index.js", - "exports": { - ".": { - "import": "./index.js", - "types": "./index.d.ts" - }, - "./typebox": { - "import": "./typebox.js", - "types": "./typebox.d.ts" - }, - "./zod": { - "import": "./zod.js", - "types": "./zod.d.ts" - }, - "./valibot": { - "import": "./valibot.js", - "types": "./valibot.d.ts" - } - }, "peerDependencies": { - "@sinclair/typebox": ">=0.34.13" + "@sinclair/typebox": "^0.34.13" }, "optionalDependencies": { - "valibot": ">=1.0.0-beta.9", - "zod": ">=3.24.1" + "valibot": "^1.0.0-beta.11", + "zod": "^3.24.1" }, "devDependencies": { "@arethetypeswrong/cli": "^0.17.2", diff --git a/readme.md b/readme.md index 92faa43..6ca8a24 100644 --- a/readme.md +++ b/readme.md @@ -26,6 +26,8 @@ $ npm install @sinclair/typebox-adapter --save TypeBox Adapter converts Valibot and Zod Types into TypeBox compatible schematics +[TypeScript Example](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgIQgDzgXzgMyhEOAcgAEBnYAOwGMAbAQ2CgHoYBPMAUwCN0BaegBN6YGJyhEAUKEixEcAMox6MYNSy58hUhRoMmrDj3RSZ0eACo49MnABumgsTv1awXjFPhzcKzbgAXo7aARCCUpLMzHAAaq7uEPAwEHAAKkaoaJKS7FyxcAC8isqq1AA8uZwQOLEAfNnUEJRk8DGFKOgAFHYAdBDcAFac1DCdSHATk1PTMzNRcI3Nre0IkhNoAFz2PZQAriDc4p0AlAA0sxeXVxPzE5VbRP1DI0Sna3BsW717B0dn1wDAbc4FBOABHXZMTiCLYAbSIaFexDYSKIASIAF03hMAl8dvtDlAToCSVdgWB8FxYMBOGQtqtMMdjqSWay4MD1vS4PdiD9CUQsNi2cKSRyPlyeUQ+eIBZghSKFZcxbj5JLpRIsO9FdrpsDMFqdYb5vrItEAFphbkpdJcTLZSpwM3tJQqNQVIzVR31SSLFqO9qZToBPqDYajcaG9nRX3wM1bVIAeVDIzKqwm9C2wZaUCoAHMTudI0roun40oc5Rc0LuJmetm8wWi8XJjW0uW80LqLX65XiU2LsCu22YBXc5JGcz+8LjbUgA) + ```typescript import { Box } from '@sinclair/typebox-adapter' @@ -117,15 +119,15 @@ Results show validate performance for the type. ┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐ │ (index) │ library │ using │ iterations │ elapsed │ ├─────────┼────────────────┼────────────────────┼────────────┼────────────┤ -│ 0 │ 'valibot ' │ 'valibot ' │ 10000000 │ '1911 ms ' │ -│ 1 │ 'valibot ' │ 'typebox:value ' │ 10000000 │ '1200 ms ' │ -│ 2 │ 'valibot ' │ 'typebox:compile ' │ 10000000 │ '47 ms ' │ +│ 0 │ 'valibot ' │ 'valibot ' │ 10000000 │ '1534 ms ' │ +│ 1 │ 'valibot ' │ 'typebox:value ' │ 10000000 │ '1377 ms ' │ +│ 2 │ 'valibot ' │ 'typebox:compile ' │ 10000000 │ '46 ms ' │ └─────────┴────────────────┴────────────────────┴────────────┴────────────┘ ┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐ │ (index) │ library │ using │ iterations │ elapsed │ ├─────────┼────────────────┼────────────────────┼────────────┼────────────┤ -│ 0 │ 'zod ' │ 'zod ' │ 10000000 │ '4429 ms ' │ -│ 1 │ 'zod ' │ 'typebox:value ' │ 10000000 │ '1170 ms ' │ +│ 0 │ 'zod ' │ 'zod ' │ 10000000 │ '4669 ms ' │ +│ 1 │ 'zod ' │ 'typebox:value ' │ 10000000 │ '1359 ms ' │ │ 2 │ 'zod ' │ 'typebox:compile ' │ 10000000 │ '47 ms ' │ └─────────┴────────────────┴────────────────────┴────────────┴────────────┘ ``` diff --git a/src/box.ts b/src/box.ts index eddfd7d..a1c6cef 100644 --- a/src/box.ts +++ b/src/box.ts @@ -27,9 +27,9 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ import { TSchema, KindGuard, Unknown, type TUnknown } from '@sinclair/typebox' -import * as TypeBox from './typebox' -import * as Valibot from './valibot' -import * as Zod from './zod' +import * as TypeBox from './typebox/index' +import * as Valibot from './valibot/index' +import * as Zod from './zod/index' /** Converts a Zod, Valibot or TypeBox Type to a TypeBox Type */ // prettier-ignore diff --git a/src/typebox.ts b/src/typebox/box.ts similarity index 100% rename from src/typebox.ts rename to src/typebox/box.ts diff --git a/src/typebox/index.ts b/src/typebox/index.ts new file mode 100644 index 0000000..a89712c --- /dev/null +++ b/src/typebox/index.ts @@ -0,0 +1,29 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * from './box' diff --git a/src/valibot.ts b/src/valibot/box.ts similarity index 99% rename from src/valibot.ts rename to src/valibot/box.ts index a4d4159..8c22d2a 100644 --- a/src/valibot.ts +++ b/src/valibot/box.ts @@ -418,12 +418,12 @@ export interface TNaN = v.NanSchema> extends static: v.InferOutput type: Type } -function NaN>(type: Type, options?: tb.SchemaOptions): TNaN { +function _NaN>(type: Type, options?: tb.SchemaOptions): TNaN { return tb.CreateType({ [tb.Kind]: 'ValibotNaN', type }, options) as never } type TFromNaN> = tb.Ensure> function FromNaN(type: BaseSchema): tb.TSchema { - return NaN(type as v.NanSchema, Options(type)) + return _NaN(type as v.NanSchema, Options(type)) } // ------------------------------------------------------------------ // Never diff --git a/src/valibot/index.ts b/src/valibot/index.ts new file mode 100644 index 0000000..a89712c --- /dev/null +++ b/src/valibot/index.ts @@ -0,0 +1,29 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * from './box' diff --git a/src/zod.ts b/src/zod/box.ts similarity index 99% rename from src/zod.ts rename to src/zod/box.ts index e44816c..3c87177 100644 --- a/src/zod.ts +++ b/src/zod/box.ts @@ -231,7 +231,7 @@ function FromReadonly(def: Def): tb.TSchema { // ------------------------------------------------------------------ // Record // ------------------------------------------------------------------ -export type TFromRecord = tb.Ensure, TFromType>> +type TFromRecord = tb.Ensure, TFromType>> function FromRecord(def: Def): tb.TSchema { return tb.Record(FromType(def.keyType), FromType(def.valueType)) } diff --git a/src/zod/index.ts b/src/zod/index.ts new file mode 100644 index 0000000..a89712c --- /dev/null +++ b/src/zod/index.ts @@ -0,0 +1,29 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * from './box' diff --git a/benchmark/index.ts b/task/benchmark/index.ts similarity index 98% rename from benchmark/index.ts rename to task/benchmark/index.ts index c69f659..7583aa2 100644 --- a/benchmark/index.ts +++ b/task/benchmark/index.ts @@ -81,5 +81,7 @@ function valibot_using_compiler() { return benchmark('valibot', 'typebox:compile', () => T.Check({ x: 'hello', y: 42, z: true })) } +console.log('running benchmark') console.table([valibot(), valibot_using_value(), valibot_using_compiler()]) console.table([zod(), zod_using_value(), zod_using_compiler()]) + diff --git a/task/build/cjs/build.ts b/task/build/cjs/build.ts new file mode 100644 index 0000000..6903a9a --- /dev/null +++ b/task/build/cjs/build.ts @@ -0,0 +1,38 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { removeNotices } from '../notices/remove-notices' +import { compile } from './compile' + +/** Builds the CommonJS version of this package */ +export async function build(target: string) { + console.log('building...cjs') + const buildTarget = `${target}/build/cjs` + await compile(buildTarget) + await removeNotices(buildTarget) +} diff --git a/task/build/cjs/compile.ts b/task/build/cjs/compile.ts new file mode 100644 index 0000000..de4fbef --- /dev/null +++ b/task/build/cjs/compile.ts @@ -0,0 +1,40 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +declare function shell(command: string): Promise + +// prettier-ignore +export async function compile(target: string) { + const options = [ + `--outDir ${target}`, + '--target ES2020', + '--module CommonJS', + '--declaration', + ].join(' ') + await shell(`tsc -p ./src/tsconfig.json ${options}`) +} diff --git a/task/build/esm/build.ts b/task/build/esm/build.ts new file mode 100644 index 0000000..2ea97b7 --- /dev/null +++ b/task/build/esm/build.ts @@ -0,0 +1,40 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { removeNotices } from '../notices/remove-notices' +import { convertToEsm } from './convert-to-esm' +import { compile } from './compile' + +/** Builds the ESM version of this package */ +export async function build(target: string) { + console.log('building...esm') + const buildTarget = `${target}/build/esm` + await compile(buildTarget) + await convertToEsm(buildTarget) + await removeNotices(buildTarget) +} diff --git a/task/build/esm/compile.ts b/task/build/esm/compile.ts new file mode 100644 index 0000000..c47d1a6 --- /dev/null +++ b/task/build/esm/compile.ts @@ -0,0 +1,40 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +declare function shell(command: string): Promise + +// prettier-ignore +export async function compile(target: string) { + const options = [ + `--outDir ${target}`, + '--target ES2020', + '--module ESNext', + '--declaration', + ].join(' ') + await shell(`tsc -p ./src/tsconfig.json ${options}`) +} diff --git a/task/build/esm/convert-to-esm.ts b/task/build/esm/convert-to-esm.ts new file mode 100644 index 0000000..ee1a37e --- /dev/null +++ b/task/build/esm/convert-to-esm.ts @@ -0,0 +1,110 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as Path from 'node:path' +import * as Fs from 'node:fs' + +// ------------------------------------------------------------------ +// Specifier Rewrite +// ------------------------------------------------------------------ + +// prettier-ignore +function replaceInlineImportSpecifiers(content: string): string { + const pattern = /import\((.*?)\)/g + while (true) { + const match = pattern.exec(content) + if (match === null) return content + const captured = match[1] + if(captured.includes('.mjs')) continue + const specifier = captured.slice(1, captured.length - 1) + content = content.replace(captured, `"${specifier}.mjs"`) + } +} +// prettier-ignore +function replaceExportSpecifiers(content: string): string { + const pattern = /(export|import)(.*) from ('(.*)');/g + while(true) { + const match = pattern.exec(content) + if(match === null) return content + const captured = match[3] + const specifier = captured.slice(1, captured.length - 1) + content = content.replace(captured, `'${specifier}.mjs'`) + } +} +function replaceSpecifiers(content: string): string { + const pass1 = replaceExportSpecifiers(content) + const pass2 = replaceInlineImportSpecifiers(pass1) + return pass2 +} + +// ------------------------------------------------------------------ +// ConvertToEsm +// ------------------------------------------------------------------ +// prettier-ignore +function shouldProcess(sourcePath: string) { + const extname = Path.extname(sourcePath) + return ['.js', '.ts'].includes(extname) +} +// prettier-ignore +function newExtension(extname: string) { + return ( + extname === '.js' ? '.mjs' : + extname === '.ts' ? '.mts' : + extname + ) +} +// prettier-ignore +function processFile(sourcePath: string) { + if(!shouldProcess(sourcePath)) return + const extname = Path.extname(sourcePath) + const dirname = Path.dirname(sourcePath) + const basename = Path.basename(sourcePath, extname) + const new_extname = newExtension(extname) + const sourceContent = Fs.readFileSync(sourcePath, 'utf-8') + const targetContent = replaceSpecifiers(sourceContent) + const targetPath = `${Path.join(dirname, basename)}${new_extname}` + Fs.writeFileSync(sourcePath, targetContent) + Fs.renameSync(sourcePath, targetPath) +} +// prettier-ignore +function processSourcePath(sourcePath: string) { + const stat = Fs.statSync(sourcePath) + if(stat.isDirectory()) return readDirectory(sourcePath) + if(stat.isFile()) return processFile(sourcePath) +} +// prettier-ignore +function readDirectory(sourceDirectory: string) { + for(const entry of Fs.readdirSync(sourceDirectory)) { + const sourcePath = Path.join(sourceDirectory, entry) + processSourcePath(sourcePath) + } +} +/** Converts the JavaScript and TypeScript declaration modules in the given source directory to use .mjs extensions */ +export function convertToEsm(sourceDirectory: string) { + readDirectory(sourceDirectory) +} diff --git a/task/build/index.ts b/task/build/index.ts new file mode 100644 index 0000000..189238a --- /dev/null +++ b/task/build/index.ts @@ -0,0 +1,31 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +export * as Package from './package/build' +export * as Esm from './esm/build' +export * as Cjs from './cjs/build' diff --git a/task/build/notices/remove-notices.ts b/task/build/notices/remove-notices.ts new file mode 100644 index 0000000..5d3c020 --- /dev/null +++ b/task/build/notices/remove-notices.ts @@ -0,0 +1,82 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as Path from 'node:path' +import * as Fs from 'node:fs' + +// ---------------------------------------------------------------------- +// Remove Module Level MIT Notice on Package Distribution +// +// The MIT copyright notice the unnecessarily increases the distribution +// size of the package, this code removes it. The MIT license is available +// in the package root. +// +// ---------------------------------------------------------------------- +// prettier-ignore +function escape(content: string) { + return content.split('').map((c) => `\\${c}`).join('') +} +// prettier-ignore +function removeNotice(content: string): string { + const open = escape('/*--------------------------------------------------------------------------') + const close = escape('---------------------------------------------------------------------------*/') + const critera = 'Permission is hereby granted, free of charge' + const pattern = new RegExp(`${open}[\\s\\S]*?${close}`, 'gm') + while (true) { + const match = pattern.exec(content) + if (match === null) return content.trimStart() + if (!match[0].includes(critera)) continue + content = content.replace(match[0], '') + } +} +// ------------------------------------------------------------------ +// Directory Enumeration +// ------------------------------------------------------------------ +// prettier-ignore +function processFile(sourcePath: string) { + const sourceContent = Fs.readFileSync(sourcePath, 'utf-8') + const targetContent = removeNotice(sourceContent) + Fs.writeFileSync(sourcePath, targetContent) +} +// prettier-ignore +function processSourcePath(sourcePath: string) { + const stat = Fs.statSync(sourcePath) + if(stat.isDirectory()) return readDirectory(sourcePath) + if(stat.isFile()) return processFile(sourcePath) +} +// prettier-ignore +function readDirectory(sourceDirectory: string) { + for(const entry of Fs.readdirSync(sourceDirectory)) { + const sourcePath = Path.join(sourceDirectory, entry) + processSourcePath(sourcePath) + } +} +/** Removes the MIT copyright notices from each source file in the given directory */ +export function removeNotices(sourceDirectory: string) { + readDirectory(sourceDirectory) +} diff --git a/task/build/package/build.ts b/task/build/package/build.ts new file mode 100644 index 0000000..1ddc400 --- /dev/null +++ b/task/build/package/build.ts @@ -0,0 +1,38 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import { createPackageJsonRedirect } from './create-package-json-redirect' +import { createPackageJson } from './create-package-json' + +/** Builds package.json and redirect directories */ +export async function build(target: string) { + console.log('building...package.json') + const submodules = ['typebox', 'valibot', 'zod'] + await createPackageJsonRedirect(target, submodules) + await createPackageJson(target, submodules) +} diff --git a/task/build/package/create-package-json-redirect.ts b/task/build/package/create-package-json-redirect.ts new file mode 100644 index 0000000..f586763 --- /dev/null +++ b/task/build/package/create-package-json-redirect.ts @@ -0,0 +1,50 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as Fs from 'node:fs' + +// prettier-ignore +function writeRedirect(target: string, submodule: string) { + Fs.mkdirSync(`${target}/${submodule}`, { recursive: true }) + Fs.writeFileSync(`${target}/${submodule}/package.json`,JSON.stringify({ + main: `../build/cjs/${submodule}/index.js`, + types: `../build/cjs/${submodule}/index.d.ts`, + }, null, 2)) +} +// -------------------------------------------------------------------------------------------------------------------------- +// Builds redirect directories for earlier versions of Node. Note that TypeScript will use these directories to +// resolve types when tsconfig.json is configured for `moduleResolution: 'node'`. This approach is referred to as +// `package-json-redirect` and enables correct type resolution in lieu of a correct end user configuration. +// +// https://github.com/andrewbranch/example-subpath-exports-ts-compat/tree/main/examples/node_modules/package-json-redirects +// -------------------------------------------------------------------------------------------------------------------------- + +// prettier-ignore +export function createPackageJsonRedirect(target: string, submodules: string[]) { + submodules.forEach((submodule) => writeRedirect(target, submodule)) +} diff --git a/task/build/package/create-package-json.ts b/task/build/package/create-package-json.ts new file mode 100644 index 0000000..1eb02ac --- /dev/null +++ b/task/build/package/create-package-json.ts @@ -0,0 +1,102 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox-adapter + +The MIT License (MIT) + +Copyright (c) 2017-2024 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as Fs from 'node:fs' +import * as Path from 'node:path' + +// prettier-ignore +export function createPackageJson(target: string, submodules: string[]) { + const content = JSON.stringify(resolvePackageJson(submodules), null, 2) + const targetPath = Path.join(target, 'package.json') + const targetDir = Path.dirname(targetPath) + Fs.mkdirSync(targetDir, { recursive: true }) + Fs.writeFileSync(targetPath, content, 'utf-8') +} +// prettier-ignore +function resolvePackageJson(submodules: string[]) { + return { + ...resolveMetadata(), + ...resolveExports(submodules) + } +} +// prettier-ignore +function resolveSubmoduleExports(submodule: string) { + return { + require: { + types: `./build/cjs/${submodule}/index.d.ts`, + default: `./build/cjs/${submodule}/index.js`, + }, + import: { + types: `./build/esm/${submodule}/index.d.mts`, + default: `./build/esm/${submodule}/index.mjs`, + } + } +} +// prettier-ignore +function resolveExports(submodules: string[]) { + const exports = submodules.reduce((acc, submodule) => { + return { ...acc, [`./${submodule}`]: resolveSubmoduleExports(submodule) } + }, { + // ... and root module + ".": { + "require": { + "types": "./build/cjs/index.d.ts", + "default": "./build/cjs/index.js", + + }, + "import": { + "types": "./build/esm/index.d.mts", + "default": "./build/esm/index.mjs", + } + } + }) + return { exports } +} +// prettier-ignore +function resolveMetadata() { + const packagePath = Path.join(process.cwd(), 'package.json') + const packageJson = JSON.parse(Fs.readFileSync(packagePath, 'utf-8')) + return { + name: packageJson.name, + version: packageJson.version, + description: packageJson.description, + keywords: packageJson.keywords, + author: packageJson.author, + license: packageJson.license, + repository: packageJson.repository, + peerDependencies: packageJson.peerDependencies, + optionalDependencies: packageJson.optionalDependencies, + // flagged by socket.dev if not present + scripts: { test: 'echo test' }, + types: "./build/cjs/index.d.ts", + main: "./build/cjs/index.js", + module: "./build/esm/index.mjs", + // disable auto bundle strategy: see https://github.com/esm-dev/esm.sh#bundling-strategy + 'esm.sh': { 'bundle': false }, + } +} diff --git a/tsconfig.json b/tsconfig.json index 62f2d9d..6d0789e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,9 +5,9 @@ "moduleResolution": "Node", "baseUrl": ".", "paths": { - "@sinclair/typebox-adapter/typebox": ["src/typebox.ts"], - "@sinclair/typebox-adapter/valibot": ["src/valibot.ts"], - "@sinclair/typebox-adapter/zod": ["src/zod.ts"], + "@sinclair/typebox-adapter/typebox": ["src/typebox/index.ts"], + "@sinclair/typebox-adapter/valibot": ["src/valibot/index.ts"], + "@sinclair/typebox-adapter/zod": ["src/zod/index.ts"], "@sinclair/typebox-adapter": ["src/index.ts"] } }