``` ├── .eslintrc.js ├── .github/ ├── FUNDING.yaml ├── ISSUE_TEMPLATE/ ├── 2-bug-report.yml ├── 3-feature-request.yml ├── config.yml ├── dependabot.yml ├── workflows/ ├── ci.yml ├── publish.yml ├── .gitignore ├── .npmignore ├── .prettierrc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── benchmarks/ ├── array.ts ├── large-manual.ts ├── large.ts ├── medium-manual.ts ├── medium.ts ├── message.ts ├── multiple-queries.ts ├── quote.ts ├── small-manual.ts ├── small.ts ├── small2.ts ├── utils.ts ├── build.ts ├── bun.lock ├── example/ ├── index.ts ├── package.json ├── src/ ├── index.ts ├── test/ ├── array.test.ts ├── default.test.ts ├── index.test.ts ├── merge-intersection.test.ts ├── node/ ├── .gitignore ├── cjs/ ├── index.js ├── package.json ├── esm/ ├── index.js ├── package.json ├── record.test.ts ├── ref.test.ts ├── sample.test.ts ├── sanitize-auto.test.ts ├── sanitize-manual.test.ts ├── sanitize-throw.test.ts ├── tuple.test.ts ├── utils.ts ├── tsconfig.dts.json ├── tsconfig.json ``` ## /.eslintrc.js ```js path="/.eslintrc.js" module.exports = { "env": { "es2021": true, "node": true }, "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ], "parser": "@typescript-eslint/parser", "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "plugins": [ "@typescript-eslint" ], "rules": { "@typescript-eslint/ban-types": 'off', '@typescript-eslint/no-explicit-any': 'off' }, "ignorePatterns": ["example/*", "tests/**/*"] } ``` ## /.github/FUNDING.yaml ```yaml path="/.github/FUNDING.yaml" github: SaltyAom ``` ## /.github/ISSUE_TEMPLATE/2-bug-report.yml ```yml path="/.github/ISSUE_TEMPLATE/2-bug-report.yml" name: 🐛 Bug Report description: Report an issue that should be fixed labels: [bug] body: - type: markdown attributes: value: | Thank you for submitting a bug report. It helps make Elysia.JS better. If you need help or support using Elysia.JS, and are not reporting a bug, please head over to Q&A discussions [Discussions](https://github.com/elysiajs/elysia/discussions/categories/q-a), where you can ask questions in the Q&A forum. Make sure you are running the version of Elysia.JS and Bun.Sh The bug you are experiencing may already have been fixed. Please try to include as much information as possible. - type: input attributes: label: What version of Elysia is running? description: Copy the output of `Elysia --revision` - type: input attributes: label: What platform is your computer? description: | For MacOS and Linux: copy the output of `uname -mprs` For Windows: copy the output of `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` in the PowerShell console - type: textarea attributes: label: What steps can reproduce the bug? description: Explain the bug and provide a code snippet that can reproduce it. validations: required: true - type: textarea attributes: label: What is the expected behavior? description: If possible, please provide text instead of a screenshot. - type: textarea attributes: label: What do you see instead? description: If possible, please provide text instead of a screenshot. - type: textarea attributes: label: Additional information description: Is there anything else you think we should know? - type: input attributes: label: Have you try removing the `node_modules` and `bun.lockb` and try again yet? description: rm -rf node_modules && bun.lockb ``` ## /.github/ISSUE_TEMPLATE/3-feature-request.yml ```yml path="/.github/ISSUE_TEMPLATE/3-feature-request.yml" name: 🚀 Feature Request description: Suggest an idea, feature, or enhancement labels: [enhancement] body: - type: markdown attributes: value: | Thank you for submitting an idea. It helps make Elysia.JS better. If you want to discuss Elysia.JS, or learn how others are using Elysia.JS, please head to our [Discord](https://discord.com/invite/y7kH46ZE) server, where you can chat among the community. - type: textarea attributes: label: What is the problem this feature would solve? validations: required: true - type: textarea attributes: label: What is the feature you are proposing to solve the problem? validations: required: true - type: textarea attributes: label: What alternatives have you considered? ``` ## /.github/ISSUE_TEMPLATE/config.yml ```yml path="/.github/ISSUE_TEMPLATE/config.yml" blank_issues_enabled: true contact_links: - name: 📗 Documentation Issue url: https://github.com/elysiajs/documentation/issues/new/choose about: Head over to our Documentation repository! - name: 💬 Ask a Question url: https://discord.gg/eaFJ2KDJck about: Head over to our Discord! ``` ## /.github/dependabot.yml ```yml path="/.github/dependabot.yml" version: 2 updates: - package-ecosystem: 'npm' directory: './' schedule: interval: 'daily' - package-ecosystem: 'github-actions' directory: './' schedule: interval: 'daily' ``` ## /.github/workflows/ci.yml ```yml path="/.github/workflows/ci.yml" name: Build and Test on: push: pull_request: jobs: build: name: Build and test code runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Setup bun uses: oven-sh/setup-bun@v1 with: bun-version: latest - name: Install packages run: bun install - name: Build code run: bun run build - name: Test run: bun run test ``` ## /.github/workflows/publish.yml ```yml path="/.github/workflows/publish.yml" name: Publish on: release: types: [published] defaults: run: shell: bash permissions: id-token: write env: # Enable debug logging for actions ACTIONS_RUNNER_DEBUG: true jobs: publish-npm: name: 'Publish: npm Registry' runs-on: ubuntu-latest steps: - name: 'Checkout' uses: actions/checkout@v4 - name: 'Setup Bun' uses: oven-sh/setup-bun@v1 with: bun-version: latest registry-url: "https://registry.npmjs.org" - uses: actions/setup-node@v4 with: node-version: '20.x' registry-url: 'https://registry.npmjs.org' - name: Install packages run: bun install - name: Build code run: bun run build - name: Test run: bun run test - name: 'Publish' env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} run: | npm publish --provenance --access=public ``` ## /.gitignore ```gitignore path="/.gitignore" .DS_Store node_modules .pnpm-debug.log dist ``` ## /.npmignore ```npmignore path="/.npmignore" .git .github .gitignore .prettierrc .cjs.swcrc .es.swcrc bun.lockb bun.lock node_modules tsconfig.json pnpm-lock.yaml jest.config.js nodemon.json benchmarks example tests test CHANGELOG.md .eslintrc.js tsconfig.cjs.json tsconfig.esm.json tsconfig.dts.json build.ts src ``` ## /.prettierrc ```prettierrc path="/.prettierrc" { "useTabs": true, "tabWidth": 4, "semi": false, "singleQuote": true, "trailingComma": "none" } ``` ## /CHANGELOG.md # 0.1.7 - 25 Apr 2025 Improvement: - improve array operation # 0.1.6 - 24 Apr 2025 Improvement: - reduce instruction for string placement - inline regex test to each string # 0.1.5 - 22 Apr 2025 Improvement: - add `schema.trusted` for string - improve string placement when using `t.String({ trusted: true })` and `sanitize: manual` # 0.1.4 - 27 Mar 2025 Improvement: - improve array performance by avoiding unnecessary closure reference # 0.1.3 - 14 Mar 2025 Bug fix: - support `t.Module`, `t.Ref` # 0.1.2 - 4 Mar 2025 Bug fix: - handle primitive type when array is root # 0.1.1 - 4 Mar 2025 Feature: - support Record Improvement: - add Tuple test case # 0.1.0 - 5 Feb 2025 Feature: - replace `arrayItems.join('",\"')` in favour of inline `joinStringArray` to improve performance - add `sanitize` option for handling unsafe character - new behavior is `sanitize`, previously is equivalent to `manual` - support inline a literal value # 0.0.2 - 4 Feb 2025 Feature: - support integer, bigint, date, datetime - support `default` value for optional, and nullable on primitive type Improvement: - refactor properties instruction generation - flatten optional properties to speed up runtime performance in Bun - remove negate where possible in runtime - use stringified null to prevent `toString()` call Bug fix: - `integer` is using `JSON.stringify` # 0.0.1 - 3 Feb 2025 Bug fix: - separate optional comma flag between closure # 0.0.0 - 3 Feb 2025 Feature: - initial release ## /LICENSE ``` path="/LICENSE" Copyright 2022 saltyAom 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. ``` ## /README.md # JSON Accelerator Accelerate JSON stringification by providing OpenAPI/TypeBox model. By providing model ahead of time, the library will generate a function that will serialize the object into a JSON string. ``` $ npx tsx benchmarks/medium-manual.ts clk: ~3.02 GHz cpu: Apple M1 Max runtime: node 22.6.0 (arm64-darwin) summary JSON Accelerator 2.12x faster than JSON Stingify 2.66x faster than Fast Json Stringify ``` ## Installation ```bash # Using either one of the package manager npm install json-accelerator yarn add json-accelerator pnpm add json-accelerator bun add json-accelerator ``` ## Usage It is designed to be used with [TypeBox](https://github.com/sinclairzx81/typebox) but an OpenAPI schema should also work. ```typescript import { Type as t } from '@sinclair/typebox' import { createAccelerator } from 'json-accelerator' const shape = t.Object({ name: t.String(), id: t.Number() }) const value = { id: 0, name: 'saltyaom' } satisfies typeof shape.static const encode = createAccelerator(shape) console.log(encode(value)) // {"id":0,"name":"saltyaom"} ``` ## Caveat This library **WILL NOT** check for the type validity of the schema, it is expected that the schema is **always** correct. This can be achieved by checking the input validity with TypeBox before passing it to the accelerator. ```typescript import { Type as t } from '@sinclair/typebox' import { TypeCompiler } from '@sinclair/typebox/compiler' import { createAccelerator } from 'json-accelerator' const shape = t.Object({ name: t.String(), id: t.Number() }) const value = { id: 0, name: 'saltyaom' } const guard = TypeCompiler.Compile(shape) const encode = createAccelerator(shape) if (guard.Check(value)) encode(value) ``` If the shape is incorrect, the output will try to corece the value into an expected model but if failed the error will be thrown. ## Options This section is used to configure the behavior of the encoder. `Options` can be passed as a second argument to `createAccelerator`. ```ts createAccelerator(shape, { unsafe: 'throw' }) ``` ## Unsafe If unsafe character is found, how should the encoder handle it? This value only applied to string field. - `'auto'`: Sanitize the string and continue encoding - `'manual'`: Ignore the unsafe character, this implied that end user should specify fields that should be sanitized manually - `'throw'`: Throw an error The default behavior is `auto`. ### format sanitize Since this library is designed for a controlled environment (eg. Restful API), most fields are controlled by end user which doesn't include unsafe characters for JSON encoding. We can improve performance by specifying a `sanitize: 'manual'` and provide a field that should be sanitized manually. We can add `sanitize: true` to a schema which is an uncontrolled field submit by user that might contains unsafe characters. When a field is marked as `sanitize`, the encoder will sanitize the string and continue encoding regardless of the `unsafe` configuration. ```ts import { Type as t } from '@sinclair/typebox' import { createAccelerator } from 'json-accelerator' const shape = t.Object({ name: t.String(), id: t.Number(), unknown: t.String({ sanitize: true }) }) const value = { id: 0, name: 'saltyaom', unknown: `hello\nworld` } satisfies typeof shape.static const encode = createAccelerator(shape, { sanitize: 'manual' }) console.log(encode(value)) // {"id":0,"name":"saltyaom","unknown":"hello\\nworld"} ``` This allows us to speed up a hardcode ## /benchmarks/array.ts ```ts path="/benchmarks/array.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ ids: t.Array(t.Number()), names: t.Array(t.String()), games: t.Array( t.Object({ name: t.String(), tags: t.Array(t.String()) }) ) }), { ids: [1, 2, 3], names: ['SaltyAom', 'SaltyAom', 'SaltyAom'], games: [ { name: 'MiSide', tags: ['Psychological Horror', 'Cute', 'Dating Sim'] }, { name: 'Strinova', tags: ['Free to Play', 'Anime', 'Third-Person Shooter'] }, { name: "Tom Clancy's Rainbow Six Siege", tags: ['FPS', 'Multiplayer', 'Tactical'] } ] } ) ``` ## /benchmarks/large-manual.ts ```ts path="/benchmarks/large-manual.ts" /** * *-manual.ts is where end user specifiy which fields should be sanitized manually **/ import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Array( t.Object({ id: t.Number(), name: t.String(), bio: t.String({ sanitize: true }), user: t.Object({ name: t.String(), password: t.String(), email: t.Optional(t.String({ format: 'email' })), age: t.Optional(t.Number()), avatar: t.Optional(t.String({ format: 'uri' })), cover: t.Optional(t.String({ format: 'uri' })) }), playing: t.Optional(t.String()), wishlist: t.Optional(t.Array(t.Number())), games: t.Array( t.Object({ id: t.Number(), name: t.String(), hoursPlay: t.Optional(t.Number({ default: 0 })), tags: t.Array( t.Object({ name: t.String(), count: t.Number() }) ) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()), region: t.Optional(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }) ), [ { id: 1, name: 'SaltyAom', bio: 'I like train\n', user: { name: 'SaltyAom', password: '123456', avatar: 'https://avatars.githubusercontent.com/u/35027979?v=4', cover: 'https://saltyaom.com/cosplay/pekomama.webp' }, playing: 'Strinova', wishlist: [4_154_456, 2_345_345], games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] }, { id: 2_345_345, name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: [ { name: 'FPS', count: 855_324 }, { name: 'Multiplayer', count: 456_567 }, { name: 'Tactical', count: 544_467 } ] } ], metadata: { alias: 'SaltyAom', country: 'Thailand', region: 'Asia' }, social: { twitter: 'SaltyAom' } }, { id: 2, name: 'VLost', bio: 'ไม่พี่คืองี้\n', user: { name: 'nattapon_kub', password: '123456' }, games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'vlost', country: 'Thailand' } }, { id: 2, name: 'eika', bio: 'こんにちわ!', user: { name: 'ei_ka', password: '123456' }, games: [ { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'eika', country: 'Japan' } } ], { sanitize: 'manual' } ) ``` ## /benchmarks/large.ts ```ts path="/benchmarks/large.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Array( t.Object({ id: t.Number(), name: t.String(), bio: t.String(), user: t.Object({ name: t.String(), password: t.String(), email: t.Optional(t.String()), age: t.Optional(t.Number()), avatar: t.Optional(t.String()), cover: t.Optional(t.String()) }), playing: t.Optional(t.String()), wishlist: t.Optional(t.Array(t.Number())), games: t.Array( t.Object({ id: t.Number(), name: t.String(), hoursPlay: t.Optional(t.Number({ default: 0 })), tags: t.Array( t.Object({ name: t.String(), count: t.Number() }) ) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()), region: t.Optional(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }) ), [ { id: 1, name: 'SaltyAom', bio: 'I like train', user: { name: 'SaltyAom', password: '123456', avatar: 'https://avatars.githubusercontent.com/u/35027979?v=4', cover: 'https://saltyaom.com/cosplay/pekomama.webp' }, playing: 'Strinova', wishlist: [4_154_456, 2_345_345], games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] }, { id: 2_345_345, name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: [ { name: 'FPS', count: 855_324 }, { name: 'Multiplayer', count: 456_567 }, { name: 'Tactical', count: 544_467 } ] } ], metadata: { alias: 'SaltyAom', country: 'Thailand', region: 'Asia' }, social: { twitter: 'SaltyAom' } }, { id: 2, name: 'VLost', bio: 'ไม่พี่คืองี้', user: { name: 'nattapon_kub', password: '123456' }, games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'vlost', country: 'Thailand' } }, { id: 2, name: 'eika', bio: 'こんにちわ!', user: { name: 'ei_ka', password: '123456' }, games: [ { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'eika', country: 'Japan' } } ] ) ``` ## /benchmarks/medium-manual.ts ```ts path="/benchmarks/medium-manual.ts" /** * *-manual.ts is where end user specifiy which fields should be sanitized manually **/ import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ id: t.Number(), name: t.Literal('SaltyAom'), bio: t.String({ sanitize: true }), user: t.Object({ name: t.String(), password: t.String() }), playing: t.Optional(t.String()), games: t.Array( t.Object({ name: t.String(), hoursPlay: t.Number({ default: 0 }), tags: t.Array(t.String()) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }), { id: 1, name: 'SaltyAom', bio: 'I like train\n', user: { name: 'SaltyAom', password: '123456' }, games: [ { name: 'MiSide', hoursPlay: 17, tags: ['Psychological Horror', 'Cute', 'Dating Sim'] }, { name: 'Strinova', hoursPlay: 365, tags: ['Free to Play', 'Anime', 'Third-Person Shooter'] }, { name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: ['FPS', 'Multiplayer', 'Tactical'] } ], metadata: { alias: 'SaltyAom', country: 'Thailand' }, social: { twitter: 'SaltyAom' } }, { sanitize: 'manual' } ) ``` ## /benchmarks/medium.ts ```ts path="/benchmarks/medium.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ id: t.Number(), name: t.Literal('SaltyAom'), bio: t.String({ sanitize: true }), user: t.Object({ name: t.String(), password: t.String() }), playing: t.Optional(t.String()), games: t.Array( t.Object({ name: t.String(), hoursPlay: t.Number({ default: 0 }), tags: t.Array(t.String()) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }), { id: 1, name: 'SaltyAom', bio: 'I like train\nhere', user: { name: 'SaltyAom', password: '123456' }, games: [ { name: 'MiSide', hoursPlay: 17, tags: ['Psychological Horror', 'Cute', 'Dating Sim'] }, { name: 'Strinova', hoursPlay: 365, tags: ['Free to Play', 'Anime', 'Third-Person Shooter'] }, { name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: ['FPS', 'Multiplayer', 'Tactical'] } ], metadata: { alias: 'SaltyAom', country: 'Thailand' }, social: { twitter: 'SaltyAom' } } ) ``` ## /benchmarks/message.ts ```ts path="/benchmarks/message.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ message: t.String({ trusted: true }) }), { message: 'Hello, World!' as const } ) ``` ## /benchmarks/multiple-queries.ts ```ts path="/benchmarks/multiple-queries.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Array( t.Object({ id: t.Number(), randomNumber: t.Number() }) ), [ { id: 4174, randomNumber: 331 }, { id: 51, randomNumber: 6544 }, { id: 4462, randomNumber: 952 }, { id: 2221, randomNumber: 532 }, { id: 9276, randomNumber: 3097 }, { id: 3056, randomNumber: 7293 }, { id: 6964, randomNumber: 620 }, { id: 675, randomNumber: 6601 }, { id: 8414, randomNumber: 6569 }, { id: 2753, randomNumber: 4065 } ] ) ``` ## /benchmarks/quote.ts ```ts path="/benchmarks/quote.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ id: t.String({ format: 'input' }), name: t.String() }), { id: '\n', name: 'SaltyAom' } ) ``` ## /benchmarks/small-manual.ts ```ts path="/benchmarks/small-manual.ts" /** * *-manual.ts is where end user specifiy which fields should be sanitized manually **/ import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ id: t.Number(), name: t.String(), bio: t.String({ sanitize: true }), metadata: t.Object({ alias: t.String(), country: t.String() }) }), { id: 1, name: 'SaltyAom', bio: 'I like train\n', metadata: { alias: 'SaltyAom', country: 'Thailand' } }, { sanitize: 'manual' } ) ``` ## /benchmarks/small.ts ```ts path="/benchmarks/small.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Object({ id: t.Number(), name: t.String(), bio: t.String(), metadata: t.Object({ alias: t.String(), country: t.String() }) }), { id: 1, name: 'SaltyAom', bio: 'I like train', metadata: { alias: 'SaltyAom', country: 'Thailand' } } ) ``` ## /benchmarks/small2.ts ```ts path="/benchmarks/small2.ts" import { t } from 'elysia' import { benchmark } from './utils' benchmark( t.Array( t.Object({ name: t.String(), pwd: t.String(), id: t.Array(t.Number()) }) ), [ { name: 'SaltyAom', pwd: 'password', id: [1, 2, 3] }, { name: 'JohnDoe', pwd: 'password', id: [4, 5, 6] }, { name: 'JaneDoe', pwd: 'password', id: [7, 8, 9] } ] ) ``` ## /benchmarks/utils.ts ```ts path="/benchmarks/utils.ts" import { bench, run, barplot, summary, compact, do_not_optimize } from 'mitata' import { createAccelerator } from '../src' import { TypeCompiler } from '@sinclair/typebox/compiler' import fastJson from 'fast-json-stringify' import type { TAnySchema } from '@sinclair/typebox' export const benchmark = ( model: T, value: T['static'], options?: Parameters[1] ) => { const fastJsonStringify = fastJson(model) const encode = createAccelerator(model, options) if (process.env.DEBUG) { console.log(encode.toString()) } if (encode(value) !== JSON.stringify(value)) { console.log(encode(value)) console.log('---') console.log(encode.toString()) throw new Error('Invalid result') } compact(() => { barplot(() => { summary(() => { bench('JSON Accelerator', () => { return encode(value) }) bench('Fast JSON Stringify', () => { return fastJsonStringify(value) }) bench('JSON Stringify', () => { return JSON.stringify(value) }) // const validator = TypeCompiler.Compile(model) // bench('JSON Accelerator w/ validation', () => { // validator.Check(value) // return encode(value) // }) }) }) }) run() } ``` ## /build.ts ```ts path="/build.ts" import { $ } from 'bun' import { build, type Options } from 'tsup' await $`rm -rf dist` const tsupConfig: Options = { entry: ['src/**/*.ts'], splitting: false, sourcemap: false, clean: true, bundle: true } satisfies Options await Promise.all([ // ? tsup esm build({ outDir: 'dist', format: 'esm', target: 'node20', cjsInterop: false, ...tsupConfig }), // ? tsup cjs build({ outDir: 'dist/cjs', format: 'cjs', target: 'node20', // dts: true, ...tsupConfig }) ]) await $`tsc --project tsconfig.dts.json` await Promise.all([$`cp dist/*.d.ts dist/cjs`]) process.exit() ``` ## /bun.lock ```lock path="/bun.lock" { "lockfileVersion": 1, "workspaces": { "": { "name": "json-accelerator", "devDependencies": { "@types/bun": "1.2.10", "elysia": "^1.2.25", "eslint": "9.6.0", "fast-json-stringify": "^6.0.1", "mitata": "^1.0.34", "tsup": "^8.4.0", "tsx": "^4.19.2", "typescript": "^5.8.2", }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0", }, "optionalPeers": [ "@sinclair/typebox", ], }, }, "packages": { "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.1", "", { "os": "aix", "cpu": "ppc64" }, "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.25.1", "", { "os": "android", "cpu": "arm" }, "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q=="], "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.1", "", { "os": "android", "cpu": "arm64" }, "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA=="], "@esbuild/android-x64": ["@esbuild/android-x64@0.25.1", "", { "os": "android", "cpu": "x64" }, "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw=="], "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ=="], "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA=="], "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A=="], "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww=="], "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.1", "", { "os": "linux", "cpu": "arm" }, "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ=="], "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ=="], "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.1", "", { "os": "linux", "cpu": "ia32" }, "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ=="], "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg=="], "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg=="], "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg=="], "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.1", "", { "os": "linux", "cpu": "none" }, "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ=="], "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ=="], "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA=="], "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.1", "", { "os": "none", "cpu": "arm64" }, "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g=="], "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.1", "", { "os": "none", "cpu": "x64" }, "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA=="], "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.1", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg=="], "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw=="], "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.1", "", { "os": "sunos", "cpu": "x64" }, "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg=="], "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ=="], "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A=="], "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.1", "", { "os": "win32", "cpu": "x64" }, "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.5.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w=="], "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="], "@eslint/config-array": ["@eslint/config-array@0.17.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA=="], "@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="], "@eslint/js": ["@eslint/js@9.6.0", "", {}, "sha512-D9B0/3vNg44ZeWbYMpBoXqNP4j6eQD5vNwIlGAuFRRzK/WtT/jvDQW3Bi9kkf3PMDMlM7Yi+73VLUsn5bJcl8A=="], "@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="], "@fastify/merge-json-schemas": ["@fastify/merge-json-schemas@0.2.1", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A=="], "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], "@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="], "@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.8", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA=="], "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], "@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="], "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="], "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="], "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], "@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.37.0", "", { "os": "android", "cpu": "arm" }, "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.37.0", "", { "os": "android", "cpu": "arm64" }, "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA=="], "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.37.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA=="], "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.37.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ=="], "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.37.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA=="], "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.37.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA=="], "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w=="], "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.37.0", "", { "os": "linux", "cpu": "arm" }, "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag=="], "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA=="], "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.37.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ=="], "@rollup/rollup-linux-loongarch64-gnu": ["@rollup/rollup-linux-loongarch64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA=="], "@rollup/rollup-linux-powerpc64le-gnu": ["@rollup/rollup-linux-powerpc64le-gnu@4.37.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ=="], "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw=="], "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.37.0", "", { "os": "linux", "cpu": "none" }, "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA=="], "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.37.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A=="], "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ=="], "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.37.0", "", { "os": "linux", "cpu": "x64" }, "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w=="], "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.37.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg=="], "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.37.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA=="], "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.37.0", "", { "os": "win32", "cpu": "x64" }, "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA=="], "@sinclair/typebox": ["@sinclair/typebox@0.34.31", "", {}, "sha512-qQ71T9DsITbX3dVCrcBERbs11YuSMg3wZPnT472JhqhWGPdiLgyvihJXU8m+ADJtJvRdjATIiACJD22dEknBrQ=="], "@types/bun": ["@types/bun@1.2.10", "", { "dependencies": { "bun-types": "1.2.10" } }, "sha512-eilv6WFM3M0c9ztJt7/g80BDusK98z/FrFwseZgT4bXCq2vPhXD4z8R3oddmAn+R/Nmz9vBn4kweJKmGTZj+lg=="], "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], "@types/node": ["@types/node@22.13.14", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w=="], "acorn": ["acorn@8.14.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg=="], "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], "ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="], "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], "bun-types": ["bun-types@1.2.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-b5ITZMnVdf3m1gMvJHG+gIfeJHiQPJak0f7925Hxu6ZN5VKA8AGy4GZ4lM+Xkn6jtWxg5S3ldWvfmXdvnkp3GQ=="], "bundle-require": ["bundle-require@5.1.0", "", { "dependencies": { "load-tsconfig": "^0.2.3" }, "peerDependencies": { "esbuild": ">=0.18" } }, "sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA=="], "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], "commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], "eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], "elysia": ["elysia@1.2.25", "", { "dependencies": { "@sinclair/typebox": "^0.34.27", "cookie": "^1.0.2", "memoirist": "^0.3.0", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-WsdQpORJvb4uszzeqYT0lg97knw1iBW1NTzJ1Jm57tiHg+DfAotlWXYbjmvQ039ssV0fYELDHinLLoUazZkEHg=="], "emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], "esbuild": ["esbuild@0.25.1", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.1", "@esbuild/android-arm": "0.25.1", "@esbuild/android-arm64": "0.25.1", "@esbuild/android-x64": "0.25.1", "@esbuild/darwin-arm64": "0.25.1", "@esbuild/darwin-x64": "0.25.1", "@esbuild/freebsd-arm64": "0.25.1", "@esbuild/freebsd-x64": "0.25.1", "@esbuild/linux-arm": "0.25.1", "@esbuild/linux-arm64": "0.25.1", "@esbuild/linux-ia32": "0.25.1", "@esbuild/linux-loong64": "0.25.1", "@esbuild/linux-mips64el": "0.25.1", "@esbuild/linux-ppc64": "0.25.1", "@esbuild/linux-riscv64": "0.25.1", "@esbuild/linux-s390x": "0.25.1", "@esbuild/linux-x64": "0.25.1", "@esbuild/netbsd-arm64": "0.25.1", "@esbuild/netbsd-x64": "0.25.1", "@esbuild/openbsd-arm64": "0.25.1", "@esbuild/openbsd-x64": "0.25.1", "@esbuild/sunos-x64": "0.25.1", "@esbuild/win32-arm64": "0.25.1", "@esbuild/win32-ia32": "0.25.1", "@esbuild/win32-x64": "0.25.1" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ=="], "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], "eslint": ["eslint@9.6.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", "@eslint/config-array": "^0.17.0", "@eslint/eslintrc": "^3.1.0", "@eslint/js": "9.6.0", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.0.1", "eslint-visitor-keys": "^4.0.0", "espree": "^10.1.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" } }, "sha512-ElQkdLMEEqQNM9Njff+2Y4q2afHk7JpkPvrd7Xh7xefwgQynqPxwf55J7di9+MEibWUGdNjFF9ITG9Pck5M84w=="], "eslint-scope": ["eslint-scope@8.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="], "eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="], "espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="], "esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="], "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], "fast-json-stringify": ["fast-json-stringify@6.0.1", "", { "dependencies": { "@fastify/merge-json-schemas": "^0.2.0", "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "fast-uri": "^3.0.0", "json-schema-ref-resolver": "^2.0.0", "rfdc": "^1.2.0" } }, "sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg=="], "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], "fast-uri": ["fast-uri@3.0.6", "", {}, "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw=="], "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], "fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="], "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], "foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], "get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="], "glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], "globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], "is-path-inside": ["is-path-inside@3.0.3", "", {}, "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], "jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], "json-schema-ref-resolver": ["json-schema-ref-resolver@2.0.1", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q=="], "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], "lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="], "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], "load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="], "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], "lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="], "lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], "memoirist": ["memoirist@0.3.0", "", {}, "sha512-wR+4chMgVPq+T6OOsk40u9Wlpw1Pjx66NMNiYxCQQ4EUJ7jDs3D9kTCeKdBOkvAiqXlHLVJlvYL01PvIJ1MPNg=="], "minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="], "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "mitata": ["mitata@1.0.34", "", {}, "sha512-Mc3zrtNBKIMeHSCQ0XqRLo1vbdIx1wvFV9c8NJAiyho6AjNfMY8bVhbS12bwciUdd1t4rj8099CH3N3NFahaUA=="], "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], "natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="], "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], "openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="], "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], "package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], "pirates": ["pirates@4.0.6", "", {}, "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg=="], "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="], "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], "rollup": ["rollup@4.37.0", "", { "dependencies": { "@types/estree": "1.0.6" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.37.0", "@rollup/rollup-android-arm64": "4.37.0", "@rollup/rollup-darwin-arm64": "4.37.0", "@rollup/rollup-darwin-x64": "4.37.0", "@rollup/rollup-freebsd-arm64": "4.37.0", "@rollup/rollup-freebsd-x64": "4.37.0", "@rollup/rollup-linux-arm-gnueabihf": "4.37.0", "@rollup/rollup-linux-arm-musleabihf": "4.37.0", "@rollup/rollup-linux-arm64-gnu": "4.37.0", "@rollup/rollup-linux-arm64-musl": "4.37.0", "@rollup/rollup-linux-loongarch64-gnu": "4.37.0", "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-gnu": "4.37.0", "@rollup/rollup-linux-riscv64-musl": "4.37.0", "@rollup/rollup-linux-s390x-gnu": "4.37.0", "@rollup/rollup-linux-x64-gnu": "4.37.0", "@rollup/rollup-linux-x64-musl": "4.37.0", "@rollup/rollup-win32-arm64-msvc": "4.37.0", "@rollup/rollup-win32-ia32-msvc": "4.37.0", "@rollup/rollup-win32-x64-msvc": "4.37.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg=="], "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], "source-map": ["source-map@0.8.0-beta.0", "", { "dependencies": { "whatwg-url": "^7.0.0" } }, "sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA=="], "string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], "string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], "sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="], "supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], "text-table": ["text-table@0.2.0", "", {}, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="], "tr46": ["tr46@1.0.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA=="], "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], "tsup": ["tsup@8.4.0", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.25.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "0.8.0-beta.0", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ=="], "tsx": ["tsx@4.19.3", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-4H8vUNGNjQ4V2EOoGw005+c+dGuPSnhpPBPHBtsZdGZBk/iJb4kguGlPWaZTZ3q5nMtFOEsY0nRDlh9PJyd6SQ=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], "webidl-conversions": ["webidl-conversions@4.0.2", "", {}, "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="], "whatwg-url": ["whatwg-url@7.1.0", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", "webidl-conversions": "^4.0.2" } }, "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], "wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], "wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], "@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "fast-json-stringify/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "string-width/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], "string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], "wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], "wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "ajv-formats/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "fast-json-stringify/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], "string-width/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], "wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], } } ``` ## /example/index.ts ```ts path="/example/index.ts" import { t } from 'elysia' import { createAccelerator } from '../src/index' const shape = t.Array( t.Object({ name: t.String() }) ) const value = [ { name: 'a' }, { name: 'b' } ] satisfies typeof shape.static const mirror = createAccelerator(shape) console.log((mirror(value))) ``` ## /package.json ```json path="/package.json" { "name": "json-accelerator", "version": "0.1.7", "description": "Speed up JSON stringification by providing OpenAPI/TypeBox model", "license": "MIT", "scripts": { "dev": "bun run --watch example/index.ts", "test": "bun test && npm run test:node", "test:node": "npm install --prefix ./test/node/cjs/ && npm install --prefix ./test/node/esm/ && node ./test/node/cjs/index.js && node ./test/node/esm/index.js", "build": "bun build.ts", "release": "npm run build && npm run test && npm publish --access public" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0" }, "peerDependenciesMeta": { "@sinclair/typebox": { "optional": true } }, "devDependencies": { "@types/bun": "1.2.10", "elysia": "^1.2.25", "eslint": "9.6.0", "fast-json-stringify": "^6.0.1", "mitata": "^1.0.34", "tsup": "^8.4.0", "tsx": "^4.19.2", "typescript": "^5.8.2" }, "main": "./dist/cjs/index.js", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", "exports": { "./package.json": "./package.json", ".": { "types": "./dist/index.d.ts", "import": "./dist/index.mjs", "require": "./dist/cjs/index.js" } }, "keywords": [ "elysia", "json", "stringify", "accelerator" ], "repository": { "type": "git", "url": "https://github.com/elysiajs/json-accelerator" }, "author": { "name": "saltyAom", "url": "https://github.com/SaltyAom", "email": "saltyaom@gmail.com" }, "homepage": "https://github.com/elysiajs/json-accelerator", "bugs": "https://github.com/elysiajs/json-accelerator/issues" } ``` ## /src/index.ts ```ts path="/src/index.ts" import type { TAnySchema, TRecord } from '@sinclair/typebox' const Kind = Symbol.for('TypeBox.Kind') const OptionalKind = Symbol.for('TypeBox.Optional') const isSpecialProperty = (name: string) => /(\ |-|\t|\n)/.test(name) const joinProperty = (v1: string, v2: string | number) => { if (typeof v2 === 'number') return `${v1}[${v2}]` if (isSpecialProperty(v2)) return `${v1}["${v2}"]` return `${v1}.${v2}` } const encodeProperty = (v: string) => `"${v}"` const isInteger = (schema: TAnySchema) => { if (!schema.anyOf || (Kind in schema && schema[Kind] !== 'Union')) return false let hasIntegerFormat = false let hasNumberType = false for (const type of schema.anyOf) { if (type.type === 'null' || type.type === 'undefined') { continue } if ( !hasIntegerFormat && type.type === 'string' && type.format === 'integer' ) { hasIntegerFormat = true continue } if ( !hasNumberType && (type.type === 'number' || type.type === 'integer') ) { hasNumberType = true continue } return false } return hasIntegerFormat && hasNumberType } const getMetadata = (schema: TAnySchema) => { let isNullable = false let isUndefinable = false let newSchema if (!schema.anyOf || (Kind in schema && schema[Kind] !== 'Union')) return { schema, isNullable, isUndefinable } for (const type of schema.anyOf) { if (type.type === 'null') { isNullable = true continue } if (type.type === 'undefined') { isUndefinable = true continue } if (!newSchema) { newSchema = type continue } return { schema, isNullable, isUndefinable } } return { schema: newSchema, isNullable, isUndefinable } } export const mergeObjectIntersection = (schema: TAnySchema): TAnySchema => { if ( !schema.allOf || (Kind in schema && (schema[Kind] !== 'Intersect' || schema.type !== 'object')) ) return schema const { allOf, ...newSchema } = schema newSchema.properties = {} if (Kind in newSchema) newSchema[Kind as any] = 'Object' for (const type of allOf) { if (type.type !== 'object') continue const { properties, required, type: _, [Kind]: __, ...rest } = type if (required) newSchema.required = newSchema.required ? newSchema.required.concat(required) : required Object.assign(newSchema, rest) for (const property in type.properties) newSchema.properties[property] = mergeObjectIntersection( type.properties[property] ) } return newSchema } const isDateType = (schema: TAnySchema): boolean => { if (!schema.anyOf || (Kind in schema && schema[Kind] !== 'Union')) return false if (!schema.anyOf) return false let hasDateType = false let hasStringFormatDate = false let hasNumberType = false if (schema.anyOf) for (const type of schema.anyOf) { if (!hasDateType && type.type === 'Date') hasDateType = true if ( !hasStringFormatDate && type.type === 'string' && (type.format === 'date' || type.format === 'date-time') ) hasStringFormatDate = true if (!hasNumberType && type.type === 'number') hasNumberType = true } return hasDateType } interface Instruction { array: number optional: number properties: string[] /** * If unsafe character is found, how should the encoder handle it? * * This value only applied to string field. * * - 'throw': Throw an error * - 'ignore': Ignore the unsafe character, this implied that end user should handle it * - 'sanitize': Sanitize the string and continue encoding * * @default 'sanitize' **/ sanitize: 'auto' | 'manual' | 'throw' definitions: Record } // equivalent to /["\n\r\t\b\f\v]/ const findEscapeSequence = /["\b\t\n\v\f\r\/]/ const SANITIZE = { auto: (property: string) => `${findEscapeSequence}.test(${property})?JSON.stringify(${property}).slice(1,-1):${property}`, manual: (property: string) => `${property}`, throw: (property: string) => `${findEscapeSequence}.test(${property})?(()=>{throw new Error("Property '${property}' contains invalid characters")})():${property}` } satisfies Record string> const joinStringArray = (p: string) => `"$\{` + `((p)=>{` + `if(p.length===1)return p\n` + `let ars=p[0]\n` + `for(let i=1;i { const child = schema.patternProperties['^(.*)$'] ?? schema.patternProperties[Object.keys(schema.patternProperties)[0]] if (!child) return property const i = instruction.array instruction.array++ return ( `\${((ar${i}n)=>{` + `const ar${i}s=Object.keys(ar${i}n);` + `let ar${i}v='{';` + `for(let i=0;i { if (!schema) return '' if ( Kind in schema && schema[Kind] === 'Import' && schema.$ref in schema.$defs ) return accelerate(schema.$defs[schema.$ref], property, { ...instruction, definitions: Object.assign(instruction.definitions, schema.$defs) }) let v = '' const isRoot = property === 'v' const { schema: newSchema, isNullable, isUndefinable } = getMetadata(schema) schema = newSchema // const error = '' // `??(()=>{throw new Error("Property '${property}' is missing")})()` const nullableCondition = isNullable && isUndefinable ? `${property}===null||${property}===undefined` : isNullable ? `${property}===null` : isUndefinable ? `${property}===undefined` : '' let sanitize = SANITIZE[instruction.sanitize] switch (schema.type) { case 'string': // string operation would be repeated multiple time // it's fine to optimize it to the most optimized way if ( instruction.sanitize === 'auto' || // Elysia specific format, this implied that format might contain unescaped JSON string schema.sanitize ) { sanitize = SANITIZE['auto'] // Sanitize use JSON.stringify which wrap double quotes // this handle the case where the string contains double quotes // As slice(1,-1) is use several compute and would be called multiple times // it's not ideal to slice(1, -1) of JSON.stringify if (nullableCondition) { if (schema.trusted) sanitize = (v: string) => `\`"$\{${SANITIZE['manual'](v)}}"\`` v = `\${${nullableCondition}?${schema.const !== undefined ? `'${JSON.stringify(schema.const)}'` : schema.default !== undefined ? `'${JSON.stringify(schema.default)}'` : `'null'`}:\`"\${${sanitize(property)}}"\`}` } else { if (schema.const !== undefined) v = JSON.stringify(schema.const) else if (schema.trusted) v = `"\${${SANITIZE['manual'](property)}}"` else v = `"\${${sanitize(property)}}"` } } else { // In this case quote is handle outside to improve performance if (nullableCondition) v = `\${${nullableCondition}?${schema.const !== undefined ? `'${JSON.stringify(schema.const)}'` : schema.default !== undefined ? `'${JSON.stringify(schema.default)}'` : `'null'`}:\`\\"\${${sanitize(property)}}\\"\`}` else v = `${schema.const !== undefined ? `${JSON.stringify(schema.const)}` : `"\${${sanitize(property)}}"`}` } break case 'number': case 'boolean': case 'bigint': if (nullableCondition) v = `\${${property}??${schema.default !== undefined ? schema.default : `'null'`}}` else v = `\${${property}}` break case 'null': v = `\${${property}}` break case 'undefined': break case 'object': if (nullableCondition) v += `\${${nullableCondition}?"null":\`` v += '{' if (schema.additionalProperties) { v = `$\{JSON.stringify(${property})}` break } schema = mergeObjectIntersection(schema) let init = true let hasOptional = false let op = `op${instruction.optional}` if (schema[Kind as any] === 'Record') { v = handleRecord(schema as TRecord, property, instruction) break } if ( !Object.keys(schema.properties).length && schema.patternProperties ) { v = `$\{JSON.stringify(${property})}` break } for (const key in schema.properties) if (OptionalKind in schema.properties[key]) { instruction.optional++ hasOptional = true break } for (const key in schema.properties) { const isOptional = OptionalKind in schema.properties[key] const name = joinProperty(property, key) const hasShortName = schema.properties[key].type === 'object' && !name.startsWith('ar') const i = instruction.properties.length if (hasShortName) instruction.properties.push(name) const k = encodeProperty(key) const p = accelerate( schema.properties[key], hasShortName ? `s${i}` : name, instruction ) const comma = `\${${op}?',':(${op}=true)&&''}` let defaultValue = schema.properties[key].default if (defaultValue !== undefined) { if (typeof defaultValue === 'string') defaultValue = `"${defaultValue}"` defaultValue = `\`${comma}${k}:${defaultValue}\`` } else defaultValue = '""' v += isOptional ? `\${(${name}===undefined?${defaultValue}:\`${comma}${k}:${p}\`)}` : hasOptional ? `${!init ? ',' : `\${(${op}=true)&&""}`}${k}:${p}` : `${!init ? ',' : ''}${k}:${p}` init = false } v += '}' if (nullableCondition) v += `\`}` break case 'array': const i = instruction.array instruction.array++ if (schema.items.type === 'string') { if (isRoot) v += 'return `' if (nullableCondition) v += `\${${nullableCondition}?"null":${property}.length?\`[${joinStringArray(property)}]\`:"[]"}` else v += `\${${property}.length?\`[${joinStringArray(property)}]\`:"[]"}` if (isRoot) v += '`' break } if ( schema.items.type === 'number' || schema.items.type === 'boolean' || schema.items.type === 'bigint' || isInteger(schema.items) ) { if (isRoot) v += 'return `' if (nullableCondition) v += `\${${nullableCondition}?'"null"':${property}.length?\`[$\{${property}.toString()}]\`:"[]"` else v += `\${${property}.length?\`[$\{${property}.toString()}]\`:"[]"}` if (isRoot) v += '`' break } if (isNullable || isUndefinable) v += `\${!${property}?'"null"':\`` if (isRoot) v += `const ar${i}s=${property};` else v += `\${((ar${i}s)=>{` v += `let ar${i}v='[';` + `for(let i=0;i( schema: T, { sanitize = 'auto', definitions = {} }: Partial> = {} ): ((v: T['static']) => string) => { const f = accelerate(schema, 'v', { array: 0, optional: 0, properties: [], sanitize, definitions }) // console.log(f) return Function('v', f) as any } export default createAccelerator // const shape = t.Object({ // a: t.Nullable( // t.Object({ // a: t.String() // }) // ) // }) // const shape = t.Object({ // a: t.String(), // social: t.Optional( // t.Object({ // facebook: t.Nullable(t.String()), // twitter: t.Nullable(t.String()), // youtube: t.Nullable(t.String()) // }) // ) // }) // const stringify = createaccelerate(shape) // console.log( // stringify({ // a: 'a', // social: { // a: 'a', // } // }) // ) ``` ## /test/array.test.ts ```ts path="/test/array.test.ts" import { describe, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' describe('Array', () => { it('handle string array at root', () => { const shape = t.Array(t.String()) isEqual(shape, ['a', 'b']) }) it('handle number array at root', () => { const shape = t.Array(t.Number()) isEqual(shape, [1, 2]) }) it('handle boolean array at root', () => { const shape = t.Array(t.Number()) isEqual(shape, [true, false]) }) it('handle big int array at root', () => { const shape = t.Array(t.Number()) isEqual(shape, [1n, 2n], [1, 2]) }) it('handle array union at root', () => { const shape = t.Array(t.Union([t.String(), t.Number()])) isEqual(shape, ['a', 'b', 1, 2, 'c']) }) it('handle array object', () => { const shape = t.Array( t.Object({ a: t.String(), b: t.String() }) ) isEqual( shape, [ { a: 'a', b: 'b' }, { a: 'a', b: 'b', c: 'c' } ], [ { a: 'a', b: 'b' }, { a: 'a', b: 'b' } ] ) }) it('handle array object with optional', () => { const shape = t.Array( t.Object({ a: t.String(), b: t.Optional(t.String()) }) ) isEqual( shape, [ { a: 'a' }, { a: 'a', b: 'b' }, { a: 'a', b: 'b', c: 'c' } ], [ { a: 'a' }, { a: 'a', b: 'b' }, { a: 'a', b: 'b' } ] ) }) }) ``` ## /test/default.test.ts ```ts path="/test/default.test.ts" import { describe, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' describe('Default', () => { it('handle default value for optional string', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.String({ default: 'Strinova' })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 'Strinova' }) }) it('handle default value for optional number', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.Number({ default: 2 })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value for optional boolean', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.Boolean({ default: true })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: true }) }) it('handle default value for optional integer', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.Integer({ default: 2 })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value for optional bigint', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.BigInt({ default: BigInt(2) })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value for optional date', () => { const date = new Date() const shape = t.Object({ name: t.String(), playing: t.Optional(t.Date({ default: date.toISOString() })) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: date.toISOString() }) }) it('handle default value nullable string', () => { const shape = t.Object({ name: t.String(), playing: t.Nullable(t.String({ default: 'Strinova' })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 'Strinova' }) }) it('handle default value nullable number', () => { const shape = t.Object({ name: t.String(), playing: t.Nullable(t.Number({ default: 2 })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value nullable boolean', () => { const shape = t.Object({ name: t.String(), playing: t.Nullable(t.Boolean({ default: true })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: true }) }) it('handle default value nullable integer', () => { const shape = t.Object({ name: t.String(), playing: t.Nullable(t.Integer({ default: 2 })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value nullable bigint', () => { const shape = t.Object({ name: t.String(), playing: t.Nullable(t.BigInt({ default: BigInt(2) })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: 2 }) }) it('handle default value nullable date', () => { const date = new Date() const shape = t.Object({ name: t.String(), playing: t.Nullable(t.Date({ default: date.toISOString() })) }) const value = { name: 'saltyaom', playing: null } satisfies typeof shape.static isEqual(shape, value, { name: 'saltyaom', playing: date.toISOString() }) }) }) ``` ## /test/index.test.ts ```ts path="/test/index.test.ts" import { describe, expect, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' import { createAccelerator } from '../src' describe('Core', () => { it('handle string', () => { const shape = t.String() const value = 'saltyaom' satisfies typeof shape.static isEqual(shape, value) }) it('handle number', () => { const shape = t.Number() const value = 0 satisfies typeof shape.static isEqual(shape, value) }) it('handle boolean', () => { const shape = t.Boolean() const value = true satisfies typeof shape.static isEqual(shape, value) }) it('handle literal', () => { const shape = t.Literal('saltyaom') const value = 'saltyaom' satisfies typeof shape.static isEqual(shape, value) }) it('handle null', () => { const shape = t.Null() const value = null satisfies typeof shape.static isEqual(shape, value) }) it('handle undefined', () => { const shape = t.Undefined() const value = undefined satisfies typeof shape.static expect(createAccelerator(shape)(value)).toBe('') }) it('handle date', () => { const shape = t.Date() const value = new Date() satisfies typeof shape.static expect(createAccelerator(shape)(value)).toBe(`"${value.toISOString()}"`) }) it('handle date timestamp', () => { const shape = t.Date() const value = Date.now() isEqual(shape, value) }) it('handle nullable date', () => { const shape = t.Nullable(t.Date()) const value = new Date() satisfies typeof shape.static expect(createAccelerator(shape)(value)).toBe(`"${value.toISOString()}"`) const value2 = null satisfies typeof shape.static isEqual(shape, value2) }) it('handle nullable date timestamp', () => { const shape = t.Nullable(t.Date()) const value = 2 isEqual(shape, value) const value2 = null satisfies typeof shape.static isEqual(shape, value2) }) it('handle integer', () => { const shape = t.Integer() const value = 2.2 satisfies typeof shape.static isEqual(shape, value) }) it('handle bigint', () => { const shape = t.BigInt() const value = BigInt(2) satisfies typeof shape.static isEqual(shape, +(value + '')) }) it('handle object', () => { const shape = t.Object({ name: t.String(), id: t.Number() }) const value = { id: 0, name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value) }) it('handle string array', () => { const shape = t.Object({ name: t.String(), games: t.Array(t.String()) }) const value = { name: 'saltyaom', games: ['MiSide', 'Strinova'] } satisfies typeof shape.static isEqual(shape, value) }) it('handle number array', () => { const shape = t.Object({ name: t.String(), games: t.Array(t.Number()) }) const value = { name: 'saltyaom', games: [1, 2, 3] } satisfies typeof shape.static isEqual(shape, value) }) it('handle boolean array', () => { const shape = t.Object({ name: t.String(), games: t.Array(t.Boolean()) }) const value = { name: 'saltyaom', games: [true, false, true] } satisfies typeof shape.static isEqual(shape, value) }) it('handle object array', () => { const shape = t.Object({ name: t.String(), games: t.Array( t.Object({ name: t.String(), hoursPlay: t.Number({ default: 0 }), tags: t.Array(t.String()) }) ) }) const value = { name: 'saltyaom', games: [ { name: 'MiSide', hoursPlay: 17, tags: ['Psychological Horror', 'Cute', 'Dating Sim'] }, { name: 'Strinova', hoursPlay: 365, tags: ['Free to Play', 'Anime', 'Third-Person Shooter'] }, { name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: ['FPS', 'Multiplayer', 'Tactical'] } ] } satisfies typeof shape.static isEqual(shape, value) }) it('handle optional', () => { const shape = t.Object({ name: t.String(), playing: t.Optional(t.String()) }) const value = { name: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value) }) it('handle nullable', () => { const shape = t.Object({ name: t.String(), country: t.Nullable(t.String()) }) const value = { name: 'saltyaom', country: null } satisfies typeof shape.static isEqual(shape, value) }) it('handle undefinable', () => { const shape = t.Object({ name: t.String(), country: t.MaybeEmpty(t.String()) }) const value = { name: 'saltyaom', // Transform undefined to null country: null } satisfies typeof shape.static isEqual(shape, value) }) it('handle intersect', () => { const shape = t.Intersect([ t.Object({ name: t.String(), playing: t.Optional(t.String()) }), t.Object({ country: t.String() }) ]) const value = { name: 'saltyaom', country: 'Thailand' } satisfies typeof shape.static isEqual(shape, value) }) it('handle union', () => { const shape = t.Union([ t.Object({ name: t.String(), playing: t.Optional(t.String()) }), t.Object({ country: t.String() }) ]) const value = { name: 'saltyaom', playing: 'MiSide' } satisfies typeof shape.static isEqual(shape, value) }) it('handle union with nullable', () => { const shape = t.Union([ t.Object({ name: t.String(), playing: t.Optional(t.String()) }), t.Object({ country: t.Nullable(t.String()) }) ]) const value = { country: null } satisfies typeof shape.static isEqual(shape, value) }) it('handle additionalProperties', () => { const shape = t.Object( { name: t.String(), playing: t.Optional(t.String()) }, { additionalProperties: true } ) const value = { name: 'saltyaom', playing: 'Strinova' } satisfies typeof shape.static isEqual(shape, value) }) it('handle nullable array', () => { const shape = t.Object({ name: t.String(), games: t.Nullable(t.Array(t.String())) }) const value = { name: 'saltyaom', games: null } satisfies typeof shape.static isEqual(shape, value) }) it('handle nullable object', () => { const shape = t.Object({ name: t.String(), metadata: t.Nullable( t.Object({ alias: t.String() }) ) }) const value = { name: 'saltyaom', metadata: null } satisfies typeof shape.static isEqual(shape, value) }) }) ``` ## /test/merge-intersection.test.ts ```ts path="/test/merge-intersection.test.ts" import { describe, expect, it } from 'bun:test' import { Type as t } from '@sinclair/typebox' import { mergeObjectIntersection } from '../src' describe('Merge Object Intersection', () => { it('work', () => { expect( mergeObjectIntersection( t.Intersect([ t.Object({ a: t.String() }), t.Object({ b: t.String() }) ]) ) ).toEqual( t.Object({ a: t.String(), b: t.String() }) ) }) it('handle nested intersection', () => { expect( mergeObjectIntersection( t.Intersect([ t.Object({ a: t.String() }), t.Object({ b: t.Intersect([ t.Object({ c: t.String() }), t.Object({ d: t.String() }) ]) }) ]) ) ).toEqual( t.Object({ a: t.String(), b: t.Object({ c: t.String(), d: t.String() }) }) ) }) it('merge property', () => { expect( mergeObjectIntersection( t.Intersect([ t.Object( { a: t.String() }, { description: 'ok' } ), t.Object( { b: t.Number({ minimum: 0 }) }, { additionalProperties: true } ) ]) ) ).toEqual( t.Object( { a: t.String(), b: t.Number({ minimum: 0 }) }, { description: 'ok', additionalProperties: true } ) ) }) }) ``` ## /test/node/.gitignore ```gitignore path="/test/node/.gitignore" node_modules/ package-lock.json ``` ## /test/node/cjs/index.js ```js path="/test/node/cjs/index.js" if ('Bun' in globalThis) { throw new Error('❌ Use Node.js to run this test!'); } const { createAccelerator } = require('json-accelerator'); if (typeof createAccelerator !== 'function') { throw new Error('❌ CommonJS Node.js failed'); } console.log('✅ CommonJS Node.js works!'); ``` ## /test/node/cjs/package.json ```json path="/test/node/cjs/package.json" { "type": "commonjs", "dependencies": { "json-accelerator": "../../.." } } ``` ## /test/node/esm/index.js ```js path="/test/node/esm/index.js" if ('Bun' in globalThis) { throw new Error('❌ Use Node.js to run this test!'); } import { createAccelerator } from 'json-accelerator'; if (typeof createAccelerator !== 'function') { throw new Error('❌ ESM Node.js failed'); } console.log('✅ ESM Node.js works!'); ``` ## /test/node/esm/package.json ```json path="/test/node/esm/package.json" { "type": "module", "dependencies": { "json-accelerator": "../../.." } } ``` ## /test/record.test.ts ```ts path="/test/record.test.ts" import { describe, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' describe('Record', () => { it('handle record', () => { const shape = t.Record(t.String(), t.String()) const value = { name: 'saltyaom', alias: 'saltyaom' } satisfies typeof shape.static isEqual(shape, value) }) it('handle record object', () => { const shape = t.Record( t.String(), t.Object({ name: t.String(), age: t.Number() }) ) const value = { saltyaom: { name: 'saltyaom', age: 23 }, chiffon: { name: 'chiffon', age: 24 } } satisfies typeof shape.static isEqual(shape, value) }) it('handle nested record', () => { const shape = t.Record(t.String(), t.Record(t.String(), t.Number())) const value = { saltyaom: { id: 1, age: 23 }, chiffon: { id: 2, age: 24 } } satisfies typeof shape.static isEqual(shape, value) }) it('handle unknown record', () => { const shape = t.Object( {}, { patternProperties: { '^[a-z]+$': t.String() } } ) const value = { name: 'saltyaom', alias: 'saltyaom', unknown: { a: 1, b: ['a', { hello: 'world' }] } } satisfies typeof shape.static isEqual(shape, value) }) }) ``` ## /test/ref.test.ts ```ts path="/test/ref.test.ts" import { describe, it, expect } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' import { createAccelerator } from '../src' describe('Ref', () => { it('handle module', () => { const modules = t.Module({ object: t.Object({ name: t.String(), optional: t.Optional(t.String()) }) }) const shape = modules.Import('object') const value = { name: 'salt' } satisfies typeof shape.static isEqual(shape, value) }) it('handle nested ref', () => { const modules = t.Module({ object: t.Object({ name: t.String(), info: t.Ref('info') }), info: t.Object({ id: t.Number(), name: t.String() }) }) const shape = modules.Import('object') const value = { name: 'salt', info: { id: 123, name: 'salt' } } satisfies typeof shape.static isEqual(shape, value) }) it('handle optional ref', () => { const modules = t.Module({ object: t.Object({ name: t.String(), info: t.Optional(t.Ref('info')) }), info: t.Object({ id: t.Number(), name: t.String() }) }) const shape = modules.Import('object') const value = { name: 'salt' } satisfies typeof shape.static isEqual(shape, { name: 'salt' }) isEqual(shape, { name: 'salt', info: { id: 123, name: 'salt' } }) }) it('handle custom modules', () => { const definitions = { object: t.Object({ name: t.String(), optional: t.Optional(t.String()) }) } const shape = definitions.object const value = { name: 'salt' } satisfies typeof shape.static expect( createAccelerator(shape, { definitions })(value) ).toEqual(JSON.stringify(value)) }) }) ``` ## /test/sample.test.ts ```ts path="/test/sample.test.ts" import { describe, expect, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' describe('Sample', () => { it('Medium', () => { const shape = t.Object({ id: t.Number(), name: t.Literal('SaltyAom'), bio: t.String(), user: t.Object({ name: t.String(), password: t.String() }), playing: t.Optional(t.String()), games: t.Array( t.Object({ name: t.String(), hoursPlay: t.Number({ default: 0 }), tags: t.Array(t.String()) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }) const value = { id: 1, name: 'SaltyAom', bio: 'I like train', user: { name: 'SaltyAom', password: '123456' }, games: [ { name: 'MiSide', hoursPlay: 17, tags: ['Psychological Horror', 'Cute', 'Dating Sim'] }, { name: 'Strinova', hoursPlay: 365, tags: ['Free to Play', 'Anime', 'Third-Person Shooter'] }, { name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: ['FPS', 'Multiplayer', 'Tactical'] } ], metadata: { alias: 'SaltyAom', country: 'Thailand' }, social: { twitter: 'SaltyAom' } } satisfies typeof shape.static isEqual(shape, value) }) it('Large', () => { const shape = t.Array( t.Object({ id: t.Number(), name: t.String(), bio: t.String(), user: t.Object({ name: t.String(), password: t.String(), email: t.Optional(t.String({ format: 'email' })), age: t.Optional(t.Number()), avatar: t.Optional(t.String({ format: 'uri' })), cover: t.Optional(t.String({ format: 'uri' })) }), playing: t.Optional(t.String()), wishlist: t.Optional(t.Array(t.Number())), games: t.Array( t.Object({ id: t.Number(), name: t.String(), hoursPlay: t.Optional(t.Number({ default: 0 })), tags: t.Array( t.Object({ name: t.String(), count: t.Number() }) ) }) ), metadata: t.Intersect([ t.Object({ alias: t.String() }), t.Object({ country: t.Nullable(t.String()), region: t.Optional(t.String()) }) ]), social: t.Optional( t.Object({ facebook: t.Optional(t.String()), twitter: t.Optional(t.String()), youtube: t.Optional(t.String()) }) ) }) ) const value = [ { id: 1, name: 'SaltyAom', bio: 'I like train', user: { name: 'SaltyAom', password: '123456', avatar: 'https://avatars.githubusercontent.com/u/35027979?v=4', cover: 'https://saltyaom.com/cosplay/pekomama.webp' }, playing: 'Strinova', wishlist: [4_154_456, 2_345_345], games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] }, { id: 2_345_345, name: "Tom Clancy's Rainbow Six Siege", hoursPlay: 287, tags: [ { name: 'FPS', count: 855_324 }, { name: 'Multiplayer', count: 456_567 }, { name: 'Tactical', count: 544_467 } ] } ], metadata: { alias: 'SaltyAom', country: 'Thailand', region: 'Asia' }, social: { twitter: 'SaltyAom' } }, { id: 2, name: 'VLost', bio: 'ไม่พี่คืองี้', user: { name: 'nattapon_kub', password: '123456' }, games: [ { id: 4_154_456, name: 'MiSide', hoursPlay: 17, tags: [ { name: 'Psychological Horror', count: 236_432 }, { name: 'Cute', count: 495_439 }, { name: 'Dating Sim', count: 395_532 } ] }, { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'vlost', country: 'Thailand' } }, { id: 2, name: 'eika', bio: 'こんにちわ!', user: { name: 'ei_ka', password: '123456' }, games: [ { id: 4_356_345, name: 'Strinova', hoursPlay: 365, tags: [ { name: 'Free to Play', count: 205_593 }, { name: 'Anime', count: 504_304 }, { name: 'Third-Person Shooter', count: 395_532 } ] } ], metadata: { alias: 'eika', country: 'Japan' } } ] satisfies typeof shape.static isEqual(shape, value) }) }) ``` ## /test/sanitize-auto.test.ts ```ts path="/test/sanitize-auto.test.ts" import { describe, expect, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' import { createAccelerator } from '../src' describe('sanitize auto', () => { it('sanitize invalid value', () => { const shape = t.Object({ a: t.String(), b: t.String() }) const value = { a: 'hello', b: 'hello\nworld' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'auto' })(value) ).not.toThrow() expect(() => JSON.parse( createAccelerator(shape, { sanitize: 'auto' })(value) ) ).not.toThrow() expect( createAccelerator(shape, { sanitize: 'auto' })(value) ).toEqual(`{"a":"hello","b":"hello\\nworld"}`) }) it('create literal value', () => { const shape = t.Object({ a: t.String(), b: t.Literal('SaltyAom') }) const value = { a: 'hello', b: 'SaltyAom' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'auto' })(value) ).not.toThrow() isEqual(shape, value) }) }) ``` ## /test/sanitize-manual.test.ts ```ts path="/test/sanitize-manual.test.ts" import { describe, expect, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' import { createAccelerator } from '../src' describe('sanitize manual', () => { it('ignore invalid value', () => { const shape = t.Object({ a: t.String(), b: t.String() }) const value = { a: 'hello', b: 'hello\nworld' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'manual' })(value) ).not.toThrow() expect(() => JSON.parse( createAccelerator(shape, { sanitize: 'manual' })(value) ) ).toThrow() expect( createAccelerator(shape, { sanitize: 'manual' })(value) ).toEqual(`{"a":"hello","b":"hello\nworld"}`) }) it('create a literal value', () => { const shape = t.Object({ a: t.String(), b: t.Literal('SaltyAom') }) const value = { a: 'hello', b: 'SaltyAom' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'manual' })(value) ).not.toThrow() isEqual(shape, value) }) }) ``` ## /test/sanitize-throw.test.ts ```ts path="/test/sanitize-throw.test.ts" import { describe, expect, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' import { createAccelerator } from '../src' describe('sanitize throw', () => { it('throw on invalid value', () => { const shape = t.Object({ a: t.String(), b: t.String() }) const value = { a: 'hello', b: 'hello\nworld' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'throw' })(value) ).toThrow() }) it("don't throw on valid value", () => { const shape = t.Object({ a: t.String(), b: t.String() }) const value = { a: 'hello', b: 'hello world' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'throw' })(value) ).not.toThrow() isEqual(shape, value) }) it("don't throw on valid value", () => { const shape = t.Object({ a: t.String(), b: t.String({ sanitize: true }) }) const value = { a: 'hello', b: 'hello world' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'throw' })(value) ).not.toThrow() isEqual(shape, value) }) it('handle sanitize value', () => { const shape = t.Object({ a: t.String(), b: t.String({ sanitize: true }) }) const value = { a: 'hello', b: 'hello\nworld' } satisfies typeof shape.static expect(() => createAccelerator(shape, { sanitize: 'throw' })(value) ).not.toThrow() isEqual(shape, value) }) }) ``` ## /test/tuple.test.ts ```ts path="/test/tuple.test.ts" import { describe, it } from 'bun:test' import { isEqual } from './utils' import { t } from 'elysia' describe('Tuple', () => { it('handle tuple', () => { const shape = t.Tuple([t.String(), t.Number()]) const value = ['saltyaom', 123] satisfies typeof shape.static isEqual(shape, value) }) it('handle tuple object', () => { const shape = t.Tuple([ t.String(), t.Object({ name: t.String(), age: t.Number() }) ]) const value = [ 'a', { name: 'saltyaom', age: 123 } ] satisfies typeof shape.static isEqual(shape, value) }) it('handle nested tuple', () => { const shape = t.Tuple([t.String(), t.Tuple([t.String(), t.Number()])]) const value = ['a', ['b', 123]] satisfies typeof shape.static isEqual(shape, value) }) }) ``` ## /test/utils.ts ```ts path="/test/utils.ts" import { type TAnySchema } from '@sinclair/typebox' import { createAccelerator } from '../src' import { expect } from 'bun:test' export const isEqual = (shape: TAnySchema, value: unknown, expected = value) => expect(JSON.parse(createAccelerator(shape)(value))).toEqual(expected) ``` ## /tsconfig.dts.json ```json path="/tsconfig.dts.json" { "compilerOptions": { "preserveSymlinks": true, /* Visit https://aka.ms/tsconfig to read more about this file */ /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ "target": "ES2021", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "lib": ["ESNext"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ "module": "ES2022", /* Specify what module code is generated. */ "rootDir": "./src", /* Specify the root folder within your source files. */ "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": ["bun-types"], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ "resolveJsonModule": true, /* Enable importing .json files. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ "outDir": "./dist", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ }, "exclude": ["node_modules", "test", "example", "dist", "build.ts", "benchmarks"] // "include": ["src/**/*"] } ``` ## /tsconfig.json ```json path="/tsconfig.json" { "compilerOptions": { /* Visit https://aka.ms/tsconfig to read more about this file */ /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ "target": "ES2020", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ "lib": ["ESNext", "DOM", "ScriptHost"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ "module": "ES2022", /* Specify what module code is generated. */ // "rootDir": "./src", /* Specify the root folder within your source files. */ "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./src", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ // "types": ["bun-types"], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ // "resolveJsonModule": true, /* Enable importing .json files. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./dist", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ // "newLine": "crlf", /* Set the newline character for emitting files. */ // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ /* Interop Constraints */ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ "strict": true, /* Enable all strict type-checking options. */ // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true, /* Skip type checking all .d.ts files. */ }, // "include": ["src/**/*"] } ``` The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.