@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,8 +1,42 @@
|
|
|
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.generateCustomQueryOpsFile = generateCustomQueryOpsFile;
|
|
4
37
|
exports.generateCustomMutationOpsFile = generateCustomMutationOpsFile;
|
|
5
|
-
const
|
|
38
|
+
const t = __importStar(require("@babel/types"));
|
|
39
|
+
const babel_ast_1 = require("../babel-ast");
|
|
6
40
|
const utils_1 = require("../utils");
|
|
7
41
|
const type_resolver_1 = require("../type-resolver");
|
|
8
42
|
const scalars_1 = require("../scalars");
|
|
@@ -65,274 +99,197 @@ function getSelectTypeName(returnType) {
|
|
|
65
99
|
}
|
|
66
100
|
return null;
|
|
67
101
|
}
|
|
102
|
+
function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
|
|
103
|
+
const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
|
|
104
|
+
const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
|
|
105
|
+
decl.importKind = typeOnly ? 'type' : 'value';
|
|
106
|
+
return decl;
|
|
107
|
+
}
|
|
108
|
+
function createVariablesInterface(op) {
|
|
109
|
+
if (op.args.length === 0)
|
|
110
|
+
return null;
|
|
111
|
+
const varTypeName = `${(0, utils_1.ucFirst)(op.name)}Variables`;
|
|
112
|
+
const props = op.args.map((arg) => {
|
|
113
|
+
const optional = !(0, type_resolver_1.isTypeRequired)(arg.type);
|
|
114
|
+
const prop = t.tsPropertySignature(t.identifier(arg.name), t.tsTypeAnnotation(parseTypeAnnotation((0, type_resolver_1.typeRefToTsType)(arg.type))));
|
|
115
|
+
prop.optional = optional;
|
|
116
|
+
return prop;
|
|
117
|
+
});
|
|
118
|
+
const interfaceDecl = t.tsInterfaceDeclaration(t.identifier(varTypeName), null, null, t.tsInterfaceBody(props));
|
|
119
|
+
return t.exportNamedDeclaration(interfaceDecl);
|
|
120
|
+
}
|
|
121
|
+
function parseTypeAnnotation(typeStr) {
|
|
122
|
+
if (typeStr === 'string')
|
|
123
|
+
return t.tsStringKeyword();
|
|
124
|
+
if (typeStr === 'number')
|
|
125
|
+
return t.tsNumberKeyword();
|
|
126
|
+
if (typeStr === 'boolean')
|
|
127
|
+
return t.tsBooleanKeyword();
|
|
128
|
+
if (typeStr === 'null')
|
|
129
|
+
return t.tsNullKeyword();
|
|
130
|
+
if (typeStr === 'undefined')
|
|
131
|
+
return t.tsUndefinedKeyword();
|
|
132
|
+
if (typeStr === 'unknown')
|
|
133
|
+
return t.tsUnknownKeyword();
|
|
134
|
+
if (typeStr.includes(' | ')) {
|
|
135
|
+
const parts = typeStr.split(' | ').map((p) => parseTypeAnnotation(p.trim()));
|
|
136
|
+
return t.tsUnionType(parts);
|
|
137
|
+
}
|
|
138
|
+
if (typeStr.endsWith('[]')) {
|
|
139
|
+
return t.tsArrayType(parseTypeAnnotation(typeStr.slice(0, -2)));
|
|
140
|
+
}
|
|
141
|
+
return t.tsTypeReference(t.identifier(typeStr));
|
|
142
|
+
}
|
|
143
|
+
function buildOperationMethod(op, operationType) {
|
|
144
|
+
const hasArgs = op.args.length > 0;
|
|
145
|
+
const varTypeName = `${(0, utils_1.ucFirst)(op.name)}Variables`;
|
|
146
|
+
const varDefs = op.args.map((arg) => ({
|
|
147
|
+
name: arg.name,
|
|
148
|
+
type: formatGraphQLType(arg.type),
|
|
149
|
+
}));
|
|
150
|
+
const selectTypeName = getSelectTypeName(op.returnType);
|
|
151
|
+
const payloadTypeName = (0, type_resolver_1.getTypeBaseName)(op.returnType);
|
|
152
|
+
// Build the arrow function parameters
|
|
153
|
+
const params = [];
|
|
154
|
+
if (hasArgs) {
|
|
155
|
+
const argsParam = t.identifier('args');
|
|
156
|
+
argsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier(varTypeName)));
|
|
157
|
+
params.push(argsParam);
|
|
158
|
+
}
|
|
159
|
+
const optionsParam = t.identifier('options');
|
|
160
|
+
optionsParam.optional = true;
|
|
161
|
+
if (selectTypeName) {
|
|
162
|
+
optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
163
|
+
(() => {
|
|
164
|
+
const prop = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('S'))));
|
|
165
|
+
prop.optional = true;
|
|
166
|
+
return prop;
|
|
167
|
+
})(),
|
|
168
|
+
]));
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeLiteral([
|
|
172
|
+
(() => {
|
|
173
|
+
const prop = t.tsPropertySignature(t.identifier('select'), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([t.tsStringKeyword(), t.tsUnknownKeyword()]))));
|
|
174
|
+
prop.optional = true;
|
|
175
|
+
return prop;
|
|
176
|
+
})(),
|
|
177
|
+
]));
|
|
178
|
+
}
|
|
179
|
+
params.push(optionsParam);
|
|
180
|
+
// Build the QueryBuilder call
|
|
181
|
+
const queryBuilderArgs = t.objectExpression([
|
|
182
|
+
t.objectProperty(t.identifier('client'), t.identifier('client'), false, true),
|
|
183
|
+
t.objectProperty(t.identifier('operation'), t.stringLiteral(operationType)),
|
|
184
|
+
t.objectProperty(t.identifier('operationName'), t.stringLiteral((0, utils_1.ucFirst)(op.name))),
|
|
185
|
+
t.objectProperty(t.identifier('fieldName'), t.stringLiteral(op.name)),
|
|
186
|
+
t.spreadElement(t.callExpression(t.identifier('buildCustomDocument'), [
|
|
187
|
+
t.stringLiteral(operationType),
|
|
188
|
+
t.stringLiteral((0, utils_1.ucFirst)(op.name)),
|
|
189
|
+
t.stringLiteral(op.name),
|
|
190
|
+
t.optionalMemberExpression(t.identifier('options'), t.identifier('select'), false, true),
|
|
191
|
+
hasArgs ? t.identifier('args') : t.identifier('undefined'),
|
|
192
|
+
t.arrayExpression(varDefs.map((v) => t.objectExpression([
|
|
193
|
+
t.objectProperty(t.identifier('name'), t.stringLiteral(v.name)),
|
|
194
|
+
t.objectProperty(t.identifier('type'), t.stringLiteral(v.type)),
|
|
195
|
+
]))),
|
|
196
|
+
])),
|
|
197
|
+
]);
|
|
198
|
+
const newExpr = t.newExpression(t.identifier('QueryBuilder'), [queryBuilderArgs]);
|
|
199
|
+
// Add type parameter if we have a select type
|
|
200
|
+
if (selectTypeName && payloadTypeName) {
|
|
201
|
+
newExpr.typeParameters = t.tsTypeParameterInstantiation([
|
|
202
|
+
t.tsTypeLiteral([
|
|
203
|
+
t.tsPropertySignature(t.identifier(op.name), t.tsTypeAnnotation(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
204
|
+
t.tsTypeReference(t.identifier(payloadTypeName)),
|
|
205
|
+
t.tsTypeReference(t.identifier('S')),
|
|
206
|
+
])))),
|
|
207
|
+
]),
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
const arrowFunc = t.arrowFunctionExpression(params, newExpr);
|
|
211
|
+
// Add type parameters to arrow function if we have a select type
|
|
212
|
+
if (selectTypeName) {
|
|
213
|
+
const typeParam = t.tsTypeParameter(t.tsTypeReference(t.identifier(selectTypeName)), null, 'S');
|
|
214
|
+
typeParam.const = true;
|
|
215
|
+
arrowFunc.typeParameters = t.tsTypeParameterDeclaration([typeParam]);
|
|
216
|
+
}
|
|
217
|
+
return t.objectProperty(t.identifier(op.name), arrowFunc);
|
|
218
|
+
}
|
|
68
219
|
/**
|
|
69
220
|
* Generate the query/index.ts file for custom query operations
|
|
70
221
|
*/
|
|
71
222
|
function generateCustomQueryOpsFile(operations) {
|
|
72
|
-
const
|
|
73
|
-
const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'index.ts');
|
|
223
|
+
const statements = [];
|
|
74
224
|
// Collect all input type names and payload type names
|
|
75
225
|
const inputTypeNames = collectInputTypeNamesFromOps(operations);
|
|
76
226
|
const payloadTypeNames = collectPayloadTypeNamesFromOps(operations);
|
|
77
|
-
// Generate Select type names for payloads
|
|
78
227
|
const selectTypeNames = payloadTypeNames.map((p) => `${p}Select`);
|
|
79
|
-
|
|
80
|
-
const allTypeImports = [
|
|
81
|
-
...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames]),
|
|
82
|
-
];
|
|
83
|
-
// Add file header
|
|
84
|
-
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Custom query operations') + '\n\n');
|
|
228
|
+
const allTypeImports = [...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames])];
|
|
85
229
|
// Add imports
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
namedImports: ['OrmClient'],
|
|
90
|
-
}),
|
|
91
|
-
(0, ts_ast_1.createImport)({
|
|
92
|
-
moduleSpecifier: '../query-builder',
|
|
93
|
-
namedImports: ['QueryBuilder', 'buildCustomDocument'],
|
|
94
|
-
}),
|
|
95
|
-
(0, ts_ast_1.createImport)({
|
|
96
|
-
moduleSpecifier: '../select-types',
|
|
97
|
-
typeOnlyNamedImports: ['InferSelectResult'],
|
|
98
|
-
}),
|
|
99
|
-
]);
|
|
100
|
-
// Import types from input-types if we have any
|
|
230
|
+
statements.push(createImportDeclaration('../client', ['OrmClient']));
|
|
231
|
+
statements.push(createImportDeclaration('../query-builder', ['QueryBuilder', 'buildCustomDocument']));
|
|
232
|
+
statements.push(createImportDeclaration('../select-types', ['InferSelectResult'], true));
|
|
101
233
|
if (allTypeImports.length > 0) {
|
|
102
|
-
|
|
103
|
-
(0, ts_ast_1.createImport)({
|
|
104
|
-
moduleSpecifier: '../input-types',
|
|
105
|
-
typeOnlyNamedImports: allTypeImports,
|
|
106
|
-
}),
|
|
107
|
-
]);
|
|
234
|
+
statements.push(createImportDeclaration('../input-types', allTypeImports, true));
|
|
108
235
|
}
|
|
109
|
-
// Generate variable
|
|
110
|
-
sourceFile.addStatements('\n// ============================================================================');
|
|
111
|
-
sourceFile.addStatements('// Variable Types');
|
|
112
|
-
sourceFile.addStatements('// ============================================================================\n');
|
|
236
|
+
// Generate variable interfaces
|
|
113
237
|
for (const op of operations) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const optional = !(0, type_resolver_1.isTypeRequired)(arg.type);
|
|
118
|
-
return `${arg.name}${optional ? '?' : ''}: ${(0, type_resolver_1.typeRefToTsType)(arg.type)};`;
|
|
119
|
-
});
|
|
120
|
-
sourceFile.addStatements(`export interface ${varTypeName} {\n ${props.join('\n ')}\n}\n`);
|
|
121
|
-
}
|
|
238
|
+
const varInterface = createVariablesInterface(op);
|
|
239
|
+
if (varInterface)
|
|
240
|
+
statements.push(varInterface);
|
|
122
241
|
}
|
|
123
242
|
// Generate factory function
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
type: formatGraphQLType(arg.type),
|
|
134
|
-
}));
|
|
135
|
-
const varDefsJson = JSON.stringify(varDefs);
|
|
136
|
-
// Get Select type for return type
|
|
137
|
-
const selectTypeName = getSelectTypeName(op.returnType);
|
|
138
|
-
const payloadTypeName = (0, type_resolver_1.getTypeBaseName)(op.returnType);
|
|
139
|
-
// Use typed select if available, otherwise fall back to Record<string, unknown>
|
|
140
|
-
const selectType = selectTypeName ?? 'Record<string, unknown>';
|
|
141
|
-
const returnTypePart = selectTypeName && payloadTypeName
|
|
142
|
-
? `{ ${op.name}: InferSelectResult<${payloadTypeName}, S> }`
|
|
143
|
-
: 'unknown';
|
|
144
|
-
if (hasArgs) {
|
|
145
|
-
if (selectTypeName) {
|
|
146
|
-
return `${op.name}: <const S extends ${selectType}>(args: ${varTypeName}, options?: { select?: S }) =>
|
|
147
|
-
new QueryBuilder<${returnTypePart}>({
|
|
148
|
-
client,
|
|
149
|
-
operation: 'query',
|
|
150
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
151
|
-
fieldName: '${op.name}',
|
|
152
|
-
...buildCustomDocument('query', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, args, ${varDefsJson}),
|
|
153
|
-
})`;
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
return `${op.name}: (args: ${varTypeName}, options?: { select?: Record<string, unknown> }) =>
|
|
157
|
-
new QueryBuilder({
|
|
158
|
-
client,
|
|
159
|
-
operation: 'query',
|
|
160
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
161
|
-
fieldName: '${op.name}',
|
|
162
|
-
...buildCustomDocument('query', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, args, ${varDefsJson}),
|
|
163
|
-
})`;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
// No args - still provide typed select
|
|
168
|
-
if (selectTypeName) {
|
|
169
|
-
return `${op.name}: <const S extends ${selectType}>(options?: { select?: S }) =>
|
|
170
|
-
new QueryBuilder<${returnTypePart}>({
|
|
171
|
-
client,
|
|
172
|
-
operation: 'query',
|
|
173
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
174
|
-
fieldName: '${op.name}',
|
|
175
|
-
...buildCustomDocument('query', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, undefined, []),
|
|
176
|
-
})`;
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
return `${op.name}: (options?: { select?: Record<string, unknown> }) =>
|
|
180
|
-
new QueryBuilder({
|
|
181
|
-
client,
|
|
182
|
-
operation: 'query',
|
|
183
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
184
|
-
fieldName: '${op.name}',
|
|
185
|
-
...buildCustomDocument('query', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, undefined, []),
|
|
186
|
-
})`;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
sourceFile.addFunction({
|
|
191
|
-
name: 'createQueryOperations',
|
|
192
|
-
isExported: true,
|
|
193
|
-
parameters: [{ name: 'client', type: 'OrmClient' }],
|
|
194
|
-
statements: `return {
|
|
195
|
-
${operationMethods.join(',\n ')},
|
|
196
|
-
};`,
|
|
197
|
-
});
|
|
243
|
+
const operationProperties = operations.map((op) => buildOperationMethod(op, 'query'));
|
|
244
|
+
const returnObj = t.objectExpression(operationProperties);
|
|
245
|
+
const returnStmt = t.returnStatement(returnObj);
|
|
246
|
+
const clientParam = t.identifier('client');
|
|
247
|
+
clientParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('OrmClient')));
|
|
248
|
+
const factoryFunc = t.functionDeclaration(t.identifier('createQueryOperations'), [clientParam], t.blockStatement([returnStmt]));
|
|
249
|
+
statements.push(t.exportNamedDeclaration(factoryFunc));
|
|
250
|
+
const header = (0, utils_1.getGeneratedFileHeader)('Custom query operations');
|
|
251
|
+
const code = (0, babel_ast_1.generateCode)(statements);
|
|
198
252
|
return {
|
|
199
253
|
fileName: 'query/index.ts',
|
|
200
|
-
content:
|
|
254
|
+
content: header + '\n' + code,
|
|
201
255
|
};
|
|
202
256
|
}
|
|
203
257
|
/**
|
|
204
258
|
* Generate the mutation/index.ts file for custom mutation operations
|
|
205
259
|
*/
|
|
206
260
|
function generateCustomMutationOpsFile(operations) {
|
|
207
|
-
const
|
|
208
|
-
const sourceFile = (0, ts_ast_1.createSourceFile)(project, 'index.ts');
|
|
261
|
+
const statements = [];
|
|
209
262
|
// Collect all input type names and payload type names
|
|
210
263
|
const inputTypeNames = collectInputTypeNamesFromOps(operations);
|
|
211
264
|
const payloadTypeNames = collectPayloadTypeNamesFromOps(operations);
|
|
212
|
-
// Generate Select type names for payloads
|
|
213
265
|
const selectTypeNames = payloadTypeNames.map((p) => `${p}Select`);
|
|
214
|
-
|
|
215
|
-
const allTypeImports = [
|
|
216
|
-
...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames]),
|
|
217
|
-
];
|
|
218
|
-
// Add file header
|
|
219
|
-
sourceFile.insertText(0, (0, ts_ast_1.createFileHeader)('Custom mutation operations') + '\n\n');
|
|
266
|
+
const allTypeImports = [...new Set([...inputTypeNames, ...payloadTypeNames, ...selectTypeNames])];
|
|
220
267
|
// Add imports
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
namedImports: ['OrmClient'],
|
|
225
|
-
}),
|
|
226
|
-
(0, ts_ast_1.createImport)({
|
|
227
|
-
moduleSpecifier: '../query-builder',
|
|
228
|
-
namedImports: ['QueryBuilder', 'buildCustomDocument'],
|
|
229
|
-
}),
|
|
230
|
-
(0, ts_ast_1.createImport)({
|
|
231
|
-
moduleSpecifier: '../select-types',
|
|
232
|
-
typeOnlyNamedImports: ['InferSelectResult'],
|
|
233
|
-
}),
|
|
234
|
-
]);
|
|
235
|
-
// Import types from input-types if we have any
|
|
268
|
+
statements.push(createImportDeclaration('../client', ['OrmClient']));
|
|
269
|
+
statements.push(createImportDeclaration('../query-builder', ['QueryBuilder', 'buildCustomDocument']));
|
|
270
|
+
statements.push(createImportDeclaration('../select-types', ['InferSelectResult'], true));
|
|
236
271
|
if (allTypeImports.length > 0) {
|
|
237
|
-
|
|
238
|
-
(0, ts_ast_1.createImport)({
|
|
239
|
-
moduleSpecifier: '../input-types',
|
|
240
|
-
typeOnlyNamedImports: allTypeImports,
|
|
241
|
-
}),
|
|
242
|
-
]);
|
|
272
|
+
statements.push(createImportDeclaration('../input-types', allTypeImports, true));
|
|
243
273
|
}
|
|
244
|
-
// Generate variable
|
|
245
|
-
sourceFile.addStatements('\n// ============================================================================');
|
|
246
|
-
sourceFile.addStatements('// Variable Types');
|
|
247
|
-
sourceFile.addStatements('// ============================================================================\n');
|
|
274
|
+
// Generate variable interfaces
|
|
248
275
|
for (const op of operations) {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
const optional = !(0, type_resolver_1.isTypeRequired)(arg.type);
|
|
253
|
-
return `${arg.name}${optional ? '?' : ''}: ${(0, type_resolver_1.typeRefToTsType)(arg.type)};`;
|
|
254
|
-
});
|
|
255
|
-
sourceFile.addStatements(`export interface ${varTypeName} {\n ${props.join('\n ')}\n}\n`);
|
|
256
|
-
}
|
|
276
|
+
const varInterface = createVariablesInterface(op);
|
|
277
|
+
if (varInterface)
|
|
278
|
+
statements.push(varInterface);
|
|
257
279
|
}
|
|
258
280
|
// Generate factory function
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
type: formatGraphQLType(arg.type),
|
|
269
|
-
}));
|
|
270
|
-
const varDefsJson = JSON.stringify(varDefs);
|
|
271
|
-
// Get Select type for return type
|
|
272
|
-
const selectTypeName = getSelectTypeName(op.returnType);
|
|
273
|
-
const payloadTypeName = (0, type_resolver_1.getTypeBaseName)(op.returnType);
|
|
274
|
-
// Use typed select if available, otherwise fall back to Record<string, unknown>
|
|
275
|
-
const selectType = selectTypeName ?? 'Record<string, unknown>';
|
|
276
|
-
const returnTypePart = selectTypeName && payloadTypeName
|
|
277
|
-
? `{ ${op.name}: InferSelectResult<${payloadTypeName}, S> }`
|
|
278
|
-
: 'unknown';
|
|
279
|
-
if (hasArgs) {
|
|
280
|
-
if (selectTypeName) {
|
|
281
|
-
return `${op.name}: <const S extends ${selectType}>(args: ${varTypeName}, options?: { select?: S }) =>
|
|
282
|
-
new QueryBuilder<${returnTypePart}>({
|
|
283
|
-
client,
|
|
284
|
-
operation: 'mutation',
|
|
285
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
286
|
-
fieldName: '${op.name}',
|
|
287
|
-
...buildCustomDocument('mutation', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, args, ${varDefsJson}),
|
|
288
|
-
})`;
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
return `${op.name}: (args: ${varTypeName}, options?: { select?: Record<string, unknown> }) =>
|
|
292
|
-
new QueryBuilder({
|
|
293
|
-
client,
|
|
294
|
-
operation: 'mutation',
|
|
295
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
296
|
-
fieldName: '${op.name}',
|
|
297
|
-
...buildCustomDocument('mutation', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, args, ${varDefsJson}),
|
|
298
|
-
})`;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
else {
|
|
302
|
-
// No args - still provide typed select
|
|
303
|
-
if (selectTypeName) {
|
|
304
|
-
return `${op.name}: <const S extends ${selectType}>(options?: { select?: S }) =>
|
|
305
|
-
new QueryBuilder<${returnTypePart}>({
|
|
306
|
-
client,
|
|
307
|
-
operation: 'mutation',
|
|
308
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
309
|
-
fieldName: '${op.name}',
|
|
310
|
-
...buildCustomDocument('mutation', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, undefined, []),
|
|
311
|
-
})`;
|
|
312
|
-
}
|
|
313
|
-
else {
|
|
314
|
-
return `${op.name}: (options?: { select?: Record<string, unknown> }) =>
|
|
315
|
-
new QueryBuilder({
|
|
316
|
-
client,
|
|
317
|
-
operation: 'mutation',
|
|
318
|
-
operationName: '${(0, utils_1.ucFirst)(op.name)}',
|
|
319
|
-
fieldName: '${op.name}',
|
|
320
|
-
...buildCustomDocument('mutation', '${(0, utils_1.ucFirst)(op.name)}', '${op.name}', options?.select, undefined, []),
|
|
321
|
-
})`;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
sourceFile.addFunction({
|
|
326
|
-
name: 'createMutationOperations',
|
|
327
|
-
isExported: true,
|
|
328
|
-
parameters: [{ name: 'client', type: 'OrmClient' }],
|
|
329
|
-
statements: `return {
|
|
330
|
-
${operationMethods.join(',\n ')},
|
|
331
|
-
};`,
|
|
332
|
-
});
|
|
281
|
+
const operationProperties = operations.map((op) => buildOperationMethod(op, 'mutation'));
|
|
282
|
+
const returnObj = t.objectExpression(operationProperties);
|
|
283
|
+
const returnStmt = t.returnStatement(returnObj);
|
|
284
|
+
const clientParam = t.identifier('client');
|
|
285
|
+
clientParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('OrmClient')));
|
|
286
|
+
const factoryFunc = t.functionDeclaration(t.identifier('createMutationOperations'), [clientParam], t.blockStatement([returnStmt]));
|
|
287
|
+
statements.push(t.exportNamedDeclaration(factoryFunc));
|
|
288
|
+
const header = (0, utils_1.getGeneratedFileHeader)('Custom mutation operations');
|
|
289
|
+
const code = (0, babel_ast_1.generateCode)(statements);
|
|
333
290
|
return {
|
|
334
291
|
fileName: 'mutation/index.ts',
|
|
335
|
-
content:
|
|
292
|
+
content: header + '\n' + code,
|
|
336
293
|
};
|
|
337
294
|
}
|
|
338
295
|
/**
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input types generator for ORM client (Babel AST-based)
|
|
3
|
+
*
|
|
4
|
+
* Generates TypeScript interfaces for:
|
|
5
|
+
* 1. Scalar filter types (StringFilter, IntFilter, UUIDFilter, etc.)
|
|
6
|
+
* 2. Entity interfaces (User, Order, etc.)
|
|
7
|
+
* 3. Table filter types (UserFilter, OrderFilter, etc.)
|
|
8
|
+
* 4. OrderBy enums (UsersOrderBy, OrdersOrderBy, etc.)
|
|
9
|
+
* 5. Input types (LoginInput, CreateUserInput, etc.)
|
|
10
|
+
*
|
|
11
|
+
* Uses Babel AST for robust code generation.
|
|
12
|
+
*/
|
|
1
13
|
import type { TypeRegistry, CleanArgument, CleanTable } from '../../../types/schema';
|
|
2
14
|
export interface GeneratedInputTypesFile {
|
|
3
15
|
fileName: string;
|
|
@@ -16,6 +28,6 @@ export declare function collectPayloadTypeNames(operations: Array<{
|
|
|
16
28
|
returnType: CleanArgument['type'];
|
|
17
29
|
}>): Set<string>;
|
|
18
30
|
/**
|
|
19
|
-
* Generate comprehensive input-types.ts file using
|
|
31
|
+
* Generate comprehensive input-types.ts file using Babel AST
|
|
20
32
|
*/
|
|
21
33
|
export declare function generateInputTypesFile(typeRegistry: TypeRegistry, usedInputTypes: Set<string>, tables?: CleanTable[], usedPayloadTypes?: Set<string>): GeneratedInputTypesFile;
|