@constructive-io/graphql-codegen 2.23.3 → 2.24.1

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.
Files changed (92) hide show
  1. package/README.md +147 -2
  2. package/cli/codegen/babel-ast.d.ts +53 -0
  3. package/cli/codegen/babel-ast.js +160 -0
  4. package/cli/codegen/barrel.d.ts +7 -2
  5. package/cli/codegen/barrel.js +193 -102
  6. package/cli/codegen/client.js +61 -0
  7. package/cli/codegen/custom-mutations.d.ts +2 -12
  8. package/cli/codegen/custom-mutations.js +116 -124
  9. package/cli/codegen/custom-queries.d.ts +2 -10
  10. package/cli/codegen/custom-queries.js +236 -335
  11. package/cli/codegen/gql-ast.js +22 -1
  12. package/cli/codegen/index.d.ts +3 -0
  13. package/cli/codegen/index.js +73 -3
  14. package/cli/codegen/invalidation.d.ts +20 -0
  15. package/cli/codegen/invalidation.js +327 -0
  16. package/cli/codegen/mutation-keys.d.ts +24 -0
  17. package/cli/codegen/mutation-keys.js +247 -0
  18. package/cli/codegen/mutations.d.ts +5 -19
  19. package/cli/codegen/mutations.js +385 -383
  20. package/cli/codegen/orm/barrel.d.ts +1 -1
  21. package/cli/codegen/orm/barrel.js +42 -10
  22. package/cli/codegen/orm/client-generator.d.ts +1 -19
  23. package/cli/codegen/orm/client-generator.js +108 -77
  24. package/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  25. package/cli/codegen/orm/custom-ops-generator.js +192 -235
  26. package/cli/codegen/orm/input-types-generator.d.ts +13 -1
  27. package/cli/codegen/orm/input-types-generator.js +425 -147
  28. package/cli/codegen/orm/model-generator.d.ts +1 -19
  29. package/cli/codegen/orm/model-generator.js +229 -234
  30. package/cli/codegen/queries.d.ts +4 -12
  31. package/cli/codegen/queries.js +660 -390
  32. package/cli/codegen/query-keys.d.ts +15 -0
  33. package/cli/codegen/query-keys.js +477 -0
  34. package/cli/codegen/scalars.js +1 -0
  35. package/cli/codegen/schema-types-generator.d.ts +15 -10
  36. package/cli/codegen/schema-types-generator.js +87 -175
  37. package/cli/codegen/type-resolver.d.ts +1 -30
  38. package/cli/codegen/type-resolver.js +0 -53
  39. package/cli/codegen/types.d.ts +1 -1
  40. package/cli/codegen/types.js +76 -21
  41. package/cli/codegen/utils.d.ts +6 -0
  42. package/cli/codegen/utils.js +19 -0
  43. package/esm/cli/codegen/babel-ast.d.ts +53 -0
  44. package/esm/cli/codegen/babel-ast.js +111 -0
  45. package/esm/cli/codegen/barrel.d.ts +7 -2
  46. package/esm/cli/codegen/barrel.js +161 -103
  47. package/esm/cli/codegen/client.js +61 -0
  48. package/esm/cli/codegen/custom-mutations.d.ts +2 -12
  49. package/esm/cli/codegen/custom-mutations.js +83 -124
  50. package/esm/cli/codegen/custom-queries.d.ts +2 -10
  51. package/esm/cli/codegen/custom-queries.js +204 -336
  52. package/esm/cli/codegen/gql-ast.js +23 -2
  53. package/esm/cli/codegen/index.d.ts +3 -0
  54. package/esm/cli/codegen/index.js +69 -2
  55. package/esm/cli/codegen/invalidation.d.ts +20 -0
  56. package/esm/cli/codegen/invalidation.js +291 -0
  57. package/esm/cli/codegen/mutation-keys.d.ts +24 -0
  58. package/esm/cli/codegen/mutation-keys.js +211 -0
  59. package/esm/cli/codegen/mutations.d.ts +5 -19
  60. package/esm/cli/codegen/mutations.js +353 -384
  61. package/esm/cli/codegen/orm/barrel.d.ts +1 -1
  62. package/esm/cli/codegen/orm/barrel.js +10 -11
  63. package/esm/cli/codegen/orm/client-generator.d.ts +1 -19
  64. package/esm/cli/codegen/orm/client-generator.js +76 -78
  65. package/esm/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
  66. package/esm/cli/codegen/orm/custom-ops-generator.js +160 -236
  67. package/esm/cli/codegen/orm/input-types-generator.d.ts +13 -1
  68. package/esm/cli/codegen/orm/input-types-generator.js +393 -148
  69. package/esm/cli/codegen/orm/model-generator.d.ts +1 -19
  70. package/esm/cli/codegen/orm/model-generator.js +197 -235
  71. package/esm/cli/codegen/queries.d.ts +4 -12
  72. package/esm/cli/codegen/queries.js +628 -391
  73. package/esm/cli/codegen/query-keys.d.ts +15 -0
  74. package/esm/cli/codegen/query-keys.js +441 -0
  75. package/esm/cli/codegen/scalars.js +1 -0
  76. package/esm/cli/codegen/schema-types-generator.d.ts +15 -10
  77. package/esm/cli/codegen/schema-types-generator.js +54 -175
  78. package/esm/cli/codegen/type-resolver.d.ts +1 -30
  79. package/esm/cli/codegen/type-resolver.js +0 -49
  80. package/esm/cli/codegen/types.d.ts +1 -1
  81. package/esm/cli/codegen/types.js +44 -22
  82. package/esm/cli/codegen/utils.d.ts +6 -0
  83. package/esm/cli/codegen/utils.js +18 -0
  84. package/esm/types/config.d.ts +75 -0
  85. package/esm/types/config.js +18 -0
  86. package/package.json +6 -4
  87. package/types/config.d.ts +75 -0
  88. package/types/config.js +19 -1
  89. package/cli/codegen/ts-ast.d.ts +0 -124
  90. package/cli/codegen/ts-ast.js +0 -280
  91. package/esm/cli/codegen/ts-ast.d.ts +0 -124
  92. package/esm/cli/codegen/ts-ast.js +0 -260
