@constructive-io/graphql-codegen 2.23.2 → 2.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +147 -2
- package/cli/codegen/babel-ast.d.ts +46 -0
- package/cli/codegen/babel-ast.js +145 -0
- package/cli/codegen/barrel.d.ts +7 -2
- package/cli/codegen/barrel.js +159 -97
- 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 +246 -335
- package/cli/codegen/index.d.ts +3 -0
- package/cli/codegen/index.js +72 -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 +3 -19
- package/cli/codegen/mutations.js +372 -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 +403 -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 +3 -11
- package/cli/codegen/queries.js +582 -389
- 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/commands/generate.js +1 -0
- package/cli/index.js +1 -0
- package/esm/cli/codegen/babel-ast.d.ts +46 -0
- package/esm/cli/codegen/babel-ast.js +97 -0
- package/esm/cli/codegen/barrel.d.ts +7 -2
- package/esm/cli/codegen/barrel.js +126 -97
- 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 +214 -336
- package/esm/cli/codegen/index.d.ts +3 -0
- package/esm/cli/codegen/index.js +68 -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 +3 -19
- package/esm/cli/codegen/mutations.js +340 -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 +371 -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 +3 -11
- package/esm/cli/codegen/queries.js +550 -390
- 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/commands/generate.js +1 -0
- package/esm/cli/index.js +1 -0
- package/esm/types/config.d.ts +75 -0
- package/esm/types/config.js +19 -1
- package/package.json +6 -4
- package/types/config.d.ts +75 -0
- package/types/config.js +20 -2
- 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,18 +1,46 @@
|
|
|
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.generateSchemaTypesFile = generateSchemaTypesFile;
|
|
4
|
-
const
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const babel_ast_1 = require("./babel-ast");
|
|
5
39
|
const type_resolver_1 = require("./type-resolver");
|
|
6
40
|
const scalars_1 = require("./scalars");
|
|
7
|
-
|
|
8
|
-
// Constants
|
|
9
|
-
// ============================================================================
|
|
10
|
-
/**
|
|
11
|
-
* Types that should not be generated (scalars, built-ins, types generated elsewhere)
|
|
12
|
-
*/
|
|
41
|
+
const utils_1 = require("./utils");
|
|
13
42
|
const SKIP_TYPES = new Set([
|
|
14
43
|
...scalars_1.SCALAR_NAMES,
|
|
15
|
-
// GraphQL built-ins
|
|
16
44
|
'Query',
|
|
17
45
|
'Mutation',
|
|
18
46
|
'Subscription',
|
|
@@ -22,27 +50,9 @@ const SKIP_TYPES = new Set([
|
|
|
22
50
|
'__InputValue',
|
|
23
51
|
'__EnumValue',
|
|
24
52
|
'__Directive',
|
|
25
|
-
// Note: PageInfo and Cursor are NOT skipped - they're needed by Connection types
|
|
26
|
-
// Base filter types (generated in types.ts via filters.ts)
|
|
27
53
|
...scalars_1.BASE_FILTER_TYPE_NAMES,
|
|
28
54
|
]);
|
|
29
|
-
|
|
30
|
-
* Type name patterns to skip (regex patterns)
|
|
31
|
-
*
|
|
32
|
-
* Note: We intentionally DO NOT skip Connection, Edge, Filter, Patch, Condition,
|
|
33
|
-
* or OrderBy types because they may be referenced by custom operations.
|
|
34
|
-
* Previously Condition and OrderBy were skipped but they ARE needed for
|
|
35
|
-
* custom queries like `schemata`, `apiSchemata`, etc.
|
|
36
|
-
*/
|
|
37
|
-
const SKIP_TYPE_PATTERNS = [
|
|
38
|
-
// Currently no patterns are skipped - all types may be needed by custom operations
|
|
39
|
-
];
|
|
40
|
-
// ============================================================================
|
|
41
|
-
// Type Conversion Utilities
|
|
42
|
-
// ============================================================================
|
|
43
|
-
/**
|
|
44
|
-
* Convert a CleanTypeRef to TypeScript type string
|
|
45
|
-
*/
|
|
55
|
+
const SKIP_TYPE_PATTERNS = [];
|
|
46
56
|
function typeRefToTs(typeRef) {
|
|
47
57
|
if (typeRef.kind === 'NON_NULL') {
|
|
48
58
|
if (typeRef.ofType) {
|
|
@@ -56,48 +66,26 @@ function typeRefToTs(typeRef) {
|
|
|
56
66
|
}
|
|
57
67
|
return 'unknown[]';
|
|
58
68
|
}
|
|
59
|
-
// Scalar or named type
|
|
60
69
|
const name = typeRef.name ?? 'unknown';
|
|
61
70
|
return (0, scalars_1.scalarToTsType)(name, { unknownScalar: 'name' });
|
|
62
71
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Check if a type is required (NON_NULL)
|
|
65
|
-
*/
|
|
66
72
|
function isRequired(typeRef) {
|
|
67
73
|
return typeRef.kind === 'NON_NULL';
|
|
68
74
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Check if a type should be skipped
|
|
71
|
-
*/
|
|
72
75
|
function shouldSkipType(typeName, tableTypeNames) {
|
|
73
|
-
// Skip scalars and built-ins
|
|
74
76
|
if (SKIP_TYPES.has(typeName))
|
|
75
77
|
return true;
|
|
76
|
-
// Skip table entity types (already in types.ts)
|
|
77
78
|
if (tableTypeNames.has(typeName))
|
|
78
79
|
return true;
|
|
79
|
-
// Skip types matching patterns
|
|
80
80
|
for (const pattern of SKIP_TYPE_PATTERNS) {
|
|
81
81
|
if (pattern.test(typeName))
|
|
82
82
|
return true;
|
|
83
83
|
}
|
|
84
|
-
// Skip table-specific types that would conflict with inline types in table-based hooks.
|
|
85
|
-
// Note: Patch and CreateInput are now NOT exported from hooks (isExported: false),
|
|
86
|
-
// so we only skip Filter types here.
|
|
87
|
-
// The Filter and OrderBy types are generated inline (non-exported) by table query hooks,
|
|
88
|
-
// but schema-types should still generate them for custom operations that need them.
|
|
89
|
-
// Actually, we don't skip any table-based types now since hooks don't export them.
|
|
90
84
|
return false;
|
|
91
85
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// ============================================================================
|
|
95
|
-
/**
|
|
96
|
-
* Add ENUM types to source file
|
|
97
|
-
*/
|
|
98
|
-
function addEnumTypes(sourceFile, typeRegistry, tableTypeNames) {
|
|
86
|
+
function generateEnumTypes(typeRegistry, tableTypeNames) {
|
|
87
|
+
const statements = [];
|
|
99
88
|
const generatedTypes = new Set();
|
|
100
|
-
(0, ts_ast_1.addSectionComment)(sourceFile, 'Enum Types');
|
|
101
89
|
for (const [typeName, typeInfo] of typeRegistry) {
|
|
102
90
|
if (typeInfo.kind !== 'ENUM')
|
|
103
91
|
continue;
|
|
@@ -105,23 +93,17 @@ function addEnumTypes(sourceFile, typeRegistry, tableTypeNames) {
|
|
|
105
93
|
continue;
|
|
106
94
|
if (!typeInfo.enumValues || typeInfo.enumValues.length === 0)
|
|
107
95
|
continue;
|
|
108
|
-
const
|
|
109
|
-
|
|
96
|
+
const unionType = t.tsUnionType(typeInfo.enumValues.map((v) => t.tsLiteralType(t.stringLiteral(v))));
|
|
97
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
98
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
110
99
|
generatedTypes.add(typeName);
|
|
111
100
|
}
|
|
112
|
-
return generatedTypes;
|
|
101
|
+
return { statements, generatedTypes };
|
|
113
102
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
// ============================================================================
|
|
117
|
-
/**
|
|
118
|
-
* Add INPUT_OBJECT types to source file
|
|
119
|
-
* Uses iteration to handle nested input types
|
|
120
|
-
*/
|
|
121
|
-
function addInputObjectTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
103
|
+
function generateInputObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
104
|
+
const statements = [];
|
|
122
105
|
const generatedTypes = new Set(alreadyGenerated);
|
|
123
106
|
const typesToGenerate = new Set();
|
|
124
|
-
// Collect all INPUT_OBJECT types
|
|
125
107
|
for (const [typeName, typeInfo] of typeRegistry) {
|
|
126
108
|
if (typeInfo.kind !== 'INPUT_OBJECT')
|
|
127
109
|
continue;
|
|
@@ -131,10 +113,6 @@ function addInputObjectTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGe
|
|
|
131
113
|
continue;
|
|
132
114
|
typesToGenerate.add(typeName);
|
|
133
115
|
}
|
|
134
|
-
if (typesToGenerate.size === 0)
|
|
135
|
-
return generatedTypes;
|
|
136
|
-
(0, ts_ast_1.addSectionComment)(sourceFile, 'Input Object Types');
|
|
137
|
-
// Process all types - no artificial limit
|
|
138
116
|
while (typesToGenerate.size > 0) {
|
|
139
117
|
const typeNameResult = typesToGenerate.values().next();
|
|
140
118
|
if (typeNameResult.done)
|
|
@@ -147,18 +125,14 @@ function addInputObjectTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGe
|
|
|
147
125
|
if (!typeInfo || typeInfo.kind !== 'INPUT_OBJECT')
|
|
148
126
|
continue;
|
|
149
127
|
generatedTypes.add(typeName);
|
|
128
|
+
const properties = [];
|
|
150
129
|
if (typeInfo.inputFields && typeInfo.inputFields.length > 0) {
|
|
151
|
-
const properties = [];
|
|
152
130
|
for (const field of typeInfo.inputFields) {
|
|
153
131
|
const optional = !isRequired(field.type);
|
|
154
132
|
const tsType = typeRefToTs(field.type);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
optional,
|
|
159
|
-
docs: field.description ? [field.description] : undefined,
|
|
160
|
-
});
|
|
161
|
-
// Follow nested Input types
|
|
133
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(tsType))));
|
|
134
|
+
prop.optional = optional;
|
|
135
|
+
properties.push(prop);
|
|
162
136
|
const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
|
|
163
137
|
if (baseType &&
|
|
164
138
|
!generatedTypes.has(baseType) &&
|
|
@@ -169,25 +143,15 @@ function addInputObjectTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGe
|
|
|
169
143
|
}
|
|
170
144
|
}
|
|
171
145
|
}
|
|
172
|
-
sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, properties));
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
// Empty input object
|
|
176
|
-
sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, []));
|
|
177
146
|
}
|
|
147
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(typeName), null, null, t.tsInterfaceBody(properties));
|
|
148
|
+
statements.push(t.exportNamedDeclaration(interfaceDecl));
|
|
178
149
|
}
|
|
179
|
-
return generatedTypes;
|
|
150
|
+
return { statements, generatedTypes };
|
|
180
151
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
// ============================================================================
|
|
184
|
-
/**
|
|
185
|
-
* Add UNION types to source file
|
|
186
|
-
*/
|
|
187
|
-
function addUnionTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
152
|
+
function generateUnionTypes(typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
153
|
+
const statements = [];
|
|
188
154
|
const generatedTypes = new Set(alreadyGenerated);
|
|
189
|
-
const unionTypesToGenerate = new Set();
|
|
190
|
-
// Collect all UNION types
|
|
191
155
|
for (const [typeName, typeInfo] of typeRegistry) {
|
|
192
156
|
if (typeInfo.kind !== 'UNION')
|
|
193
157
|
continue;
|
|
@@ -195,32 +159,17 @@ function addUnionTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGenerate
|
|
|
195
159
|
continue;
|
|
196
160
|
if (generatedTypes.has(typeName))
|
|
197
161
|
continue;
|
|
198
|
-
unionTypesToGenerate.add(typeName);
|
|
199
|
-
}
|
|
200
|
-
if (unionTypesToGenerate.size === 0)
|
|
201
|
-
return generatedTypes;
|
|
202
|
-
(0, ts_ast_1.addSectionComment)(sourceFile, 'Union Types');
|
|
203
|
-
for (const typeName of unionTypesToGenerate) {
|
|
204
|
-
const typeInfo = typeRegistry.get(typeName);
|
|
205
|
-
if (!typeInfo || typeInfo.kind !== 'UNION')
|
|
206
|
-
continue;
|
|
207
162
|
if (!typeInfo.possibleTypes || typeInfo.possibleTypes.length === 0)
|
|
208
163
|
continue;
|
|
209
|
-
|
|
210
|
-
const
|
|
211
|
-
|
|
164
|
+
const unionType = t.tsUnionType(typeInfo.possibleTypes.map((pt) => t.tsTypeReference(t.identifier(pt))));
|
|
165
|
+
const typeAlias = t.tsTypeAliasDeclaration(t.identifier(typeName), null, unionType);
|
|
166
|
+
statements.push(t.exportNamedDeclaration(typeAlias));
|
|
212
167
|
generatedTypes.add(typeName);
|
|
213
168
|
}
|
|
214
|
-
return generatedTypes;
|
|
169
|
+
return { statements, generatedTypes };
|
|
215
170
|
}
|
|
216
|
-
/**
|
|
217
|
-
* Collect return types from Query and Mutation root types
|
|
218
|
-
* This dynamically discovers what OBJECT types need to be generated
|
|
219
|
-
* based on actual schema structure, not pattern matching
|
|
220
|
-
*/
|
|
221
171
|
function collectReturnTypesFromRootTypes(typeRegistry, tableTypeNames) {
|
|
222
172
|
const returnTypes = new Set();
|
|
223
|
-
// Get Query and Mutation root types
|
|
224
173
|
const queryType = typeRegistry.get('Query');
|
|
225
174
|
const mutationType = typeRegistry.get('Mutation');
|
|
226
175
|
const processFields = (fields) => {
|
|
@@ -242,30 +191,16 @@ function collectReturnTypesFromRootTypes(typeRegistry, tableTypeNames) {
|
|
|
242
191
|
processFields(mutationType.fields);
|
|
243
192
|
return returnTypes;
|
|
244
193
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
* These are return types from mutations (e.g., LoginPayload, BootstrapUserPayload)
|
|
248
|
-
*
|
|
249
|
-
* Also tracks which table entity types are referenced so they can be imported.
|
|
250
|
-
*
|
|
251
|
-
* Uses dynamic type discovery from Query/Mutation return types instead of pattern matching.
|
|
252
|
-
*/
|
|
253
|
-
function addPayloadObjectTypes(sourceFile, typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
194
|
+
function generatePayloadObjectTypes(typeRegistry, tableTypeNames, alreadyGenerated) {
|
|
195
|
+
const statements = [];
|
|
254
196
|
const generatedTypes = new Set(alreadyGenerated);
|
|
255
197
|
const referencedTableTypes = new Set();
|
|
256
|
-
// Dynamically collect return types from Query and Mutation
|
|
257
198
|
const typesToGenerate = collectReturnTypesFromRootTypes(typeRegistry, tableTypeNames);
|
|
258
|
-
// Filter out already generated types
|
|
259
199
|
for (const typeName of Array.from(typesToGenerate)) {
|
|
260
200
|
if (generatedTypes.has(typeName)) {
|
|
261
201
|
typesToGenerate.delete(typeName);
|
|
262
202
|
}
|
|
263
203
|
}
|
|
264
|
-
if (typesToGenerate.size === 0) {
|
|
265
|
-
return { generatedTypes, referencedTableTypes };
|
|
266
|
-
}
|
|
267
|
-
(0, ts_ast_1.addSectionComment)(sourceFile, 'Payload/Return Object Types');
|
|
268
|
-
// Process all types - no artificial limit
|
|
269
204
|
while (typesToGenerate.size > 0) {
|
|
270
205
|
const typeNameResult = typesToGenerate.values().next();
|
|
271
206
|
if (typeNameResult.done)
|
|
@@ -278,26 +213,21 @@ function addPayloadObjectTypes(sourceFile, typeRegistry, tableTypeNames, already
|
|
|
278
213
|
if (!typeInfo || typeInfo.kind !== 'OBJECT')
|
|
279
214
|
continue;
|
|
280
215
|
generatedTypes.add(typeName);
|
|
216
|
+
const properties = [];
|
|
281
217
|
if (typeInfo.fields && typeInfo.fields.length > 0) {
|
|
282
|
-
const properties = [];
|
|
283
218
|
for (const field of typeInfo.fields) {
|
|
284
219
|
const baseType = (0, type_resolver_1.getTypeBaseName)(field.type);
|
|
285
|
-
// Skip Query and Mutation fields
|
|
286
220
|
if (baseType === 'Query' || baseType === 'Mutation')
|
|
287
221
|
continue;
|
|
288
222
|
const tsType = typeRefToTs(field.type);
|
|
289
223
|
const isNullable = !isRequired(field.type);
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
docs: field.description ? [field.description] : undefined,
|
|
295
|
-
});
|
|
296
|
-
// Track table entity types that are referenced
|
|
224
|
+
const finalType = isNullable ? `${tsType} | null` : tsType;
|
|
225
|
+
const prop = t.tsPropertySignature(t.identifier(field.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier(finalType))));
|
|
226
|
+
prop.optional = isNullable;
|
|
227
|
+
properties.push(prop);
|
|
297
228
|
if (baseType && tableTypeNames.has(baseType)) {
|
|
298
229
|
referencedTableTypes.add(baseType);
|
|
299
230
|
}
|
|
300
|
-
// Follow nested OBJECT types that aren't table types
|
|
301
231
|
if (baseType &&
|
|
302
232
|
!generatedTypes.has(baseType) &&
|
|
303
233
|
!shouldSkipType(baseType, tableTypeNames)) {
|
|
@@ -307,59 +237,41 @@ function addPayloadObjectTypes(sourceFile, typeRegistry, tableTypeNames, already
|
|
|
307
237
|
}
|
|
308
238
|
}
|
|
309
239
|
}
|
|
310
|
-
sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, properties));
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
// Empty payload object
|
|
314
|
-
sourceFile.addInterface((0, ts_ast_1.createInterface)(typeName, []));
|
|
315
240
|
}
|
|
241
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(typeName), null, null, t.tsInterfaceBody(properties));
|
|
242
|
+
statements.push(t.exportNamedDeclaration(interfaceDecl));
|
|
316
243
|
}
|
|
317
|
-
return { generatedTypes, referencedTableTypes };
|
|
244
|
+
return { statements, generatedTypes, referencedTableTypes };
|
|
318
245
|
}
|
|
319
|
-
// ============================================================================
|
|
320
|
-
// Main Generator
|
|
321
|
-
// ============================================================================
|
|
322
|
-
/**
|
|
323
|
-
* Generate comprehensive schema-types.ts file using ts-morph AST
|
|
324
|
-
*
|
|
325
|
-
* This generates all Input/Payload/Enum types from the TypeRegistry
|
|
326
|
-
* that are needed by custom mutation/query hooks.
|
|
327
|
-
*/
|
|
328
246
|
function generateSchemaTypesFile(options) {
|
|
329
247
|
const { typeRegistry, tableTypeNames } = options;
|
|
330
|
-
const
|
|
331
|
-
const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'schema-types.ts');
|
|
332
|
-
// Add file header
|
|
333
|
-
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('GraphQL schema types for custom operations') + '\n');
|
|
334
|
-
// Track all generated types
|
|
248
|
+
const allStatements = [];
|
|
335
249
|
let generatedTypes = new Set();
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
const
|
|
341
|
-
generatedTypes = new Set([...generatedTypes, ...
|
|
342
|
-
|
|
343
|
-
const inputTypes = addInputObjectTypes(sourceFile, typeRegistry, tableTypeNames, generatedTypes);
|
|
344
|
-
generatedTypes = new Set([...generatedTypes, ...inputTypes]);
|
|
345
|
-
// 4. Generate Payload OBJECT types
|
|
346
|
-
const payloadResult = addPayloadObjectTypes(sourceFile, typeRegistry, tableTypeNames, generatedTypes);
|
|
347
|
-
// 5. Add imports from types.ts (table entity types + base filter types)
|
|
250
|
+
const enumResult = generateEnumTypes(typeRegistry, tableTypeNames);
|
|
251
|
+
generatedTypes = new Set([...generatedTypes, ...enumResult.generatedTypes]);
|
|
252
|
+
const unionResult = generateUnionTypes(typeRegistry, tableTypeNames, generatedTypes);
|
|
253
|
+
generatedTypes = new Set([...generatedTypes, ...unionResult.generatedTypes]);
|
|
254
|
+
const inputResult = generateInputObjectTypes(typeRegistry, tableTypeNames, generatedTypes);
|
|
255
|
+
generatedTypes = new Set([...generatedTypes, ...inputResult.generatedTypes]);
|
|
256
|
+
const payloadResult = generatePayloadObjectTypes(typeRegistry, tableTypeNames, generatedTypes);
|
|
348
257
|
const referencedTableTypes = Array.from(payloadResult.referencedTableTypes).sort();
|
|
349
|
-
// Always import base filter types since generated Filter interfaces reference them
|
|
350
258
|
const baseFilterImports = Array.from(scalars_1.BASE_FILTER_TYPE_NAMES).sort();
|
|
351
259
|
const allTypesImports = [...referencedTableTypes, ...baseFilterImports];
|
|
352
260
|
if (allTypesImports.length > 0) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const headerEndIndex = sourceFile.getFullText().indexOf('*/') + 3;
|
|
357
|
-
sourceFile.insertText(headerEndIndex, '\n' + importStatement);
|
|
261
|
+
const typesImport = t.importDeclaration(allTypesImports.map((ti) => t.importSpecifier(t.identifier(ti), t.identifier(ti))), t.stringLiteral('./types'));
|
|
262
|
+
typesImport.importKind = 'type';
|
|
263
|
+
allStatements.push(typesImport);
|
|
358
264
|
}
|
|
265
|
+
allStatements.push(...enumResult.statements);
|
|
266
|
+
allStatements.push(...unionResult.statements);
|
|
267
|
+
allStatements.push(...inputResult.statements);
|
|
268
|
+
allStatements.push(...payloadResult.statements);
|
|
269
|
+
const code = (0, babel_ast_1.generateCode)(allStatements);
|
|
270
|
+
const content = (0, utils_1.getGeneratedFileHeader)('GraphQL schema types for custom operations') + '\n\n' + code;
|
|
359
271
|
return {
|
|
360
272
|
fileName: 'schema-types.ts',
|
|
361
|
-
content
|
|
362
|
-
generatedEnums: Array.from(
|
|
273
|
+
content,
|
|
274
|
+
generatedEnums: Array.from(enumResult.generatedTypes).sort(),
|
|
363
275
|
referencedTableTypes,
|
|
364
276
|
};
|
|
365
277
|
}
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
* Utilities for converting CleanTypeRef and other GraphQL types
|
|
5
5
|
* into TypeScript type strings and interface definitions.
|
|
6
6
|
*/
|
|
7
|
-
import type { CleanTypeRef,
|
|
8
|
-
import type { InterfaceProperty } from './ts-ast';
|
|
7
|
+
import type { CleanTypeRef, CleanObjectField } from '../../types/schema';
|
|
9
8
|
/**
|
|
10
9
|
* Interface for tracking referenced types during code generation
|
|
11
10
|
*/
|
|
@@ -70,34 +69,6 @@ export declare function getTypeBaseName(typeRef: CleanTypeRef): string | null;
|
|
|
70
69
|
* Get the base type kind (unwrapping LIST and NON_NULL)
|
|
71
70
|
*/
|
|
72
71
|
export declare function getBaseTypeKind(typeRef: CleanTypeRef): CleanTypeRef['kind'];
|
|
73
|
-
/**
|
|
74
|
-
* Convert CleanArgument to InterfaceProperty for ts-morph
|
|
75
|
-
*
|
|
76
|
-
* @param arg - The GraphQL argument
|
|
77
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
78
|
-
*/
|
|
79
|
-
export declare function argumentToInterfaceProperty(arg: CleanArgument, tracker?: TypeTracker): InterfaceProperty;
|
|
80
|
-
/**
|
|
81
|
-
* Convert CleanObjectField to InterfaceProperty for ts-morph
|
|
82
|
-
*
|
|
83
|
-
* @param field - The GraphQL object field
|
|
84
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
85
|
-
*/
|
|
86
|
-
export declare function fieldToInterfaceProperty(field: CleanObjectField, tracker?: TypeTracker): InterfaceProperty;
|
|
87
|
-
/**
|
|
88
|
-
* Convert an array of CleanArguments to InterfaceProperty array
|
|
89
|
-
*
|
|
90
|
-
* @param args - The GraphQL arguments
|
|
91
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
92
|
-
*/
|
|
93
|
-
export declare function argumentsToInterfaceProperties(args: CleanArgument[], tracker?: TypeTracker): InterfaceProperty[];
|
|
94
|
-
/**
|
|
95
|
-
* Convert an array of CleanObjectFields to InterfaceProperty array
|
|
96
|
-
*
|
|
97
|
-
* @param fields - The GraphQL object fields
|
|
98
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
99
|
-
*/
|
|
100
|
-
export declare function fieldsToInterfaceProperties(fields: CleanObjectField[], tracker?: TypeTracker): InterfaceProperty[];
|
|
101
72
|
/**
|
|
102
73
|
* Check if a field should be skipped in selections
|
|
103
74
|
*/
|
|
@@ -8,10 +8,6 @@ exports.isTypeRequired = isTypeRequired;
|
|
|
8
8
|
exports.isTypeList = isTypeList;
|
|
9
9
|
exports.getTypeBaseName = getTypeBaseName;
|
|
10
10
|
exports.getBaseTypeKind = getBaseTypeKind;
|
|
11
|
-
exports.argumentToInterfaceProperty = argumentToInterfaceProperty;
|
|
12
|
-
exports.fieldToInterfaceProperty = fieldToInterfaceProperty;
|
|
13
|
-
exports.argumentsToInterfaceProperties = argumentsToInterfaceProperties;
|
|
14
|
-
exports.fieldsToInterfaceProperties = fieldsToInterfaceProperties;
|
|
15
11
|
exports.shouldSkipField = shouldSkipField;
|
|
16
12
|
exports.getSelectableFields = getSelectableFields;
|
|
17
13
|
exports.operationNameToPascal = operationNameToPascal;
|
|
@@ -184,55 +180,6 @@ function getBaseTypeKind(typeRef) {
|
|
|
184
180
|
return typeRef.kind;
|
|
185
181
|
}
|
|
186
182
|
// ============================================================================
|
|
187
|
-
// Interface Property Generation
|
|
188
|
-
// ============================================================================
|
|
189
|
-
/**
|
|
190
|
-
* Convert CleanArgument to InterfaceProperty for ts-morph
|
|
191
|
-
*
|
|
192
|
-
* @param arg - The GraphQL argument
|
|
193
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
194
|
-
*/
|
|
195
|
-
function argumentToInterfaceProperty(arg, tracker) {
|
|
196
|
-
return {
|
|
197
|
-
name: arg.name,
|
|
198
|
-
type: typeRefToTsType(arg.type, tracker),
|
|
199
|
-
optional: !isTypeRequired(arg.type),
|
|
200
|
-
docs: arg.description ? [arg.description] : undefined,
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Convert CleanObjectField to InterfaceProperty for ts-morph
|
|
205
|
-
*
|
|
206
|
-
* @param field - The GraphQL object field
|
|
207
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
208
|
-
*/
|
|
209
|
-
function fieldToInterfaceProperty(field, tracker) {
|
|
210
|
-
return {
|
|
211
|
-
name: field.name,
|
|
212
|
-
type: typeRefToNullableTsType(field.type, tracker),
|
|
213
|
-
optional: false, // Fields are always present, just potentially null
|
|
214
|
-
docs: field.description ? [field.description] : undefined,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Convert an array of CleanArguments to InterfaceProperty array
|
|
219
|
-
*
|
|
220
|
-
* @param args - The GraphQL arguments
|
|
221
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
222
|
-
*/
|
|
223
|
-
function argumentsToInterfaceProperties(args, tracker) {
|
|
224
|
-
return args.map((arg) => argumentToInterfaceProperty(arg, tracker));
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Convert an array of CleanObjectFields to InterfaceProperty array
|
|
228
|
-
*
|
|
229
|
-
* @param fields - The GraphQL object fields
|
|
230
|
-
* @param tracker - Optional TypeTracker to collect referenced types
|
|
231
|
-
*/
|
|
232
|
-
function fieldsToInterfaceProperties(fields, tracker) {
|
|
233
|
-
return fields.map((field) => fieldToInterfaceProperty(field, tracker));
|
|
234
|
-
}
|
|
235
|
-
// ============================================================================
|
|
236
183
|
// Type Filtering
|
|
237
184
|
// ============================================================================
|
|
238
185
|
/**
|
package/cli/codegen/types.d.ts
CHANGED
package/cli/codegen/types.js
CHANGED
|
@@ -1,7 +1,41 @@
|
|
|
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.generateTypesFile = generateTypesFile;
|
|
4
|
-
const
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const babel_ast_1 = require("./babel-ast");
|
|
5
39
|
const utils_1 = require("./utils");
|
|
6
40
|
/** All filter type configurations - scalar and list filters */
|
|
7
41
|
const FILTER_CONFIGS = [
|
|
@@ -67,16 +101,42 @@ function buildFilterProperties(tsType, operators) {
|
|
|
67
101
|
}
|
|
68
102
|
return props;
|
|
69
103
|
}
|
|
104
|
+
function parseTypeAnnotation(typeStr) {
|
|
105
|
+
if (typeStr === 'string')
|
|
106
|
+
return t.tsStringKeyword();
|
|
107
|
+
if (typeStr === 'number')
|
|
108
|
+
return t.tsNumberKeyword();
|
|
109
|
+
if (typeStr === 'boolean')
|
|
110
|
+
return t.tsBooleanKeyword();
|
|
111
|
+
if (typeStr === 'unknown')
|
|
112
|
+
return t.tsUnknownKeyword();
|
|
113
|
+
if (typeStr.includes(' | ')) {
|
|
114
|
+
const parts = typeStr.split(' | ').map((p) => parseTypeAnnotation(p.trim()));
|
|
115
|
+
return t.tsUnionType(parts);
|
|
116
|
+
}
|
|
117
|
+
if (typeStr.endsWith('[]')) {
|
|
118
|
+
return t.tsArrayType(parseTypeAnnotation(typeStr.slice(0, -2)));
|
|
119
|
+
}
|
|
120
|
+
if (typeStr === 'null')
|
|
121
|
+
return t.tsNullKeyword();
|
|
122
|
+
return t.tsTypeReference(t.identifier(typeStr));
|
|
123
|
+
}
|
|
124
|
+
function createInterfaceDeclaration(name, properties) {
|
|
125
|
+
const props = properties.map((prop) => {
|
|
126
|
+
const propSig = t.tsPropertySignature(t.identifier(prop.name), t.tsTypeAnnotation(parseTypeAnnotation(prop.type)));
|
|
127
|
+
propSig.optional = prop.optional ?? false;
|
|
128
|
+
return propSig;
|
|
129
|
+
});
|
|
130
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(name), null, null, t.tsInterfaceBody(props));
|
|
131
|
+
return t.exportNamedDeclaration(interfaceDecl);
|
|
132
|
+
}
|
|
70
133
|
/**
|
|
71
134
|
* Generate types.ts content with all entity interfaces and base filter types
|
|
72
135
|
*/
|
|
73
136
|
function generateTypesFile(tables, options = {}) {
|
|
74
137
|
const { enumsFromSchemaTypes = [] } = options;
|
|
75
138
|
const enumSet = new Set(enumsFromSchemaTypes);
|
|
76
|
-
const
|
|
77
|
-
const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'types.ts');
|
|
78
|
-
// Add file header
|
|
79
|
-
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Entity types and filter types') + '\n\n');
|
|
139
|
+
const statements = [];
|
|
80
140
|
// Collect which enums are actually used by entity fields
|
|
81
141
|
const usedEnums = new Set();
|
|
82
142
|
for (const table of tables) {
|
|
@@ -91,16 +151,13 @@ function generateTypesFile(tables, options = {}) {
|
|
|
91
151
|
}
|
|
92
152
|
// Add import for enum types from schema-types if any are used
|
|
93
153
|
if (usedEnums.size > 0) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
154
|
+
const specifiers = Array.from(usedEnums)
|
|
155
|
+
.sort()
|
|
156
|
+
.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
|
|
157
|
+
const importDecl = t.importDeclaration(specifiers, t.stringLiteral('./schema-types'));
|
|
158
|
+
importDecl.importKind = 'type';
|
|
159
|
+
statements.push(importDecl);
|
|
99
160
|
}
|
|
100
|
-
// Add section comment for entity types
|
|
101
|
-
sourceFile.addStatements('// ============================================================================');
|
|
102
|
-
sourceFile.addStatements('// Entity types');
|
|
103
|
-
sourceFile.addStatements('// ============================================================================\n');
|
|
104
161
|
// Generate entity interfaces
|
|
105
162
|
for (const table of tables) {
|
|
106
163
|
const scalarFields = (0, utils_1.getScalarFields)(table);
|
|
@@ -108,15 +165,13 @@ function generateTypesFile(tables, options = {}) {
|
|
|
108
165
|
name: field.name,
|
|
109
166
|
type: `${(0, utils_1.fieldTypeToTs)(field.type)} | null`,
|
|
110
167
|
}));
|
|
111
|
-
|
|
168
|
+
statements.push(createInterfaceDeclaration(table.name, properties));
|
|
112
169
|
}
|
|
113
|
-
// Add section comment for filter types
|
|
114
|
-
sourceFile.addStatements('\n// ============================================================================');
|
|
115
|
-
sourceFile.addStatements('// Filter types (shared PostGraphile filter interfaces)');
|
|
116
|
-
sourceFile.addStatements('// ============================================================================\n');
|
|
117
170
|
// Generate all filter types
|
|
118
171
|
for (const { name, tsType, operators } of FILTER_CONFIGS) {
|
|
119
|
-
|
|
172
|
+
statements.push(createInterfaceDeclaration(name, buildFilterProperties(tsType, operators)));
|
|
120
173
|
}
|
|
121
|
-
|
|
174
|
+
const header = (0, utils_1.getGeneratedFileHeader)('Entity types and filter types');
|
|
175
|
+
const code = (0, babel_ast_1.generateCode)(statements);
|
|
176
|
+
return header + '\n' + code;
|
|
122
177
|
}
|