├── .github
└── workflows
│ ├── buildAndTest.yaml
│ └── publish.yaml
├── .gitignore
├── .nvmrc
├── .vimspector.json
├── .vimspector.session
├── .yarn
└── releases
│ └── yarn-3.5.1.cjs
├── .yarnrc.yml
├── LICENSE
├── README.md
├── changelog.md
├── examples
├── basic
│ ├── README.md
│ ├── generated-types.ts
│ └── types.ts
├── disable-autogen-comment
│ ├── README.md
│ ├── generated-types.ts
│ └── types.ts
├── json-schema-options
│ ├── README.md
│ ├── generated-types.ts
│ └── types.ts
├── programmatic-usage
│ ├── .gitignore
│ ├── README.md
│ ├── generated-typebox.ts
│ ├── index.ts
│ ├── package.json
│ ├── types.ts
│ └── yarn.lock
├── skip-type-generation
│ ├── .ts2typeboxrc.cjs
│ ├── README.md
│ ├── generated-schemas.ts
│ ├── index.ts
│ └── types.ts
└── transform-value-transform-type
│ ├── .ts2typeboxrc.cjs
│ ├── README.md
│ ├── generated-types.ts
│ └── types.ts
├── git-hooks
└── pre-commit
├── package.json
├── src
├── cli
│ ├── cli.ts
│ └── index.ts
├── codeOptions.cjs
├── index.ts
├── jsdoc.ts
└── programmatic-usage.ts
├── test
└── index.ts
├── tsconfig.json
└── yarn.lock
/.github/workflows/buildAndTest.yaml:
--------------------------------------------------------------------------------
1 | name: build and test codebase
2 |
3 | on: [pull_request]
4 |
5 | jobs:
6 | build-and-test:
7 | runs-on: ${{ matrix.os }}
8 |
9 | strategy:
10 | matrix:
11 | node-version: [18.x, 20.x]
12 | os: [ubuntu-latest, macos-latest]
13 |
14 | steps:
15 | - uses: actions/checkout@v3
16 | - name: Use Node.js ${{ matrix.node-version }}
17 | uses: actions/setup-node@v3
18 | with:
19 | node-version: ${{ matrix.node-version }}
20 | - name: Install Dependencies
21 | run: yarn --immutable
22 | - name: Build
23 | run: yarn build
24 | - name: Test
25 | run: npm test
26 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yaml:
--------------------------------------------------------------------------------
1 | # src: https://github.com/JS-DevTools/npm-publish
2 | on:
3 | push:
4 | branches: main
5 |
6 | jobs:
7 | publish:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v4
11 | - uses: actions/setup-node@v3
12 | with:
13 | node-version-file: ".nvmrc"
14 | - name: Use yarn via corepack
15 | run: corepack enable
16 | - name: Install Dependencies
17 | run: yarn --immutable
18 | - name: Compile
19 | run: yarn build
20 | - uses: JS-DevTools/npm-publish@v3
21 | with:
22 | token: ${{ secrets.NPM_TOKEN }}
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Taken from https://github.com/github/gitignore/blob/main/Node.gitignore
2 | # and added custom ignores
3 |
4 | # Logs
5 | logs
6 | *.log
7 | npm-debug.log*
8 | yarn-debug.log*
9 | yarn-error.log*
10 | lerna-debug.log*
11 | .pnpm-debug.log*
12 |
13 | # Diagnostic reports (https://nodejs.org/api/report.html)
14 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
15 |
16 | # Runtime data
17 | pids
18 | *.pid
19 | *.seed
20 | *.pid.lock
21 |
22 | # Directory for instrumented libs generated by jscoverage/JSCover
23 | lib-cov
24 |
25 | # Coverage directory used by tools like istanbul
26 | coverage
27 | *.lcov
28 |
29 | # nyc test coverage
30 | .nyc_output
31 |
32 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
33 | .grunt
34 |
35 | # Bower dependency directory (https://bower.io/)
36 | bower_components
37 |
38 | # node-waf configuration
39 | .lock-wscript
40 |
41 | # Compiled binary addons (https://nodejs.org/api/addons.html)
42 | build/Release
43 |
44 | # Dependency directories
45 | node_modules/
46 | jspm_packages/
47 |
48 | # Snowpack dependency directory (https://snowpack.dev/)
49 | web_modules/
50 |
51 | # TypeScript cache
52 | *.tsbuildinfo
53 |
54 | # Optional npm cache directory
55 | .npm
56 |
57 | # Optional eslint cache
58 | .eslintcache
59 |
60 | # Optional stylelint cache
61 | .stylelintcache
62 |
63 | # Microbundle cache
64 | .rpt2_cache/
65 | .rts2_cache_cjs/
66 | .rts2_cache_es/
67 | .rts2_cache_umd/
68 |
69 | # Optional REPL history
70 | .node_repl_history
71 |
72 | # Output of 'npm pack'
73 | *.tgz
74 |
75 | # Yarn Integrity file
76 | .yarn-integrity
77 |
78 | # dotenv environment variable files
79 | .env
80 | .env.development.local
81 | .env.test.local
82 | .env.production.local
83 | .env.local
84 |
85 | # parcel-bundler cache (https://parceljs.org/)
86 | .cache
87 | .parcel-cache
88 |
89 | # Next.js build output
90 | .next
91 | out
92 |
93 | # Nuxt.js build / generate output
94 | .nuxt
95 | dist
96 |
97 | # Gatsby files
98 | .cache/
99 | # Comment in the public line in if your project uses Gatsby and not Next.js
100 | # https://nextjs.org/blog/next-9-1#public-directory-support
101 | # public
102 |
103 | # vuepress build output
104 | .vuepress/dist
105 |
106 | # vuepress v2.x temp and cache directory
107 | .temp
108 | .cache
109 |
110 | # Docusaurus cache and generated files
111 | .docusaurus
112 |
113 | # Serverless directories
114 | .serverless/
115 |
116 | # FuseBox cache
117 | .fusebox/
118 |
119 | # DynamoDB Local files
120 | .dynamodb/
121 |
122 | # TernJS port file
123 | .tern-port
124 |
125 | # Stores VSCode versions used for testing VSCode extensions
126 | .vscode-test
127 |
128 | # yarn v2
129 | .yarn/cache
130 | .yarn/unplugged
131 | .yarn/build-state.yml
132 | .yarn/install-state.gz
133 | .pnp.*
134 |
135 | # custom added ignores below
136 | bundle
137 | dist
138 | node_modules
139 | TODO
140 | schema.json
141 |
142 | node_modules
143 | dist
144 | TODO
145 | coverage
146 | /generated-types.ts
147 | /types.ts
148 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 18.16.0
2 |
--------------------------------------------------------------------------------
/.vimspector.json:
--------------------------------------------------------------------------------
1 | {
2 | "configurations": {
3 | "run": {
4 | "adapter": "vscode-node",
5 | "breakpoints": {
6 | "exception": {
7 | "all": "N",
8 | "uncaught": "Y"
9 | }
10 | },
11 | "configuration": {
12 | "request": "launch",
13 | "protocol": "auto",
14 | "stopOnEntry": false,
15 | "console": "integratedTerminal",
16 | "program": "${workspaceRoot}/src/index.ts",
17 | "outFiles": ["${workspaceRoot}/dist/**/*.js"],
18 | "env": { "TS_NODE_BASEURL": "./dist" },
19 | "runtimeArgs": ["-r", "tsconfig-paths/register"],
20 | "cwd": "${workspaceRoot}"
21 | }
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/.vimspector.session:
--------------------------------------------------------------------------------
1 | {"breakpoints": {"line": {"/home/xddq/progproj/gitlab-freedom/ts2typebox/src/typescript-to-typebox.ts": [{"state": "ENABLED", "line": 129, "options": {}, "is_instruction_breakpoint": null}, {"state": "ENABLED", "line": 113, "options": {}, "is_instruction_breakpoint": null}, {"state": "ENABLED", "line": 112, "options": {}, "is_instruction_breakpoint": null}]}, "function": [], "exception": {"filters": ["uncaught"]}}, "session": {"user_choices": {}}, "variables": {"watches": []}}
--------------------------------------------------------------------------------
/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-3.5.1.cjs
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Pierre Dahmani
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | ts2typebox
3 |
4 |
5 |
6 | Creating TypeBox code from Typescript types.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Cli tool which leverages the awesome
22 | [typebox-codegen](https://github.com/sinclairzx81/typebox-codegen) package by
23 | [sinclairzx81](https://github.com/sinclairzx81).
24 |
25 | ## Installation
26 |
27 | - `npm i -g ts2typebox`
28 |
29 | ## Use Case
30 |
31 | - You got a typescript project with types already lying around and are looking
32 | for a quick and easy way to get validations and JSON schemas based on them.
33 | - You prefer leveraging typescript to define your data types and to generate
34 | your validators and/or JSON schemas.
35 |
36 | ## Usage
37 |
38 | - The cli can be used with `ts2typebox --input --output `,
39 | or by simply running `ts2typebox`. The input defaults to "types.ts" and the
40 | output to "generated-types.ts" relative to the current working directory. For
41 | more see [cli usage](#cli-usage).
42 |
43 | ## Examples
44 |
45 | ```typescript
46 | //
47 | // Let's start with a simple type
48 | //
49 |
50 | export type Person = {
51 | age: number;
52 | name: string;
53 | };
54 |
55 | //
56 | // Which becomes
57 | //
58 |
59 | import { Type, Static } from "@sinclair/typebox";
60 |
61 | export type Person = Static;
62 | export const Person = Type.Object({
63 | age: Type.Number(),
64 | name: Type.String(),
65 | });
66 |
67 | //
68 | // Similarly, with an interface
69 | //
70 |
71 | export interface IPerson {
72 | age: number;
73 | name: string;
74 | }
75 |
76 | //
77 | // Which becomes
78 | //
79 |
80 | import { Type, Static } from "@sinclair/typebox";
81 |
82 | export type IPerson = Static;
83 | export const IPerson = Type.Object({
84 | age: Type.Number(),
85 | name: Type.String(),
86 | });
87 |
88 | //
89 | // Let's add some more complicated types. What about unions and intersections?
90 | //
91 |
92 | export type T = { x: number } & { y: number };
93 | export type U = { x: number } | { y: number };
94 |
95 | //
96 | // Which becomes
97 | //
98 |
99 | import { Type, Static } from "@sinclair/typebox";
100 |
101 | export type T = Static;
102 | export const T = Type.Intersect([
103 | Type.Object({
104 | x: Type.Number(),
105 | }),
106 | Type.Object({
107 | y: Type.Number(),
108 | }),
109 | ]);
110 |
111 | export type U = Static;
112 | export const U = Type.Union([
113 | Type.Object({
114 | x: Type.Number(),
115 | }),
116 | Type.Object({
117 | y: Type.Number(),
118 | }),
119 | ]);
120 |
121 | //
122 | // Nice! But I will need some JSON schema options here and there, which can't be
123 | // expressed in typescript at all...
124 | // No worries, simply use jsdoc in your types!
125 | //
126 | /**
127 | * @minimum 100
128 | * @maximum 200
129 | * @multipleOf 2
130 | * @default 150
131 | * @description "it's a number" - strings must be quoted
132 | * @foobar "should support unknown props"
133 | */
134 | export type T = number;
135 |
136 | //
137 | // Which becomes
138 | //
139 |
140 | import { Type, Static } from "@sinclair/typebox";
141 |
142 | export type T = Static;
143 | export const T = Type.Number({
144 | minimum: 100,
145 | maximum: 200,
146 | multipleOf: 2,
147 | default: 150,
148 | description: "it's a number",
149 | foobar: "should support unknown props",
150 | });
151 |
152 | //
153 | // Well, what if I don't like that the generated type and value has the same
154 | // name?! No worries, you can define your own transformation functions!
155 | // So that this..
156 | //
157 |
158 | export type Person = {
159 | age: number;
160 | name: string;
161 | };
162 |
163 | //
164 | // Can easily become
165 | //
166 |
167 | import { Type, Static } from "@sinclair/typebox";
168 |
169 | export type PersonType = Static;
170 | export const PersonSchema = Type.Object({
171 | age: Type.Number(),
172 | name: Type.String(),
173 | });
174 |
175 | //
176 | // Sounds great! But I have many comments in my Typescript types and I want to
177 | // use them as source of truth for my code. Can this be done..?
178 | // Yup! We can start with this...
179 | //
180 |
181 | export type Person = {
182 | /**
183 | * @minimum 18
184 | */
185 | age: number;
186 | /**
187 | * @description full name of the person
188 | */
189 | name: string;
190 | };
191 |
192 | //
193 | // And end up only generating the JSON schema/TypeBox values.
194 | //
195 |
196 | export const PersonSchema = Type.Object({
197 | age: Type.Number({ minimum: 18 }),
198 | name: Type.String({ description: "full name of the person" }),
199 | });
200 |
201 | //
202 | // For an example of programmatic usage check out the examples folder.
203 | //
204 | ```
205 |
206 | For hands on examples, you can follow the simple snippets stored inside the
207 | [examples](https://github.com/xddq/ts2typebox/tree/main/examples) folder. For a
208 | more complete set of examples (every feature is tested) you can take a look at
209 | the tests inside this repo for the programmatic usage and inside the tests in
210 | [@sinclair/typebox-codegen](https://github.com/sinclairzx81/typebox-codegen)
211 | repo for the typegen.
212 |
213 | ## cli usage
214 |
215 | The following text is the output that will be displayed when you issue `ts2typebox -h` or
216 | `ts2typebox --help`.
217 |
218 | ```
219 |
220 | ts2typebox generates TypeBox code from Typescript code.
221 | Version: ${packageJson.version}
222 |
223 | Usage:
224 |
225 | ts2typebox [ARGUMENTS]
226 |
227 | Arguments:
228 |
229 | -h, --help
230 | Displays this menu.
231 |
232 | -i, --input
233 | Specifies the relative path to the file containing the typescript types
234 | that will be used to generated typebox types. Defaults to "types.ts".
235 |
236 | -o, --output
237 | Specifies the relative path to generated file that will contain the
238 | typebox types. Defaults to "generated-types.ts".
239 |
240 | --output-stdout
241 | Does not generate an output file and prints the generated code to stdout
242 | instead. Has precedence over -o/--output.
243 |
244 | --disable-autogen-comment
245 | When used, it does not add the comment at the beginning of the generated
246 | file which is stating that the code was automatically generated.
247 |
248 | --skip-type-creation
249 | When used, strips all types from the generated code. This can be helpful
250 | if you want to use your Typescript types inside your input file (which
251 | probably contains comments) as source of truth and still use the generated
252 | TypeBox code (schema validators) to validate data based on these types.
253 | When using this option you probably want to also provide a custom
254 | transformValue function since two same symbols can't be imported from two
255 | different files. For an example take a look inside the repo under
256 | ./examples/skip-type-creation.
257 |
258 | Additional:
259 |
260 | Transformations
261 |
262 | You can adapt the names of the generated types (as well as the names of the
263 | generated values) using custom transformation functions which take a string
264 | as an input and return a string as their output. These will run on each of
265 | the generated types and values, respectively. Please take a look inside the
266 | repo under ./examples/transform-value-transform-type for an example of this.
267 |
268 | Formatting
269 |
270 | The generated output is formatted based on the prettier config inside your
271 |
272 | ```
273 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # 1.6.2
2 |
3 | - Updated code generation to use `CloneType` instead of deprecated `TypeClone`. New minimum versions: @sinclair/typebox ^0.34.35 and @typebox/codegen ^0.10.5
4 |
5 | # 1.6.1
6 |
7 | - stop using fixed dependency versions so users of this package can e.g. use the latest typescript version. See https://github.com/xddq/ts2typebox/pull/27
8 |
9 | # 1.6.0
10 |
11 | - use typebox as peer dependency, update to current typebox major 0.32.X
--------------------------------------------------------------------------------
/examples/basic/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | When ts2typebox is installed (simply issue npm i -g ts2typebox to do so), clone
4 | the repo, cd into this directory and:
5 |
6 | - Remove the old generated-types.ts file `rm generated-types.ts`
7 | - Use ts2typebox to generate the typebox types based on the types.ts file
8 | `ts2typebox`
9 | - done :]
10 |
--------------------------------------------------------------------------------
/examples/basic/generated-types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
3 | * your use case, there is a high chance that direct changes to this file get
4 | * lost. Consider making changes to the underlying Typescript code you use to
5 | * generate this file instead. The default file is called "types.ts", perhaps
6 | * have a look there! :]
7 | */
8 |
9 | import { Type, Static } from "@sinclair/typebox";
10 |
11 | type Age = Static;
12 | const Age = Type.Number();
13 |
14 | export type Address = Static;
15 | export const Address = Type.Object({
16 | street: Type.String(),
17 | city: Type.String(),
18 | state: Type.String(),
19 | postalCode: Type.String(),
20 | });
21 |
22 | export type Contact = Static;
23 | export const Contact = Type.Object({
24 | phone: Type.String(),
25 | email: Type.String(),
26 | });
27 |
28 | export type Person = Static;
29 | export const Person = Type.Object({
30 | name: Type.String(),
31 | age: Age,
32 | address: Address,
33 | contact: Contact,
34 | });
35 |
--------------------------------------------------------------------------------
/examples/basic/types.ts:
--------------------------------------------------------------------------------
1 | // Arbitrary example types
2 |
3 | type Age = number;
4 |
5 | export type Address = {
6 | street: string;
7 | city: string;
8 | state: string;
9 | postalCode: string;
10 | };
11 |
12 | export type Contact = {
13 | phone: string;
14 | email: string;
15 | };
16 |
17 | export type Person = {
18 | name: string;
19 | age: Age;
20 | address: Address;
21 | contact: Contact;
22 | };
23 |
--------------------------------------------------------------------------------
/examples/disable-autogen-comment/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | When ts2typebox is installed (simply issue npm i -g ts2typebox to do so), clone
4 | the repo, cd into this directory and:
5 |
6 | - Remove the old generated-types.ts file `rm generated-types.ts`
7 | - Use ts2typebox to generate the typebox types based on the types.ts file
8 | `ts2typebox --disable-autogen-comment`
9 | - done :]
10 |
--------------------------------------------------------------------------------
/examples/disable-autogen-comment/generated-types.ts:
--------------------------------------------------------------------------------
1 | import { Type, Static } from "@sinclair/typebox";
2 |
3 | type Age = Static;
4 | const Age = Type.Number();
5 |
6 | export type Address = Static;
7 | export const Address = Type.Object({
8 | street: Type.String(),
9 | city: Type.String(),
10 | state: Type.String(),
11 | postalCode: Type.String(),
12 | });
13 |
14 | export type Contact = Static;
15 | export const Contact = Type.Object({
16 | phone: Type.String(),
17 | email: Type.String(),
18 | });
19 |
20 | export type Person = Static;
21 | export const Person = Type.Object({
22 | name: Type.String(),
23 | age: Type.Number(),
24 | address: Address,
25 | contact: Contact,
26 | });
27 |
--------------------------------------------------------------------------------
/examples/disable-autogen-comment/types.ts:
--------------------------------------------------------------------------------
1 | // Arbitrary example types
2 |
3 | type Age = number;
4 |
5 | export type Address = {
6 | street: string;
7 | city: string;
8 | state: string;
9 | postalCode: string;
10 | };
11 |
12 | export type Contact = {
13 | phone: string;
14 | email: string;
15 | };
16 |
17 | export type Person = {
18 | name: string;
19 | age: number;
20 | address: Address;
21 | contact: Contact;
22 | };
23 |
--------------------------------------------------------------------------------
/examples/json-schema-options/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | When ts2typebox is installed (simply issue npm i -g ts2typebox to do so), clone
4 | the repo, cd into this directory and:
5 |
6 | - Remove the old generated-types.ts file `rm generated-types.ts`
7 | - Use ts2typebox to generate the typebox types based on the types.ts file
8 | `ts2typebox`
9 | - done :]
10 |
--------------------------------------------------------------------------------
/examples/json-schema-options/generated-types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
3 | * your use case, there is a high chance that direct changes to this file get
4 | * lost. Consider making changes to the underlying Typescript code you use to
5 | * generate this file instead. The default file is called "types.ts", perhaps
6 | * have a look there! :]
7 | */
8 |
9 | import { Type, Static } from "@sinclair/typebox";
10 |
11 | export type T = Static;
12 | export const T = Type.Object({
13 | a: Type.Number({
14 | minimum: 100,
15 | maximum: 200,
16 | multipleOf: 2,
17 | default: 150,
18 | description: "it's a number",
19 | anotherDescription: "can also use as quotes",
20 | foobar: "should support unknown props",
21 | }),
22 | });
23 |
--------------------------------------------------------------------------------
/examples/json-schema-options/types.ts:
--------------------------------------------------------------------------------
1 | // Arbitrary example types
2 |
3 | export type T = {
4 | /**
5 | * @minimum 100
6 | * @maximum 200
7 | * @multipleOf 2
8 | * @default 150
9 | * @description "it's a number" - strings must be quoted
10 | * @anotherDescription 'can also use as quotes'
11 | * @foobar "should support unknown props"
12 | */
13 | a: number;
14 | };
15 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .yarn
3 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | - Install dependencies `yarn`
4 | - Remove the old generated-typebox.ts file `rm generated-typebox.ts`
5 | - Start the code `yarn start` (generated-typebox.ts)
6 | - generated-typebox.ts should now again exist in the folder
7 | - done 🎉
8 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/generated-typebox.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
3 | * your use case, there is a high chance that direct changes to this file get
4 | * lost. Consider making changes to the underlying Typescript code you use to
5 | * generate this file instead. The default file is called "types.ts", perhaps
6 | * have a look there! :]
7 | */
8 |
9 | import { Type, Static } from "@sinclair/typebox";
10 |
11 | type Age = Static;
12 | const Age = Type.Number();
13 |
14 | export type Address = Static;
15 | export const Address = Type.Object({
16 | street: Type.String(),
17 | city: Type.String(),
18 | state: Type.String(),
19 | postalCode: Type.String(),
20 | });
21 |
22 | export type Contact = Static;
23 | export const Contact = Type.Object({
24 | phone: Type.String(),
25 | email: Type.String(),
26 | });
27 |
28 | export type Person = Static;
29 | export const Person = Type.Object({
30 | name: Type.String(),
31 | age: Age,
32 | address: Address,
33 | contact: Contact,
34 | });
35 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/index.ts:
--------------------------------------------------------------------------------
1 | // Replace this with the 'import { ts2typebox} from "ts2typebox"' when you
2 | // install the package.
3 | import { readFileSync, writeFileSync } from "node:fs";
4 | import { ts2typebox } from "../../src/index";
5 |
6 | (async () => {
7 | const file = readFileSync(__dirname + "/types.ts", "utf-8");
8 | const result = await ts2typebox({ input: file });
9 | writeFileSync(__dirname + "/generated-typebox.ts", result);
10 | })();
11 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "programmatic-usage",
3 | "packageManager": "yarn@3.5.1",
4 | "scripts": {
5 | "start": "ts-node ./index.ts"
6 | },
7 | "dependencies": {
8 | "@sinclair/typebox-codegen": "0.8.6"
9 | },
10 | "devDependencies": {
11 | "ts-node": "10.9.1"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/types.ts:
--------------------------------------------------------------------------------
1 | // Arbitrary example types
2 |
3 | type Age = number;
4 |
5 | export type Address = {
6 | street: string;
7 | city: string;
8 | state: string;
9 | postalCode: string;
10 | };
11 |
12 | export type Contact = {
13 | phone: string;
14 | email: string;
15 | };
16 |
17 | export type Person = {
18 | name: string;
19 | age: Age;
20 | address: Address;
21 | contact: Contact;
22 | };
23 |
--------------------------------------------------------------------------------
/examples/programmatic-usage/yarn.lock:
--------------------------------------------------------------------------------
1 | # This file is generated by running "yarn install" inside your project.
2 | # Manual changes might be lost - proceed with caution!
3 |
4 | __metadata:
5 | version: 6
6 | cacheKey: 8
7 |
8 | "@cspotcode/source-map-support@npm:^0.8.0":
9 | version: 0.8.1
10 | resolution: "@cspotcode/source-map-support@npm:0.8.1"
11 | dependencies:
12 | "@jridgewell/trace-mapping": 0.3.9
13 | checksum: 5718f267085ed8edb3e7ef210137241775e607ee18b77d95aa5bd7514f47f5019aa2d82d96b3bf342ef7aa890a346fa1044532ff7cc3009e7d24fce3ce6200fa
14 | languageName: node
15 | linkType: hard
16 |
17 | "@jridgewell/resolve-uri@npm:^3.0.3":
18 | version: 3.1.1
19 | resolution: "@jridgewell/resolve-uri@npm:3.1.1"
20 | checksum: f5b441fe7900eab4f9155b3b93f9800a916257f4e8563afbcd3b5a5337b55e52bd8ae6735453b1b745457d9f6cdb16d74cd6220bbdd98cf153239e13f6cbb653
21 | languageName: node
22 | linkType: hard
23 |
24 | "@jridgewell/sourcemap-codec@npm:^1.4.10":
25 | version: 1.4.15
26 | resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
27 | checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8
28 | languageName: node
29 | linkType: hard
30 |
31 | "@jridgewell/trace-mapping@npm:0.3.9":
32 | version: 0.3.9
33 | resolution: "@jridgewell/trace-mapping@npm:0.3.9"
34 | dependencies:
35 | "@jridgewell/resolve-uri": ^3.0.3
36 | "@jridgewell/sourcemap-codec": ^1.4.10
37 | checksum: d89597752fd88d3f3480845691a05a44bd21faac18e2185b6f436c3b0fd0c5a859fbbd9aaa92050c4052caf325ad3e10e2e1d1b64327517471b7d51babc0ddef
38 | languageName: node
39 | linkType: hard
40 |
41 | "@sinclair/typebox-codegen@npm:0.8.6":
42 | version: 0.8.6
43 | resolution: "@sinclair/typebox-codegen@npm:0.8.6"
44 | dependencies:
45 | "@sinclair/typebox": ^0.31.0
46 | prettier: ^2.8.7
47 | typescript: ^5.1.6
48 | checksum: e380d191b2165e81d60eab30479a1fd4ff7ba779d3fc2375db6682a70e286eaf56778abcf5fe2e07496d337cf4ad84c9c2783079c5aabeb0d0bf6144b3ef061a
49 | languageName: node
50 | linkType: hard
51 |
52 | "@sinclair/typebox@npm:^0.31.0":
53 | version: 0.31.3
54 | resolution: "@sinclair/typebox@npm:0.31.3"
55 | checksum: 8cd8187f6e1568255616d6a721022d6dfefa92fd7d8ff3a2f0b22adfe63ded8458f4c504e8e98c25f63cd148a62b248589eef02a63e360687d3b69bca222fc3d
56 | languageName: node
57 | linkType: hard
58 |
59 | "@tsconfig/node10@npm:^1.0.7":
60 | version: 1.0.9
61 | resolution: "@tsconfig/node10@npm:1.0.9"
62 | checksum: a33ae4dc2a621c0678ac8ac4bceb8e512ae75dac65417a2ad9b022d9b5411e863c4c198b6ba9ef659e14b9fb609bbec680841a2e84c1172df7a5ffcf076539df
63 | languageName: node
64 | linkType: hard
65 |
66 | "@tsconfig/node12@npm:^1.0.7":
67 | version: 1.0.11
68 | resolution: "@tsconfig/node12@npm:1.0.11"
69 | checksum: 5ce29a41b13e7897a58b8e2df11269c5395999e588b9a467386f99d1d26f6c77d1af2719e407621412520ea30517d718d5192a32403b8dfcc163bf33e40a338a
70 | languageName: node
71 | linkType: hard
72 |
73 | "@tsconfig/node14@npm:^1.0.0":
74 | version: 1.0.3
75 | resolution: "@tsconfig/node14@npm:1.0.3"
76 | checksum: 19275fe80c4c8d0ad0abed6a96dbf00642e88b220b090418609c4376e1cef81bf16237bf170ad1b341452feddb8115d8dd2e5acdfdea1b27422071163dc9ba9d
77 | languageName: node
78 | linkType: hard
79 |
80 | "@tsconfig/node16@npm:^1.0.2":
81 | version: 1.0.4
82 | resolution: "@tsconfig/node16@npm:1.0.4"
83 | checksum: 202319785901f942a6e1e476b872d421baec20cf09f4b266a1854060efbf78cde16a4d256e8bc949d31e6cd9a90f1e8ef8fb06af96a65e98338a2b6b0de0a0ff
84 | languageName: node
85 | linkType: hard
86 |
87 | "acorn-walk@npm:^8.1.1":
88 | version: 8.2.0
89 | resolution: "acorn-walk@npm:8.2.0"
90 | checksum: 1715e76c01dd7b2d4ca472f9c58968516a4899378a63ad5b6c2d668bba8da21a71976c14ec5f5b75f887b6317c4ae0b897ab141c831d741dc76024d8745f1ad1
91 | languageName: node
92 | linkType: hard
93 |
94 | "acorn@npm:^8.4.1":
95 | version: 8.8.2
96 | resolution: "acorn@npm:8.8.2"
97 | bin:
98 | acorn: bin/acorn
99 | checksum: f790b99a1bf63ef160c967e23c46feea7787e531292bb827126334612c234ed489a0dc2c7ba33156416f0ffa8d25bf2b0fdb7f35c2ba60eb3e960572bece4001
100 | languageName: node
101 | linkType: hard
102 |
103 | "arg@npm:^4.1.0":
104 | version: 4.1.3
105 | resolution: "arg@npm:4.1.3"
106 | checksum: 544af8dd3f60546d3e4aff084d451b96961d2267d668670199692f8d054f0415d86fc5497d0e641e91546f0aa920e7c29e5250e99fc89f5552a34b5d93b77f43
107 | languageName: node
108 | linkType: hard
109 |
110 | "create-require@npm:^1.1.0":
111 | version: 1.1.1
112 | resolution: "create-require@npm:1.1.1"
113 | checksum: a9a1503d4390d8b59ad86f4607de7870b39cad43d929813599a23714831e81c520bddf61bcdd1f8e30f05fd3a2b71ae8538e946eb2786dc65c2bbc520f692eff
114 | languageName: node
115 | linkType: hard
116 |
117 | "diff@npm:^4.0.1":
118 | version: 4.0.2
119 | resolution: "diff@npm:4.0.2"
120 | checksum: f2c09b0ce4e6b301c221addd83bf3f454c0bc00caa3dd837cf6c127d6edf7223aa2bbe3b688feea110b7f262adbfc845b757c44c8a9f8c0c5b15d8fa9ce9d20d
121 | languageName: node
122 | linkType: hard
123 |
124 | "make-error@npm:^1.1.1":
125 | version: 1.3.6
126 | resolution: "make-error@npm:1.3.6"
127 | checksum: b86e5e0e25f7f777b77fabd8e2cbf15737972869d852a22b7e73c17623928fccb826d8e46b9951501d3f20e51ad74ba8c59ed584f610526a48f8ccf88aaec402
128 | languageName: node
129 | linkType: hard
130 |
131 | "prettier@npm:^2.8.7":
132 | version: 2.8.8
133 | resolution: "prettier@npm:2.8.8"
134 | bin:
135 | prettier: bin-prettier.js
136 | checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8
137 | languageName: node
138 | linkType: hard
139 |
140 | "programmatic-usage@workspace:.":
141 | version: 0.0.0-use.local
142 | resolution: "programmatic-usage@workspace:."
143 | dependencies:
144 | "@sinclair/typebox-codegen": 0.8.6
145 | ts-node: 10.9.1
146 | languageName: unknown
147 | linkType: soft
148 |
149 | "ts-node@npm:10.9.1":
150 | version: 10.9.1
151 | resolution: "ts-node@npm:10.9.1"
152 | dependencies:
153 | "@cspotcode/source-map-support": ^0.8.0
154 | "@tsconfig/node10": ^1.0.7
155 | "@tsconfig/node12": ^1.0.7
156 | "@tsconfig/node14": ^1.0.0
157 | "@tsconfig/node16": ^1.0.2
158 | acorn: ^8.4.1
159 | acorn-walk: ^8.1.1
160 | arg: ^4.1.0
161 | create-require: ^1.1.0
162 | diff: ^4.0.1
163 | make-error: ^1.1.1
164 | v8-compile-cache-lib: ^3.0.1
165 | yn: 3.1.1
166 | peerDependencies:
167 | "@swc/core": ">=1.2.50"
168 | "@swc/wasm": ">=1.2.50"
169 | "@types/node": "*"
170 | typescript: ">=2.7"
171 | peerDependenciesMeta:
172 | "@swc/core":
173 | optional: true
174 | "@swc/wasm":
175 | optional: true
176 | bin:
177 | ts-node: dist/bin.js
178 | ts-node-cwd: dist/bin-cwd.js
179 | ts-node-esm: dist/bin-esm.js
180 | ts-node-script: dist/bin-script.js
181 | ts-node-transpile-only: dist/bin-transpile.js
182 | ts-script: dist/bin-script-deprecated.js
183 | checksum: 090adff1302ab20bd3486e6b4799e90f97726ed39e02b39e566f8ab674fd5bd5f727f43615debbfc580d33c6d9d1c6b1b3ce7d8e3cca3e20530a145ffa232c35
184 | languageName: node
185 | linkType: hard
186 |
187 | "typescript@npm:^5.1.6":
188 | version: 5.2.2
189 | resolution: "typescript@npm:5.2.2"
190 | bin:
191 | tsc: bin/tsc
192 | tsserver: bin/tsserver
193 | checksum: 7912821dac4d962d315c36800fe387cdc0a6298dba7ec171b350b4a6e988b51d7b8f051317786db1094bd7431d526b648aba7da8236607febb26cf5b871d2d3c
194 | languageName: node
195 | linkType: hard
196 |
197 | "typescript@patch:typescript@^5.1.6#~builtin":
198 | version: 5.2.2
199 | resolution: "typescript@patch:typescript@npm%3A5.2.2#~builtin::version=5.2.2&hash=77c9e2"
200 | bin:
201 | tsc: bin/tsc
202 | tsserver: bin/tsserver
203 | checksum: 07106822b4305de3f22835cbba949a2b35451cad50888759b6818421290ff95d522b38ef7919e70fb381c5fe9c1c643d7dea22c8b31652a717ddbd57b7f4d554
204 | languageName: node
205 | linkType: hard
206 |
207 | "v8-compile-cache-lib@npm:^3.0.1":
208 | version: 3.0.1
209 | resolution: "v8-compile-cache-lib@npm:3.0.1"
210 | checksum: 78089ad549e21bcdbfca10c08850022b22024cdcc2da9b168bcf5a73a6ed7bf01a9cebb9eac28e03cd23a684d81e0502797e88f3ccd27a32aeab1cfc44c39da0
211 | languageName: node
212 | linkType: hard
213 |
214 | "yn@npm:3.1.1":
215 | version: 3.1.1
216 | resolution: "yn@npm:3.1.1"
217 | checksum: 2c487b0e149e746ef48cda9f8bad10fc83693cd69d7f9dcd8be4214e985de33a29c9e24f3c0d6bcf2288427040a8947406ab27f7af67ee9456e6b84854f02dd6
218 | languageName: node
219 | linkType: hard
220 |
--------------------------------------------------------------------------------
/examples/skip-type-generation/.ts2typeboxrc.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * For providing your own transform functions, you can basically copy paste this
3 | * file into your root directory, name it ".ts2typeboxrc.cjs" and adapt the
4 | * functions to your needs!
5 | *
6 | * Only options which have to be passed via code (options that are functions) may
7 | * be specified here. For now, these are transformTypeName and
8 | * transformValueName.
9 | */
10 |
11 | /**
12 | * This function will be run on every type name. For a given code
13 | *
14 | * ```
15 | * type T = number
16 | * ```
17 | *
18 | * the default output would be:
19 | *
20 | * ```
21 | * type T = Static
22 | * const T = Type.Number()
23 | * ```
24 | * This function will run on the first "T". The generated code will contain the
25 | * transformed values.
26 | *
27 | * @param input {string}
28 | */
29 | const transformTypeName = (input) => {
30 | return input;
31 | };
32 |
33 | /**
34 | * This function will be run on every value name. For a given code
35 | *
36 | * ```
37 | * type T = number
38 | * ```
39 | *
40 | * the default output would be:
41 | * ```
42 | * type T = Static
43 | * const T = Type.Number()
44 | * ```
45 | *
46 | * This function will run on the second and third "T". The generated code will
47 | * contain the transformed values.
48 | *
49 | * @param input {string}
50 | */
51 | const transformValueName = (input) => {
52 | return input + "Schema";
53 | };
54 |
55 | /**
56 | * Options that can only be passed via code (will probably only contain
57 | * functions since they are not serializeable in JS).
58 | */
59 | module.exports = {
60 | transformTypeName,
61 | transformValueName,
62 | };
63 |
--------------------------------------------------------------------------------
/examples/skip-type-generation/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | When ts2typebox is installed (simply issue npm i -g ts2typebox to do so), clone
4 | the repo, cd into this directory and:
5 |
6 | - Remove the old generated-schemas.ts file `rm generated-schemas.ts`
7 | - Take a look at the '.ts2typeboxrc.cjs' file. Here you can define
8 | transformation functions which will get applied to all values and types in the
9 | generated output. This file has to exist inside the directory from which you
10 | run ts2typebox.
11 | - Here we use the transformValue function to simply append "Schema" to each
12 | generated value.
13 | - Use ts2typebox to generate the typebox code based on the types.ts file
14 | `ts2typebox --skip-type-creation --output generated-schemas.ts`
15 | - To understand how to possibly use this, take a quick look into ./index.ts
16 | - done :]
17 |
--------------------------------------------------------------------------------
/examples/skip-type-generation/generated-schemas.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
3 | * your use case, there is a high chance that direct changes to this file get
4 | * lost. Consider making changes to the underlying Typescript code you use to
5 | * generate this file instead. The default file is called "types.ts", perhaps
6 | * have a look there! :]
7 | */
8 |
9 | import { Type } from "@sinclair/typebox";
10 |
11 | export const PersonSchema = Type.Object({
12 | age: Type.Number({ minimum: 18 }),
13 | name: Type.String({ description: "full name of the person" }),
14 | });
15 |
--------------------------------------------------------------------------------
/examples/skip-type-generation/index.ts:
--------------------------------------------------------------------------------
1 | // Here you can now import your types (with comments) from your types.ts file
2 | // and the JSON schemas/typebox code from ./generated-schemas
3 |
4 | // import { PersonSchema } from "./generated-schemas";
5 | // import { Person } from "./types";
6 |
7 | export default {};
8 |
--------------------------------------------------------------------------------
/examples/skip-type-generation/types.ts:
--------------------------------------------------------------------------------
1 | export type Person = {
2 | /**
3 | * @minimum 18
4 | */
5 | age: number;
6 | /**
7 | * @description full name of the person
8 | */
9 | name: string;
10 | };
11 |
--------------------------------------------------------------------------------
/examples/transform-value-transform-type/.ts2typeboxrc.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * For providing your own transform functions, you can basically copy paste this
3 | * file into your root directory, name it ".ts2typeboxrc.cjs" and adapt the
4 | * functions to your needs!
5 | *
6 | * Only options which have to be passed via code (options that are functions) may
7 | * be specified here. For now, these are transformTypeName and
8 | * transformValueName.
9 | */
10 |
11 | /**
12 | * This function will be run on every type name. For a given code
13 | *
14 | * ```
15 | * type T = number
16 | * ```
17 | *
18 | * the default output would be:
19 | *
20 | * ```
21 | * type T = Static
22 | * const T = Type.Number()
23 | * ```
24 | * This function will run on the first "T". The generated code will contain the
25 | * transformed values.
26 | *
27 | * @param input {string}
28 | */
29 | const transformTypeName = (input) => {
30 | return input + "Type";
31 | };
32 |
33 | /**
34 | * This function will be run on every value name. For a given code
35 | *
36 | * ```
37 | * type T = number
38 | * ```
39 | *
40 | * the default output would be:
41 | * ```
42 | * type T = Static
43 | * const T = Type.Number()
44 | * ```
45 | *
46 | * This function will run on the second and third "T". The generated code will
47 | * contain the transformed values.
48 | *
49 | * @param input {string}
50 | */
51 | const transformValueName = (input) => {
52 | // arbitrary example
53 | return input + "Schema";
54 | };
55 |
56 | /**
57 | * Options that can only be passed via code (will probably only contain
58 | * functions since they are not serializeable in JS).
59 | */
60 | module.exports = {
61 | transformTypeName,
62 | transformValueName,
63 | };
64 |
--------------------------------------------------------------------------------
/examples/transform-value-transform-type/README.md:
--------------------------------------------------------------------------------
1 | # Example
2 |
3 | When ts2typebox is installed (simply issue npm i -g ts2typebox to do so), clone
4 | the repo, cd into this directory and:
5 |
6 | - Remove the old generated-types.ts file `rm generated-types.ts`
7 | - Take a look at the '.ts2typeboxrc.cjs' file. Here you can define
8 | transformation functions which will get applied to all values and types in the
9 | generated output. This file has to exist inside the directory from which you
10 | run ts2typebox.
11 | - Use ts2typebox to generate the typebox types based on the types.ts file
12 | `ts2typebox`
13 | - done :]
14 |
--------------------------------------------------------------------------------
/examples/transform-value-transform-type/generated-types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
3 | * your use case, there is a high chance that direct changes to this file get
4 | * lost. Consider making changes to the underlying Typescript code you use to
5 | * generate this file instead. The default file is called "types.ts", perhaps
6 | * have a look there! :]
7 | */
8 |
9 | import { Type, Static } from "@sinclair/typebox";
10 |
11 | export type PersonType = Static;
12 | export const PersonSchema = Type.Object({
13 | age: Type.Number(),
14 | name: Type.String(),
15 | });
16 |
--------------------------------------------------------------------------------
/examples/transform-value-transform-type/types.ts:
--------------------------------------------------------------------------------
1 | export type Person = {
2 | age: number;
3 | name: string;
4 | };
5 |
--------------------------------------------------------------------------------
/git-hooks/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | #
3 | # Runs prettier on all files before comitting them.
4 | # src: https://prettier.io/docs/en/precommit.html
5 |
6 | FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
7 | [ -z "$FILES" ] && exit 0
8 |
9 | echo "Running prettier to format files before commiting..."
10 |
11 | # Prettify all selected files
12 | echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write
13 |
14 | echo "Done!"
15 |
16 | # Add back the modified/prettified files to staging
17 | echo "$FILES" | xargs git add
18 |
19 | exit 0
20 |
21 |
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ts2typebox",
3 | "version": "1.6.2",
4 | "description": "Creates TypeBox code from Typescript code",
5 | "main": "dist/src/index.js",
6 | "source": "dist/src/index.js",
7 | "typings": "dist/src/index.d.ts",
8 | "bin": {
9 | "ts-to-typebox": "dist/src/cli/index.js",
10 | "ts2typebox": "dist/src/cli/index.js"
11 | },
12 | "scripts": {
13 | "build": "tsc",
14 | "watch-ts": "tsc -w",
15 | "test": "tsc && node --test --test-reporter spec",
16 | "start": "node dist/src/index.js"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+https://github.com/xddq/ts2typebox.git"
21 | },
22 | "keywords": [
23 | "JSON schema",
24 | "ts2typebox",
25 | "ts-to-typebox",
26 | "typescript",
27 | "typebox",
28 | "ts",
29 | "validation",
30 | "parsing",
31 | "IO",
32 | "cli"
33 | ],
34 | "author": "Pierre Dahmani",
35 | "license": "MIT",
36 | "bugs": {
37 | "url": "https://github.com/xddq/ts2typebox/issues"
38 | },
39 | "homepage": "https://github.com/xddq/ts2typebox#readme",
40 | "dependencies": {
41 | "@sinclair/typebox-codegen": "^0.10.5",
42 | "cosmiconfig": "^8.1.3",
43 | "minimist": "^1.2.8",
44 | "prettier": "^2.8.7",
45 | "typescript": "^5.7.3"
46 | },
47 | "devDependencies": {
48 | "@sinclair/typebox": "0.34.25",
49 | "@types/minimist": "1.2.5",
50 | "@types/node": "18.16.0",
51 | "@types/prettier": "2.7.2",
52 | "@types/shelljs": "0.8.15",
53 | "shelljs": "0.8.5",
54 | "tsconfig-paths": "4.2.0"
55 | },
56 | "peerDependencies": {
57 | "@sinclair/typebox": "^0.34.25"
58 | },
59 | "packageManager": "yarn@3.5.1"
60 | }
61 |
--------------------------------------------------------------------------------
/src/cli/cli.ts:
--------------------------------------------------------------------------------
1 | import { readFileSync, createWriteStream } from "node:fs";
2 | import { Readable } from "node:stream";
3 | import minimist from "minimist";
4 |
5 | import packageJson from "../../package.json";
6 | import { ts2typebox } from "../programmatic-usage";
7 |
8 | const readCliOptions = (): minimist.ParsedArgs => {
9 | return minimist(process.argv.slice(2), {
10 | alias: {
11 | input: "i",
12 | output: "o",
13 | help: "h",
14 | },
15 | default: {
16 | input: "types.ts",
17 | output: "generated-types.ts",
18 | },
19 | });
20 | };
21 |
22 | /**
23 | * This functions is executed when running schema2typebox via the cli.
24 | *
25 | * @param getCliOptionsFn This function was added to be able to overwrite the
26 | * default behaviour of reading in the cli options in order to make them easily
27 | * testable by bassing a custom readCliOptions function.
28 | */
29 | export const runCli = async (
30 | getCliOptionsFn: typeof readCliOptions = readCliOptions
31 | ) => {
32 | const args = getCliOptionsFn();
33 |
34 | // TODO: narrow condition.
35 | if (args.help) {
36 | return process.stdout.write(getHelpText.run());
37 | }
38 |
39 | const inputPath = process.cwd() + `/${args.input ?? "schema.json"}`;
40 | const inputFileAsString = readFileSync(inputPath, "utf-8");
41 |
42 | const typeboxCode = await ts2typebox({
43 | input: inputFileAsString,
44 | disableAutogenComment: args["disable-autogen-comment"],
45 | skipTypeCreation: args["skip-type-creation"],
46 | });
47 |
48 | const generatedCodeStream = Readable.from(typeboxCode.split(/(\r\n|\r|\n)/));
49 | if (args["output-stdout"]) {
50 | return generatedCodeStream.pipe(process.stdout);
51 | }
52 |
53 | const outputPath =
54 | process.cwd() + `/${args.output ?? "generated-typebox.ts"}`;
55 | return generatedCodeStream.pipe(createWriteStream(outputPath));
56 | };
57 |
58 | /**
59 | * Declaring this as function in order to make it better testable.
60 | * Using an object to be able to mock it and track its usage.
61 | */
62 | export const getHelpText = {
63 | run: () => {
64 | return `
65 | ts2typebox generates TypeBox code from Typescript code.
66 | Version: ${packageJson.version}
67 |
68 | Usage:
69 |
70 | ts2typebox [ARGUMENTS]
71 |
72 | Arguments:
73 |
74 | -h, --help
75 | Displays this menu.
76 |
77 | -i, --input
78 | Specifies the relative path to the file containing the typescript types
79 | that will be used to generated typebox types. Defaults to "types.ts".
80 |
81 | -o, --output
82 | Specifies the relative path to generated file that will contain the
83 | typebox types. Defaults to "generated-types.ts".
84 |
85 | --output-stdout
86 | Does not generate an output file and prints the generated code to stdout
87 | instead. Has precedence over -o/--output.
88 |
89 | --disable-autogen-comment
90 | When used, it does not add the comment at the beginning of the generated
91 | file which is stating that the code was automatically generated.
92 |
93 | --skip-type-creation
94 | When used, strips all types from the generated code. This can be helpful
95 | if you want to use your Typescript types inside your input file (which
96 | probably contains comments) as source of truth and still use the generated
97 | TypeBox code (schema validators) to validate data based on these types.
98 | When using this option you probably want to also provide a custom
99 | transformValue function since two same symbols can't be imported from two
100 | different files. For an example take a look inside the repo under
101 | ./examples/skip-type-creation.
102 |
103 | Additional:
104 |
105 | Transformations
106 |
107 | You can adapt the names of the generated types (as well as the names of the
108 | generated values) using custom transformation functions which take a string
109 | as an input and return a string as their output. These will run on each of
110 | the generated types and values, respectively. Please take a look inside the
111 | repo under ./examples/transform-value-transform-type for an example of this.
112 |
113 | Formatting
114 |
115 | The generated output is formatted based on the prettier config inside your
116 | repo (or the default one, if you don't have one).
117 | `;
118 | },
119 | };
120 |
--------------------------------------------------------------------------------
/src/cli/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import { runCli } from "./cli";
4 |
5 | (async () => {
6 | await runCli();
7 | })();
8 |
--------------------------------------------------------------------------------
/src/codeOptions.cjs:
--------------------------------------------------------------------------------
1 | /**
2 | * For providing your own transform functions, you can basically copy paste this
3 | * file into your root directory, name it ".ts2typeboxrc.cjs" and adapt the
4 | * functions to your needs!
5 | *
6 | * Only options which have to be passed via code (options that are functions) may
7 | * be specified here. For now, these are transformTypeName and
8 | * transformValueName.
9 | */
10 |
11 | /**
12 | * This function will be run on every type name. For a given code
13 | *
14 | * ```
15 | * type T = number
16 | * ```
17 | *
18 | * the default output would be:
19 | *
20 | * ```
21 | * type T = Static
22 | * const T = Type.Number()
23 | * ```
24 | * This function will run on the first "T". The generated code will contain the
25 | * transformed values.
26 | *
27 | * @param input {string}
28 | */
29 | const transformTypeName = (input) => {
30 | return input;
31 | };
32 |
33 | /**
34 | * This function will be run on every value name. For a given code
35 | *
36 | * ```
37 | * type T = number
38 | * ```
39 | *
40 | * the default output would be:
41 | * ```
42 | * type T = Static
43 | * const T = Type.Number()
44 | * ```
45 | *
46 | * This function will run on the second and third "T". The generated code will
47 | * contain the transformed values.
48 | *
49 | * @param input {string}
50 | */
51 | const transformValueName = (input) => {
52 | return input;
53 | };
54 |
55 | /**
56 | * Options that can only be passed via code (will probably only contain
57 | * functions since they are not serializeable in JS).
58 | */
59 | module.exports = {
60 | transformTypeName,
61 | transformValueName,
62 | };
63 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { ts2typebox, Ts2TypeboxOptions } from "./programmatic-usage";
2 |
--------------------------------------------------------------------------------
/src/jsdoc.ts:
--------------------------------------------------------------------------------
1 | /*--------------------------------------------------------------------------
2 |
3 | @typebox/codegen
4 |
5 | The MIT License (MIT)
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in
15 | all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | THE SOFTWARE.
24 |
25 | ---------------------------------------------------------------------------*/
26 |
27 | /** JSDoc Property Parser */
28 | export namespace JsDoc {
29 | function DecodeWithNonQuotedProperties(content: string): any {
30 | const parseFunction = new Function(`return (${content});`);
31 | return parseFunction();
32 | }
33 | function Decode(content: string) {
34 | try {
35 | return DecodeWithNonQuotedProperties(content);
36 | } catch {
37 | return content;
38 | }
39 | }
40 | function* ParseValue(
41 | key: string,
42 | content: string
43 | ): IterableIterator<[string, any]> {
44 | for (let i = 0; i < content.length; i++) {
45 | if (content[i] === "\n" || content[i] === "-") {
46 | const value = content.slice(0, i).trim();
47 | const rest = content.slice(i);
48 | yield [key, Decode(value)];
49 | return yield* ParseContent(rest);
50 | }
51 | }
52 | }
53 | function* ParseKey(content: string): IterableIterator<[string, any]> {
54 | for (let i = 1; i < content.length; i++) {
55 | if (content[i] === " ") {
56 | const key = content.slice(1, i);
57 | const rest = content.slice(i).trimStart();
58 | return yield* ParseValue(key, rest);
59 | }
60 | }
61 | }
62 | function* ParseContent(content: string): IterableIterator<[string, any]> {
63 | for (let i = 0; i < content.length; i++) {
64 | if (content[i] === "@") {
65 | return yield* ParseKey(content.slice(i));
66 | }
67 | }
68 | }
69 | export function Parse(content: string): Record {
70 | const properties = [...ParseContent(content)];
71 | return properties.reduce(
72 | (acc, [key, value]) => ({ ...acc, [key]: value }),
73 | {}
74 | );
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/programmatic-usage.ts:
--------------------------------------------------------------------------------
1 | import * as prettier from "prettier";
2 | import { cosmiconfig } from "cosmiconfig";
3 | import packageJson from "../package.json";
4 | import { default as defaultCodeOptions } from "./codeOptions.cjs";
5 | import * as codegen from "@sinclair/typebox-codegen";
6 |
7 | export type Ts2TypeboxOptions = {
8 | /**
9 | * The given Typescript code as utf-8 encoded string.
10 | */
11 | input: string;
12 | /**
13 | * Removes the comment at the beginning of the generated typebox code which
14 | * mentions that the code was auto generated and should not be changed since
15 | * there is a high risk that changes might get lost.
16 | */
17 | disableAutogenComment?: true;
18 | /**
19 | * Skips the creation of types in the generated file. Only creates the typebox
20 | * validators containing the JSON schemas based on your typescript types. See
21 | * the output of ts2typebox -h for more info.
22 | */
23 | skipTypeCreation?: boolean;
24 | };
25 |
26 | /**
27 | * Just an alias for string. This gets returned by the ts2typebox function and
28 | * contains the generated types as string.
29 | */
30 | type GeneratedTypes = string;
31 |
32 | /**
33 | * Use this function for programmatic usage of ts2typebox. The options are typed
34 | * and commented.
35 | *
36 | * @returns The generated types as string if (outputStdout was set) or undefined
37 | * otherwise.
38 | *
39 | * @throws Error
40 | **/
41 | export const ts2typebox = async ({
42 | input,
43 | disableAutogenComment,
44 | skipTypeCreation,
45 | }: Ts2TypeboxOptions): Promise => {
46 | const generatedTs = codegen.TypeScriptToTypeBox.Generate(input);
47 |
48 | // post-processing
49 | // 1. transformations
50 | const ts2typeboxCodeOptions = await cosmiconfig("ts2typebox").search();
51 | // TODO: perhaps validate with typebox that these are indeed valid codeOption
52 | // configs (ts2typebox options)
53 | const usedCodeOptions =
54 | ts2typeboxCodeOptions === null
55 | ? defaultCodeOptions
56 | : (ts2typeboxCodeOptions.config as typeof defaultCodeOptions);
57 | const transformedTs = transformValuesAndTypes(generatedTs, usedCodeOptions);
58 |
59 | // 2. formatting
60 | const explorer = cosmiconfig("prettier");
61 | const searchResult = await explorer.search();
62 | // TODO: perhaps validate with typebox that these are indeed valid prettier configs
63 | const prettierConfig =
64 | searchResult === null ? {} : (searchResult.config as prettier.Options);
65 | const resultFormatted = prettier.format(transformedTs, {
66 | parser: "typescript",
67 | ...prettierConfig,
68 | });
69 |
70 | const resultFiltered =
71 | skipTypeCreation === undefined
72 | ? resultFormatted
73 | : filterTypes(resultFormatted);
74 | const result =
75 | disableAutogenComment === undefined
76 | ? addCommentThatCodeIsGenerated.run(resultFiltered)
77 | : resultFiltered;
78 |
79 | return result;
80 | };
81 |
82 | /**
83 | * Post-processing after successful code generation.
84 | * Transforms all values and types based on given functions.
85 | */
86 | const transformValuesAndTypes = (
87 | generatedTypes: string,
88 | transformFns: typeof defaultCodeOptions
89 | ) => {
90 | const tsWithTransformedTypes = generatedTypes.replace(
91 | /(type)\s(\w+)/gm,
92 | (_match, group1, group2) => {
93 | return group1 + " " + transformFns.transformTypeName(group2);
94 | }
95 | );
96 | const result = tsWithTransformedTypes.replace(
97 | /(typeof|const)\s(\w+)/gm,
98 | (_match, group1, group2) => {
99 | return group1 + " " + transformFns.transformValueName(group2);
100 | }
101 | );
102 | return result;
103 | };
104 |
105 | /**
106 | * Post-processing after successful code generation.
107 | * Removes each line starting with "export type" or "type".
108 | */
109 | const filterTypes = (input: GeneratedTypes) => {
110 | const result = input.replace(/^(export\s+)?type.*(\r?\n|$)/gm, "");
111 | // Now we still have to adapt the import line since we would otherwise get
112 | // "unused imports". For now, we simply remove the first line and append the
113 | // correct one.
114 | return (
115 | 'import { Type } from "@sinclair/typebox";\n' +
116 | result.split("\n").slice(1).join("\n")
117 | );
118 | };
119 |
120 | /**
121 | * Declaring this as function in order to make it better testable.
122 | * Using an object to be able to mock it and track its usage.
123 | */
124 | export const getHelpText = {
125 | run: () => {
126 | return `
127 | ts2typebox is a cli tool to generate typebox JSON schemas based on given
128 | typescript types. The generated output is formatted based on the prettier
129 | config inside your repo (or the default one, if you don't have one).
130 | Version: ${packageJson.version}
131 |
132 | Usage:
133 |
134 | ts2typebox [ARGUMENTS]
135 |
136 | Arguments:
137 |
138 | -h, --help
139 | Displays this menu.
140 |
141 | -i, --input
142 | Specifies the relative path to the file containing the typescript types
143 | that will be used to generated typebox types. Defaults to "types.ts".
144 |
145 | -o, --output
146 | Specifies the relative path to generated file that will contain the
147 | typebox types. Defaults to "generated-types.ts".
148 |
149 | --output-stdout
150 | Does not generate an output file and prints the generated code to stdout
151 | instead. Has precedence over -o/--output.
152 |
153 | --disable-autogen-comment
154 | When used, it does not add the comment at the beginning of the generated
155 | file which is stating that the code was automatically generated.
156 |
157 | --skip-type-creation
158 | When used, strips all types from the generated code. This can be helpful
159 | if you want to use your Typescript types inside your input file (which
160 | probably contains comments) as source of truth and still use the generated
161 | JSON schema validators (typebox values) to validate data based on these
162 | types. When using this option you probably want to also provide a custom
163 | transformValue function since two same symbols can't be imported from two
164 | different files. For an example take a look inside the repo under
165 | ./examples/skip-type-creation.
166 |
167 | Additional:
168 |
169 | You can adapt the names of the generated types (as well as the names of the
170 | generated values) using custom transformation functions which take a string
171 | as an input and return a string as their output. These will run on each of
172 | the generated types and values, respectively. Please take a look inside the
173 | repo under ./examples/transform-value-transform-type for an example of this.
174 | `;
175 | },
176 | };
177 |
178 | /**
179 | * Declaring this as an object with a function in order to make it better
180 | * testable with mocks. Allows for tracking the call count.
181 | */
182 | export const addCommentThatCodeIsGenerated = {
183 | run: (code: string) => {
184 | return `/**
185 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
186 | * your use case, there is a high chance that direct changes to this file get
187 | * lost. Consider making changes to the underlying Typescript code you use to
188 | * generate this file instead. The default file is called "types.ts", perhaps
189 | * have a look there! :]
190 | */
191 |
192 | ${code}`;
193 | },
194 | };
195 |
--------------------------------------------------------------------------------
/test/index.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, mock, beforeEach } from "node:test";
2 | import assert from "node:assert/strict";
3 | import * as prettier from "prettier";
4 | import fs from "node:fs";
5 | import path from "node:path";
6 | import shell from "shelljs";
7 | import { ts2typebox } from "../src/programmatic-usage";
8 |
9 | const SHELLJS_RETURN_CODE_OK = 0;
10 | const buildOsIndependentPath = (foldersOrFiles: string[]) => {
11 | return foldersOrFiles.join(path.sep);
12 | };
13 |
14 | const formatWithPrettier = (input: string): string => {
15 | return prettier.format(input, { parser: "typescript" });
16 | };
17 |
18 | /**
19 | * Formats given input with prettier and returns the result. This is used for
20 | * testing to be able to compare generated types with expected types without
21 | * having to take care of formatting.
22 | * @throws Error
23 | **/
24 | export const expectEqualIgnoreFormatting = (
25 | input1: string,
26 | input2: string
27 | ): void => {
28 | assert.equal(formatWithPrettier(input1), formatWithPrettier(input2));
29 | };
30 |
31 | describe("programmatic usage API", () => {
32 | beforeEach(() => {
33 | // Reset the globally tracked mocks.
34 | mock.reset();
35 | });
36 | test("generates TypeBox code", async () => {
37 | // prepares and writes a test types.ts file.
38 | const dummyTypes = `
39 | type T = {
40 | a: number;
41 | b: string;
42 | };
43 | `;
44 | const expectedOutput = `
45 | /**
46 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
47 | * your use case, there is a high chance that direct changes to this file get
48 | * lost. Consider making changes to the underlying Typescript code you use to
49 | * generate this file instead. The default file is called "types.ts", perhaps
50 | * have a look there! :]
51 | */
52 |
53 | import { Type, Static } from '@sinclair/typebox';
54 |
55 | type T = Static;
56 | const T = Type.Object({
57 | a: Type.Number(),
58 | b: Type.String(),
59 | });
60 | `;
61 | const generatedTypeBox = await ts2typebox({
62 | input: dummyTypes,
63 | });
64 | expectEqualIgnoreFormatting(generatedTypeBox, expectedOutput);
65 | });
66 | test("disableAutogenComment option", async () => {
67 | // prepares and writes a test types.ts file.
68 | const dummyTypes = `
69 | type T = {
70 | a: number;
71 | b: string;
72 | };
73 | `;
74 | const expectedOutput = `
75 | import { Type, Static } from '@sinclair/typebox';
76 |
77 | type T = Static;
78 | const T = Type.Object({
79 | a: Type.Number(),
80 | b: Type.String(),
81 | });
82 | `;
83 | const generatedTypeBox = await ts2typebox({
84 | input: dummyTypes,
85 | disableAutogenComment: true,
86 | });
87 | expectEqualIgnoreFormatting(generatedTypeBox, expectedOutput);
88 | });
89 | test("skipTypeCreation option", async () => {
90 | const dummyTypes = `
91 | type T = {
92 | a: number;
93 | b: string;
94 | };
95 | `;
96 | const expectedOutput = `
97 | /**
98 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
99 | * your use case, there is a high chance that direct changes to this file get
100 | * lost. Consider making changes to the underlying Typescript code you use to
101 | * generate this file instead. The default file is called "types.ts", perhaps
102 | * have a look there! :]
103 | */
104 |
105 | import { Type } from '@sinclair/typebox';
106 |
107 | const T = Type.Object({
108 | a: Type.Number(),
109 | b: Type.String(),
110 | });
111 | `;
112 | const generatedTypeBox = await ts2typebox({
113 | input: dummyTypes,
114 | skipTypeCreation: true,
115 | });
116 | expectEqualIgnoreFormatting(generatedTypeBox, expectedOutput);
117 | });
118 | test("with prettier config", async () => {
119 | // TODO: .prettierrc.yml should not exist before
120 |
121 | // prepares and writes a test prettierrc.yml file.
122 | const dummyPretterConfig = "singleQuote: true";
123 | const configFileAbsolute = buildOsIndependentPath([
124 | __dirname,
125 | "..",
126 | "..",
127 | ".prettierrc.yml",
128 | ]);
129 | // check that file does not exist yet
130 | await assert.rejects(async () => {
131 | return await fs.promises.access(configFileAbsolute);
132 | });
133 |
134 | fs.writeFileSync(configFileAbsolute, dummyPretterConfig);
135 |
136 | const dummyTypes = `
137 | type T = {
138 | a: number;
139 | b: string;
140 | };
141 | `;
142 | const generatedTypeBox = await ts2typebox({
143 | input: dummyTypes,
144 | });
145 | // We expect that all " will be converted to '
146 | // Therefore something like (default)
147 | // import { Type, Static } from "@sinclair/typebox";
148 | // will become (with our custom config)
149 | // import { Type, Static } from '@sinclair/typebox';
150 | assert.equal(generatedTypeBox.includes("'@sinclair/typebox'"), true);
151 |
152 | // cleanup generated files
153 | const { code: returnCode } = shell.rm("-f", [configFileAbsolute]);
154 | assert.equal(returnCode, SHELLJS_RETURN_CODE_OK);
155 | });
156 |
157 | test("with .ts2typeboxrc.cjs config", async () => {
158 | const dummyTs2TypeboxRc = `
159 | const transformTypeName = (input) => {
160 | return "TestType" + input;
161 | };
162 | const transformValueName = (input) => {
163 | return "testValue" + input;
164 | };
165 |
166 | module.exports = {
167 | transformTypeName,
168 | transformValueName,
169 | };
170 | `;
171 | const configFileAbsolute = buildOsIndependentPath([
172 | __dirname,
173 | "..",
174 | "..",
175 | ".ts2typeboxrc.cjs",
176 | ]);
177 | // check that file does not exist yet
178 | await assert.rejects(async () => {
179 | return await fs.promises.access(configFileAbsolute);
180 | });
181 | fs.writeFileSync(configFileAbsolute, dummyTs2TypeboxRc);
182 |
183 | // prepares and writes a test types.ts file.
184 | const dummyTypes = `
185 | type T = number;
186 | export type U = number;
187 | `;
188 |
189 | const expectedOutput = `
190 | /**
191 | * ATTENTION. This code was AUTO GENERATED by ts2typebox. While I don't know
192 | * your use case, there is a high chance that direct changes to this file get
193 | * lost. Consider making changes to the underlying Typescript code you use to
194 | * generate this file instead. The default file is called "types.ts", perhaps
195 | * have a look there! :]
196 | */
197 |
198 | import { Type, Static } from "@sinclair/typebox";
199 |
200 | type TestTypeT = Static;
201 | const testValueT = Type.Number();
202 |
203 | export type TestTypeU = Static;
204 | export const testValueU = Type.Number();
205 | `;
206 | const generatedTypeBox = await ts2typebox({
207 | input: dummyTypes,
208 | });
209 | expectEqualIgnoreFormatting(generatedTypeBox, expectedOutput);
210 |
211 | // cleanup generated files
212 | const { code: returnCode } = shell.rm("-f", [configFileAbsolute]);
213 | assert.equal(returnCode, SHELLJS_RETURN_CODE_OK);
214 | });
215 | });
216 | // TODO: create cli usage tests with the refactored/fixed new cli file
217 | // describe("cli usage", () => {});
218 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "CommonJS",
4 | "moduleResolution": "node",
5 | "target": "ES2021",
6 | "outDir": "./dist" /* Specify an output folder for all emitted files. */,
7 | "noEmit": false,
8 | "baseUrl": ".",
9 | "esModuleInterop": true,
10 | "allowSyntheticDefaultImports": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "strict": true,
13 | "sourceMap": true,
14 | "skipLibCheck": true,
15 | "resolveJsonModule": true,
16 | "allowJs": true,
17 | "checkJs": true,
18 | "paths": {
19 | "@/*": ["./src/*"]
20 | },
21 | "declaration": true
22 | },
23 | "include": ["src", "test"],
24 | "exclude": ["examples", "dist", "coverage"]
25 | }
26 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # This file is generated by running "yarn install" inside your project.
2 | # Manual changes might be lost - proceed with caution!
3 |
4 | __metadata:
5 | version: 6
6 | cacheKey: 8
7 |
8 | "@babel/code-frame@npm:^7.0.0":
9 | version: 7.21.4
10 | resolution: "@babel/code-frame@npm:7.21.4"
11 | dependencies:
12 | "@babel/highlight": ^7.18.6
13 | checksum: e5390e6ec1ac58dcef01d4f18eaf1fd2f1325528661ff6d4a5de8979588b9f5a8e852a54a91b923846f7a5c681b217f0a45c2524eb9560553160cd963b7d592c
14 | languageName: node
15 | linkType: hard
16 |
17 | "@babel/helper-validator-identifier@npm:^7.18.6":
18 | version: 7.19.1
19 | resolution: "@babel/helper-validator-identifier@npm:7.19.1"
20 | checksum: 0eca5e86a729162af569b46c6c41a63e18b43dbe09fda1d2a3c8924f7d617116af39cac5e4cd5d431bb760b4dca3c0970e0c444789b1db42bcf1fa41fbad0a3a
21 | languageName: node
22 | linkType: hard
23 |
24 | "@babel/highlight@npm:^7.18.6":
25 | version: 7.18.6
26 | resolution: "@babel/highlight@npm:7.18.6"
27 | dependencies:
28 | "@babel/helper-validator-identifier": ^7.18.6
29 | chalk: ^2.0.0
30 | js-tokens: ^4.0.0
31 | checksum: 92d8ee61549de5ff5120e945e774728e5ccd57fd3b2ed6eace020ec744823d4a98e242be1453d21764a30a14769ecd62170fba28539b211799bbaf232bbb2789
32 | languageName: node
33 | linkType: hard
34 |
35 | "@sinclair/typebox-codegen@npm:^0.10.5":
36 | version: 0.10.5
37 | resolution: "@sinclair/typebox-codegen@npm:0.10.5"
38 | dependencies:
39 | "@sinclair/typebox": ^0.33.1
40 | prettier: ^2.8.7
41 | typescript: ^5.4.5
42 | checksum: e5917e1ac80b5761b848cb8d6f890bffcdf3eb5f9af92d36e3d37ce9ce0e1f051f1f34214b117111180d247ffb8cb2e5fa53b947a9ae0a8ea6fac965efc6a5db
43 | languageName: node
44 | linkType: hard
45 |
46 | "@sinclair/typebox@npm:0.34.25":
47 | version: 0.34.25
48 | resolution: "@sinclair/typebox@npm:0.34.25"
49 | checksum: 72a1d04a70e28fffc54d4241baee4cd0ba3338de0ed3c40a1eca5b3be29be4be8ea8119cef4e64acacf1a679f6504ea747616eec042514455fadc709762b85c7
50 | languageName: node
51 | linkType: hard
52 |
53 | "@sinclair/typebox@npm:^0.33.1":
54 | version: 0.33.22
55 | resolution: "@sinclair/typebox@npm:0.33.22"
56 | checksum: d87c623b2b853a2684edda8d8a9f842867a9e22d0120142b8c82d0c7fc97ac0e5d95027c2f14497ccce0bd101b706645d04acd602b04c0c706002f57f51302e3
57 | languageName: node
58 | linkType: hard
59 |
60 | "@types/glob@npm:~7.2.0":
61 | version: 7.2.0
62 | resolution: "@types/glob@npm:7.2.0"
63 | dependencies:
64 | "@types/minimatch": "*"
65 | "@types/node": "*"
66 | checksum: 6ae717fedfdfdad25f3d5a568323926c64f52ef35897bcac8aca8e19bc50c0bd84630bbd063e5d52078b2137d8e7d3c26eabebd1a2f03ff350fff8a91e79fc19
67 | languageName: node
68 | linkType: hard
69 |
70 | "@types/minimatch@npm:*":
71 | version: 5.1.2
72 | resolution: "@types/minimatch@npm:5.1.2"
73 | checksum: 0391a282860c7cb6fe262c12b99564732401bdaa5e395bee9ca323c312c1a0f45efbf34dce974682036e857db59a5c9b1da522f3d6055aeead7097264c8705a8
74 | languageName: node
75 | linkType: hard
76 |
77 | "@types/minimist@npm:1.2.5":
78 | version: 1.2.5
79 | resolution: "@types/minimist@npm:1.2.5"
80 | checksum: 477047b606005058ab0263c4f58097136268007f320003c348794f74adedc3166ffc47c80ec3e94687787f2ab7f4e72c468223946e79892cf0fd9e25e9970a90
81 | languageName: node
82 | linkType: hard
83 |
84 | "@types/node@npm:*":
85 | version: 20.1.4
86 | resolution: "@types/node@npm:20.1.4"
87 | checksum: bffa6a6e92831cc805b13658c55be8e04abe3202d5e57ddd7fee4cfbe269656a1f475909a9f9514e1aff50310d0d90c516ac2c649cb6f1c77d4b1079c2fd1e88
88 | languageName: node
89 | linkType: hard
90 |
91 | "@types/node@npm:18.16.0":
92 | version: 18.16.0
93 | resolution: "@types/node@npm:18.16.0"
94 | checksum: 63e0042136663b9e85ce503a4c65406cc6621fdba63ea66c74b4b1364a9aa9bdb57cadcb76696abab177f38a819b0fa6ace9e7f1647dcb990aedb1b4bd01012f
95 | languageName: node
96 | linkType: hard
97 |
98 | "@types/prettier@npm:2.7.2":
99 | version: 2.7.2
100 | resolution: "@types/prettier@npm:2.7.2"
101 | checksum: b47d76a5252265f8d25dd2fe2a5a61dc43ba0e6a96ffdd00c594cb4fd74c1982c2e346497e3472805d97915407a09423804cc2110a0b8e1b22cffcab246479b7
102 | languageName: node
103 | linkType: hard
104 |
105 | "@types/shelljs@npm:0.8.15":
106 | version: 0.8.15
107 | resolution: "@types/shelljs@npm:0.8.15"
108 | dependencies:
109 | "@types/glob": ~7.2.0
110 | "@types/node": "*"
111 | checksum: 94939421c6c83d3075e1c56bf940eb3c34567c6b2ac0b553ec81de7f4c7e7cdfc729117d821c22418d64c45fcd4f96a6ec7ae21ed0d7a80e3e9a008672dde35f
112 | languageName: node
113 | linkType: hard
114 |
115 | "ansi-styles@npm:^3.2.1":
116 | version: 3.2.1
117 | resolution: "ansi-styles@npm:3.2.1"
118 | dependencies:
119 | color-convert: ^1.9.0
120 | checksum: d85ade01c10e5dd77b6c89f34ed7531da5830d2cb5882c645f330079975b716438cd7ebb81d0d6e6b4f9c577f19ae41ab55f07f19786b02f9dfd9e0377395665
121 | languageName: node
122 | linkType: hard
123 |
124 | "argparse@npm:^2.0.1":
125 | version: 2.0.1
126 | resolution: "argparse@npm:2.0.1"
127 | checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced
128 | languageName: node
129 | linkType: hard
130 |
131 | "balanced-match@npm:^1.0.0":
132 | version: 1.0.2
133 | resolution: "balanced-match@npm:1.0.2"
134 | checksum: 9706c088a283058a8a99e0bf91b0a2f75497f185980d9ffa8b304de1d9e58ebda7c72c07ebf01dadedaac5b2907b2c6f566f660d62bd336c3468e960403b9d65
135 | languageName: node
136 | linkType: hard
137 |
138 | "brace-expansion@npm:^1.1.7":
139 | version: 1.1.11
140 | resolution: "brace-expansion@npm:1.1.11"
141 | dependencies:
142 | balanced-match: ^1.0.0
143 | concat-map: 0.0.1
144 | checksum: faf34a7bb0c3fcf4b59c7808bc5d2a96a40988addf2e7e09dfbb67a2251800e0d14cd2bfc1aa79174f2f5095c54ff27f46fb1289fe2d77dac755b5eb3434cc07
145 | languageName: node
146 | linkType: hard
147 |
148 | "callsites@npm:^3.0.0":
149 | version: 3.1.0
150 | resolution: "callsites@npm:3.1.0"
151 | checksum: 072d17b6abb459c2ba96598918b55868af677154bec7e73d222ef95a8fdb9bbf7dae96a8421085cdad8cd190d86653b5b6dc55a4484f2e5b2e27d5e0c3fc15b3
152 | languageName: node
153 | linkType: hard
154 |
155 | "chalk@npm:^2.0.0":
156 | version: 2.4.2
157 | resolution: "chalk@npm:2.4.2"
158 | dependencies:
159 | ansi-styles: ^3.2.1
160 | escape-string-regexp: ^1.0.5
161 | supports-color: ^5.3.0
162 | checksum: ec3661d38fe77f681200f878edbd9448821924e0f93a9cefc0e26a33b145f1027a2084bf19967160d11e1f03bfe4eaffcabf5493b89098b2782c3fe0b03d80c2
163 | languageName: node
164 | linkType: hard
165 |
166 | "color-convert@npm:^1.9.0":
167 | version: 1.9.3
168 | resolution: "color-convert@npm:1.9.3"
169 | dependencies:
170 | color-name: 1.1.3
171 | checksum: fd7a64a17cde98fb923b1dd05c5f2e6f7aefda1b60d67e8d449f9328b4e53b228a428fd38bfeaeb2db2ff6b6503a776a996150b80cdf224062af08a5c8a3a203
172 | languageName: node
173 | linkType: hard
174 |
175 | "color-name@npm:1.1.3":
176 | version: 1.1.3
177 | resolution: "color-name@npm:1.1.3"
178 | checksum: 09c5d3e33d2105850153b14466501f2bfb30324a2f76568a408763a3b7433b0e50e5b4ab1947868e65cb101bb7cb75029553f2c333b6d4b8138a73fcc133d69d
179 | languageName: node
180 | linkType: hard
181 |
182 | "concat-map@npm:0.0.1":
183 | version: 0.0.1
184 | resolution: "concat-map@npm:0.0.1"
185 | checksum: 902a9f5d8967a3e2faf138d5cb784b9979bad2e6db5357c5b21c568df4ebe62bcb15108af1b2253744844eb964fc023fbd9afbbbb6ddd0bcc204c6fb5b7bf3af
186 | languageName: node
187 | linkType: hard
188 |
189 | "cosmiconfig@npm:^8.1.3":
190 | version: 8.3.6
191 | resolution: "cosmiconfig@npm:8.3.6"
192 | dependencies:
193 | import-fresh: ^3.3.0
194 | js-yaml: ^4.1.0
195 | parse-json: ^5.2.0
196 | path-type: ^4.0.0
197 | peerDependencies:
198 | typescript: ">=4.9.5"
199 | peerDependenciesMeta:
200 | typescript:
201 | optional: true
202 | checksum: dc339ebea427898c9e03bf01b56ba7afbac07fc7d2a2d5a15d6e9c14de98275a9565da949375aee1809591c152c0a3877bb86dbeaf74d5bd5aaa79955ad9e7a0
203 | languageName: node
204 | linkType: hard
205 |
206 | "error-ex@npm:^1.3.1":
207 | version: 1.3.2
208 | resolution: "error-ex@npm:1.3.2"
209 | dependencies:
210 | is-arrayish: ^0.2.1
211 | checksum: c1c2b8b65f9c91b0f9d75f0debaa7ec5b35c266c2cac5de412c1a6de86d4cbae04ae44e510378cb14d032d0645a36925d0186f8bb7367bcc629db256b743a001
212 | languageName: node
213 | linkType: hard
214 |
215 | "escape-string-regexp@npm:^1.0.5":
216 | version: 1.0.5
217 | resolution: "escape-string-regexp@npm:1.0.5"
218 | checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410
219 | languageName: node
220 | linkType: hard
221 |
222 | "fs.realpath@npm:^1.0.0":
223 | version: 1.0.0
224 | resolution: "fs.realpath@npm:1.0.0"
225 | checksum: 99ddea01a7e75aa276c250a04eedeffe5662bce66c65c07164ad6264f9de18fb21be9433ead460e54cff20e31721c811f4fb5d70591799df5f85dce6d6746fd0
226 | languageName: node
227 | linkType: hard
228 |
229 | "function-bind@npm:^1.1.1":
230 | version: 1.1.1
231 | resolution: "function-bind@npm:1.1.1"
232 | checksum: b32fbaebb3f8ec4969f033073b43f5c8befbb58f1a79e12f1d7490358150359ebd92f49e72ff0144f65f2c48ea2a605bff2d07965f548f6474fd8efd95bf361a
233 | languageName: node
234 | linkType: hard
235 |
236 | "glob@npm:^7.0.0":
237 | version: 7.2.3
238 | resolution: "glob@npm:7.2.3"
239 | dependencies:
240 | fs.realpath: ^1.0.0
241 | inflight: ^1.0.4
242 | inherits: 2
243 | minimatch: ^3.1.1
244 | once: ^1.3.0
245 | path-is-absolute: ^1.0.0
246 | checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133
247 | languageName: node
248 | linkType: hard
249 |
250 | "has-flag@npm:^3.0.0":
251 | version: 3.0.0
252 | resolution: "has-flag@npm:3.0.0"
253 | checksum: 4a15638b454bf086c8148979aae044dd6e39d63904cd452d970374fa6a87623423da485dfb814e7be882e05c096a7ccf1ebd48e7e7501d0208d8384ff4dea73b
254 | languageName: node
255 | linkType: hard
256 |
257 | "has@npm:^1.0.3":
258 | version: 1.0.3
259 | resolution: "has@npm:1.0.3"
260 | dependencies:
261 | function-bind: ^1.1.1
262 | checksum: b9ad53d53be4af90ce5d1c38331e712522417d017d5ef1ebd0507e07c2fbad8686fffb8e12ddecd4c39ca9b9b47431afbb975b8abf7f3c3b82c98e9aad052792
263 | languageName: node
264 | linkType: hard
265 |
266 | "import-fresh@npm:^3.3.0":
267 | version: 3.3.0
268 | resolution: "import-fresh@npm:3.3.0"
269 | dependencies:
270 | parent-module: ^1.0.0
271 | resolve-from: ^4.0.0
272 | checksum: 2cacfad06e652b1edc50be650f7ec3be08c5e5a6f6d12d035c440a42a8cc028e60a5b99ca08a77ab4d6b1346da7d971915828f33cdab730d3d42f08242d09baa
273 | languageName: node
274 | linkType: hard
275 |
276 | "inflight@npm:^1.0.4":
277 | version: 1.0.6
278 | resolution: "inflight@npm:1.0.6"
279 | dependencies:
280 | once: ^1.3.0
281 | wrappy: 1
282 | checksum: f4f76aa072ce19fae87ce1ef7d221e709afb59d445e05d47fba710e85470923a75de35bfae47da6de1b18afc3ce83d70facf44cfb0aff89f0a3f45c0a0244dfd
283 | languageName: node
284 | linkType: hard
285 |
286 | "inherits@npm:2":
287 | version: 2.0.4
288 | resolution: "inherits@npm:2.0.4"
289 | checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
290 | languageName: node
291 | linkType: hard
292 |
293 | "interpret@npm:^1.0.0":
294 | version: 1.4.0
295 | resolution: "interpret@npm:1.4.0"
296 | checksum: 2e5f51268b5941e4a17e4ef0575bc91ed0ab5f8515e3cf77486f7c14d13f3010df9c0959f37063dcc96e78d12dc6b0bb1b9e111cdfe69771f4656d2993d36155
297 | languageName: node
298 | linkType: hard
299 |
300 | "is-arrayish@npm:^0.2.1":
301 | version: 0.2.1
302 | resolution: "is-arrayish@npm:0.2.1"
303 | checksum: eef4417e3c10e60e2c810b6084942b3ead455af16c4509959a27e490e7aee87cfb3f38e01bbde92220b528a0ee1a18d52b787e1458ee86174d8c7f0e58cd488f
304 | languageName: node
305 | linkType: hard
306 |
307 | "is-core-module@npm:^2.11.0":
308 | version: 2.12.0
309 | resolution: "is-core-module@npm:2.12.0"
310 | dependencies:
311 | has: ^1.0.3
312 | checksum: f7f7eb2ab71fd769ee9fb2385c095d503aa4b5ce0028c04557de03f1e67a87c85e5bac1f215945fc3c955867a139a415a3ec4c4234a0bffdf715232660f440a6
313 | languageName: node
314 | linkType: hard
315 |
316 | "js-tokens@npm:^4.0.0":
317 | version: 4.0.0
318 | resolution: "js-tokens@npm:4.0.0"
319 | checksum: 8a95213a5a77deb6cbe94d86340e8d9ace2b93bc367790b260101d2f36a2eaf4e4e22d9fa9cf459b38af3a32fb4190e638024cf82ec95ef708680e405ea7cc78
320 | languageName: node
321 | linkType: hard
322 |
323 | "js-yaml@npm:^4.1.0":
324 | version: 4.1.0
325 | resolution: "js-yaml@npm:4.1.0"
326 | dependencies:
327 | argparse: ^2.0.1
328 | bin:
329 | js-yaml: bin/js-yaml.js
330 | checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a
331 | languageName: node
332 | linkType: hard
333 |
334 | "json-parse-even-better-errors@npm:^2.3.0":
335 | version: 2.3.1
336 | resolution: "json-parse-even-better-errors@npm:2.3.1"
337 | checksum: 798ed4cf3354a2d9ccd78e86d2169515a0097a5c133337807cdf7f1fc32e1391d207ccfc276518cc1d7d8d4db93288b8a50ba4293d212ad1336e52a8ec0a941f
338 | languageName: node
339 | linkType: hard
340 |
341 | "json5@npm:^2.2.2":
342 | version: 2.2.3
343 | resolution: "json5@npm:2.2.3"
344 | bin:
345 | json5: lib/cli.js
346 | checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349
347 | languageName: node
348 | linkType: hard
349 |
350 | "lines-and-columns@npm:^1.1.6":
351 | version: 1.2.4
352 | resolution: "lines-and-columns@npm:1.2.4"
353 | checksum: 0c37f9f7fa212b38912b7145e1cd16a5f3cd34d782441c3e6ca653485d326f58b3caccda66efce1c5812bde4961bbde3374fae4b0d11bf1226152337f3894aa5
354 | languageName: node
355 | linkType: hard
356 |
357 | "minimatch@npm:^3.1.1":
358 | version: 3.1.2
359 | resolution: "minimatch@npm:3.1.2"
360 | dependencies:
361 | brace-expansion: ^1.1.7
362 | checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a
363 | languageName: node
364 | linkType: hard
365 |
366 | "minimist@npm:^1.2.6, minimist@npm:^1.2.8":
367 | version: 1.2.8
368 | resolution: "minimist@npm:1.2.8"
369 | checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0
370 | languageName: node
371 | linkType: hard
372 |
373 | "once@npm:^1.3.0":
374 | version: 1.4.0
375 | resolution: "once@npm:1.4.0"
376 | dependencies:
377 | wrappy: 1
378 | checksum: cd0a88501333edd640d95f0d2700fbde6bff20b3d4d9bdc521bdd31af0656b5706570d6c6afe532045a20bb8dc0849f8332d6f2a416e0ba6d3d3b98806c7db68
379 | languageName: node
380 | linkType: hard
381 |
382 | "parent-module@npm:^1.0.0":
383 | version: 1.0.1
384 | resolution: "parent-module@npm:1.0.1"
385 | dependencies:
386 | callsites: ^3.0.0
387 | checksum: 6ba8b255145cae9470cf5551eb74be2d22281587af787a2626683a6c20fbb464978784661478dd2a3f1dad74d1e802d403e1b03c1a31fab310259eec8ac560ff
388 | languageName: node
389 | linkType: hard
390 |
391 | "parse-json@npm:^5.2.0":
392 | version: 5.2.0
393 | resolution: "parse-json@npm:5.2.0"
394 | dependencies:
395 | "@babel/code-frame": ^7.0.0
396 | error-ex: ^1.3.1
397 | json-parse-even-better-errors: ^2.3.0
398 | lines-and-columns: ^1.1.6
399 | checksum: 62085b17d64da57f40f6afc2ac1f4d95def18c4323577e1eced571db75d9ab59b297d1d10582920f84b15985cbfc6b6d450ccbf317644cfa176f3ed982ad87e2
400 | languageName: node
401 | linkType: hard
402 |
403 | "path-is-absolute@npm:^1.0.0":
404 | version: 1.0.1
405 | resolution: "path-is-absolute@npm:1.0.1"
406 | checksum: 060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8
407 | languageName: node
408 | linkType: hard
409 |
410 | "path-parse@npm:^1.0.7":
411 | version: 1.0.7
412 | resolution: "path-parse@npm:1.0.7"
413 | checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a
414 | languageName: node
415 | linkType: hard
416 |
417 | "path-type@npm:^4.0.0":
418 | version: 4.0.0
419 | resolution: "path-type@npm:4.0.0"
420 | checksum: 5b1e2daa247062061325b8fdbfd1fb56dde0a448fb1455453276ea18c60685bdad23a445dc148cf87bc216be1573357509b7d4060494a6fd768c7efad833ee45
421 | languageName: node
422 | linkType: hard
423 |
424 | "prettier@npm:^2.8.7":
425 | version: 2.8.8
426 | resolution: "prettier@npm:2.8.8"
427 | bin:
428 | prettier: bin-prettier.js
429 | checksum: b49e409431bf129dd89238d64299ba80717b57ff5a6d1c1a8b1a28b590d998a34e083fa13573bc732bb8d2305becb4c9a4407f8486c81fa7d55100eb08263cf8
430 | languageName: node
431 | linkType: hard
432 |
433 | "rechoir@npm:^0.6.2":
434 | version: 0.6.2
435 | resolution: "rechoir@npm:0.6.2"
436 | dependencies:
437 | resolve: ^1.1.6
438 | checksum: fe76bf9c21875ac16e235defedd7cbd34f333c02a92546142b7911a0f7c7059d2e16f441fe6fb9ae203f459c05a31b2bcf26202896d89e390eda7514d5d2702b
439 | languageName: node
440 | linkType: hard
441 |
442 | "resolve-from@npm:^4.0.0":
443 | version: 4.0.0
444 | resolution: "resolve-from@npm:4.0.0"
445 | checksum: f4ba0b8494846a5066328ad33ef8ac173801a51739eb4d63408c847da9a2e1c1de1e6cbbf72699211f3d13f8fc1325648b169bd15eb7da35688e30a5fb0e4a7f
446 | languageName: node
447 | linkType: hard
448 |
449 | "resolve@npm:^1.1.6":
450 | version: 1.22.2
451 | resolution: "resolve@npm:1.22.2"
452 | dependencies:
453 | is-core-module: ^2.11.0
454 | path-parse: ^1.0.7
455 | supports-preserve-symlinks-flag: ^1.0.0
456 | bin:
457 | resolve: bin/resolve
458 | checksum: 7e5df75796ebd429445d102d5824482ee7e567f0070b2b45897b29bb4f613dcbc262e0257b8aeedb3089330ccaea0d6a0464df1a77b2992cf331dcda0f4cb549
459 | languageName: node
460 | linkType: hard
461 |
462 | "resolve@patch:resolve@^1.1.6#~builtin":
463 | version: 1.22.2
464 | resolution: "resolve@patch:resolve@npm%3A1.22.2#~builtin::version=1.22.2&hash=c3c19d"
465 | dependencies:
466 | is-core-module: ^2.11.0
467 | path-parse: ^1.0.7
468 | supports-preserve-symlinks-flag: ^1.0.0
469 | bin:
470 | resolve: bin/resolve
471 | checksum: 66cc788f13b8398de18eb4abb3aed90435c84bb8935953feafcf7231ba4cd191b2c10b4a87b1e9681afc34fb138c705f91f7330ff90bfa36f457e5584076a2b8
472 | languageName: node
473 | linkType: hard
474 |
475 | "shelljs@npm:0.8.5":
476 | version: 0.8.5
477 | resolution: "shelljs@npm:0.8.5"
478 | dependencies:
479 | glob: ^7.0.0
480 | interpret: ^1.0.0
481 | rechoir: ^0.6.2
482 | bin:
483 | shjs: bin/shjs
484 | checksum: 7babc46f732a98f4c054ec1f048b55b9149b98aa2da32f6cf9844c434b43c6251efebd6eec120937bd0999e13811ebd45efe17410edb3ca938f82f9381302748
485 | languageName: node
486 | linkType: hard
487 |
488 | "strip-bom@npm:^3.0.0":
489 | version: 3.0.0
490 | resolution: "strip-bom@npm:3.0.0"
491 | checksum: 8d50ff27b7ebe5ecc78f1fe1e00fcdff7af014e73cf724b46fb81ef889eeb1015fc5184b64e81a2efe002180f3ba431bdd77e300da5c6685d702780fbf0c8d5b
492 | languageName: node
493 | linkType: hard
494 |
495 | "supports-color@npm:^5.3.0":
496 | version: 5.5.0
497 | resolution: "supports-color@npm:5.5.0"
498 | dependencies:
499 | has-flag: ^3.0.0
500 | checksum: 95f6f4ba5afdf92f495b5a912d4abee8dcba766ae719b975c56c084f5004845f6f5a5f7769f52d53f40e21952a6d87411bafe34af4a01e65f9926002e38e1dac
501 | languageName: node
502 | linkType: hard
503 |
504 | "supports-preserve-symlinks-flag@npm:^1.0.0":
505 | version: 1.0.0
506 | resolution: "supports-preserve-symlinks-flag@npm:1.0.0"
507 | checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae
508 | languageName: node
509 | linkType: hard
510 |
511 | "ts2typebox@workspace:.":
512 | version: 0.0.0-use.local
513 | resolution: "ts2typebox@workspace:."
514 | dependencies:
515 | "@sinclair/typebox": 0.34.25
516 | "@sinclair/typebox-codegen": ^0.10.5
517 | "@types/minimist": 1.2.5
518 | "@types/node": 18.16.0
519 | "@types/prettier": 2.7.2
520 | "@types/shelljs": 0.8.15
521 | cosmiconfig: ^8.1.3
522 | minimist: ^1.2.8
523 | prettier: ^2.8.7
524 | shelljs: 0.8.5
525 | tsconfig-paths: 4.2.0
526 | typescript: ^5.7.3
527 | peerDependencies:
528 | "@sinclair/typebox": ^0.34.25
529 | bin:
530 | ts-to-typebox: dist/src/cli/index.js
531 | ts2typebox: dist/src/cli/index.js
532 | languageName: unknown
533 | linkType: soft
534 |
535 | "tsconfig-paths@npm:4.2.0":
536 | version: 4.2.0
537 | resolution: "tsconfig-paths@npm:4.2.0"
538 | dependencies:
539 | json5: ^2.2.2
540 | minimist: ^1.2.6
541 | strip-bom: ^3.0.0
542 | checksum: 28c5f7bbbcabc9dabd4117e8fdc61483f6872a1c6b02a4b1c4d68c5b79d06896c3cc9547610c4c3ba64658531caa2de13ead1ea1bf321c7b53e969c4752b98c7
543 | languageName: node
544 | linkType: hard
545 |
546 | "typescript@npm:^5.4.5, typescript@npm:^5.7.3":
547 | version: 5.7.3
548 | resolution: "typescript@npm:5.7.3"
549 | bin:
550 | tsc: bin/tsc
551 | tsserver: bin/tsserver
552 | checksum: 6c38b1e989918e576f0307e6ee013522ea480dfce5f3ca85c9b2d8adb1edeffd37f4f30cd68de0c38a44563d12ba922bdb7e36aa2dac9c51de5d561e6e9a2e9c
553 | languageName: node
554 | linkType: hard
555 |
556 | "typescript@patch:typescript@^5.4.5#~builtin, typescript@patch:typescript@^5.7.3#~builtin":
557 | version: 5.7.3
558 | resolution: "typescript@patch:typescript@npm%3A5.7.3#~builtin::version=5.7.3&hash=77c9e2"
559 | bin:
560 | tsc: bin/tsc
561 | tsserver: bin/tsserver
562 | checksum: 633cd749d6cd7bc842c6b6245847173bba99742a60776fae3c0fbcc0d1733cd51a733995e5f4dadd8afb0e64e57d3c7dbbeae953a072ee303940eca69e22f311
563 | languageName: node
564 | linkType: hard
565 |
566 | "wrappy@npm:1":
567 | version: 1.0.2
568 | resolution: "wrappy@npm:1.0.2"
569 | checksum: 159da4805f7e84a3d003d8841557196034155008f817172d4e986bd591f74aa82aa7db55929a54222309e01079a65a92a9e6414da5a6aa4b01ee44a511ac3ee5
570 | languageName: node
571 | linkType: hard
572 |
--------------------------------------------------------------------------------