@@ -1,9 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.collectInputTypeNames = collectInputTypeNames;
4
37
  exports.collectPayloadTypeNames = collectPayloadTypeNames;
5
38
  exports.generateInputTypesFile = generateInputTypesFile;
6
- const ts_ast_1 = require("../ts-ast");
39
+ const t = __importStar(require("@babel/types"));
40
+ const babel_ast_1 = require("../babel-ast");
7
41
  const utils_1 = require("../utils");
8
42
  const inflekt_1 = require("inflekt");
9
43
  const type_resolver_1 = require("../type-resolver");
@@ -62,6 +96,86 @@ function typeRefToTs(typeRef) {
62
96
  function isRequired(typeRef) {
63
97
  return typeRef.kind === 'NON_NULL';
64
98
  }
99
+ // ============================================================================
100
+ // Babel AST Helper Functions
101
+ // ============================================================================
102
+ /**
103
+ * Parse a type string into a TSType node
104
+ */
105
+ function parseTypeString(typeStr) {
106
+ // Handle union types like "string | null"
107
+ if (typeStr.includes(' | ')) {
108
+ const parts = typeStr.split(' | ').map((p) => p.trim());
109
+ return t.tsUnionType(parts.map((p) => parseTypeString(p)));
110
+ }
111
+ // Handle array types like "string[]"
112
+ if (typeStr.endsWith('[]')) {
113
+ const elementType = typeStr.slice(0, -2);
114
+ return t.tsArrayType(parseTypeString(elementType));
115
+ }
116
+ // Handle generic types like "Record<string, unknown>"
117
+ if (typeStr.includes('<')) {
118
+ const match = typeStr.match(/^([^<]+)<(.+)>$/);
119
+ if (match) {
120
+ const [, baseName, params] = match;
121
+ const typeParams = params.split(',').map((p) => parseTypeString(p.trim()));
122
+ return t.tsTypeReference(t.identifier(baseName), t.tsTypeParameterInstantiation(typeParams));
123
+ }
124
+ }
125
+ // Handle primitive types
126
+ switch (typeStr) {
127
+ case 'string':
128
+ return t.tsStringKeyword();
129
+ case 'number':
130
+ return t.tsNumberKeyword();
131
+ case 'boolean':
132
+ return t.tsBooleanKeyword();
133
+ case 'null':
134
+ return t.tsNullKeyword();
135
+ case 'unknown':
136
+ return t.tsUnknownKeyword();
137
+ default:
138
+ return t.tsTypeReference(t.identifier(typeStr));
139
+ }
140
+ }
141
+ /**
142
+ * Create an interface property signature
143
+ */
144
+ function createPropertySignature(name, typeStr, optional) {
145
+ const prop = t.tsPropertySignature(t.identifier(name), t.tsTypeAnnotation(parseTypeString(typeStr)));
146
+ prop.optional = optional;
147
+ return prop;
148
+ }
149
+ /**
150
+ * Create an exported interface declaration
151
+ */
152
+ function createExportedInterface(name, properties) {
153
+ const props = properties.map((p) => createPropertySignature(p.name, p.type, p.optional));
154
+ const body = t.tsInterfaceBody(props);
155
+ const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(name), null, null, body);
156
+ return t.exportNamedDeclaration(interfaceDecl);
157
+ }
158
+ /**
159
+ * Create an exported type alias declaration
160
+ */
161
+ function createExportedTypeAlias(name, typeStr) {
162
+ const typeAlias = t.tsTypeAliasDeclaration(t.identifier(name), null, parseTypeString(typeStr));
163
+ return t.exportNamedDeclaration(typeAlias);
164
+ }
165
+ /**
166
+ * Create a union type from string literals
167
+ */
168
+ function createStringLiteralUnion(values) {
169
+ return t.tsUnionType(values.map((v) => t.tsLiteralType(t.stringLiteral(v))));
170
+ }
171
+ /**
172
+ * Add a section comment to the first statement in an array
173
+ */
174
+ function addSectionComment(statements, sectionName) {
175
+ if (statements.length > 0) {
176
+ (0, babel_ast_1.addLineComment)(statements[0], `============ ${sectionName} ============`);
177
+ }
178
+ }
65
179
  /** Configuration for all scalar filter types - matches PostGraphile's generated filters */
