@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.
- package/README.md +147 -2
- package/cli/codegen/babel-ast.d.ts +53 -0
- package/cli/codegen/babel-ast.js +160 -0
- package/cli/codegen/barrel.d.ts +7 -2
- package/cli/codegen/barrel.js +193 -102
- package/cli/codegen/client.js +61 -0
- package/cli/codegen/custom-mutations.d.ts +2 -12
- package/cli/codegen/custom-mutations.js +116 -124
- package/cli/codegen/custom-queries.d.ts +2 -10
- package/cli/codegen/custom-queries.js +236 -335
- package/cli/codegen/gql-ast.js +22 -1
- package/cli/codegen/index.d.ts +3 -0
- package/cli/codegen/index.js +73 -3
- package/cli/codegen/invalidation.d.ts +20 -0
- package/cli/codegen/invalidation.js +327 -0
- package/cli/codegen/mutation-keys.d.ts +24 -0
- package/cli/codegen/mutation-keys.js +247 -0
- package/cli/codegen/mutations.d.ts +5 -19
- package/cli/codegen/mutations.js +385 -383
- package/cli/codegen/orm/barrel.d.ts +1 -1
- package/cli/codegen/orm/barrel.js +42 -10
- package/cli/codegen/orm/client-generator.d.ts +1 -19
- package/cli/codegen/orm/client-generator.js +108 -77
- package/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
- package/cli/codegen/orm/custom-ops-generator.js +192 -235
- package/cli/codegen/orm/input-types-generator.d.ts +13 -1
- package/cli/codegen/orm/input-types-generator.js +425 -147
- package/cli/codegen/orm/model-generator.d.ts +1 -19
- package/cli/codegen/orm/model-generator.js +229 -234
- package/cli/codegen/queries.d.ts +4 -12
- package/cli/codegen/queries.js +660 -390
- package/cli/codegen/query-keys.d.ts +15 -0
- package/cli/codegen/query-keys.js +477 -0
- package/cli/codegen/scalars.js +1 -0
- package/cli/codegen/schema-types-generator.d.ts +15 -10
- package/cli/codegen/schema-types-generator.js +87 -175
- package/cli/codegen/type-resolver.d.ts +1 -30
- package/cli/codegen/type-resolver.js +0 -53
- package/cli/codegen/types.d.ts +1 -1
- package/cli/codegen/types.js +76 -21
- package/cli/codegen/utils.d.ts +6 -0
- package/cli/codegen/utils.js +19 -0
- package/esm/cli/codegen/babel-ast.d.ts +53 -0
- package/esm/cli/codegen/babel-ast.js +111 -0
- package/esm/cli/codegen/barrel.d.ts +7 -2
- package/esm/cli/codegen/barrel.js +161 -103
- package/esm/cli/codegen/client.js +61 -0
- package/esm/cli/codegen/custom-mutations.d.ts +2 -12
- package/esm/cli/codegen/custom-mutations.js +83 -124
- package/esm/cli/codegen/custom-queries.d.ts +2 -10
- package/esm/cli/codegen/custom-queries.js +204 -336
- package/esm/cli/codegen/gql-ast.js +23 -2
- package/esm/cli/codegen/index.d.ts +3 -0
- package/esm/cli/codegen/index.js +69 -2
- package/esm/cli/codegen/invalidation.d.ts +20 -0
- package/esm/cli/codegen/invalidation.js +291 -0
- package/esm/cli/codegen/mutation-keys.d.ts +24 -0
- package/esm/cli/codegen/mutation-keys.js +211 -0
- package/esm/cli/codegen/mutations.d.ts +5 -19
- package/esm/cli/codegen/mutations.js +353 -384
- package/esm/cli/codegen/orm/barrel.d.ts +1 -1
- package/esm/cli/codegen/orm/barrel.js +10 -11
- package/esm/cli/codegen/orm/client-generator.d.ts +1 -19
- package/esm/cli/codegen/orm/client-generator.js +76 -78
- package/esm/cli/codegen/orm/custom-ops-generator.d.ts +1 -12
- package/esm/cli/codegen/orm/custom-ops-generator.js +160 -236
- package/esm/cli/codegen/orm/input-types-generator.d.ts +13 -1
- package/esm/cli/codegen/orm/input-types-generator.js +393 -148
- package/esm/cli/codegen/orm/model-generator.d.ts +1 -19
- package/esm/cli/codegen/orm/model-generator.js +197 -235
- package/esm/cli/codegen/queries.d.ts +4 -12
- package/esm/cli/codegen/queries.js +628 -391
- package/esm/cli/codegen/query-keys.d.ts +15 -0
- package/esm/cli/codegen/query-keys.js +441 -0
- package/esm/cli/codegen/scalars.js +1 -0
- package/esm/cli/codegen/schema-types-generator.d.ts +15 -10
- package/esm/cli/codegen/schema-types-generator.js +54 -175
- package/esm/cli/codegen/type-resolver.d.ts +1 -30
- package/esm/cli/codegen/type-resolver.js +0 -49
- package/esm/cli/codegen/types.d.ts +1 -1
- package/esm/cli/codegen/types.js +44 -22
- package/esm/cli/codegen/utils.d.ts +6 -0
- package/esm/cli/codegen/utils.js +18 -0
- package/esm/types/config.d.ts +75 -0
- package/esm/types/config.js +18 -0
- package/package.json +6 -4
- package/types/config.d.ts +75 -0
- package/types/config.js +19 -1
- package/cli/codegen/ts-ast.d.ts +0 -124
- package/cli/codegen/ts-ast.js +0 -280
- package/esm/cli/codegen/ts-ast.d.ts +0 -124
- package/esm/cli/codegen/ts-ast.js +0 -260
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import * as t from '@babel/types';
|
|
2
|
+
import { generateCode, addLineComment } from '../babel-ast';
|
|
3
|
+
import { getTableNames, getFilterTypeName, getConditionTypeName, getOrderByTypeName, isRelationField, getGeneratedFileHeader, } from '../utils';
|
|
3
4
|
import { pluralize } from 'inflekt';
|
|
4
5
|
import { getTypeBaseName } from '../type-resolver';
|
|
5
6
|
import { scalarToTsType, scalarToFilterType } from '../scalars';
|
|
@@ -57,6 +58,86 @@ function typeRefToTs(typeRef) {
|
|
|
57
58
|
function isRequired(typeRef) {
|
|
58
59
|
return typeRef.kind === 'NON_NULL';
|
|
59
60
|
}
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// Babel AST Helper Functions
|
|
63
|
+
// ============================================================================
|
|
64
|
+
/**
|
|
65
|
+
* Parse a type string into a TSType node
|
|
66
|
+
*/
|
|
67
|
+
function parseTypeString(typeStr) {
|
|
68
|
+
// Handle union types like "string | null"
|
|
69
|
+
if (typeStr.includes(' | ')) {
|
|
70
|
+
const parts = typeStr.split(' | ').map((p) => p.trim());
|
|
71
|
+
return t.tsUnionType(parts.map((p) => parseTypeString(p)));
|
|
72
|
+
}
|
|
73
|
+
// Handle array types like "string[]"
|
|
74
|
+
if (typeStr.endsWith('[]')) {
|
|
75
|
+
const elementType = typeStr.slice(0, -2);
|
|
76
|
+
return t.tsArrayType(parseTypeString(elementType));
|
|
77
|
+
}
|
|
78
|
+
// Handle generic types like "Record<string, unknown>"
|
|
79
|
+
if (typeStr.includes('<')) {
|
|
80
|
+
const match = typeStr.match(/^([^<]+)<(.+)>$/);
|
|
81
|
+
if (match) {
|
|
82
|
+
const [, baseName, params] = match;
|
|
83
|
+
const typeParams = params.split(',').map((p) => parseTypeString(p.trim()));
|
|
84
|
+
return t.tsTypeReference(t.identifier(baseName), t.tsTypeParameterInstantiation(typeParams));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Handle primitive types
|
|
88
|
+
switch (typeStr) {
|
|
89
|
+
case 'string':
|
|
90
|
+
return t.tsStringKeyword();
|
|
91
|
+
case 'number':
|
|
92
|
+
return t.tsNumberKeyword();
|
|
93
|
+
case 'boolean':
|
|
94
|
+
return t.tsBooleanKeyword();
|
|
95
|
+
case 'null':
|
|
96
|
+
return t.tsNullKeyword();
|
|
97
|
+
case 'unknown':
|
|
98
|
+
return t.tsUnknownKeyword();
|
|
99
|
+
default:
|
|
100
|
+
return t.tsTypeReference(t.identifier(typeStr));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create an interface property signature
|
|
105
|
+
*/
|
|
106
|
+
function createPropertySignature(name, typeStr, optional) {
|
|
107
|
+
const prop = t.tsPropertySignature(t.identifier(name), t.tsTypeAnnotation(parseTypeString(typeStr)));
|
|
108
|
+
prop.optional = optional;
|
|
109
|
+
return prop;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Create an exported interface declaration
|
|
113
|
+
*/
|
|
114
|
+
function createExportedInterface(name, properties) {
|
|
115
|
+
const props = properties.map((p) => createPropertySignature(p.name, p.type, p.optional));
|
|
116
|
+
const body = t.tsInterfaceBody(props);
|
|
117
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(name), null, null, body);
|
|
118
|
+
return t.exportNamedDeclaration(interfaceDecl);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create an exported type alias declaration
|
|
122
|
+
*/
|
|
123
|
+
function createExportedTypeAlias(name, typeStr) {
|
|
124
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(name), null, parseTypeString(typeStr));
|
|
125
|
+
return t.exportNamedDeclaration(typeAlias);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Create a union type from string literals
|
|
129
|
+
*/
|
|
130
|
+
function createStringLiteralUnion(values) {
|
|
131
|
+
return t.tsUnionType(values.map((v) => t.tsLiteralType(t.stringLiteral(v))));
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Add a section comment to the first statement in an array
|
|
135
|
+
*/
|
|
136
|
+
function addSectionComment(statements, sectionName) {
|
|
137
|
+
if (statements.length > 0) {
|
|
138
|
+
addLineComment(statements[0], `============ ${sectionName} ============`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
60
141
|
/** Configuration for all scalar filter types - matches PostGraphile's generated filters */
|
|
61
142
|
const SCALAR_FILTER_CONFIGS = [
|
|
62
143
|
{
|
|
@@ -112,6 +193,22 @@ const SCALAR_FILTER_CONFIGS = [
|
|
|
112
193
|
operators: ['equality', 'distinct', 'inArray', 'comparison', 'inet'],
|
|
113
194
|
},
|
|
114
195
|
{ name: 'FullTextFilter', tsType: 'string', operators: ['fulltext'] },
|
|
196
|
+
// List filters (for array fields like string[], int[], uuid[])
|
|
197
|
+
{
|
|
198
|
+
name: 'StringListFilter',
|
|
199
|
+
tsType: 'string[]',
|
|
200
|
+
operators: ['equality', 'distinct', 'comparison', 'listArray'],
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
name: 'IntListFilter',
|
|
204
|
+
tsType: 'number[]',
|
|
205
|
+
operators: ['equality', 'distinct', 'comparison', 'listArray'],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: 'UUIDListFilter',
|
|
209
|
+
tsType: 'string[]',
|
|
210
|
+
operators: ['equality', 'distinct', 'comparison', 'listArray'],
|
|
211
|
+
},
|
|
115
212
|
];
|
|
116
213
|
/**
|
|
117
214
|
* Build filter properties based on operator sets
|
|
@@ -151,16 +248,24 @@ function buildScalarFilterProperties(config) {
|
|
|
151
248
|
if (operators.includes('fulltext')) {
|
|
152
249
|
props.push({ name: 'matches', type: 'string', optional: true });
|
|
153
250
|
}
|
|
251
|
+
// List/Array operators (contains, overlaps, anyEqualTo, etc.)
|
|
252
|
+
if (operators.includes('listArray')) {
|
|
253
|
+
// Extract base type from array type (e.g., 'string[]' -> 'string')
|
|
254
|
+
const baseType = tsType.replace('[]', '');
|
|
255
|
+
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 });
|
|
256
|
+
}
|
|
154
257
|
return props;
|
|
155
258
|
}
|
|
156
259
|
/**
|
|
157
|
-
*
|
|
260
|
+
* Generate scalar filter type statements
|
|
158
261
|
*/
|
|
159
|
-
function
|
|
160
|
-
|
|
262
|
+
function generateScalarFilterTypes() {
|
|
263
|
+
const statements = [];
|
|
161
264
|
for (const config of SCALAR_FILTER_CONFIGS) {
|
|
162
|
-
|
|
265
|
+
statements.push(createExportedInterface(config.name, buildScalarFilterProperties(config)));
|
|
163
266
|
}
|
|
267
|
+
addSectionComment(statements, 'Scalar Filter Types');
|
|
268
|
+
return statements;
|
|
164
269
|
}
|
|
165
270
|
// ============================================================================
|
|
166
271
|
// Enum Types Collector
|
|
@@ -189,19 +294,24 @@ function collectEnumTypesFromTables(tables, typeRegistry) {
|
|
|
189
294
|
return enumTypes;
|
|
190
295
|
}
|
|
191
296
|
/**
|
|
192
|
-
*
|
|
297
|
+
* Generate enum type statements
|
|
193
298
|
*/
|
|
194
|
-
function
|
|
299
|
+
function generateEnumTypes(typeRegistry, enumTypeNames) {
|
|
195
300
|
if (enumTypeNames.size === 0)
|
|
196
|
-
return;
|
|
197
|
-
|
|
301
|
+
return [];
|
|
302
|
+
const statements = [];
|
|
198
303
|
for (const typeName of Array.from(enumTypeNames).sort()) {
|
|
199
304
|
const typeInfo = typeRegistry.get(typeName);
|
|
200
305
|
if (!typeInfo || typeInfo.kind !== 'ENUM' || !typeInfo.enumValues)
|
|
201
306
|
continue;
|
|
202
|
-
const
|
|
203
|
-
|
|
307
|
+
const unionType = createStringLiteralUnion(typeInfo.enumValues);
|
|
308
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
309
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
310
|
+
}
|
|
311
|
+
if (statements.length > 0) {
|
|
312
|
+
addSectionComment(statements, 'Enum Types');
|
|
204
313
|
}
|
|
314
|
+
return statements;
|
|
205
315
|
}
|
|
206
316
|
// ============================================================================
|
|
207
317
|
// Entity Types Generator (AST-based)
|
|
@@ -226,40 +336,47 @@ function buildEntityProperties(table) {
|
|
|
226
336
|
return properties;
|
|
227
337
|
}
|
|
228
338
|
/**
|
|
229
|
-
*
|
|
339
|
+
* Generate entity type statements
|
|
230
340
|
*/
|
|
231
|
-
function
|
|
232
|
-
const
|
|
233
|
-
sourceFile.addInterface(createInterface(typeName, buildEntityProperties(table)));
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Add all entity types
|
|
237
|
-
*/
|
|
238
|
-
function addEntityTypes(sourceFile, tables) {
|
|
239
|
-
addSectionComment(sourceFile, 'Entity Types');
|
|
341
|
+
function generateEntityTypes(tables) {
|
|
342
|
+
const statements = [];
|
|
240
343
|
for (const table of tables) {
|
|
241
|
-
|
|
344
|
+
const { typeName } = getTableNames(table);
|
|
345
|
+
statements.push(createExportedInterface(typeName, buildEntityProperties(table)));
|
|
346
|
+
}
|
|
347
|
+
if (statements.length > 0) {
|
|
348
|
+
addSectionComment(statements, 'Entity Types');
|
|
242
349
|
}
|
|
350
|
+
return statements;
|
|
243
351
|
}
|
|
244
352
|
// ============================================================================
|
|
245
353
|
// Relation Helper Types Generator (AST-based)
|
|
246
354
|
// ============================================================================
|
|
247
355
|
/**
|
|
248
|
-
*
|
|
356
|
+
* Generate relation helper type statements (ConnectionResult, PageInfo)
|
|
249
357
|
*/
|
|
250
|
-
function
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
358
|
+
function generateRelationHelperTypes() {
|
|
359
|
+
const statements = [];
|
|
360
|
+
// ConnectionResult<T> interface with type parameter
|
|
361
|
+
const connectionResultProps = [
|
|
362
|
+
createPropertySignature('nodes', 'T[]', false),
|
|
363
|
+
createPropertySignature('totalCount', 'number', false),
|
|
364
|
+
createPropertySignature('pageInfo', 'PageInfo', false),
|
|
365
|
+
];
|
|
366
|
+
const connectionResultBody = t.tsInterfaceBody(connectionResultProps);
|
|
367
|
+
const connectionResultDecl = t.tsInterfaceDeclaration(t.identifier('ConnectionResult'), t.tsTypeParameterDeclaration([
|
|
368
|
+
t.tsTypeParameter(null, null, 'T'),
|
|
369
|
+
]), null, connectionResultBody);
|
|
370
|
+
statements.push(t.exportNamedDeclaration(connectionResultDecl));
|
|
371
|
+
// PageInfo interface
|
|
372
|
+
statements.push(createExportedInterface('PageInfo', [
|
|
258
373
|
{ name: 'hasNextPage', type: 'boolean', optional: false },
|
|
259
374
|
{ name: 'hasPreviousPage', type: 'boolean', optional: false },
|
|
260
375
|
{ name: 'startCursor', type: 'string | null', optional: true },
|
|
261
376
|
{ name: 'endCursor', type: 'string | null', optional: true },
|
|
262
377
|
]));
|
|
378
|
+
addSectionComment(statements, 'Relation Helper Types');
|
|
379
|
+
return statements;
|
|
263
380
|
}
|
|
264
381
|
// ============================================================================
|
|
265
382
|
// Entity Relation Types Generator (AST-based)
|
|
@@ -332,44 +449,65 @@ function buildEntityRelationProperties(table, tableByName) {
|
|
|
332
449
|
return properties;
|
|
333
450
|
}
|
|
334
451
|
/**
|
|
335
|
-
*
|
|
452
|
+
* Generate entity relation type statements
|
|
336
453
|
*/
|
|
337
|
-
function
|
|
338
|
-
|
|
454
|
+
function generateEntityRelationTypes(tables, tableByName) {
|
|
455
|
+
const statements = [];
|
|
339
456
|
for (const table of tables) {
|
|
340
457
|
const { typeName } = getTableNames(table);
|
|
341
|
-
|
|
458
|
+
statements.push(createExportedInterface(`${typeName}Relations`, buildEntityRelationProperties(table, tableByName)));
|
|
342
459
|
}
|
|
460
|
+
if (statements.length > 0) {
|
|
461
|
+
addSectionComment(statements, 'Entity Relation Types');
|
|
462
|
+
}
|
|
463
|
+
return statements;
|
|
343
464
|
}
|
|
344
465
|
/**
|
|
345
|
-
*
|
|
466
|
+
* Generate entity types with relations (intersection types)
|
|
346
467
|
*/
|
|
347
|
-
function
|
|
348
|
-
|
|
468
|
+
function generateEntityWithRelations(tables) {
|
|
469
|
+
const statements = [];
|
|
349
470
|
for (const table of tables) {
|
|
350
471
|
const { typeName } = getTableNames(table);
|
|
351
|
-
|
|
472
|
+
statements.push(createExportedTypeAlias(`${typeName}WithRelations`, `${typeName} & ${typeName}Relations`));
|
|
473
|
+
}
|
|
474
|
+
if (statements.length > 0) {
|
|
475
|
+
addSectionComment(statements, 'Entity Types With Relations');
|
|
352
476
|
}
|
|
477
|
+
return statements;
|
|
353
478
|
}
|
|
354
479
|
// ============================================================================
|
|
355
480
|
// Entity Select Types Generator (AST-based)
|
|
356
481
|
// ============================================================================
|
|
357
482
|
/**
|
|
358
|
-
* Build the
|
|
483
|
+
* Build the Select type as a TSTypeLiteral
|
|
359
484
|
*/
|
|
360
|
-
function
|
|
361
|
-
const
|
|
485
|
+
function buildSelectTypeLiteral(table, tableByName) {
|
|
486
|
+
const members = [];
|
|
362
487
|
// Add scalar fields
|
|
363
488
|
for (const field of table.fields) {
|
|
364
489
|
if (!isRelationField(field.name, table)) {
|
|
365
|
-
|
|
490
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsBooleanKeyword()));
|
|
491
|
+
prop.optional = true;
|
|
492
|
+
members.push(prop);
|
|
366
493
|
}
|
|
367
494
|
}
|
|
368
495
|
// Add belongsTo relations
|
|
369
496
|
for (const relation of table.relations.belongsTo) {
|
|
370
497
|
if (relation.fieldName) {
|
|
371
498
|
const relatedTypeName = getRelatedTypeName(relation.referencesTable, tableByName);
|
|
372
|
-
|
|
499
|
+
const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
|
|
500
|
+
t.tsBooleanKeyword(),
|
|
501
|
+
t.tsTypeLiteral([
|
|
502
|
+
(() => {
|
|
503
|
+
const selectProp = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
|
|
504
|
+
selectProp.optional = true;
|
|
505
|
+
return selectProp;
|
|
506
|
+
})(),
|
|
507
|
+
]),
|
|
508
|
+
])));
|
|
509
|
+
prop.optional = true;
|
|
510
|
+
members.push(prop);
|
|
373
511
|
}
|
|
374
512
|
}
|
|
375
513
|
// Add hasMany relations
|
|
@@ -378,12 +516,33 @@ function buildSelectTypeBody(table, tableByName) {
|
|
|
378
516
|
const relatedTypeName = getRelatedTypeName(relation.referencedByTable, tableByName);
|
|
379
517
|
const filterName = getRelatedFilterName(relation.referencedByTable, tableByName);
|
|
380
518
|
const orderByName = getRelatedOrderByName(relation.referencedByTable, tableByName);
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
519
|
+
const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
|
|
520
|
+
t.tsBooleanKeyword(),
|
|
521
|
+
t.tsTypeLiteral([
|
|
522
|
+
(() => {
|
|
523
|
+
const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
|
|
524
|
+
p.optional = true;
|
|
525
|
+
return p;
|
|
526
|
+
})(),
|
|
527
|
+
(() => {
|
|
528
|
+
const p = t.tsPropertySignature(t.identifier('first'), t.tsTypeAnnotation(t.tsNumberKeyword()));
|
|
529
|
+
p.optional = true;
|
|
530
|
+
return p;
|
|
531
|
+
})(),
|
|
532
|
+
(() => {
|
|
533
|
+
const p = t.tsPropertySignature(t.identifier('filter'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(filterName))));
|
|
534
|
+
p.optional = true;
|
|
535
|
+
return p;
|
|
536
|
+
})(),
|
|
537
|
+
(() => {
|
|
538
|
+
const p = t.tsPropertySignature(t.identifier('orderBy'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier(orderByName)))));
|
|
539
|
+
p.optional = true;
|
|
540
|
+
return p;
|
|
541
|
+
})(),
|
|
542
|
+
]),
|
|
543
|
+
])));
|
|
544
|
+
prop.optional = true;
|
|
545
|
+
members.push(prop);
|
|
387
546
|
}
|
|
388
547
|
}
|
|
389
548
|
// Add manyToMany relations
|
|
@@ -392,33 +551,69 @@ function buildSelectTypeBody(table, tableByName) {
|
|
|
392
551
|
const relatedTypeName = getRelatedTypeName(relation.rightTable, tableByName);
|
|
393
552
|
const filterName = getRelatedFilterName(relation.rightTable, tableByName);
|
|
394
553
|
const orderByName = getRelatedOrderByName(relation.rightTable, tableByName);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
554
|
+
const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
|
|
555
|
+
t.tsBooleanKeyword(),
|
|
556
|
+
t.tsTypeLiteral([
|
|
557
|
+
(() => {
|
|
558
|
+
const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
|
|
559
|
+
p.optional = true;
|
|
560
|
+
return p;
|
|
561
|
+
})(),
|
|
562
|
+
(() => {
|
|
563
|
+
const p = t.tsPropertySignature(t.identifier('first'), t.tsTypeAnnotation(t.tsNumberKeyword()));
|
|
564
|
+
p.optional = true;
|
|
565
|
+
return p;
|
|
566
|
+
})(),
|
|
567
|
+
(() => {
|
|
568
|
+
const p = t.tsPropertySignature(t.identifier('filter'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(filterName))));
|
|
569
|
+
p.optional = true;
|
|
570
|
+
return p;
|
|
571
|
+
})(),
|
|
572
|
+
(() => {
|
|
573
|
+
const p = t.tsPropertySignature(t.identifier('orderBy'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier(orderByName)))));
|
|
574
|
+
p.optional = true;
|
|
575
|
+
return p;
|
|
576
|
+
})(),
|
|
577
|
+
]),
|
|
578
|
+
])));
|
|
579
|
+
prop.optional = true;
|
|
580
|
+
members.push(prop);
|
|
401
581
|
}
|
|
402
582
|
}
|
|
403
583
|
// Add hasOne relations
|
|
404
584
|
for (const relation of table.relations.hasOne) {
|
|
405
585
|
if (relation.fieldName) {
|
|
406
586
|
const relatedTypeName = getRelatedTypeName(relation.referencedByTable, tableByName);
|
|
407
|
-
|
|
587
|
+
const prop = t.tsPropertySignature(t.identifier(relation.fieldName), t.tsTypeAnnotation(t.tsUnionType([
|
|
588
|
+
t.tsBooleanKeyword(),
|
|
589
|
+
t.tsTypeLiteral([
|
|
590
|
+
(() => {
|
|
591
|
+
const selectProp = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${relatedTypeName}Select`))));
|
|
592
|
+
selectProp.optional = true;
|
|
593
|
+
return selectProp;
|
|
594
|
+
})(),
|
|
595
|
+
]),
|
|
596
|
+
])));
|
|
597
|
+
prop.optional = true;
|
|
598
|
+
members.push(prop);
|
|
408
599
|
}
|
|
409
600
|
}
|
|
410
|
-
|
|
411
|
-
return lines.join('\n');
|
|
601
|
+
return t.tsTypeLiteral(members);
|
|
412
602
|
}
|
|
413
603
|
/**
|
|
414
|
-
*
|
|
604
|
+
* Generate entity Select type statements
|
|
415
605
|
*/
|
|
416
|
-
function
|
|
417
|
-
|
|
606
|
+
function generateEntitySelectTypes(tables, tableByName) {
|
|
607
|
+
const statements = [];
|
|
418
608
|
for (const table of tables) {
|
|
419
609
|
const { typeName } = getTableNames(table);
|
|
420
|
-
|
|
610
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(`${typeName}Select`), null, buildSelectTypeLiteral(table, tableByName));
|
|
611
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
421
612
|
}
|
|
613
|
+
if (statements.length > 0) {
|
|
614
|
+
addSectionComment(statements, 'Entity Select Types');
|
|
615
|
+
}
|
|
616
|
+
return statements;
|
|
422
617
|
}
|
|
423
618
|
// ============================================================================
|
|
424
619
|
// Table Filter Types Generator (AST-based)
|
|
@@ -449,14 +644,18 @@ function buildTableFilterProperties(table) {
|
|
|
449
644
|
return properties;
|
|
450
645
|
}
|
|
451
646
|
/**
|
|
452
|
-
*
|
|
647
|
+
* Generate table filter type statements
|
|
453
648
|
*/
|
|
454
|
-
function
|
|
455
|
-
|
|
649
|
+
function generateTableFilterTypes(tables) {
|
|
650
|
+
const statements = [];
|
|
456
651
|
for (const table of tables) {
|
|
457
652
|
const filterName = getFilterTypeName(table);
|
|
458
|
-
|
|
653
|
+
statements.push(createExportedInterface(filterName, buildTableFilterProperties(table)));
|
|
654
|
+
}
|
|
655
|
+
if (statements.length > 0) {
|
|
656
|
+
addSectionComment(statements, 'Table Filter Types');
|
|
459
657
|
}
|
|
658
|
+
return statements;
|
|
460
659
|
}
|
|
461
660
|
// ============================================================================
|
|
462
661
|
// Condition Types Generator (AST-based)
|
|
@@ -482,22 +681,26 @@ function buildTableConditionProperties(table) {
|
|
|
482
681
|
return properties;
|
|
483
682
|
}
|
|
484
683
|
/**
|
|
485
|
-
*
|
|
684
|
+
* Generate table condition type statements
|
|
486
685
|
*/
|
|
487
|
-
function
|
|
488
|
-
|
|
686
|
+
function generateTableConditionTypes(tables) {
|
|
687
|
+
const statements = [];
|
|
489
688
|
for (const table of tables) {
|
|
490
689
|
const conditionName = getConditionTypeName(table);
|
|
491
|
-
|
|
690
|
+
statements.push(createExportedInterface(conditionName, buildTableConditionProperties(table)));
|
|
691
|
+
}
|
|
692
|
+
if (statements.length > 0) {
|
|
693
|
+
addSectionComment(statements, 'Table Condition Types');
|
|
492
694
|
}
|
|
695
|
+
return statements;
|
|
493
696
|
}
|
|
494
697
|
// ============================================================================
|
|
495
698
|
// OrderBy Types Generator (AST-based)
|
|
496
699
|
// ============================================================================
|
|
497
700
|
/**
|
|
498
|
-
* Build OrderBy union type
|
|
701
|
+
* Build OrderBy union type values
|
|
499
702
|
*/
|
|
500
|
-
function
|
|
703
|
+
function buildOrderByValues(table) {
|
|
501
704
|
const values = ['PRIMARY_KEY_ASC', 'PRIMARY_KEY_DESC', 'NATURAL'];
|
|
502
705
|
for (const field of table.fields) {
|
|
503
706
|
if (isRelationField(field.name, table))
|
|
@@ -506,19 +709,24 @@ function buildOrderByUnion(table) {
|
|
|
506
709
|
values.push(`${upperSnake}_ASC`);
|
|
507
710
|
values.push(`${upperSnake}_DESC`);
|
|
508
711
|
}
|
|
509
|
-
return values
|
|
712
|
+
return values;
|
|
510
713
|
}
|
|
511
714
|
/**
|
|
512
|
-
*
|
|
513
|
-
* Uses inflection from table metadata for correct pluralization
|
|
715
|
+
* Generate OrderBy type statements
|
|
514
716
|
*/
|
|
515
|
-
function
|
|
516
|
-
|
|
717
|
+
function generateOrderByTypes(tables) {
|
|
718
|
+
const statements = [];
|
|
517
719
|
for (const table of tables) {
|
|
518
|
-
// Use getOrderByTypeName which respects table.inflection.orderByType
|
|
519
720
|
const enumName = getOrderByTypeName(table);
|
|
520
|
-
|
|
721
|
+
const values = buildOrderByValues(table);
|
|
722
|
+
const unionType = createStringLiteralUnion(values);
|
|
723
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(enumName), null, unionType);
|
|
724
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
521
725
|
}
|
|
726
|
+
if (statements.length > 0) {
|
|
727
|
+
addSectionComment(statements, 'OrderBy Types');
|
|
728
|
+
}
|
|
729
|
+
return statements;
|
|
522
730
|
}
|
|
523
731
|
// ============================================================================
|
|
524
732
|
// CRUD Input Types Generator (AST-based)
|
|
@@ -541,27 +749,30 @@ function buildCreateDataFields(table) {
|
|
|
541
749
|
return fields;
|
|
542
750
|
}
|
|
543
751
|
/**
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
* ts-morph doesn't handle nested object types in interface properties well,
|
|
547
|
-
* so we build this manually with pre-doubled indentation (4→2, 8→4) since
|
|
548
|
-
* getMinimalFormattedOutput halves all indentation.
|
|
752
|
+
* Build Create input interface as AST
|
|
549
753
|
*/
|
|
550
754
|
function buildCreateInputInterface(table) {
|
|
551
755
|
const { typeName, singularName } = getTableNames(table);
|
|
552
756
|
const fields = buildCreateDataFields(table);
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
757
|
+
// Build the nested object type for the entity data
|
|
758
|
+
const nestedProps = fields.map((field) => {
|
|
759
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(parseTypeString(field.type)));
|
|
760
|
+
prop.optional = field.optional;
|
|
761
|
+
return prop;
|
|
762
|
+
});
|
|
763
|
+
const nestedObjectType = t.tsTypeLiteral(nestedProps);
|
|
764
|
+
// Build the main interface properties
|
|
765
|
+
const mainProps = [
|
|
766
|
+
(() => {
|
|
767
|
+
const prop = t.tsPropertySignature(t.identifier('clientMutationId'), t.tsTypeAnnotation(t.tsStringKeyword()));
|
|
768
|
+
prop.optional = true;
|
|
769
|
+
return prop;
|
|
770
|
+
})(),
|
|
771
|
+
t.tsPropertySignature(t.identifier(singularName), t.tsTypeAnnotation(nestedObjectType)),
|
|
557
772
|
];
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
}
|
|
562
|
-
lines.push(' };');
|
|
563
|
-
lines.push('}');
|
|
564
|
-
return lines.join('\n');
|
|
773
|
+
const body = t.tsInterfaceBody(mainProps);
|
|
774
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(`Create${typeName}Input`), null, null, body);
|
|
775
|
+
return t.exportNamedDeclaration(interfaceDecl);
|
|
565
776
|
}
|
|
566
777
|
/**
|
|
567
778
|
* Build Patch type properties
|
|
@@ -584,35 +795,41 @@ function buildPatchProperties(table) {
|
|
|
584
795
|
return properties;
|
|
585
796
|
}
|
|
586
797
|
/**
|
|
587
|
-
*
|
|
798
|
+
* Generate CRUD input type statements for a table
|
|
588
799
|
*/
|
|
589
|
-
function
|
|
800
|
+
function generateCrudInputTypes(table) {
|
|
801
|
+
const statements = [];
|
|
590
802
|
const { typeName } = getTableNames(table);
|
|
591
803
|
const patchName = `${typeName}Patch`;
|
|
592
|
-
// Create input
|
|
593
|
-
|
|
804
|
+
// Create input
|
|
805
|
+
statements.push(buildCreateInputInterface(table));
|
|
594
806
|
// Patch interface
|
|
595
|
-
|
|
807
|
+
statements.push(createExportedInterface(patchName, buildPatchProperties(table)));
|
|
596
808
|
// Update input
|
|
597
|
-
|
|
809
|
+
statements.push(createExportedInterface(`Update${typeName}Input`, [
|
|
598
810
|
{ name: 'clientMutationId', type: 'string', optional: true },
|
|
599
811
|
{ name: 'id', type: 'string', optional: false },
|
|
600
812
|
{ name: 'patch', type: patchName, optional: false },
|
|
601
813
|
]));
|
|
602
814
|
// Delete input
|
|
603
|
-
|
|
815
|
+
statements.push(createExportedInterface(`Delete${typeName}Input`, [
|
|
604
816
|
{ name: 'clientMutationId', type: 'string', optional: true },
|
|
605
817
|
{ name: 'id', type: 'string', optional: false },
|
|
606
818
|
]));
|
|
819
|
+
return statements;
|
|
607
820
|
}
|
|
608
821
|
/**
|
|
609
|
-
*
|
|
822
|
+
* Generate all CRUD input type statements
|
|
610
823
|
*/
|
|
611
|
-
function
|
|
612
|
-
|
|
824
|
+
function generateAllCrudInputTypes(tables) {
|
|
825
|
+
const statements = [];
|
|
613
826
|
for (const table of tables) {
|
|
614
|
-
|
|
827
|
+
statements.push(...generateCrudInputTypes(table));
|
|
615
828
|
}
|
|
829
|
+
if (statements.length > 0) {
|
|
830
|
+
addSectionComment(statements, 'CRUD Input Types');
|
|
831
|
+
}
|
|
832
|
+
return statements;
|
|
616
833
|
}
|
|
617
834
|
// ============================================================================
|
|
618
835
|
// Custom Input Types Generator (AST-based)
|
|
@@ -640,7 +857,7 @@ export function collectInputTypeNames(operations) {
|
|
|
640
857
|
}
|
|
641
858
|
/**
|
|
642
859
|
* Build a set of exact table CRUD input type names to skip
|
|
643
|
-
* These are generated by
|
|
860
|
+
* These are generated by generateAllCrudInputTypes, so we don't need to regenerate them
|
|
644
861
|
*/
|
|
645
862
|
function buildTableCrudTypeNames(tables) {
|
|
646
863
|
const crudTypes = new Set();
|
|
@@ -655,10 +872,10 @@ function buildTableCrudTypeNames(tables) {
|
|
|
655
872
|
return crudTypes;
|
|
656
873
|
}
|
|
657
874
|
/**
|
|
658
|
-
*
|
|
875
|
+
* Generate custom input type statements from TypeRegistry
|
|
659
876
|
*/
|
|
660
|
-
function
|
|
661
|
-
|
|
877
|
+
function generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes) {
|
|
878
|
+
const statements = [];
|
|
662
879
|
const generatedTypes = new Set();
|
|
663
880
|
const typesToGenerate = new Set(Array.from(usedInputTypes));
|
|
664
881
|
// Filter out types we've already generated (exact matches for table CRUD types only)
|
|
@@ -681,8 +898,11 @@ function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrud
|
|
|
681
898
|
generatedTypes.add(typeName);
|
|
682
899
|
const typeInfo = typeRegistry.get(typeName);
|
|
683
900
|
if (!typeInfo) {
|
|
684
|
-
|
|
685
|
-
|
|
901
|
+
// Add comment for missing type
|
|
902
|
+
const commentStmt = t.emptyStatement();
|
|
903
|
+
addLineComment(commentStmt, ` Type '${typeName}' not found in schema`);
|
|
904
|
+
statements.push(commentStmt);
|
|
905
|
+
statements.push(createExportedTypeAlias(typeName, 'Record<string, unknown>'));
|
|
686
906
|
continue;
|
|
687
907
|
}
|
|
688
908
|
if (typeInfo.kind === 'INPUT_OBJECT' && typeInfo.inputFields) {
|
|
@@ -699,17 +919,25 @@ function addCustomInputTypes(sourceFile, typeRegistry, usedInputTypes, tableCrud
|
|
|
699
919
|
typesToGenerate.add(baseType);
|
|
700
920
|
}
|
|
701
921
|
}
|
|
702
|
-
|
|
922
|
+
statements.push(createExportedInterface(typeName, properties));
|
|
703
923
|
}
|
|
704
924
|
else if (typeInfo.kind === 'ENUM' && typeInfo.enumValues) {
|
|
705
|
-
const
|
|
706
|
-
|
|
925
|
+
const unionType = createStringLiteralUnion(typeInfo.enumValues);
|
|
926
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
927
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
707
928
|
}
|
|
708
929
|
else {
|
|
709
|
-
|
|
710
|
-
|
|
930
|
+
// Add comment for unsupported type kind
|
|
931
|
+
const commentStmt = t.emptyStatement();
|
|
932
|
+
addLineComment(commentStmt, ` Type '${typeName}' is ${typeInfo.kind}`);
|
|
933
|
+
statements.push(commentStmt);
|
|
934
|
+
statements.push(createExportedTypeAlias(typeName, 'unknown'));
|
|
711
935
|
}
|
|
712
936
|
}
|
|
937
|
+
if (statements.length > 0) {
|
|
938
|
+
addSectionComment(statements, 'Custom Input Types (from schema)');
|
|
939
|
+
}
|
|
940
|
+
return statements;
|
|
713
941
|
}
|
|
714
942
|
// ============================================================================
|
|
715
943
|
// Payload/Return Types Generator (AST-based)
|
|
@@ -729,10 +957,10 @@ export function collectPayloadTypeNames(operations) {
|
|
|
729
957
|
return payloadTypes;
|
|
730
958
|
}
|
|
731
959
|
/**
|
|
732
|
-
*
|
|
960
|
+
* Generate payload/return type statements
|
|
733
961
|
*/
|
|
734
|
-
function
|
|
735
|
-
|
|
962
|
+
function generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes) {
|
|
963
|
+
const statements = [];
|
|
736
964
|
const generatedTypes = new Set(alreadyGeneratedTypes);
|
|
737
965
|
const typesToGenerate = new Set(Array.from(usedPayloadTypes));
|
|
738
966
|
const skipTypes = new Set([
|
|
@@ -790,63 +1018,77 @@ function addPayloadTypes(sourceFile, typeRegistry, usedPayloadTypes, alreadyGene
|
|
|
790
1018
|
}
|
|
791
1019
|
}
|
|
792
1020
|
}
|
|
793
|
-
|
|
794
|
-
// Build Select type
|
|
795
|
-
const
|
|
1021
|
+
statements.push(createExportedInterface(typeName, interfaceProps));
|
|
1022
|
+
// Build Select type
|
|
1023
|
+
const selectMembers = [];
|
|
796
1024
|
for (const field of typeInfo.fields) {
|
|
797
1025
|
const baseType = getTypeBaseName(field.type);
|
|
798
1026
|
if (baseType === 'Query' || baseType === 'Mutation')
|
|
799
1027
|
continue;
|
|
800
1028
|
const nestedType = baseType ? typeRegistry.get(baseType) : null;
|
|
1029
|
+
let propType;
|
|
801
1030
|
if (nestedType?.kind === 'OBJECT') {
|
|
802
|
-
|
|
1031
|
+
propType = t.tsUnionType([
|
|
1032
|
+
t.tsBooleanKeyword(),
|
|
1033
|
+
t.tsTypeLiteral([
|
|
1034
|
+
(() => {
|
|
1035
|
+
const p = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(`${baseType}Select`))));
|
|
1036
|
+
p.optional = true;
|
|
1037
|
+
return p;
|
|
1038
|
+
})(),
|
|
1039
|
+
]),
|
|
1040
|
+
]);
|
|
803
1041
|
}
|
|
804
1042
|
else {
|
|
805
|
-
|
|
1043
|
+
propType = t.tsBooleanKeyword();
|
|
806
1044
|
}
|
|
1045
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(propType));
|
|
1046
|
+
prop.optional = true;
|
|
1047
|
+
selectMembers.push(prop);
|
|
807
1048
|
}
|
|
808
|
-
|
|
809
|
-
|
|
1049
|
+
const selectTypeAlias = t.tsTypeAliasDeclaration(t.identifier(`${typeName}Select`), null, t.tsTypeLiteral(selectMembers));
|
|
1050
|
+
statements.push(t.exportNamedDeclaration(selectTypeAlias));
|
|
1051
|
+
}
|
|
1052
|
+
if (statements.length > 0) {
|
|
1053
|
+
addSectionComment(statements, 'Payload/Return Types (for custom operations)');
|
|
810
1054
|
}
|
|
1055
|
+
return statements;
|
|
811
1056
|
}
|
|
812
1057
|
// ============================================================================
|
|
813
1058
|
// Main Generator (AST-based)
|
|
814
1059
|
// ============================================================================
|
|
815
1060
|
/**
|
|
816
|
-
* Generate comprehensive input-types.ts file using
|
|
1061
|
+
* Generate comprehensive input-types.ts file using Babel AST
|
|
817
1062
|
*/
|
|
818
1063
|
export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes) {
|
|
819
|
-
const
|
|
820
|
-
const sourceFile = createSourceFile(project, 'input-types.ts');
|
|
821
|
-
// Add file header
|
|
822
|
-
sourceFile.insertText(0, createFileHeader('GraphQL types for ORM client') + '\n');
|
|
1064
|
+
const statements = [];
|
|
823
1065
|
// 1. Scalar filter types
|
|
824
|
-
|
|
1066
|
+
statements.push(...generateScalarFilterTypes());
|
|
825
1067
|
// 2. Enum types used by table fields
|
|
826
1068
|
if (tables && tables.length > 0) {
|
|
827
1069
|
const enumTypes = collectEnumTypesFromTables(tables, typeRegistry);
|
|
828
|
-
|
|
1070
|
+
statements.push(...generateEnumTypes(typeRegistry, enumTypes));
|
|
829
1071
|
}
|
|
830
1072
|
// 3. Entity and relation types (if tables provided)
|
|
831
1073
|
if (tables && tables.length > 0) {
|
|
832
1074
|
const tableByName = new Map(tables.map((table) => [table.name, table]));
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1075
|
+
statements.push(...generateEntityTypes(tables));
|
|
1076
|
+
statements.push(...generateRelationHelperTypes());
|
|
1077
|
+
statements.push(...generateEntityRelationTypes(tables, tableByName));
|
|
1078
|
+
statements.push(...generateEntityWithRelations(tables));
|
|
1079
|
+
statements.push(...generateEntitySelectTypes(tables, tableByName));
|
|
838
1080
|
// 4. Table filter types
|
|
839
|
-
|
|
1081
|
+
statements.push(...generateTableFilterTypes(tables));
|
|
840
1082
|
// 4b. Table condition types (simple equality filter)
|
|
841
|
-
|
|
1083
|
+
statements.push(...generateTableConditionTypes(tables));
|
|
842
1084
|
// 5. OrderBy types
|
|
843
|
-
|
|
1085
|
+
statements.push(...generateOrderByTypes(tables));
|
|
844
1086
|
// 6. CRUD input types
|
|
845
|
-
|
|
1087
|
+
statements.push(...generateAllCrudInputTypes(tables));
|
|
846
1088
|
}
|
|
847
1089
|
// 7. Custom input types from TypeRegistry
|
|
848
1090
|
const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined;
|
|
849
|
-
|
|
1091
|
+
statements.push(...generateCustomInputTypes(typeRegistry, usedInputTypes, tableCrudTypes));
|
|
850
1092
|
// 8. Payload/return types for custom operations
|
|
851
1093
|
if (usedPayloadTypes && usedPayloadTypes.size > 0) {
|
|
852
1094
|
const alreadyGeneratedTypes = new Set();
|
|
@@ -856,10 +1098,13 @@ export function generateInputTypesFile(typeRegistry, usedInputTypes, tables, use
|
|
|
856
1098
|
alreadyGeneratedTypes.add(typeName);
|
|
857
1099
|
}
|
|
858
1100
|
}
|
|
859
|
-
|
|
1101
|
+
statements.push(...generatePayloadTypes(typeRegistry, usedPayloadTypes, alreadyGeneratedTypes));
|
|
860
1102
|
}
|
|
1103
|
+
// Generate code with file header
|
|
1104
|
+
const header = getGeneratedFileHeader('GraphQL types for ORM client');
|
|
1105
|
+
const code = generateCode(statements);
|
|
861
1106
|
return {
|
|
862
1107
|
fileName: 'input-types.ts',
|
|
863
|
-
content:
|
|
1108
|
+
content: header + '\n' + code,
|
|
864
1109
|
};
|
|
865
1110
|
}
|