@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,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
|
|
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
|
-
*
|
|
298
|
+
* Generate scalar filter type statements
|
|
163
299
|
*/
|
|
164
|
-
function
|
|
165
|
-
|
|
300
|
+
function generateScalarFilterTypes() {
|
|
301
|
+
const statements = [];
|
|
166
302
|
for (const config of SCALAR_FILTER_CONFIGS) {
|
|
167
|
-
|
|
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
|
-
*
|
|
335
|
+
* Generate enum type statements
|
|
198
336
|
*/
|
|
199
|
-
function
|
|
337
|
+
function generateEnumTypes(typeRegistry, enumTypeNames) {
|
|
200
338
|
if (enumTypeNames.size === 0)
|
|
201
|
-
return;
|
|
202
|
-
|
|
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
|
|
208
|
-
|
|
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
|
-
*
|
|
377
|
+
* Generate entity type statements
|
|
235
378
|
*/
|
|
236
|
-
function
|
|
237
|
-
const
|
|
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
|
-
|
|
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
|
-
*
|
|
394
|
+
* Generate relation helper type statements (ConnectionResult, PageInfo)
|
|
254
395
|
*/
|
|
255
|
-
function
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
-
*
|
|
490
|
+
* Generate entity relation type statements
|
|
341
491
|
*/
|
|
342
|
-
function
|
|
343
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
504
|
+
* Generate entity types with relations (intersection types)
|
|
351
505
|
*/
|
|
352
|
-
function
|
|
353
|
-
|
|
506
|
+
function generateEntityWithRelations(tables) {
|
|
507
|
+
const statements = [];
|
|
354
508
|
for (const table of tables) {
|
|
355
509
|
const { typeName } = (0, utils_1.getTableNames)(table);
|
|
356
|
-
|
|
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
|
|
521
|
+
* Build the Select type as a TSTypeLiteral
|
|
364
522
|
*/
|
|
365
|
-
function
|
|
366
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
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
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
-
|
|
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
|
-
|
|
416
|
-
return lines.join('\n');
|
|
639
|
+
return t.tsTypeLiteral(members);
|
|
417
640
|
}
|
|
418
641
|
/**
|
|
419
|
-
*
|
|
642
|
+
* Generate entity Select type statements
|
|
420
643
|
*/
|
|
421
|
-
function
|
|
422
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
685
|
+
* Generate table filter type statements
|
|
458
686
|
*/
|
|
459
|
-
function
|
|
460
|
-
|
|
687
|
+
function generateTableFilterTypes(tables) {
|
|
688
|
+
const statements = [];
|
|
461
689
|
for (const table of tables) {
|
|
462
690
|
const filterName = (0, utils_1.getFilterTypeName)(table);
|
|
463
|
-
|
|
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
|
-
*
|
|
722
|
+
* Generate table condition type statements
|
|
491
723
|
*/
|
|
492
|
-
function
|
|
493
|
-
|
|
724
|
+
function generateTableConditionTypes(tables) {
|
|
725
|
+
const statements = [];
|
|
494
726
|
for (const table of tables) {
|
|
495
727
|
const conditionName = (0, utils_1.getConditionTypeName)(table);
|
|
496
|
-
|
|
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
|
|
739
|
+
* Build OrderBy union type values
|
|
504
740
|
*/
|
|
505
|
-
function
|
|
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
|
|
750
|
+
return values;
|
|
515
751
|
}
|
|
516
752
|
/**
|
|
517
|
-
*
|
|
518
|
-
* Uses inflection from table metadata for correct pluralization
|
|
753
|
+
* Generate OrderBy type statements
|
|
519
754
|
*/
|
|
520
|
-
function
|
|
521
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
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
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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
|
-
*
|
|
836
|
+
* Generate CRUD input type statements for a table
|
|
593
837
|
*/
|
|
594
|
-
function
|
|
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
|
|
598
|
-
|
|
842
|
+
// Create input
|
|
843
|
+
statements.push(buildCreateInputInterface(table));
|
|
599
844
|
// Patch interface
|
|
600
|
-
|
|
845
|
+
statements.push(createExportedInterface(patchName, buildPatchProperties(table)));
|
|
601
846
|
// Update input
|
|
602
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
860
|
+
* Generate all CRUD input type statements
|
|
615
861
|
*/
|
|
616
|
-
function
|
|
617
|
-
|
|
862
|
+
function generateAllCrudInputTypes(tables) {
|
|
863
|
+
const statements = [];
|
|
618
864
|
for (const table of tables) {
|
|
619
|
-
|
|
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
|
|
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
|
-
*
|
|
913
|
+
* Generate custom input type statements from TypeRegistry
|
|
664
914
|
*/
|
|
665
|
-
function
|
|
666
|
-
|
|
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
|
-
|
|
690
|
-
|
|
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
|
-
|
|
960
|
+
statements.push(createExportedInterface(typeName, properties));
|
|
708
961
|
}
|
|
709
962
|
else if (typeInfo.kind === 'ENUM' && typeInfo.enumValues) {
|
|
710
|
-
const
|
|
711
|
-
|
|
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
|
-
|
|
715
|
-
|
|
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
|
-
*
|
|
998
|
+
* Generate payload/return type statements
|
|
738
999
|
*/
|
|
739
|
-
function
|
|
740
|
-
|
|
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
|
-
|
|
799
|
-
// Build Select type
|
|
800
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
814
|
-
|
|
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
|
|
1099
|
+
* Generate comprehensive input-types.ts file using Babel AST
|
|
822
1100
|
*/
|
|
823
1101
|
function generateInputTypesFile(typeRegistry, usedInputTypes, tables, usedPayloadTypes) {
|
|
824
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
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
|
-
|
|
1119
|
+
statements.push(...generateTableFilterTypes(tables));
|
|
845
1120
|
// 4b. Table condition types (simple equality filter)
|
|
846
|
-
|
|
1121
|
+
statements.push(...generateTableConditionTypes(tables));
|
|
847
1122
|
// 5. OrderBy types
|
|
848
|
-
|
|
1123
|
+
statements.push(...generateOrderByTypes(tables));
|
|
849
1124
|
// 6. CRUD input types
|
|
850
|
-
|
|
1125
|
+
statements.push(...generateAllCrudInputTypes(tables));
|
|
851
1126
|
}
|
|
852
1127
|
// 7. Custom input types from TypeRegistry
|
|
853
1128
|
const tableCrudTypes = tables ? buildTableCrudTypeNames(tables) : undefined;
|
|
854
|
-
|
|
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
|
-
|
|
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:
|
|
1146
|
+
content: header + '\n' + code,
|
|
869
1147
|
};
|
|
870
1148
|
}
|