66
180
  const SCALAR_FILTER_CONFIGS = [
67
181
  {
@@ -117,6 +231,22 @@ const SCALAR_FILTER_CONFIGS = [
117
231
  operators: ['equality', 'distinct', 'inArray', 'comparison', 'inet'],
118
232
  },
119
233
  { name: 'FullTextFilter', tsType: 'string', operators: ['fulltext'] },
234
+ // List filters (for array fields like string[], int[], uuid[])
235
+ {
236
+ name: 'StringListFilter',
237
+ tsType: 'string[]',
238
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
239
+ },
240
+ {
241
+ name: 'IntListFilter',
242
+ tsType: 'number[]',
243
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
244
+ },
245
+ {
246
+ name: 'UUIDListFilter',
247
+ tsType: 'string[]',
248
+ operators: ['equality', 'distinct', 'comparison', 'listArray'],
249
+ },
120
250
  ];
121
251
  /**
122
252
  * Build filter properties based on operator sets
@@ -156,16 +286,24 @@ function buildScalarFilterProperties(config) {
156
286
  if (operators.includes('fulltext')) {
157
287
  props.push({ name: 'matches', type: 'string', optional: true });
158
288
  }
289
+ // List/Array operators (contains, overlaps, anyEqualTo, etc.)
290
+ if (operators.includes('listArray')) {
291
+ // Extract base type from array type (e.g., 'string[]' -> 'string')
292
+ const baseType = tsType.replace('[]', '');
293
+ props.push({ name: 'contains', type: tsType, optional: true }, { name: 'containedBy', type: tsType, optional: true }, { name: 'overlaps', type: tsType, optional: true }, { name: 'anyEqualTo', type: baseType, optional: true }, { name: 'anyNotEqualTo', type: baseType, optional: true }, { name: 'anyLessThan', type: baseType, optional: true }, { name: 'anyLessThanOrEqualTo', type: baseType, optional: true }, { name: 'anyGreaterThan', type: baseType, optional: true }, { name: 'anyGreaterThanOrEqualTo', type: baseType, optional: true });
294
+ }
159
295
  return props;
160
296
  }
161
297
  /**
162
- * Add scalar filter types to source file using ts-morph
298
+ * Generate scalar filter type statements
163
299
  */
164
- function addScalarFilterTypes(sourceFile) {
165
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Scalar Filter Types');
300
+ function generateScalarFilterTypes() {
301
+ const statements = [];
166
302
  for (const config of SCALAR_FILTER_CONFIGS) {
167
- sourceFile.addInterface((0, ts_ast_1.createInterface)(config.name, buildScalarFilterProperties(config)));
303
+ statements.push(createExportedInterface(config.name, buildScalarFilterProperties(config)));
168
304
  }
305
+ addSectionComment(statements, 'Scalar Filter Types');
306
+ return statements;
169
307
  }
170
308
  // ============================================================================
171
309
  // Enum Types Collector
@@ -194,19 +332,24 @@ function collectEnumTypesFromTables(tables, typeRegistry) {
194
332
  return enumTypes;
195
333
  }
196
334
  /**
197
- * Add enum types to source file
335
+ * Generate enum type statements
198
336
  */
199
- function addEnumTypes(sourceFile, typeRegistry, enumTypeNames) {
337
+ function generateEnumTypes(typeRegistry, enumTypeNames) {
200
338
  if (enumTypeNames.size === 0)
201
- return;
202
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Enum Types');
339
+ return [];
340
+ const statements = [];
203
341
  for (const typeName of Array.from(enumTypeNames).sort()) {
204
342
  const typeInfo = typeRegistry.get(typeName);
205
343
  if (!typeInfo || typeInfo.kind !== 'ENUM' || !typeInfo.enumValues)
206
344
  continue;
207
- const values = typeInfo.enumValues.map((v) => `'${v}'`).join(' | ');
208
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(typeName, values));
345
+ const unionType = createStringLiteralUnion(typeInfo.enumValues);
346
+ const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
347
+ statements.push(t.exportNamedDeclaration(typeAlias));
348
+ }
349
+ if (statements.length > 0) {
350
+ addSectionComment(statements, 'Enum Types');
209
351
  }
352
+ return statements;
210
353
  }
211
354
  // ============================================================================
212
355
  // Entity Types Generator (AST-based)
@@ -231,40 +374,47 @@ function buildEntityProperties(table) {
231
374
  return properties;
232
375
  }
233
376
  /**
234
- * Add entity type interface for a table
377
+ * Generate entity type statements
235
378
  */
236
- function addEntityType(sourceFile, table) {
237
- const { typeName } = (0, utils_1.getTableNames)(table);
238
- sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, buildEntityProperties(table)));
239
- }
240
- /**
241
- * Add all entity types
242
- */
243
- function addEntityTypes(sourceFile, tables) {
244
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Entity Types');
379
+ function generateEntityTypes(tables) {
380
+ const statements = [];
245
381
  for (const table of tables) {
246
- addEntityType(sourceFile, table);
382
+ const { typeName } = (0, utils_1.getTableNames)(table);
383
+ statements.push(createExportedInterface(typeName, buildEntityProperties(table)));
247
384
  }
385
+ if (statements.length > 0) {
386
+ addSectionComment(statements, 'Entity Types');
387
+ }
388
+ return statements;
248
389
  }
249
390
  // ============================================================================
250
391
  // Relation Helper Types Generator (AST-based)
251
392
  // ============================================================================
252
393
  /**
253
- * Add relation helper types (ConnectionResult, PageInfo)
394
+ * Generate relation helper type statements (ConnectionResult, PageInfo)
254
395
  */
255
- function addRelationHelperTypes(sourceFile) {
256
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Relation Helper Types');
257
- sourceFile.addInterface((0, ts_ast_1.createInterface)('ConnectionResult<T>', [
258
- { name: 'nodes', type: 'T[]', optional: false },
259
- { name: 'totalCount', type: 'number', optional: false },
260
- { name: 'pageInfo', type: 'PageInfo', optional: false },
261
- ]));
262
- sourceFile.addInterface((0, ts_ast_1.createInterface)('PageInfo', [
396
+ function generateRelationHelperTypes() {
397
+ const statements = [];
398
+ // ConnectionResult<T> interface with type parameter
399
+ const connectionResultProps = [
400
+ createPropertySignature('nodes', 'T[]', false),
401
+ createPropertySignature('totalCount', 'number', false),
402
+ createPropertySignature('pageInfo', 'PageInfo', false),
403
+ ];
404
+ const connectionResultBody = t.tsInterfaceBody(connectionResultProps);
405
+ const connectionResultDecl = t.tsInterfaceDeclaration(t.identifier('ConnectionResult'), t.tsTypeParameterDeclaration([
406
+ t.tsTypeParameter(null, null, 'T'),
407
+ ]), null, connectionResultBody);
408
+ statements.push(t.exportNamedDeclaration(connectionResultDecl));
409
+ // PageInfo interface
410
+ statements.push(createExportedInterface('PageInfo', [
263
411
  { name: 'hasNextPage', type: 'boolean', optional: false },
264
412
  { name: 'hasPreviousPage', type: 'boolean', optional: false },
265
413
  { name: 'startCursor', type: 'string | null', optional: true },
266
414
  { name: 'endCursor', type: 'string | null', optional: true },
267
415
  ]));
416
+ addSectionComment(statements, 'Relation Helper Types');
417
+ return statements;
268
418
  }
269
419
  // ============================================================================
270
420
  // Entity Relation Types Generator (AST-based)
@@ -337,44 +487,65 @@ function buildEntityRelationProperties(table, tableByName) {
337
487
  return properties;
338
488
  }
339
489
  /**
340
- * Add entity relation types
490
+ * Generate entity relation type statements
341
491
  */
342
- function addEntityRelationTypes(sourceFile, tables, tableByName) {
343
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Entity Relation Types');
492
+ function generateEntityRelationTypes(tables, tableByName) {
493
+ const statements = [];
344
494
  for (const table of tables) {
345
495
  const { typeName } = (0, utils_1.getTableNames)(table);
346
- sourceFile.addInterface((0, ts_ast_1.createInterface)(`${typeName}Relations`, buildEntityRelationProperties(table, tableByName)));
496
+ statements.push(createExportedInterface(`${typeName}Relations`, buildEntityRelationProperties(table, tableByName)));
497
+ }
498
+ if (statements.length > 0) {
499
+ addSectionComment(statements, 'Entity Relation Types');
347
500
  }
501
+ return statements;
348
502
  }
349
503
  /**
350
- * Add entity types with relations (intersection types)
504
+ * Generate entity types with relations (intersection types)
351
505
  */
352
- function addEntityWithRelations(sourceFile, tables) {
353
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Entity Types With Relations');
506
+ function generateEntityWithRelations(tables) {
507
+ const statements = [];
354
508
  for (const table of tables) {
355
509
  const { typeName } = (0, utils_1.getTableNames)(table);
356
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(`${typeName}WithRelations`, `${typeName} & ${typeName}Relations`));
510
+ statements.push(createExportedTypeAlias(`${typeName}WithRelations`, `${typeName} & ${typeName}Relations`));
357
511
  }
512
+ if (statements.length > 0) {
513
+ addSectionComment(statements, 'Entity Types With Relations');
514
+ }
515
+ return statements;
358
516
  }
359
517
  // ============================================================================
360
518
  // Entity Select Types Generator (AST-based)
361
519
  // ============================================================================
362
520
  /**
363
- * Build the type string for a Select type (as object type literal)
521
+ * Build the Select type as a TSTypeLiteral
364
522
  */
365
- function buildSelectTypeBody(table, tableByName) {
366
- const lines = ['{'];
523
+ function buildSelectTypeLiteral(table, tableByName) {
524
+ const members = [];
367
525
  // Add scalar fields
368
526
  for (const field of table.fields) {
369
527
  if (!(0, utils_1.isRelationField)(field.name, table)) {
370
- lines.push(`${field.name}?: boolean;`);
528
+ const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsBooleanKeyword()));
529
+ prop.optional = true;
530
+ members.push(prop);
371
531
  }
372
532
  }
373
533
  // Add belongsTo relations
374
534
  for (const relation of table.relations.belongsTo) {
375
535
  if (relation.fieldName) {
376
536
  const relatedTypeName = getRelatedTypeName(relation.referencesTable, tableByName);
377
- lines.push(`${relation.fieldName}?: boolean | { select?: ${relatedTypeName}Select };`);
537
+ const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
538
+ t.tsBooleanKeyword(),
539
+ t.tsTypeLiteral([
540
+ (() => {
541
+ const selectProp = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
542
+ selectProp.optional = true;
543
+ return selectProp;
544
+ })(),
545
+ ]),
546
+ ])));
547
+ prop.optional = true;
548
+ members.push(prop);
378
549
  }
379
550
  }
380
551
  // Add hasMany relations
@@ -383,12 +554,33 @@ function buildSelectTypeBody(table, tableByName) {
383
554
  const relatedTypeName = getRelatedTypeName(relation.referencedByTable, tableByName);
384
555
  const filterName = getRelatedFilterName(relation.referencedByTable, tableByName);
385
556
  const orderByName = getRelatedOrderByName(relation.referencedByTable, tableByName);
386
- lines.push(`${relation.fieldName}?: boolean | {`);
387
- lines.push(` select?: ${relatedTypeName}Select;`);
388
- lines.push(` first?: number;`);
389
- lines.push(` filter?: ${filterName};`);
390
- lines.push(` orderBy?: ${orderByName}[];`);
391
- lines.push(`};`);
557
+ const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
558
+ t.tsBooleanKeyword(),
559
+ t.tsTypeLiteral([
560
+ (() => {
561
+ const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
562
+ p.optional = true;
563
+ return p;
564
+ })(),
565
+ (() => {
566
+ const p = t.tsPropertySignature(t.identifier('first'), t.tsTypeAnnotation(t.tsNumberKeyword()));
567
+ p.optional = true;
568
+ return p;
569
+ })(),
570
+ (() => {
571
+ const p = t.tsPropertySignature(t.identifier('filter'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(filterName))));
572
+ p.optional = true;
573
+ return p;
574
+ })(),
575
+ (() => {
576
+ const p = t.tsPropertySignature(t.identifier('orderBy'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier(orderByName)))));
577
+ p.optional = true;
578
+ return p;
579
+ })(),
580
+ ]),
581
+ ])));
582
+ prop.optional = true;
583
+ members.push(prop);
392
584
  }
