@nxgt/graphql-codegen-zod 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +232 -2
- package/dist/collect-fields.d.ts +24 -0
- package/dist/collect-fields.d.ts.map +1 -0
- package/dist/config.d.ts +53 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/cycles.d.ts +16 -0
- package/dist/cycles.d.ts.map +1 -0
- package/dist/defaults.d.ts +21 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/imports.d.ts +14 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1114 -0
- package/dist/index.js.map +25 -0
- package/dist/naming.d.ts +24 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/objects-output.d.ts +16 -0
- package/dist/objects-output.d.ts.map +1 -0
- package/dist/output-types.d.ts +15 -0
- package/dist/output-types.d.ts.map +1 -0
- package/dist/results-output.d.ts +16 -0
- package/dist/results-output.d.ts.map +1 -0
- package/dist/results-selections.d.ts +21 -0
- package/dist/results-selections.d.ts.map +1 -0
- package/dist/scalars.d.ts +21 -0
- package/dist/scalars.d.ts.map +1 -0
- package/dist/schema-output.d.ts +10 -0
- package/dist/schema-output.d.ts.map +1 -0
- package/dist/source.d.ts +9 -0
- package/dist/source.d.ts.map +1 -0
- package/dist/type-code.d.ts +12 -0
- package/dist/type-code.d.ts.map +1 -0
- package/dist/variables-output.d.ts +13 -0
- package/dist/variables-output.d.ts.map +1 -0
- package/dist/writer.d.ts +36 -0
- package/dist/writer.d.ts.map +1 -0
- package/docs/README.md +14 -0
- package/docs/guide/output.md +732 -0
- package/docs/roadmap.md +38 -0
- package/docs/troubleshooting.md +267 -0
- package/package.json +62 -5
package/docs/roadmap.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Roadmap
|
|
2
|
+
|
|
3
|
+
What `@nxgt/graphql-codegen-zod` is heading for, phrased as what you get.
|
|
4
|
+
|
|
5
|
+
## Now
|
|
6
|
+
|
|
7
|
+
- **Output types.** Zod schemas and types for the SDL's object types,
|
|
8
|
+
interfaces and unions, and for each named operation's result and each
|
|
9
|
+
fragment, with `__typename` discriminating abstract types. Both parts are
|
|
10
|
+
written; they ship with the next release.
|
|
11
|
+
|
|
12
|
+
## Next
|
|
13
|
+
|
|
14
|
+
Candidates, not commitments.
|
|
15
|
+
|
|
16
|
+
- **Emit only some parts**, an option to write just the arguments, or just
|
|
17
|
+
the variables, of a file.
|
|
18
|
+
- **Your own formats**, once `@nxgt/graphql-validation` supports custom
|
|
19
|
+
`@constraint(format: "...")` values; the plugin will carry them.
|
|
20
|
+
|
|
21
|
+
## Later
|
|
22
|
+
|
|
23
|
+
Nothing yet.
|
|
24
|
+
|
|
25
|
+
## Not planned
|
|
26
|
+
|
|
27
|
+
- **An `Int` for an `ID` on the client.** An id is a string in what the
|
|
28
|
+
client sends, as in what the resolver receives.
|
|
29
|
+
|
|
30
|
+
- **Zod 3.** The schemas use Zod 4's getters, `prefault`, `z.strictObject` and
|
|
31
|
+
`z.email()`; they have no Zod 3 form.
|
|
32
|
+
|
|
33
|
+
## Shipped
|
|
34
|
+
|
|
35
|
+
- **The first release, 0.1.0.** Zod 4 schemas and types for enums, input
|
|
36
|
+
types, field arguments and operation variables, carrying every
|
|
37
|
+
`@constraint` of `@nxgt/graphql-validation`, so the client refuses what the
|
|
38
|
+
server refuses.
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
One entry per error you can hit, headed by the message you will search for.
|
|
4
|
+
Configuration, Scalars, Operations and The schema happen while
|
|
5
|
+
`graphql-codegen` runs; The generated file is what `tsc` and the generated
|
|
6
|
+
schemas report.
|
|
7
|
+
|
|
8
|
+
- [Configuration](#configuration)
|
|
9
|
+
- [Scalars](#scalars)
|
|
10
|
+
- [Operations](#operations)
|
|
11
|
+
- [The generated file](#the-generated-file)
|
|
12
|
+
- [The schema](#the-schema)
|
|
13
|
+
|
|
14
|
+
## Configuration
|
|
15
|
+
|
|
16
|
+
### `@nxgt/graphql-codegen-zod: namingConvention "my-module#myCase" is not one this plugin reads. Use 'keep', a function, or 'change-case-all#<case>' with one of camelCase, capitalCase, constantCase, dotCase, headerCase, noCase, paramCase, pascalCase, pathCase, sentenceCase, snakeCase, lowerCase, upperCase, lowerCaseFirst, upperCaseFirst.`
|
|
17
|
+
|
|
18
|
+
**When:** running codegen with a `namingConvention` string that names another module, or a case not in the list. The string in the message is what you wrote.
|
|
19
|
+
**Why:** the plugin reads the forms the typescript plugins take for type names, but only `change-case-all` and `change-case` cases; it does not load a module.
|
|
20
|
+
**Fix:** use one of the forms, or pass a function.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
config: { namingConvention: 'change-case-all#pascalCase' }
|
|
24
|
+
// or
|
|
25
|
+
config: { namingConvention: (name) => name.toUpperCase() }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Scalars
|
|
29
|
+
|
|
30
|
+
### `@nxgt/graphql-codegen-zod: the scalar Money is not in zodScalars, and no scalarSchemas is set. Map it: zodScalars: { Money: './module#export' }, or set scalarSchemas: '@nxgt/graphql-scalars'.`
|
|
31
|
+
|
|
32
|
+
**When:** running codegen on a schema with a custom scalar (here `Money`),
|
|
33
|
+
on an input or, since 0.2.0, on an object type's field or in an operation's
|
|
34
|
+
result only (`createdAt: Money`). 0.1.0 did not read output fields, so such a
|
|
35
|
+
scalar used to need no schema.
|
|
36
|
+
**Why:** a scalar written as `z.unknown()` would check nothing, in silence, so
|
|
37
|
+
the plugin refuses instead.
|
|
38
|
+
**Fix:** map the scalar, or point `scalarSchemas` at a module that has it. If
|
|
39
|
+
the scalar is only on output fields and in operations' results, and you do not
|
|
40
|
+
need those types, `objects: false` and `operations: false` together skip them:
|
|
41
|
+
either alone still reads it, wherever an operation selects the scalar.
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
config: { zodScalars: { Money: './money#moneySchema' } }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### `@nxgt/graphql-codegen-zod: the scalar Money is neither in zodScalars nor in @nxgt/graphql-scalars's scalarSchemas. Map it: zodScalars: { Money: './module#export' }, or set scalarSchemas: '@nxgt/graphql-scalars'.`
|
|
48
|
+
|
|
49
|
+
**When:** running codegen with `scalarSchemas` set, on a scalar the record has
|
|
50
|
+
no key for. The module path in the message is the one you configured.
|
|
51
|
+
**Why:** the plugin loaded the record and `Money` is not one of its keys.
|
|
52
|
+
**Fix:** map that one scalar next to the record; `zodScalars` wins over it.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
config: {
|
|
56
|
+
scalarSchemas: '@nxgt/graphql-scalars',
|
|
57
|
+
zodScalars: { Money: './money#moneySchema' },
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### `@nxgt/graphql-codegen-zod: zodScalars.Money is "moneySchema"; write it '<module>#<export>', e.g. './money#moneySchema'.`
|
|
62
|
+
|
|
63
|
+
**When:** running codegen with a `zodScalars` entry that is not `module#export`.
|
|
64
|
+
**Why:** the entry needs a module and an export name on either side of the
|
|
65
|
+
last `#`; the one in the message has none, or an empty side.
|
|
66
|
+
**Fix:**
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
config: { zodScalars: { Money: './money#moneySchema' } }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `@nxgt/graphql-codegen-zod: @nxgt/graphql-scalars exports no scalarSchemas record.`
|
|
73
|
+
|
|
74
|
+
**When:** running codegen with `scalarSchemas` set.
|
|
75
|
+
**Why:** the module loaded, but exports no `scalarSchemas` object. The module
|
|
76
|
+
path in the message is the one you configured. For `@nxgt/graphql-scalars`,
|
|
77
|
+
the record is exported from 0.4.0; an older version has none.
|
|
78
|
+
**Fix:** upgrade the package, or export the record yourself.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
// scalars.ts
|
|
82
|
+
import { z } from 'zod';
|
|
83
|
+
|
|
84
|
+
export const scalarSchemas = {
|
|
85
|
+
DateTime: z.iso.datetime({ offset: true }),
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Operations
|
|
90
|
+
|
|
91
|
+
### `@nxgt/graphql-codegen-zod: SignUp's $input has a type the schema does not define.`
|
|
92
|
+
|
|
93
|
+
**When:** running codegen on a document.
|
|
94
|
+
**Why:** the operation (`SignUp`) declares a variable (`$input`) of a type the
|
|
95
|
+
schema has no input type for, usually a typo, or a document written against
|
|
96
|
+
another schema.
|
|
97
|
+
**Fix:** declare the type in the schema, or correct the variable's type in the
|
|
98
|
+
document.
|
|
99
|
+
|
|
100
|
+
```graphql
|
|
101
|
+
mutation SignUp($input: SignUpInput!) { signUp(input: $input) }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### `@nxgt/graphql-codegen-zod: Bare.search selects the abstract type SearchResult without __typename for User. Select __typename there, so the result tells its members apart.`
|
|
105
|
+
|
|
106
|
+
**When:** running codegen on a named operation or a fragment. The operation
|
|
107
|
+
(or `fragment <Name>`), the path, the type and the member in the message are
|
|
108
|
+
yours.
|
|
109
|
+
**Why:** when the possible types of an interface or a union select different
|
|
110
|
+
fields, the selection becomes a union discriminated on `__typename`, and
|
|
111
|
+
without it the result cannot tell the members apart. When they all select the
|
|
112
|
+
same fields, no `__typename` is needed. A `__typename` under `@skip` or
|
|
113
|
+
`@include` may be absent, so it counts as missing.
|
|
114
|
+
**Fix:** select `__typename` in that selection, or set `operations: false`.
|
|
115
|
+
|
|
116
|
+
```graphql
|
|
117
|
+
# fails
|
|
118
|
+
query Bare { search(text: "a") { ... on User { id } } }
|
|
119
|
+
# generates
|
|
120
|
+
query Bare { search(text: "a") { __typename ... on User { id } } }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `@nxgt/graphql-codegen-zod: Keys.search selects __typename under a different key for each member of SearchResult (t, k). Select it under one key for every member, so the result tells its members apart.`
|
|
124
|
+
|
|
125
|
+
**When:** running codegen on an operation or a fragment. The path, the type
|
|
126
|
+
and the keys in the message are yours.
|
|
127
|
+
**Why:** the union is discriminated on one key, and the members select
|
|
128
|
+
`__typename` under different aliases. When several keys select it,
|
|
129
|
+
`__typename` itself is preferred.
|
|
130
|
+
**Fix:** select `__typename` under one key for every member.
|
|
131
|
+
|
|
132
|
+
```graphql
|
|
133
|
+
query Keys { search(text: "a") { ... on User { t: __typename id } ... on Post { k: __typename title } } }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `@nxgt/graphql-codegen-zod: Both($v:) is passed to Query.e(v:) (format: "email") and to Query.u(v:) (format: "uuid"), whose schemas cannot both apply. Use one variable for each.`
|
|
137
|
+
|
|
138
|
+
**When:** running codegen on an operation that passes one variable to two
|
|
139
|
+
places whose `@constraint(format:)` differ. The operation, variable and places
|
|
140
|
+
in the message are yours.
|
|
141
|
+
**Why:** each `format` replaces the schema, so the variable cannot be both.
|
|
142
|
+
**Fix:** use one variable for each.
|
|
143
|
+
|
|
144
|
+
```graphql
|
|
145
|
+
query Both($e: String, $u: String) { e(v: $e) u(v: $u) }
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## The generated file
|
|
149
|
+
|
|
150
|
+
### `Property 'Money' does not exist on type '{ DateTime: ... }'` (or `TS2339`)
|
|
151
|
+
|
|
152
|
+
**When:** type-checking the generated file, with `scalarSchemas` set.
|
|
153
|
+
**Why:** the plugin loads the record's module to check its keys, but cannot
|
|
154
|
+
when it is a `.ts` file under Node. It then trusts the record, and the file
|
|
155
|
+
reads `scalarSchemas.Money` which the record lacks.
|
|
156
|
+
**Fix:** add the key to the record, or map the scalar with `zodScalars`, or run
|
|
157
|
+
codegen under Bun so the module loads and the plugin refuses with the message
|
|
158
|
+
above.
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
config: { zodScalars: { Money: './money#moneySchema' } }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### `TS2300: Duplicate identifier 'SignUpInput'`
|
|
165
|
+
|
|
166
|
+
**When:** type-checking, with the plugin and `@graphql-codegen/typescript`
|
|
167
|
+
writing to the same file.
|
|
168
|
+
**Why:** both write a type of the same name.
|
|
169
|
+
**Fix:** generate into a file of its own.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
generates: {
|
|
173
|
+
'src/generated/zod.ts': { plugins: ['@nxgt/graphql-codegen-zod'] },
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### A client request is refused for `{ id: 5 }`: `Invalid input: expected string, received number`
|
|
178
|
+
|
|
179
|
+
**When:** `safeParse` of a variables schema with a number where the schema has
|
|
180
|
+
an `ID`.
|
|
181
|
+
**Why:** `graphql` accepts an `Int` for an `ID`; the generated schema is
|
|
182
|
+
`z.string()`: an id is a string in what the client sends, as in what the
|
|
183
|
+
resolver receives.
|
|
184
|
+
**Fix:** send the id as a string.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
zUserQueryVariables.safeParse({ id: String(id) });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### A client request is refused: `Unrecognized key: "nickname"`
|
|
191
|
+
|
|
192
|
+
**When:** `safeParse` of a variables schema whose input object carries a field
|
|
193
|
+
the input type does not declare.
|
|
194
|
+
**Why:** input types are `z.strictObject`, as `graphql` refuses an unknown
|
|
195
|
+
field. The variables object itself ignores an extra variable, as `graphql` does.
|
|
196
|
+
**Fix:** remove the field, or add it to the input type in the schema.
|
|
197
|
+
|
|
198
|
+
## The schema
|
|
199
|
+
|
|
200
|
+
### `@nxgt/graphql-codegen-zod: the file would declare FilterInput twice: two GraphQL names, or a type in a cycle and its Input or Wire type, give the same name. Rename one of the GraphQL types or operations, set typesSuffix, or set objects: false or operations: false.`
|
|
201
|
+
|
|
202
|
+
**When:** running codegen on a schema where two declarations of the same kind
|
|
203
|
+
get one name:
|
|
204
|
+
- an input type in a cycle (`Filter`) declares `FilterInput`, or an object
|
|
205
|
+
type in a cycle (`User`) declares `UserWire`, and the schema also has a
|
|
206
|
+
type of that name;
|
|
207
|
+
- an object type is named like a type the plugin already writes, such as
|
|
208
|
+
`QueryFindArgs` beside a field `Query.find(...)`. With 0.1.0 this generated,
|
|
209
|
+
because object types were not written.
|
|
210
|
+
|
|
211
|
+
**Why:** the file cannot declare one name twice.
|
|
212
|
+
**Fix:** rename one of the GraphQL types, or set `typesSuffix`: `Filter`
|
|
213
|
+
then declares `FilterTInput`, apart from `FilterInputT`. A `typesPrefix`
|
|
214
|
+
does not part them. When the clash comes from an object type and you do not
|
|
215
|
+
need the output types, `objects: false` writes none of them. When it comes
|
|
216
|
+
from an operation's or a fragment's result (`SearchQuery`), `operations:
|
|
217
|
+
false` writes none of them.
|
|
218
|
+
|
|
219
|
+
```graphql
|
|
220
|
+
input Filter { and: [Filter] }
|
|
221
|
+
input FilterFields { a: Int } # was FilterInput
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `@nxgt/graphql-codegen-zod: the default of Query.a(n:) holds 9007199254740993, which a JavaScript number cannot keep exact. Write it as a string, if its scalar takes one.`
|
|
225
|
+
|
|
226
|
+
**When:** running codegen on an argument, input field or variable whose
|
|
227
|
+
default is an integer past `Number.MAX_SAFE_INTEGER`, given to an `ID` or a
|
|
228
|
+
custom scalar (`Long`, `BigInt`). An `Int` or a `Float` rounds on the server
|
|
229
|
+
too, and is written as it is.
|
|
230
|
+
**Why:** the generated `.prefault(...)` would hold a rounded number, while the
|
|
231
|
+
server hands the scalar every digit.
|
|
232
|
+
**Fix:** write the default as a string, when the scalar parses one.
|
|
233
|
+
|
|
234
|
+
```graphql
|
|
235
|
+
type Query { a(n: Long = "9007199254740993"): Int }
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### `@nxgt/graphql-codegen-zod: the schema declares @constraint, but Query has no SDL to read it from (an introspected schema?). Point codegen's schema at the SDL files.`
|
|
239
|
+
|
|
240
|
+
**When:** running codegen on a schema that declares `@constraint` but was
|
|
241
|
+
introspected or loaded from a URL. The type in the message is the first found.
|
|
242
|
+
**Why:** an introspected schema carries no directives on its arguments, so
|
|
243
|
+
every constraint would be dropped in silence.
|
|
244
|
+
**Fix:** point codegen's `schema` at the SDL files. A schema without
|
|
245
|
+
`@constraint` can still be introspected; its defaults are read back.
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
schema: 'src/schema/**/*.graphql',
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Errors of `@constraint`
|
|
252
|
+
|
|
253
|
+
The plugin refuses a schema `withValidation` would refuse, with the same
|
|
254
|
+
message, for example `@constraint(minLength) on Query.a(n:) needs a String or
|
|
255
|
+
an ID, not Int.`. Each is explained, with its fix, in
|
|
256
|
+
[`@nxgt/graphql-validation`'s troubleshooting](https://github.com/softistx/nxgt-graphql/blob/develop/packages/graphql-validation/docs/troubleshooting.md).
|
|
257
|
+
|
|
258
|
+
### No error, and nothing is constrained
|
|
259
|
+
|
|
260
|
+
**When:** the generated schemas have no `.min()`, `.email()` and the like.
|
|
261
|
+
**Why:** the schema codegen reads does not declare `@constraint`, so the
|
|
262
|
+
plugin reads none; plain types are still generated, without a warning.
|
|
263
|
+
**Fix:** add the directive to the schema codegen loads.
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
import { constraintTypeDefs } from '@nxgt/graphql-validation';
|
|
267
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,63 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
"name": "@nxgt/graphql-codegen-zod",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A graphql-codegen plugin that writes Zod schemas from your SDL — inputs, enums, field arguments, operation variables, operation results and output types — with the @constraint rules of @nxgt/graphql-validation",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"docs",
|
|
12
|
+
"README.md",
|
|
13
|
+
"package.json",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"graphql",
|
|
26
|
+
"codegen",
|
|
27
|
+
"graphql-codegen",
|
|
28
|
+
"zod",
|
|
29
|
+
"validation",
|
|
30
|
+
"constraint",
|
|
31
|
+
"typescript"
|
|
32
|
+
],
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git+https://github.com/softistx/nxgt-graphql.git",
|
|
36
|
+
"directory": "packages/graphql-codegen-zod"
|
|
37
|
+
},
|
|
38
|
+
"publishConfig": {
|
|
39
|
+
"registry": "https://registry.npmjs.org",
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "bun run ../../build.ts",
|
|
44
|
+
"test": "bun test src",
|
|
45
|
+
"typecheck": "tsc --noEmit",
|
|
46
|
+
"generated:write": "bun run test/write-generated.ts"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@nxgt/graphql-validation": "^0.2.0",
|
|
50
|
+
"change-case": "^5.4.4"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@nxgt/graphql-scalars": "^0.4.0",
|
|
54
|
+
"@types/bun": "^1.4.0",
|
|
55
|
+
"graphql": "16.11.0",
|
|
56
|
+
"zod": "4.6.5"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"graphql": "^16.11.0 || ^17.0.0",
|
|
60
|
+
"typescript": "^6.0.3",
|
|
61
|
+
"zod": ">=4.6.5 <5"
|
|
62
|
+
}
|
|
63
|
+
}
|