@nxgt/graphql-codegen-zod 0.1.0 → 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/README.md +98 -10
- package/dist/collect-fields.d.ts +24 -0
- package/dist/collect-fields.d.ts.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/cycles.d.ts +7 -0
- package/dist/cycles.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +530 -133
- package/dist/index.js.map +12 -7
- package/dist/naming.d.ts +4 -0
- package/dist/naming.d.ts.map +1 -1
- 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/docs/README.md +1 -1
- package/docs/guide/output.md +279 -7
- package/docs/roadmap.md +8 -5
- package/docs/troubleshooting.md +53 -6
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import { checkConstraints } from "@nxgt/graphql-validation/codegen";
|
|
3
3
|
import {
|
|
4
4
|
isInputObjectType as isInputObjectType7,
|
|
5
|
-
isInterfaceType as
|
|
6
|
-
isObjectType as
|
|
5
|
+
isInterfaceType as isInterfaceType4,
|
|
6
|
+
isObjectType as isObjectType6
|
|
7
7
|
} from "graphql";
|
|
8
8
|
|
|
9
9
|
// src/imports.ts
|
|
@@ -51,10 +51,18 @@ class Naming {
|
|
|
51
51
|
return this.#wrap(this.#convert(`${parent}${underscore}${this.#convert(field)}Args`));
|
|
52
52
|
}
|
|
53
53
|
variables(operation, kind) {
|
|
54
|
+
return this.#wrap(this.#convert(`${operation}${this.#suffix(operation, kind)}Variables`));
|
|
55
|
+
}
|
|
56
|
+
result(operation, kind) {
|
|
57
|
+
return this.#wrap(this.#convert(`${operation}${this.#suffix(operation, kind)}`));
|
|
58
|
+
}
|
|
59
|
+
fragment(name) {
|
|
60
|
+
return this.#wrap(this.#convert(`${name}${this.#suffix(name, "fragment")}`));
|
|
61
|
+
}
|
|
62
|
+
#suffix(operation, kind) {
|
|
54
63
|
const type = changeCase.pascalCase(kind);
|
|
55
64
|
const { omitOperationSuffix, dedupeOperationSuffix } = this.#config;
|
|
56
|
-
|
|
57
|
-
return this.#wrap(this.#convert(`${operation}${suffix}Variables`));
|
|
65
|
+
return omitOperationSuffix || dedupeOperationSuffix && operation.toLowerCase().endsWith(type.toLowerCase()) ? "" : type;
|
|
58
66
|
}
|
|
59
67
|
schema(type) {
|
|
60
68
|
return `${this.#config.schemaPrefix ?? "z"}${type}`;
|
|
@@ -124,6 +132,456 @@ function caseNamed(spec) {
|
|
|
124
132
|
throw new Error(`@nxgt/graphql-codegen-zod: namingConvention "${spec}" is not one this plugin reads. Use 'keep', a function, or 'change-case-all#<case>' with one of ${Object.keys(cases["change-case-all"] ?? {}).join(", ")}.`);
|
|
125
133
|
}
|
|
126
134
|
|
|
135
|
+
// src/objects-output.ts
|
|
136
|
+
import {
|
|
137
|
+
GraphQLBoolean as GraphQLBoolean2,
|
|
138
|
+
GraphQLFloat as GraphQLFloat2,
|
|
139
|
+
GraphQLID as GraphQLID2,
|
|
140
|
+
GraphQLInt as GraphQLInt2,
|
|
141
|
+
GraphQLString as GraphQLString2,
|
|
142
|
+
getNamedType as getNamedType2,
|
|
143
|
+
isAbstractType as isAbstractType3,
|
|
144
|
+
isEnumType as isEnumType2,
|
|
145
|
+
isInterfaceType as isInterfaceType2,
|
|
146
|
+
isListType as isListType2,
|
|
147
|
+
isNonNullType as isNonNullType2,
|
|
148
|
+
isObjectType as isObjectType3,
|
|
149
|
+
isScalarType,
|
|
150
|
+
isUnionType
|
|
151
|
+
} from "graphql";
|
|
152
|
+
|
|
153
|
+
// src/cycles.ts
|
|
154
|
+
import {
|
|
155
|
+
getNamedType,
|
|
156
|
+
isAbstractType,
|
|
157
|
+
isInputObjectType,
|
|
158
|
+
isInterfaceType,
|
|
159
|
+
isObjectType
|
|
160
|
+
} from "graphql";
|
|
161
|
+
function inputCycles(schema) {
|
|
162
|
+
return cycles(Object.values(schema.getTypeMap()).filter(isInputObjectType), (type) => isInputObjectType(type) ? Object.values(type.getFields()).map((field) => getNamedType(field.type)).filter(isInputObjectType) : []);
|
|
163
|
+
}
|
|
164
|
+
function outputCycles(schema) {
|
|
165
|
+
return cycles(Object.values(schema.getTypeMap()).filter((type) => isObjectType(type) && !type.name.startsWith("__")), (type) => {
|
|
166
|
+
if (isAbstractType(type))
|
|
167
|
+
return schema.getPossibleTypes(type);
|
|
168
|
+
if (!isObjectType(type) && !isInterfaceType(type))
|
|
169
|
+
return [];
|
|
170
|
+
return Object.values(type.getFields()).map((field) => getNamedType(field.type)).filter((named) => isObjectType(named) || isAbstractType(named));
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function cycles(starts, next) {
|
|
174
|
+
const reaches = (from, target, seen) => next(from).some((named) => {
|
|
175
|
+
if (named.name === target)
|
|
176
|
+
return true;
|
|
177
|
+
if (seen.has(named.name))
|
|
178
|
+
return false;
|
|
179
|
+
seen.add(named.name);
|
|
180
|
+
return reaches(named, target, seen);
|
|
181
|
+
});
|
|
182
|
+
return new Set(starts.filter((start) => reaches(start, start.name, new Set)).map((start) => start.name));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// src/output-types.ts
|
|
186
|
+
import {
|
|
187
|
+
GraphQLBoolean,
|
|
188
|
+
GraphQLFloat,
|
|
189
|
+
GraphQLID,
|
|
190
|
+
GraphQLInt,
|
|
191
|
+
GraphQLString,
|
|
192
|
+
isAbstractType as isAbstractType2,
|
|
193
|
+
isEnumType,
|
|
194
|
+
isListType,
|
|
195
|
+
isNonNullType,
|
|
196
|
+
isObjectType as isObjectType2
|
|
197
|
+
} from "graphql";
|
|
198
|
+
|
|
199
|
+
// src/source.ts
|
|
200
|
+
function docComment(description, indent = "") {
|
|
201
|
+
if (!description)
|
|
202
|
+
return "";
|
|
203
|
+
const lines = description.replaceAll(`\r
|
|
204
|
+
`, `
|
|
205
|
+
`).replaceAll("*/", "*\\/").split(`
|
|
206
|
+
`);
|
|
207
|
+
if (lines.length === 1)
|
|
208
|
+
return `${indent}/** ${lines[0]} */
|
|
209
|
+
`;
|
|
210
|
+
return `${indent}/**
|
|
211
|
+
${lines.map((line) => `${indent} * ${line}`.trimEnd()).join(`
|
|
212
|
+
`)}
|
|
213
|
+
${indent} */
|
|
214
|
+
`;
|
|
215
|
+
}
|
|
216
|
+
function objectMembers(members) {
|
|
217
|
+
return members.map(([name, { code, lazy, description }]) => {
|
|
218
|
+
const doc = docComment(description, "\t");
|
|
219
|
+
return lazy ? `${doc} get ${name}() {
|
|
220
|
+
return ${code};
|
|
221
|
+
},` : `${doc} ${name}: ${code},`;
|
|
222
|
+
}).join(`
|
|
223
|
+
`);
|
|
224
|
+
}
|
|
225
|
+
function declare(typeName, naming, code, side, description) {
|
|
226
|
+
const schemaName = naming.schema(typeName);
|
|
227
|
+
const doc = docComment(description);
|
|
228
|
+
return `${doc}export const ${schemaName} = ${code};
|
|
229
|
+
${doc}export type ${typeName} = z.${side}<typeof ${schemaName}>;`;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// src/output-types.ts
|
|
233
|
+
var builtIns = {
|
|
234
|
+
[GraphQLString.name]: "string",
|
|
235
|
+
[GraphQLID.name]: "string",
|
|
236
|
+
[GraphQLInt.name]: "number",
|
|
237
|
+
[GraphQLFloat.name]: "number",
|
|
238
|
+
[GraphQLBoolean.name]: "boolean"
|
|
239
|
+
};
|
|
240
|
+
function declareCyclicObject(type, code, context) {
|
|
241
|
+
const types = new OutputTypeCode(context);
|
|
242
|
+
const output = context.naming.type(type.name);
|
|
243
|
+
const input = `${output}Wire`;
|
|
244
|
+
const doc = docComment(type.description);
|
|
245
|
+
return [
|
|
246
|
+
`${doc}export type ${output} = ${types.object(type, "output")};`,
|
|
247
|
+
`${doc}export type ${input} = ${types.object(type, "input")};`,
|
|
248
|
+
`${doc}export const ${context.naming.schema(output)}: z.ZodType<${output}, ${input}> = ${code};`
|
|
249
|
+
].join(`
|
|
250
|
+
`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
class OutputTypeCode {
|
|
254
|
+
#context;
|
|
255
|
+
constructor(context) {
|
|
256
|
+
this.#context = context;
|
|
257
|
+
}
|
|
258
|
+
object(type, side) {
|
|
259
|
+
const members = [
|
|
260
|
+
` __typename?: ${JSON.stringify(type.name)} | undefined;`,
|
|
261
|
+
...Object.values(type.getFields()).map((field) => `${docComment(field.description, "\t")} ${this.#member(field, side)};`)
|
|
262
|
+
];
|
|
263
|
+
return `{
|
|
264
|
+
${members.join(`
|
|
265
|
+
`)}
|
|
266
|
+
}`;
|
|
267
|
+
}
|
|
268
|
+
#member(field, side) {
|
|
269
|
+
const type = this.#required(field.type, side);
|
|
270
|
+
return isNonNullType(field.type) ? `${field.name}: ${type}` : `${field.name}?: ${type} | null | undefined`;
|
|
271
|
+
}
|
|
272
|
+
#required(type, side) {
|
|
273
|
+
if (isNonNullType(type))
|
|
274
|
+
return this.#required(type.ofType, side);
|
|
275
|
+
if (!isListType(type))
|
|
276
|
+
return this.#named(type, side);
|
|
277
|
+
const item = this.#required(type.ofType, side);
|
|
278
|
+
return isNonNullType(type.ofType) ? `Array<${item}>` : `Array<${item} | null | undefined>`;
|
|
279
|
+
}
|
|
280
|
+
#named(type, side) {
|
|
281
|
+
const { writer, naming, cyclic } = this.#context;
|
|
282
|
+
const builtIn = builtIns[type.name];
|
|
283
|
+
if (builtIn)
|
|
284
|
+
return builtIn;
|
|
285
|
+
if (isEnumType(type))
|
|
286
|
+
return `z.output<typeof ${writer.schemaName(type)}>`;
|
|
287
|
+
if (isAbstractType2(type))
|
|
288
|
+
return `z.${side}<typeof ${naming.schema(naming.type(type.name))}>`;
|
|
289
|
+
if (isObjectType2(type)) {
|
|
290
|
+
const name = naming.type(type.name);
|
|
291
|
+
if (cyclic.has(type.name))
|
|
292
|
+
return side === "output" ? name : `${name}Wire`;
|
|
293
|
+
return `z.${side}<typeof ${naming.schema(name)}>`;
|
|
294
|
+
}
|
|
295
|
+
return `z.${side}<typeof ${writer.scalarCode(type)}>`;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// src/objects-output.ts
|
|
300
|
+
var builtIns2 = {
|
|
301
|
+
[GraphQLString2.name]: "z.string()",
|
|
302
|
+
[GraphQLID2.name]: "z.string()",
|
|
303
|
+
[GraphQLInt2.name]: "z.int32()",
|
|
304
|
+
[GraphQLFloat2.name]: "z.number()",
|
|
305
|
+
[GraphQLBoolean2.name]: "z.boolean()"
|
|
306
|
+
};
|
|
307
|
+
function objectBlocks(schema, writer, naming) {
|
|
308
|
+
const types = Object.values(schema.getTypeMap()).filter((type) => !type.name.startsWith("__"));
|
|
309
|
+
const context = { writer, naming, cyclic: outputCycles(schema) };
|
|
310
|
+
return [
|
|
311
|
+
...types.filter(isObjectType3).map((type) => objectBlock(type, context)),
|
|
312
|
+
...types.filter(isAbstractType3).map((type) => abstractBlock(schema, type, naming))
|
|
313
|
+
];
|
|
314
|
+
}
|
|
315
|
+
function objectBlock(type, context) {
|
|
316
|
+
const { writer, naming } = context;
|
|
317
|
+
const typename = {
|
|
318
|
+
code: `z.literal(${JSON.stringify(type.name)}).optional()`,
|
|
319
|
+
lazy: false
|
|
320
|
+
};
|
|
321
|
+
const members = Object.values(type.getFields()).map((field) => [
|
|
322
|
+
field.name,
|
|
323
|
+
{
|
|
324
|
+
...outputCode(field.type, writer, naming),
|
|
325
|
+
description: field.description
|
|
326
|
+
}
|
|
327
|
+
]);
|
|
328
|
+
const code = `z.object({
|
|
329
|
+
${objectMembers([["__typename", typename], ...members])}
|
|
330
|
+
})`;
|
|
331
|
+
return context.cyclic.has(type.name) ? declareCyclicObject(type, code, context) : declare(naming.type(type.name), naming, code, "output", type.description);
|
|
332
|
+
}
|
|
333
|
+
function abstractBlock(schema, type, naming) {
|
|
334
|
+
const members = (isUnionType(type) ? type.getTypes() : schema.getPossibleTypes(type)).map((member) => naming.schema(naming.type(member.name)));
|
|
335
|
+
const code = members.length === 0 ? "z.never()" : members.length === 1 ? members[0] ?? "z.never()" : `z.union([${members.join(", ")}])`;
|
|
336
|
+
return declare(naming.type(type.name), naming, code, "output", type.description);
|
|
337
|
+
}
|
|
338
|
+
function outputCode(type, writer, naming) {
|
|
339
|
+
const named = getNamedType2(type);
|
|
340
|
+
const lazy = !isScalarType(named) && !isEnumType2(named);
|
|
341
|
+
return { code: nullable(type, writer, naming), lazy };
|
|
342
|
+
}
|
|
343
|
+
function nullable(type, writer, naming) {
|
|
344
|
+
if (isNonNullType2(type))
|
|
345
|
+
return required(type.ofType, writer, naming);
|
|
346
|
+
return `${required(type, writer, naming)}.nullish()`;
|
|
347
|
+
}
|
|
348
|
+
function required(type, writer, naming) {
|
|
349
|
+
if (isNonNullType2(type))
|
|
350
|
+
return required(type.ofType, writer, naming);
|
|
351
|
+
if (isListType2(type))
|
|
352
|
+
return `z.array(${nullable(type.ofType, writer, naming)})`;
|
|
353
|
+
if (isScalarType(type))
|
|
354
|
+
return builtIns2[type.name] ?? writer.scalarCode(type);
|
|
355
|
+
if (isEnumType2(type))
|
|
356
|
+
return writer.schemaName(type);
|
|
357
|
+
if (isObjectType3(type) || isInterfaceType2(type) || isUnionType(type))
|
|
358
|
+
return naming.schema(naming.type(type.name));
|
|
359
|
+
return "z.never()";
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// src/results-output.ts
|
|
363
|
+
import {
|
|
364
|
+
isCompositeType,
|
|
365
|
+
Kind as Kind2
|
|
366
|
+
} from "graphql";
|
|
367
|
+
|
|
368
|
+
// src/results-selections.ts
|
|
369
|
+
import {
|
|
370
|
+
isEnumType as isEnumType3,
|
|
371
|
+
isListType as isListType3,
|
|
372
|
+
isNonNullType as isNonNullType3,
|
|
373
|
+
isObjectType as isObjectType4,
|
|
374
|
+
isScalarType as isScalarType2
|
|
375
|
+
} from "graphql";
|
|
376
|
+
|
|
377
|
+
// src/collect-fields.ts
|
|
378
|
+
import {
|
|
379
|
+
isAbstractType as isAbstractType4,
|
|
380
|
+
Kind
|
|
381
|
+
} from "graphql";
|
|
382
|
+
var conditions = new Set(["skip", "include", "defer"]);
|
|
383
|
+
function collectFields(schema, fragments, type, sets) {
|
|
384
|
+
const fields = new Map;
|
|
385
|
+
const applies = (condition) => {
|
|
386
|
+
const named = schema.getType(condition);
|
|
387
|
+
if (!named)
|
|
388
|
+
return false;
|
|
389
|
+
if (named.name === type.name)
|
|
390
|
+
return true;
|
|
391
|
+
return isAbstractType4(named) && schema.isSubType(named, type);
|
|
392
|
+
};
|
|
393
|
+
const visit = (set, optional, seen) => {
|
|
394
|
+
for (const selection of set.selections) {
|
|
395
|
+
const conditional = optional || isConditional(selection);
|
|
396
|
+
if (selection.kind === Kind.FIELD) {
|
|
397
|
+
const key = selection.alias?.value ?? selection.name.value;
|
|
398
|
+
const entry = { node: selection, conditional };
|
|
399
|
+
const field = fields.get(key);
|
|
400
|
+
if (field) {
|
|
401
|
+
field.nodes.push(entry);
|
|
402
|
+
field.optional &&= conditional;
|
|
403
|
+
} else
|
|
404
|
+
fields.set(key, {
|
|
405
|
+
name: selection.name.value,
|
|
406
|
+
nodes: [entry],
|
|
407
|
+
optional: conditional
|
|
408
|
+
});
|
|
409
|
+
} else if (selection.kind === Kind.INLINE_FRAGMENT) {
|
|
410
|
+
const condition = selection.typeCondition?.name.value;
|
|
411
|
+
if (!condition || applies(condition))
|
|
412
|
+
visit(selection.selectionSet, conditional, seen);
|
|
413
|
+
} else {
|
|
414
|
+
const name = selection.name.value;
|
|
415
|
+
const fragment = fragments.get(name);
|
|
416
|
+
if (fragment && !seen.has(name) && applies(fragment.typeCondition.name.value))
|
|
417
|
+
visit(fragment.selectionSet, conditional, new Set([...seen, name]));
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
for (const { set, conditional } of sets)
|
|
422
|
+
visit(set, conditional, new Set);
|
|
423
|
+
return fields;
|
|
424
|
+
}
|
|
425
|
+
function isConditional(selection) {
|
|
426
|
+
return (selection.directives ?? []).some((directive) => conditions.has(directive.name.value));
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// src/results-selections.ts
|
|
430
|
+
var failure = "@nxgt/graphql-codegen-zod:";
|
|
431
|
+
var typename = "\x00typename\x00";
|
|
432
|
+
var hoistDepth = 5;
|
|
433
|
+
|
|
434
|
+
class Selections {
|
|
435
|
+
#schema;
|
|
436
|
+
#fragments;
|
|
437
|
+
#writer;
|
|
438
|
+
#hoisted = new Map;
|
|
439
|
+
#prefix = "";
|
|
440
|
+
constructor(schema, fragments, writer) {
|
|
441
|
+
this.#schema = schema;
|
|
442
|
+
this.#fragments = fragments;
|
|
443
|
+
this.#writer = writer;
|
|
444
|
+
}
|
|
445
|
+
declare(name, type, sets, path) {
|
|
446
|
+
this.#hoisted = new Map;
|
|
447
|
+
this.#prefix = name;
|
|
448
|
+
const code = this.#code(type, sets, [path], "", 0);
|
|
449
|
+
return {
|
|
450
|
+
hoisted: [...this.#hoisted].map(([body, hoisted]) => `const ${hoisted}$ = ${body};
|
|
451
|
+
const ${hoisted}: z.ZodType<z.output<typeof ${hoisted}$>, z.input<typeof ${hoisted}$>> = ${hoisted}$;`),
|
|
452
|
+
code
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
#code(type, sets, path, indent, depth) {
|
|
456
|
+
if (depth >= hoistDepth) {
|
|
457
|
+
const body = this.#code(type, sets, path, "", 0);
|
|
458
|
+
const known = this.#hoisted.get(body);
|
|
459
|
+
if (known)
|
|
460
|
+
return known;
|
|
461
|
+
const name = `${this.#prefix}$${this.#hoisted.size + 1}`;
|
|
462
|
+
this.#hoisted.set(body, name);
|
|
463
|
+
return name;
|
|
464
|
+
}
|
|
465
|
+
if (isObjectType4(type))
|
|
466
|
+
return this.#object(type, sets, path, indent, depth).replaceAll(typename, `z.literal(${JSON.stringify(type.name)})`);
|
|
467
|
+
return this.#abstract(type, sets, path, indent, depth);
|
|
468
|
+
}
|
|
469
|
+
#abstract(type, sets, path, indent, depth) {
|
|
470
|
+
const members = this.#schema.getPossibleTypes(type);
|
|
471
|
+
if (members.length === 0)
|
|
472
|
+
return "z.never()";
|
|
473
|
+
const inner = `${indent} `;
|
|
474
|
+
const groups = new Map;
|
|
475
|
+
const keys = new Map;
|
|
476
|
+
for (const member of members) {
|
|
477
|
+
const code = this.#object(member, sets, path, inner, depth);
|
|
478
|
+
groups.set(code, [...groups.get(code) ?? [], member]);
|
|
479
|
+
keys.set(member.name, [...collectFields(this.#schema, this.#fragments, member, sets)].filter(([, field]) => field.name === "__typename" && !field.optional).map(([key]) => key));
|
|
480
|
+
}
|
|
481
|
+
const fill = (code, group) => {
|
|
482
|
+
const names = group.map((member) => JSON.stringify(member.name));
|
|
483
|
+
return code.replaceAll(typename, names.length === 1 ? `z.literal(${names[0]})` : `z.enum([${names.join(", ")}])`);
|
|
484
|
+
};
|
|
485
|
+
const all = [...groups];
|
|
486
|
+
if (all.length === 1) {
|
|
487
|
+
const [code = "", group = []] = all[0] ?? [];
|
|
488
|
+
return fill(code.replaceAll(`
|
|
489
|
+
${inner}`, `
|
|
490
|
+
${indent}`), group);
|
|
491
|
+
}
|
|
492
|
+
const discriminator = this.#discriminator(type.name, keys, path);
|
|
493
|
+
return `z.discriminatedUnion(${JSON.stringify(discriminator)}, [
|
|
494
|
+
${all.map(([code, group]) => `${inner}${fill(code, group)},`).join(`
|
|
495
|
+
`)}
|
|
496
|
+
${indent}])`;
|
|
497
|
+
}
|
|
498
|
+
#discriminator(type, keys, path) {
|
|
499
|
+
for (const [member, selected] of keys)
|
|
500
|
+
if (selected.length === 0)
|
|
501
|
+
throw new Error(`${failure} ${path.join(".")} selects the abstract type ${type} without __typename for ${member}. Select __typename there, so the result tells its members apart.`);
|
|
502
|
+
const lists = [...keys.values()];
|
|
503
|
+
const shared = (lists[0] ?? []).filter((key) => lists.every((selected) => selected.includes(key)));
|
|
504
|
+
const key = shared.includes("__typename") ? "__typename" : shared[0];
|
|
505
|
+
if (key === undefined)
|
|
506
|
+
throw new Error(`${failure} ${path.join(".")} selects __typename under a different key for each member of ${type} (${[...new Set(lists.flat())].join(", ")}). Select it under one key for every member, so the result tells its members apart.`);
|
|
507
|
+
return key;
|
|
508
|
+
}
|
|
509
|
+
#object(type, sets, path, indent, depth) {
|
|
510
|
+
const inner = `${indent} `;
|
|
511
|
+
const members = [
|
|
512
|
+
...collectFields(this.#schema, this.#fragments, type, sets)
|
|
513
|
+
].map(([key, field]) => {
|
|
514
|
+
const code = this.#field(type, field, [...path, key], inner, depth);
|
|
515
|
+
return `${inner}${key}: ${field.optional ? `${code}.optional()` : code},`;
|
|
516
|
+
});
|
|
517
|
+
return members.length === 0 ? "z.object({})" : `z.object({
|
|
518
|
+
${members.join(`
|
|
519
|
+
`)}
|
|
520
|
+
${indent}})`;
|
|
521
|
+
}
|
|
522
|
+
#field(parent, field, path, indent, depth) {
|
|
523
|
+
if (field.name === "__typename")
|
|
524
|
+
return typename;
|
|
525
|
+
const definition = parent.getFields()[field.name];
|
|
526
|
+
if (!definition)
|
|
527
|
+
return "z.unknown()";
|
|
528
|
+
const implied = field.optional && field.nodes.length === 1;
|
|
529
|
+
const sets = field.nodes.flatMap(({ node, conditional }) => node.selectionSet ? [{ set: node.selectionSet, conditional: conditional && !implied }] : []);
|
|
530
|
+
return this.#nullable(definition.type, sets, path, indent, depth + 1);
|
|
531
|
+
}
|
|
532
|
+
#nullable(type, sets, path, indent, depth) {
|
|
533
|
+
if (isNonNullType3(type))
|
|
534
|
+
return this.#required(type.ofType, sets, path, indent, depth);
|
|
535
|
+
return `${this.#required(type, sets, path, indent, depth)}.nullable()`;
|
|
536
|
+
}
|
|
537
|
+
#required(type, sets, path, indent, depth) {
|
|
538
|
+
if (isNonNullType3(type))
|
|
539
|
+
return this.#required(type.ofType, sets, path, indent, depth);
|
|
540
|
+
if (isListType3(type))
|
|
541
|
+
return `z.array(${this.#nullable(type.ofType, sets, path, indent, depth)})`;
|
|
542
|
+
if (isScalarType2(type))
|
|
543
|
+
return builtIns2[type.name] ?? this.#writer.scalarCode(type);
|
|
544
|
+
if (isEnumType3(type))
|
|
545
|
+
return this.#writer.schemaName(type);
|
|
546
|
+
return this.#code(type, sets, path, indent, depth);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/results-output.ts
|
|
551
|
+
function resultsBlocks(schema, documents, writer, naming) {
|
|
552
|
+
const definitions = documents.flatMap((file) => file.document?.definitions ?? []);
|
|
553
|
+
const fragments = new Map(definitions.filter((node) => node.kind === Kind2.FRAGMENT_DEFINITION).map((node) => [node.name.value, node]));
|
|
554
|
+
const selections = new Selections(schema, fragments, writer);
|
|
555
|
+
const block = (typeName, written) => [
|
|
556
|
+
...written.hoisted,
|
|
557
|
+
declare(typeName, naming, written.code, "output")
|
|
558
|
+
].join(`
|
|
559
|
+
`);
|
|
560
|
+
return [
|
|
561
|
+
...[...fragments.values()].flatMap((fragment) => {
|
|
562
|
+
const type = schema.getType(fragment.typeCondition.name.value);
|
|
563
|
+
if (!isCompositeType(type))
|
|
564
|
+
return [];
|
|
565
|
+
const typeName = naming.fragment(fragment.name.value);
|
|
566
|
+
const set = { set: fragment.selectionSet, conditional: false };
|
|
567
|
+
return [
|
|
568
|
+
block(typeName, selections.declare(naming.schema(typeName), type, [set], `fragment ${fragment.name.value}`))
|
|
569
|
+
];
|
|
570
|
+
}),
|
|
571
|
+
...definitions.filter((node) => node.kind === Kind2.OPERATION_DEFINITION).flatMap((operation) => {
|
|
572
|
+
const name = operation.name?.value;
|
|
573
|
+
const root = schema.getRootType(operation.operation);
|
|
574
|
+
if (!name || !root)
|
|
575
|
+
return [];
|
|
576
|
+
const typeName = naming.result(name, operation.operation);
|
|
577
|
+
const set = { set: operation.selectionSet, conditional: false };
|
|
578
|
+
return [
|
|
579
|
+
block(typeName, selections.declare(naming.schema(typeName), root, [set], name))
|
|
580
|
+
];
|
|
581
|
+
})
|
|
582
|
+
];
|
|
583
|
+
}
|
|
584
|
+
|
|
127
585
|
// src/scalars.ts
|
|
128
586
|
import { createRequire } from "node:module";
|
|
129
587
|
import { dirname, resolve } from "node:path";
|
|
@@ -180,55 +638,25 @@ async function recordKeys(module, outputFile) {
|
|
|
180
638
|
// src/schema-output.ts
|
|
181
639
|
import { constraintsOn } from "@nxgt/graphql-validation/codegen";
|
|
182
640
|
import {
|
|
183
|
-
isEnumType as
|
|
641
|
+
isEnumType as isEnumType5,
|
|
184
642
|
isInputObjectType as isInputObjectType4,
|
|
185
|
-
isInterfaceType,
|
|
186
|
-
isObjectType
|
|
643
|
+
isInterfaceType as isInterfaceType3,
|
|
644
|
+
isObjectType as isObjectType5
|
|
187
645
|
} from "graphql";
|
|
188
646
|
|
|
189
|
-
// src/cycles.ts
|
|
190
|
-
import {
|
|
191
|
-
getNamedType,
|
|
192
|
-
isInputObjectType
|
|
193
|
-
} from "graphql";
|
|
194
|
-
function inputCycles(schema) {
|
|
195
|
-
const inputs = Object.values(schema.getTypeMap()).filter(isInputObjectType);
|
|
196
|
-
const cyclic = new Set;
|
|
197
|
-
for (const start of inputs) {
|
|
198
|
-
if (reaches(start, start.name, new Set))
|
|
199
|
-
cyclic.add(start.name);
|
|
200
|
-
}
|
|
201
|
-
return cyclic;
|
|
202
|
-
}
|
|
203
|
-
function reaches(from, target, seen) {
|
|
204
|
-
for (const field of Object.values(from.getFields())) {
|
|
205
|
-
const named = getNamedType(field.type);
|
|
206
|
-
if (!isInputObjectType(named))
|
|
207
|
-
continue;
|
|
208
|
-
if (named.name === target)
|
|
209
|
-
return true;
|
|
210
|
-
if (seen.has(named.name))
|
|
211
|
-
continue;
|
|
212
|
-
seen.add(named.name);
|
|
213
|
-
if (reaches(named, target, seen))
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
|
-
return false;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
647
|
// src/defaults.ts
|
|
220
648
|
import * as graphql from "graphql";
|
|
221
649
|
import {
|
|
222
650
|
astFromValue,
|
|
223
|
-
GraphQLID,
|
|
224
|
-
getNamedType as
|
|
651
|
+
GraphQLID as GraphQLID3,
|
|
652
|
+
getNamedType as getNamedType3,
|
|
225
653
|
getNullableType,
|
|
226
654
|
isInputObjectType as isInputObjectType2,
|
|
227
|
-
isListType,
|
|
228
|
-
isNonNullType,
|
|
229
|
-
isScalarType,
|
|
655
|
+
isListType as isListType4,
|
|
656
|
+
isNonNullType as isNonNullType4,
|
|
657
|
+
isScalarType as isScalarType3,
|
|
230
658
|
isSpecifiedScalarType,
|
|
231
|
-
Kind,
|
|
659
|
+
Kind as Kind3,
|
|
232
660
|
valueFromASTUntyped
|
|
233
661
|
} from "graphql";
|
|
234
662
|
function parsedDefault(literal, type, where) {
|
|
@@ -237,14 +665,14 @@ function parsedDefault(literal, type, where) {
|
|
|
237
665
|
}
|
|
238
666
|
function assertExact(literal, type, where) {
|
|
239
667
|
const nullable = getNullableType(type);
|
|
240
|
-
if (
|
|
241
|
-
const items = literal.kind ===
|
|
668
|
+
if (isListType4(nullable)) {
|
|
669
|
+
const items = literal.kind === Kind3.LIST ? literal.values : [literal];
|
|
242
670
|
for (const item of items)
|
|
243
671
|
assertExact(item, nullable.ofType, where);
|
|
244
672
|
return;
|
|
245
673
|
}
|
|
246
674
|
if (isInputObjectType2(nullable)) {
|
|
247
|
-
if (literal.kind !==
|
|
675
|
+
if (literal.kind !== Kind3.OBJECT)
|
|
248
676
|
return;
|
|
249
677
|
const fields = nullable.getFields();
|
|
250
678
|
for (const field of literal.fields) {
|
|
@@ -254,8 +682,8 @@ function assertExact(literal, type, where) {
|
|
|
254
682
|
}
|
|
255
683
|
return;
|
|
256
684
|
}
|
|
257
|
-
const keeps = nullable ===
|
|
258
|
-
if (keeps && literal.kind ===
|
|
685
|
+
const keeps = nullable === GraphQLID3 || isScalarType3(nullable) && !isSpecifiedScalarType(nullable);
|
|
686
|
+
if (keeps && literal.kind === Kind3.INT && !Number.isSafeInteger(Number(literal.value)))
|
|
259
687
|
throw new Error(`@nxgt/graphql-codegen-zod: the default of ${where} holds ${literal.value}, which a JavaScript number cannot keep exact. Write it as a string, if its scalar takes one.`);
|
|
260
688
|
}
|
|
261
689
|
function defaultLiteral(input) {
|
|
@@ -275,10 +703,10 @@ function defaultLiteral(input) {
|
|
|
275
703
|
return astFromValue(loose.defaultValue, input.type) ?? undefined;
|
|
276
704
|
}
|
|
277
705
|
function coerced(value, type) {
|
|
278
|
-
const nullable =
|
|
706
|
+
const nullable = isNonNullType4(type) ? type.ofType : type;
|
|
279
707
|
if (value === null || value === undefined)
|
|
280
708
|
return value;
|
|
281
|
-
if (
|
|
709
|
+
if (isListType4(nullable)) {
|
|
282
710
|
const items = Array.isArray(value) ? value : [value];
|
|
283
711
|
return items.map((item) => coerced(item, nullable.ofType));
|
|
284
712
|
}
|
|
@@ -289,63 +717,30 @@ function coerced(value, type) {
|
|
|
289
717
|
return [key, definition ? coerced(field, definition.type) : field];
|
|
290
718
|
}));
|
|
291
719
|
}
|
|
292
|
-
if (
|
|
720
|
+
if (getNamedType3(nullable) === GraphQLID3 && typeof value === "number")
|
|
293
721
|
return String(value);
|
|
294
722
|
return value;
|
|
295
723
|
}
|
|
296
724
|
|
|
297
|
-
// src/source.ts
|
|
298
|
-
function docComment(description, indent = "") {
|
|
299
|
-
if (!description)
|
|
300
|
-
return "";
|
|
301
|
-
const lines = description.replaceAll(`\r
|
|
302
|
-
`, `
|
|
303
|
-
`).replaceAll("*/", "*\\/").split(`
|
|
304
|
-
`);
|
|
305
|
-
if (lines.length === 1)
|
|
306
|
-
return `${indent}/** ${lines[0]} */
|
|
307
|
-
`;
|
|
308
|
-
return `${indent}/**
|
|
309
|
-
${lines.map((line) => `${indent} * ${line}`.trimEnd()).join(`
|
|
310
|
-
`)}
|
|
311
|
-
${indent} */
|
|
312
|
-
`;
|
|
313
|
-
}
|
|
314
|
-
function objectMembers(members) {
|
|
315
|
-
return members.map(([name, { code, lazy, description }]) => {
|
|
316
|
-
const doc = docComment(description, "\t");
|
|
317
|
-
return lazy ? `${doc} get ${name}() {
|
|
318
|
-
return ${code};
|
|
319
|
-
},` : `${doc} ${name}: ${code},`;
|
|
320
|
-
}).join(`
|
|
321
|
-
`);
|
|
322
|
-
}
|
|
323
|
-
function declare(typeName, naming, code, side, description) {
|
|
324
|
-
const schemaName = naming.schema(typeName);
|
|
325
|
-
const doc = docComment(description);
|
|
326
|
-
return `${doc}export const ${schemaName} = ${code};
|
|
327
|
-
${doc}export type ${typeName} = z.${side}<typeof ${schemaName}>;`;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
725
|
// src/type-code.ts
|
|
331
726
|
import {
|
|
332
|
-
GraphQLBoolean,
|
|
333
|
-
GraphQLFloat,
|
|
334
|
-
GraphQLID as
|
|
335
|
-
GraphQLInt,
|
|
336
|
-
GraphQLString,
|
|
337
|
-
getNamedType as
|
|
338
|
-
isEnumType,
|
|
727
|
+
GraphQLBoolean as GraphQLBoolean3,
|
|
728
|
+
GraphQLFloat as GraphQLFloat3,
|
|
729
|
+
GraphQLID as GraphQLID4,
|
|
730
|
+
GraphQLInt as GraphQLInt3,
|
|
731
|
+
GraphQLString as GraphQLString3,
|
|
732
|
+
getNamedType as getNamedType4,
|
|
733
|
+
isEnumType as isEnumType4,
|
|
339
734
|
isInputObjectType as isInputObjectType3,
|
|
340
|
-
isListType as
|
|
341
|
-
isNonNullType as
|
|
735
|
+
isListType as isListType5,
|
|
736
|
+
isNonNullType as isNonNullType5
|
|
342
737
|
} from "graphql";
|
|
343
|
-
var
|
|
344
|
-
[
|
|
345
|
-
[
|
|
346
|
-
[
|
|
347
|
-
[
|
|
348
|
-
[
|
|
738
|
+
var builtIns3 = {
|
|
739
|
+
[GraphQLString3.name]: "string",
|
|
740
|
+
[GraphQLID4.name]: "string",
|
|
741
|
+
[GraphQLInt3.name]: "number",
|
|
742
|
+
[GraphQLFloat3.name]: "number",
|
|
743
|
+
[GraphQLBoolean3.name]: "boolean"
|
|
349
744
|
};
|
|
350
745
|
function declareCyclic(type, code, writer, naming, cyclic) {
|
|
351
746
|
const types = new TypeCode(writer, naming, cyclic);
|
|
@@ -380,7 +775,7 @@ ${members.join(`
|
|
|
380
775
|
}`;
|
|
381
776
|
}
|
|
382
777
|
#member(field, side) {
|
|
383
|
-
const nullable = !
|
|
778
|
+
const nullable = !isNonNullType5(field.type);
|
|
384
779
|
const filled = defaultLiteral(field) !== undefined;
|
|
385
780
|
const type = this.#required(field.type, side);
|
|
386
781
|
if (!nullable)
|
|
@@ -390,19 +785,19 @@ ${members.join(`
|
|
|
390
785
|
return `${field.name}?: ${type} | null | undefined`;
|
|
391
786
|
}
|
|
392
787
|
#required(type, side) {
|
|
393
|
-
if (
|
|
788
|
+
if (isNonNullType5(type))
|
|
394
789
|
return this.#required(type.ofType, side);
|
|
395
|
-
if (!
|
|
790
|
+
if (!isListType5(type))
|
|
396
791
|
return this.#named(type, side);
|
|
397
|
-
const item =
|
|
792
|
+
const item = isNonNullType5(type.ofType) ? this.#required(type.ofType, side) : `${this.#required(type.ofType, side)} | null | undefined`;
|
|
398
793
|
const list = `Array<${item}>`;
|
|
399
|
-
return side === "input" ? `${this.#named(
|
|
794
|
+
return side === "input" ? `${this.#named(getNamedType4(type), side)} | ${list}` : list;
|
|
400
795
|
}
|
|
401
796
|
#named(type, side) {
|
|
402
|
-
const builtIn =
|
|
797
|
+
const builtIn = builtIns3[type.name];
|
|
403
798
|
if (builtIn)
|
|
404
799
|
return builtIn;
|
|
405
|
-
if (
|
|
800
|
+
if (isEnumType4(type))
|
|
406
801
|
return `z.output<typeof ${this.#writer.schemaName(type)}>`;
|
|
407
802
|
if (isInputObjectType3(type)) {
|
|
408
803
|
const name = this.#naming.type(type.name);
|
|
@@ -419,10 +814,10 @@ function schemaBlocks(schema, writer, naming) {
|
|
|
419
814
|
const types = Object.values(schema.getTypeMap()).filter((type) => !type.name.startsWith("__"));
|
|
420
815
|
const cyclic = inputCycles(schema);
|
|
421
816
|
return [
|
|
422
|
-
...types.filter(
|
|
817
|
+
...types.filter(isEnumType5).map((type) => enumBlock(type, naming)),
|
|
423
818
|
...types.filter(isInputObjectType4).map((type) => inputBlock(type, writer, naming, cyclic)),
|
|
424
819
|
...types.flatMap((type) => {
|
|
425
|
-
if (!
|
|
820
|
+
if (!isObjectType5(type) && !isInterfaceType3(type))
|
|
426
821
|
return [];
|
|
427
822
|
return Object.values(type.getFields()).filter((field) => field.args.length > 0).map((field) => {
|
|
428
823
|
const name = naming.args(type.name, field.name);
|
|
@@ -489,11 +884,11 @@ import {
|
|
|
489
884
|
constraintsOn as constraintsOn2
|
|
490
885
|
} from "@nxgt/graphql-validation/codegen";
|
|
491
886
|
import {
|
|
492
|
-
getNamedType as
|
|
887
|
+
getNamedType as getNamedType5,
|
|
493
888
|
isInputObjectType as isInputObjectType5,
|
|
494
|
-
isListType as
|
|
495
|
-
isNonNullType as
|
|
496
|
-
Kind as
|
|
889
|
+
isListType as isListType6,
|
|
890
|
+
isNonNullType as isNonNullType6,
|
|
891
|
+
Kind as Kind4,
|
|
497
892
|
TypeInfo,
|
|
498
893
|
typeFromAST,
|
|
499
894
|
visit,
|
|
@@ -501,8 +896,8 @@ import {
|
|
|
501
896
|
} from "graphql";
|
|
502
897
|
function variablesBlocks(schema, documents, writer, naming) {
|
|
503
898
|
const definitions = documents.flatMap((file) => file.document?.definitions ?? []);
|
|
504
|
-
const fragments = new Map(definitions.filter((node) => node.kind ===
|
|
505
|
-
return definitions.filter((node) => node.kind ===
|
|
899
|
+
const fragments = new Map(definitions.filter((node) => node.kind === Kind4.FRAGMENT_DEFINITION).map((node) => [node.name.value, node]));
|
|
900
|
+
return definitions.filter((node) => node.kind === Kind4.OPERATION_DEFINITION).flatMap((operation) => {
|
|
506
901
|
const operationName = operation.name?.value;
|
|
507
902
|
if (!operationName)
|
|
508
903
|
return [];
|
|
@@ -558,7 +953,7 @@ function usages(schema, directive, operation, fragments) {
|
|
|
558
953
|
return walk.found;
|
|
559
954
|
}
|
|
560
955
|
function walkValue(walk, value, type, constraints, where) {
|
|
561
|
-
if (value.kind ===
|
|
956
|
+
if (value.kind === Kind4.VARIABLE) {
|
|
562
957
|
if (!walk.variables.has(value.name.value))
|
|
563
958
|
return;
|
|
564
959
|
const list = walk.found.get(value.name.value) ?? [];
|
|
@@ -566,15 +961,15 @@ function walkValue(walk, value, type, constraints, where) {
|
|
|
566
961
|
walk.found.set(value.name.value, list);
|
|
567
962
|
return;
|
|
568
963
|
}
|
|
569
|
-
const nullable =
|
|
570
|
-
if (value.kind ===
|
|
964
|
+
const nullable = isNonNullType6(type) ? type.ofType : type;
|
|
965
|
+
if (value.kind === Kind4.LIST && isListType6(nullable)) {
|
|
571
966
|
const items = constraints.filter(({ rule }) => rule.target !== "list");
|
|
572
967
|
for (const item of value.values)
|
|
573
968
|
walkValue(walk, item, nullable.ofType, items, where);
|
|
574
969
|
return;
|
|
575
970
|
}
|
|
576
|
-
const named =
|
|
577
|
-
if (value.kind ===
|
|
971
|
+
const named = getNamedType5(type);
|
|
972
|
+
if (value.kind === Kind4.OBJECT && isInputObjectType5(named)) {
|
|
578
973
|
for (const field of value.fields) {
|
|
579
974
|
const definition = named.getFields()[field.name.value];
|
|
580
975
|
if (definition) {
|
|
@@ -606,11 +1001,11 @@ import {
|
|
|
606
1001
|
} from "@nxgt/graphql-validation/codegen";
|
|
607
1002
|
import {
|
|
608
1003
|
GraphQLNonNull,
|
|
609
|
-
getNamedType as
|
|
610
|
-
isEnumType as
|
|
1004
|
+
getNamedType as getNamedType6,
|
|
1005
|
+
isEnumType as isEnumType6,
|
|
611
1006
|
isInputObjectType as isInputObjectType6,
|
|
612
|
-
isNonNullType as
|
|
613
|
-
isScalarType as
|
|
1007
|
+
isNonNullType as isNonNullType7,
|
|
1008
|
+
isScalarType as isScalarType4,
|
|
614
1009
|
isSpecifiedScalarType as isSpecifiedScalarType2
|
|
615
1010
|
} from "graphql";
|
|
616
1011
|
class Writer {
|
|
@@ -635,7 +1030,7 @@ class Writer {
|
|
|
635
1030
|
lazy = true;
|
|
636
1031
|
return this.schemaName(named);
|
|
637
1032
|
}
|
|
638
|
-
if (
|
|
1033
|
+
if (isEnumType6(named))
|
|
639
1034
|
return this.schemaName(named);
|
|
640
1035
|
return this.#scalars.code(named);
|
|
641
1036
|
};
|
|
@@ -646,7 +1041,7 @@ class Writer {
|
|
|
646
1041
|
}),
|
|
647
1042
|
lazy
|
|
648
1043
|
};
|
|
649
|
-
const nullable = !
|
|
1044
|
+
const nullable = !isNonNullType7(type);
|
|
650
1045
|
const required = inputCode2(nullable ? new GraphQLNonNull(type) : type, constraints, where, named, { list: singleOrList });
|
|
651
1046
|
const value = JSON.stringify(parsedDefault(defaultValue, type, where));
|
|
652
1047
|
return {
|
|
@@ -655,7 +1050,7 @@ class Writer {
|
|
|
655
1050
|
};
|
|
656
1051
|
}
|
|
657
1052
|
required(type, constraints, where) {
|
|
658
|
-
return this.value(
|
|
1053
|
+
return this.value(isNonNullType7(type) ? type : new GraphQLNonNull(type), constraints, where);
|
|
659
1054
|
}
|
|
660
1055
|
}
|
|
661
1056
|
var singleOrList = ({
|
|
@@ -663,8 +1058,8 @@ var singleOrList = ({
|
|
|
663
1058
|
code,
|
|
664
1059
|
single
|
|
665
1060
|
}) => {
|
|
666
|
-
const named =
|
|
667
|
-
const transforms = isInputObjectType6(named) ||
|
|
1061
|
+
const named = getNamedType6(type);
|
|
1062
|
+
const transforms = isInputObjectType6(named) || isScalarType4(named) && !isSpecifiedScalarType2(named);
|
|
668
1063
|
const first = transforms ? `z.custom<z.input<typeof ${single}>>((value) => value != null && !Array.isArray(value))` : single;
|
|
669
1064
|
return `z.union([${code}, ${first}.transform((value): unknown[] => [value]).pipe(${code})])`;
|
|
670
1065
|
};
|
|
@@ -680,13 +1075,15 @@ async function plugin(schema, documents, config = {}, info) {
|
|
|
680
1075
|
const writer = new Writer(directive, naming, scalars);
|
|
681
1076
|
return [
|
|
682
1077
|
...schemaBlocks(schema, writer, naming),
|
|
683
|
-
...
|
|
1078
|
+
...config.objects === false ? [] : objectBlocks(schema, writer, naming),
|
|
1079
|
+
...variablesBlocks(schema, documents, writer, naming),
|
|
1080
|
+
...config.operations === false ? [] : resultsBlocks(schema, documents, writer, naming)
|
|
684
1081
|
];
|
|
685
1082
|
};
|
|
686
|
-
const declarations = (await write(new Imports)).flatMap((block) => [...block.matchAll(/^export (const|type) (\w+)/gm)].map((m) => `${m[1]} ${m[2]}`));
|
|
1083
|
+
const declarations = (await write(new Imports)).flatMap((block) => [...block.matchAll(/^(?:export )?(const|type) ([\w$]+)/gm)].map((m) => `${m[1]} ${m[2]}`));
|
|
687
1084
|
const twice = declarations.find((declaration, index) => declarations.indexOf(declaration) !== index);
|
|
688
1085
|
if (twice)
|
|
689
|
-
throw new Error(`@nxgt/graphql-codegen-zod: the file would declare ${twice.split(" ")[1]} twice: two GraphQL names, or
|
|
1086
|
+
throw new Error(`@nxgt/graphql-codegen-zod: the file would declare ${twice.split(" ")[1]} 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.`);
|
|
690
1087
|
const declared = declarations.map((declaration) => declaration.split(" ")[1] ?? "");
|
|
691
1088
|
const imports = new Imports(declared);
|
|
692
1089
|
const blocks = await write(imports);
|
|
@@ -702,7 +1099,7 @@ function assertSdl(schema) {
|
|
|
702
1099
|
for (const type of Object.values(schema.getTypeMap())) {
|
|
703
1100
|
if (type.name.startsWith("__"))
|
|
704
1101
|
continue;
|
|
705
|
-
const inputs = isInputObjectType7(type) ? Object.values(type.getFields()) :
|
|
1102
|
+
const inputs = isInputObjectType7(type) ? Object.values(type.getFields()) : isObjectType6(type) || isInterfaceType4(type) ? Object.values(type.getFields()).flatMap((field) => field.args) : [];
|
|
706
1103
|
const bare = inputs.find((input) => !input.astNode);
|
|
707
1104
|
if (bare) {
|
|
708
1105
|
throw new Error(`@nxgt/graphql-codegen-zod: the schema declares @constraint, but ${type.name} has no SDL to read it from (an introspected schema?). Point codegen's schema at the SDL files.`);
|
|
@@ -713,5 +1110,5 @@ export {
|
|
|
713
1110
|
plugin
|
|
714
1111
|
};
|
|
715
1112
|
|
|
716
|
-
//# debugId=
|
|
1113
|
+
//# debugId=7FB3A417D01910B464756E2164756E21
|
|
717
1114
|
//# sourceMappingURL=index.js.map
|