393
585
  }
394
586
  // Add manyToMany relations
@@ -397,33 +589,69 @@ function buildSelectTypeBody(table, tableByName) {
397
589
  const relatedTypeName = getRelatedTypeName(relation.rightTable, tableByName);
398
590
  const filterName = getRelatedFilterName(relation.rightTable, tableByName);
399
591
  const orderByName = getRelatedOrderByName(relation.rightTable, tableByName);
400
- lines.push(`${relation.fieldName}?: boolean | {`);
401
- lines.push(` select?: ${relatedTypeName}Select;`);
402
- lines.push(` first?: number;`);
403
- lines.push(` filter?: ${filterName};`);
404
- lines.push(` orderBy?: ${orderByName}[];`);
405
- lines.push(`};`);
592
+ const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
593
+ t.tsBooleanKeyword(),
594
+ t.tsTypeLiteral([
595
+ (() => {
596
+ const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
597
+ p.optional = true;
598
+ return p;
599
+ })(),
600
+ (() => {
601
+ const p = t.tsPropertySignature(t.identifier('first'), t.tsTypeAnnotation(t.tsNumberKeyword()));
602
+ p.optional = true;
603
+ return p;
604
+ })(),
605
+ (() => {
606
+ const p = t.tsPropertySignature(t.identifier('filter'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(filterName))));
607
+ p.optional = true;
608
+ return p;
609
+ })(),
610
+ (() => {
611
+ const p = t.tsPropertySignature(t.identifier('orderBy'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier(orderByName)))));
612
+ p.optional = true;
613
+ return p;
614
+ })(),
615
+ ]),
616
+ ])));
617
+ prop.optional = true;
618
+ members.push(prop);
406
619
  }
407
620
  }
408
621
  // Add hasOne relations
409
622
  for (const relation of table.relations.hasOne) {
410
623
  if (relation.fieldName) {
411
624
  const relatedTypeName = getRelatedTypeName(relation.referencedByTable, tableByName);
412
- lines.push(`${relation.fieldName}?: boolean | { select?: ${relatedTypeName}Select };`);
625
+ const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
626
+ t.tsBooleanKeyword(),
627
+ t.tsTypeLiteral([
628
+ (() => {
629
+ const selectProp = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
630
+ selectProp.optional = true;
631
+ return selectProp;
632
+ })(),
633
+ ]),
634
+ ])));
635
+ prop.optional = true;
636
+ members.push(prop);
413
637
  }
414
638
  }
415
- lines.push('}');
416
- return lines.join('\n');
639
+ return t.tsTypeLiteral(members);
417
640
  }
418
641
  /**
419
- * Add entity Select types
642
+ * Generate entity Select type statements
420
643
  */
421
- function addEntitySelectTypes(sourceFile, tables, tableByName) {
422
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Entity Select Types');
644
+ function generateEntitySelectTypes(tables, tableByName) {
645
+ const statements = [];
423
646
  for (const table of tables) {
424
647
  const { typeName } = (0, utils_1.getTableNames)(table);
425
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(`${typeName}Select`, buildSelectTypeBody(table, tableByName)));
648
+ const typeAlias = t.tsTypeAliasDeclaration(t.identifier(`${typeName}Select`), null, buildSelectTypeLiteral(table, tableByName));
649
+ statements.push(t.exportNamedDeclaration(typeAlias));
650
+ }
651
+ if (statements.length > 0) {
652
+ addSectionComment(statements, 'Entity Select Types');
426
653
  }
654
+ return statements;
427
655
  }
428
656
  // ============================================================================
429
657
  // Table Filter Types Generator (AST-based)
@@ -454,14 +682,18 @@ function buildTableFilterProperties(table) {
454
682
  return properties;
455
683
  }
456
684
  /**
457
- * Add table filter types
685
+ * Generate table filter type statements
458
686
  */
459
- function addTableFilterTypes(sourceFile, tables) {
460
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Table Filter Types');
687
+ function generateTableFilterTypes(tables) {
688
+ const statements = [];
461
689
  for (const table of tables) {
462
690
  const filterName = (0, utils_1.getFilterTypeName)(table);
463
- sourceFile.addInterface((0, ts_ast_1.createInterface)(filterName, buildTableFilterProperties(table)));
691
+ statements.push(createExportedInterface(filterName, buildTableFilterProperties(table)));
692
+ }
693
+ if (statements.length > 0) {
694
+ addSectionComment(statements, 'Table Filter Types');
464
695
  }
696
+ return statements;
465
697
  }
466
698
  // ============================================================================
467
699
  // Condition Types Generator (AST-based)
@@ -487,22 +719,26 @@ function buildTableConditionProperties(table) {
487
719
  return properties;
488
720
  }
489
721
  /**
490
- * Add table condition types
722
+ * Generate table condition type statements
491
723
  */
492
- function addTableConditionTypes(sourceFile, tables) {
493
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Table Condition Types');
724
+ function generateTableConditionTypes(tables) {
725
+ const statements = [];
494
726
  for (const table of tables) {
495
727
  const conditionName = (0, utils_1.getConditionTypeName)(table);
496
- sourceFile.addInterface((0, ts_ast_1.createInterface)(conditionName, buildTableConditionProperties(table)));
728
+ statements.push(createExportedInterface(conditionName, buildTableConditionProperties(table)));
497
729
  }
730
+ if (statements.length > 0) {
731
+ addSectionComment(statements, 'Table Condition Types');
732
+ }
733
+ return statements;
498
734
  }
499
735
  // ============================================================================
500
736
  // OrderBy Types Generator (AST-based)
501
737
  // ============================================================================
502
738
  /**
503
- * Build OrderBy union type string
739
+ * Build OrderBy union type values
504
740
  */
505
- function buildOrderByUnion(table) {
741
+ function buildOrderByValues(table) {
506
742
  const values = ['PRIMARY_KEY_ASC', 'PRIMARY_KEY_DESC', 'NATURAL'];
507
743
  for (const field of table.fields) {
508
744
  if ((0, utils_1.isRelationField)(field.name, table))
@@ -511,19 +747,24 @@ function buildOrderByUnion(table) {
511
747
  values.push(`${upperSnake}_ASC`);
512
748
  values.push(`${upperSnake}_DESC`);
513
749
  }
514
- return values.map((v) => `'${v}'`).join(' | ');
750
+ return values;
515
751
  }
516
752
  /**
517
- * Add OrderBy types
518
- * Uses inflection from table metadata for correct pluralization
753
+ * Generate OrderBy type statements
519
754
  */
520
- function addOrderByTypes(sourceFile, tables) {
521
- (0, ts_ast_1.addSectionComment)(sourceFile, 'OrderBy Types');
755
+ function generateOrderByTypes(tables) {
756
+ const statements = [];
522
757
  for (const table of tables) {
523
- // Use getOrderByTypeName which respects table.inflection.orderByType
524
758
  const enumName = (0, utils_1.getOrderByTypeName)(table);
525
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(enumName, buildOrderByUnion(table)));
759
+ const values = buildOrderByValues(table);
760
+ const unionType = createStringLiteralUnion(values);
761
+ const typeAlias = t.tsTypeAliasDeclaration(t.identifier(enumName), null, unionType);
762
+ statements.push(t.exportNamedDeclaration(typeAlias));
763
+ }
764
+ if (statements.length > 0) {
765
+ addSectionComment(statements, 'OrderBy Types');
526
766
  }
767
+ return statements;
527
768
  }
528
769
  // ============================================================================
529
770
  // CRUD Input Types Generator (AST-based)
@@ -546,27 +787,30 @@ function buildCreateDataFields(table) {
546
787
  return fields;
547
788
  }
548
789
  /**
549
- * Generate Create input interface as formatted string.
550
- *
551
- * ts-morph doesn't handle nested object types in interface properties well,
552
- * so we build this manually with pre-doubled indentation (4→2, 8→4) since
553
- * getMinimalFormattedOutput halves all indentation.
790
+ * Build Create input interface as AST
554
791
  */
555
792
  function buildCreateInputInterface(table) {
556
793
  const { typeName, singularName } = (0, utils_1.getTableNames)(table);
557
794
  const fields = buildCreateDataFields(table);
558
- const lines = [
559
- `export interface Create${typeName}Input {`,
560
- ` clientMutationId?: string;`,
561
- ` ${singularName}: {`,
795
+ // Build the nested object type for the entity data
796
+ const nestedProps = fields.map((field) => {
797
+ const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(parseTypeString(field.type)));
798
+ prop.optional = field.optional;
799
+ return prop;
800
+ });
801
+ const nestedObjectType = t.tsTypeLiteral(nestedProps);
802
+ // Build the main interface properties
803
+ const mainProps = [
804
+ (() => {
805
+ const prop = t.tsPropertySignature(t.identifier('clientMutationId'), t.tsTypeAnnotation(t.tsStringKeyword()));
806
+ prop.optional = true;
807
+ return prop;
808
+ })(),
809
+ t.tsPropertySignature(t.identifier(singularName), t.tsTypeAnnotation(nestedObjectType)),
562
810
  ];
563
- for (const field of fields) {
564
- const opt = field.optional ? '?' : '';
565
- lines.push(` ${field.name}${opt}: ${field.type};`);
566
- }
567
- lines.push(' };');
568
- lines.push('}');
569
- return lines.join('\n');
811
+ const body = t.tsInterfaceBody(mainProps);
812
+ const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(`Create${typeName}Input`), null, null, body);
813
+ return t.exportNamedDeclaration(interfaceDecl);
570
814
  }
571
815
  /**
572
816
  * Build Patch type properties
@@ -589,35 +833,41 @@ function buildPatchProperties(table) {
589
833
  return properties;
590
834
  }
591
835
  /**
592
- * Add CRUD input types for a table
836
+ * Generate CRUD input type statements for a table
593
837
  */
594
- function addCrudInputTypes(sourceFile, table) {
838
+ function generateCrudInputTypes(table) {
839
+ const statements = [];
595
840
  const { typeName } = (0, utils_1.getTableNames)(table);
596
841
  const patchName = `${typeName}Patch`;
597
- // Create input - build as raw statement due to nested object type formatting
598
- sourceFile.addStatements(buildCreateInputInterface(table));
842
+ // Create input
843
+ statements.push(buildCreateInputInterface(table));
599
844
  // Patch interface
600
- sourceFile.addInterface((0, ts_ast_1.createInterface)(patchName, buildPatchProperties(table)));
845
+ statements.push(createExportedInterface(patchName, buildPatchProperties(table)));
601
846
  // Update input
602
- sourceFile.addInterface((0, ts_ast_1.createInterface)(`Update${typeName}Input`, [
847
+ statements.push(createExportedInterface(`Update${typeName}Input`, [
603
848
  { name: 'clientMutationId', type: 'string', optional: true },
604
849
  { name: 'id', type: 'string', optional: false },
605
850
  { name: 'patch', type: patchName, optional: false },
606
851
  ]));
607
852
  // Delete input
608
- sourceFile.addInterface((0, ts_ast_1.createInterface)(`Delete${typeName}Input`, [
853
+ statements.push(createExportedInterface(`Delete${typeName}Input`, [
609
854
  { name: 'clientMutationId', type: 'string', optional: true },
610
855
  { name: 'id', type: 'string', optional: false },
611
856
  ]));
857
+ return statements;
612
858
  }
613
859
  /**
614
- * Add all CRUD input types
860
+ * Generate all CRUD input type statements
615
861
  */
616
- function addAllCrudInputTypes(sourceFile, tables) {
617
- (0, ts_ast_1.addSectionComment)(sourceFile, 'CRUD Input Types');
862
+ function generateAllCrudInputTypes(tables) {
863
+ const statements = [];
618
864
  for (const table of tables) {
619
- addCrudInputTypes(sourceFile, table);
865
+ statements.push(...generateCrudInputTypes(table));
620
866
  }
867
+ if (statements.length > 0) {
868
+ addSectionComment(statements, 'CRUD Input Types');
869
+ }
870
+ return statements;
621
871
  }
622
872
  // ============================================================================
623
873
  // Custom Input Types Generator (AST-based)
@@ -645,7 +895,7 @@ function collectInputTypeNames(operations) {
645
895
  }
646
896
  /**
647
897
  * Build a set of exact table CRUD input type names to skip
648
- * These are generated by addAllCrudInputTypes, so we don't need to regenerate them
898
+ * These are generated by generateAllCrudInputTypes, so we don't need to regenerate them
649
899
  */
650
900
  function buildTableCrudTypeNames(tables) {
651
901
  const crudTypes = new Set();
@@ -660,10 +910,10 @@ function buildTableCrudTypeNames(tables) {
660
910
  return crudTypes;
661
911
  }
662
912
  /**
663
- * Add custom input types from TypeRegistry
913
+ * Generate custom input type statements from TypeRegistry
664
914
  */
665
- function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrudTypes) {
666
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Custom Input Types (from schema)');
915
+ function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes) {
916
+ const statements = [];
667
917
  const generatedTypes = new Set();
668
918
  const typesToGenerate = new Set(Array.from(usedInputTypes));
669
919
  // Filter out types we've already generated (exact matches for table CRUD types only)
@@ -686,8 +936,11 @@ function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrud
686
936
  generatedTypes.add(typeName);
687
937
  const typeInfo = typeRegistry.get(typeName);
688
938
  if (!typeInfo) {
689
- sourceFile.addStatements(`// Type '${typeName}' not found in schema`);
690
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(typeName, 'Record<string, unknown>'));
939
+ // Add comment for missing type
940
+ const commentStmt = t.emptyStatement();
941
+ (0, babel_ast_1.addLineComment)(commentStmt, ` Type '${typeName}' not found in schema`);
942
+ statements.push(commentStmt);
943
+ statements.push(createExportedTypeAlias(typeName, 'Record<string, unknown>'));
691
944
  continue;
692
945
  }
693
946
  if (typeInfo.kind === 'INPUT_OBJECT' && typeInfo.inputFields) {
@@ -704,17 +957,25 @@ function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrud
704
957
  typesToGenerate.add(baseType);
705
958
  }
706
959
  }
707
- sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, properties));
960
+ statements.push(createExportedInterface(typeName, properties));
708
961
  }
709
962
  else if (typeInfo.kind === 'ENUM' && typeInfo.enumValues) {
710
- const values = typeInfo.enumValues.map((v) => `'${v}'`).join(' | ');
711
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(typeName, values));
963
+ const unionType = createStringLiteralUnion(typeInfo.enumValues);
964
+ const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
965
+ statements.push(t.exportNamedDeclaration(typeAlias));
712
966
  }
713
967
  else {
714
- sourceFile.addStatements(`// Type '${typeName}' is ${typeInfo.kind}`);
715
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(typeName, 'unknown'));
968
+ // Add comment for unsupported type kind
969
+ const commentStmt = t.emptyStatement();
970
+ (0, babel_ast_1.addLineComment)(commentStmt, ` Type '${typeName}' is ${typeInfo.kind}`);
971
+ statements.push(commentStmt);
972
+ statements.push(createExportedTypeAlias(typeName, 'unknown'));
716
973
  }
717
974
  }
975
+ if (statements.length > 0) {
976
+ addSectionComment(statements, 'Custom Input Types (from schema)');
977
+ }
978
+ return statements;
718
979
  }
719
980
  // ============================================================================
720
981
  // Payload/Return Types Generator (AST-based)
@@ -734,10 +995,10 @@ function collectPayloadTypeNames(operations) {
734
995
  return payloadTypes;
735
996
  }
736
997
  /**
737
- * Add payload/return types
998
+ * Generate payload/return type statements
738
999
  */
739
- function addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGeneratedTypes) {
740
- (0, ts_ast_1.addSectionComment)(sourceFile, 'Payload/Return Types (for custom operations)');
1000
+ function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes) {
1001
+ const statements = [];
741
1002
  const generatedTypes = new Set(alreadyGeneratedTypes);
742
1003
  const typesToGenerate = new Set(Array.from(usedPayloadTypes));
743
1004
  const skipTypes = new Set([
@@ -795,63 +1056,77 @@ function addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGene
795
1056
  }
796
1057
  }
797
1058
  }
798
- sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, interfaceProps));
799
- // Build Select type (no indentation - ts-morph adds it)
800
- const selectLines = ['{'];
1059
+ statements.push(createExportedInterface(typeName, interfaceProps));
1060
+ // Build Select type
1061
+ const selectMembers = [];
801
1062
  for (const field of typeInfo.fields) {
802
1063
  const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
803
1064
  if (baseType === 'Query' || baseType === 'Mutation')
804
1065
  continue;
805
1066
  const nestedType = baseType ? typeRegistry.get(baseType) : null;
1067
+ let propType;
806
1068
  if (nestedType?.kind === 'OBJECT') {
807
- selectLines.push(`${field.name}?: boolean | { select?: ${baseType}Select };`);
1069
+ propType = t.tsUnionType([
1070
+ t.tsBooleanKeyword(),
1071
+ t.tsTypeLiteral([
1072
+ (() => {
1073
+ const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${baseType}Select`))));
1074
+ p.optional = true;
1075
+ return p;
1076
+ })(),
1077
+ ]),
1078
+ ]);
808
1079
  }
809
1080
  else {
810
- selectLines.push(`${field.name}?: boolean;`);
1081
+ propType = t.tsBooleanKeyword();
811
1082
  }
1083
+ const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(propType));
1084
+ prop.optional = true;
1085
+ selectMembers.push(prop);
812
1086
  }
813
- selectLines.push('}');
814
- sourceFile.addTypeAlias((0, ts_ast_1.createTypeAlias)(`${typeName}Select`, selectLines.join('\n')));
1087
+ const selectTypeAlias = t.tsTypeAliasDeclaration(t.identifier(`${typeName}Select`), null, t.tsTypeLiteral(selectMembers));
1088
+ statements.push(t.exportNamedDeclaration(selectTypeAlias));
1089
+ }
1090
+ if (statements.length > 0) {
1091
+ addSectionComment(statements, 'Payload/Return Types (for custom operations)');
815
1092
  }
1093
+ return statements;
816
1094
  }
817
1095
  // ============================================================================
818
1096
  // Main Generator (AST-based)
819
1097
  // ============================================================================
820
1098
  /**
821
- * Generate comprehensive input-types.ts file using ts-morph AST
1099
+ * Generate comprehensive input-types.ts file using Babel AST
822
1100
  */
823
1101
  function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes) {
824
- const project = (0, ts_ast_1.createProject)();
825
- const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'input-types.ts');
826
- // Add file header
827
- sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('GraphQL types for ORM client') + '\n');
1102
+ const statements = [];
828
1103
  // 1. Scalar filter types
829
- addScalarFilterTypes(sourceFile);
1104
+ statements.push(...generateScalarFilterTypes());
830
1105
  // 2. Enum types used by table fields
831
1106
  if (tables && tables.length > 0) {
832
1107
  const enumTypes = collectEnumTypesFromTables(tables, typeRegistry);
833
- addEnumTypes(sourceFile, typeRegistry, enumTypes);
1108
+ statements.push(...generateEnumTypes(typeRegistry, enumTypes));
834
1109
  }
835
1110
  // 3. Entity and relation types (if tables provided)
836
1111
  if (tables && tables.length > 0) {
837
1112
  const tableByName = new Map(tables.map((table) => [table.name, table]));
838
- addEntityTypes(sourceFile, tables);
839
- addRelationHelperTypes(sourceFile);
840
- addEntityRelationTypes(sourceFile, tables, tableByName);
841
- addEntityWithRelations(sourceFile, tables);
842
- addEntitySelectTypes(sourceFile, tables, tableByName);
1113
+ statements.push(...generateEntityTypes(tables));
1114
+ statements.push(...generateRelationHelperTypes());
1115
+ statements.push(...generateEntityRelationTypes(tables, tableByName));
1116
+ statements.push(...generateEntityWithRelations(tables));
1117
+ statements.push(...generateEntitySelectTypes(tables, tableByName));
843
1118
  // 4. Table filter types
844
- addTableFilterTypes(sourceFile, tables);
1119
+ statements.push(...generateTableFilterTypes(tables));
845
1120
  // 4b. Table condition types (simple equality filter)
846
- addTableConditionTypes(sourceFile, tables);
1121
+ statements.push(...generateTableConditionTypes(tables));
847
1122
  // 5. OrderBy types
848
- addOrderByTypes(sourceFile, tables);
1123
+ statements.push(...generateOrderByTypes(tables));
849
1124
  // 6. CRUD input types
850
- addAllCrudInputTypes(sourceFile, tables);
1125
+ statements.push(...generateAllCrudInputTypes(tables));
851
1126
  }
852
1127
  // 7. Custom input types from TypeRegistry
853
1128
  const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined;
854
- addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrudTypes);
1129
+ statements.push(...generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes));
855
1130
  // 8. Payload/return types for custom operations
856
1131
  if (usedPayloadTypes && usedPayloadTypes.size > 0) {
857
1132
  const alreadyGeneratedTypes = new Set();
@@ -861,10 +1136,13 @@ function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloa
861
1136
  alreadyGeneratedTypes.add(typeName);
862
1137
  }
863
1138
  }
864
- addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGeneratedTypes);
1139
+ statements.push(...generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes));
865
1140
  }
1141
+ // Generate code with file header
1142
+ const header = (0, utils_1.getGeneratedFileHeader)('GraphQL types for ORM client');
1143
+ const code = (0, babel_ast_1.generateCode)(statements);
866
1144
  return {
867
1145
  fileName: 'input-types.ts',
868
- content: (0, ts_ast_1.getMinimalFormattedOutput)(sourceFile),
1146
+ content: header + '\n' + code,
869
1147
  };
870
1148
  }