@constructive-io/graphql-codegen 4.40.6 → 4.41.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/core/codegen/cli/executor-generator.d.ts +2 -6
- package/core/codegen/cli/executor-generator.js +12 -48
- package/core/codegen/cli/index.d.ts +0 -2
- package/core/codegen/cli/index.js +2 -16
- package/core/codegen/cli/table-command-generator.js +141 -2
- package/core/codegen/cli/utils-generator.d.ts +0 -8
- package/core/codegen/cli/utils-generator.js +0 -14
- package/core/codegen/mutation-keys.js +18 -0
- package/core/codegen/mutations.js +187 -0
- package/core/codegen/orm/client-generator.d.ts +1 -3
- package/core/codegen/orm/client-generator.js +1 -7
- package/core/codegen/orm/index.js +1 -1
- package/core/codegen/orm/model-generator.js +167 -5
- package/core/codegen/orm/select-types.d.ts +2 -1
- package/core/codegen/queries.js +1 -1
- package/core/codegen/templates/cli-utils.ts +4 -2
- package/core/codegen/templates/query-builder.ts +170 -1
- package/core/codegen/templates/select-types.ts +30 -1
- package/core/codegen/utils.d.ts +8 -0
- package/core/codegen/utils.js +39 -0
- package/core/generate.js +2 -19
- package/esm/core/codegen/cli/executor-generator.d.ts +2 -6
- package/esm/core/codegen/cli/executor-generator.js +12 -48
- package/esm/core/codegen/cli/index.d.ts +0 -2
- package/esm/core/codegen/cli/index.js +3 -17
- package/esm/core/codegen/cli/table-command-generator.js +141 -2
- package/esm/core/codegen/cli/utils-generator.d.ts +0 -8
- package/esm/core/codegen/cli/utils-generator.js +0 -13
- package/esm/core/codegen/mutation-keys.js +18 -0
- package/esm/core/codegen/mutations.js +188 -1
- package/esm/core/codegen/orm/client-generator.d.ts +1 -3
- package/esm/core/codegen/orm/client-generator.js +1 -7
- package/esm/core/codegen/orm/index.js +1 -1
- package/esm/core/codegen/orm/model-generator.js +168 -6
- package/esm/core/codegen/orm/select-types.d.ts +2 -1
- package/esm/core/codegen/queries.js +1 -1
- package/esm/core/codegen/utils.d.ts +8 -0
- package/esm/core/codegen/utils.js +31 -0
- package/esm/core/generate.js +2 -19
- package/esm/types/config.d.ts +0 -18
- package/esm/types/schema.d.ts +8 -0
- package/package.json +3 -3
- package/types/config.d.ts +0 -18
- package/types/schema.d.ts +8 -0
- package/core/codegen/templates/node-fetch.ts +0 -198
|
@@ -7,9 +7,5 @@ export interface MultiTargetExecutorInput {
|
|
|
7
7
|
endpoint: string;
|
|
8
8
|
ormImportPath: string;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
nodeHttpAdapter?: boolean;
|
|
13
|
-
}
|
|
14
|
-
export declare function generateExecutorFile(toolName: string, options?: ExecutorOptions): GeneratedFile;
|
|
15
|
-
export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[], options?: ExecutorOptions): GeneratedFile;
|
|
10
|
+
export declare function generateExecutorFile(toolName: string): GeneratedFile;
|
|
11
|
+
export declare function generateMultiTargetExecutorFile(toolName: string, targets: MultiTargetExecutorInput[]): GeneratedFile;
|
|
@@ -44,12 +44,8 @@ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false
|
|
|
44
44
|
decl.importKind = typeOnly ? 'type' : 'value';
|
|
45
45
|
return decl;
|
|
46
46
|
}
|
|
47
|
-
function generateExecutorFile(toolName
|
|
47
|
+
function generateExecutorFile(toolName) {
|
|
48
48
|
const statements = [];
|
|
49
|
-
// Import NodeHttpAdapter for *.localhost subdomain routing
|
|
50
|
-
if (options?.nodeHttpAdapter) {
|
|
51
|
-
statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
|
|
52
|
-
}
|
|
53
49
|
statements.push(createImportDeclaration('appstash', ['createConfigStore']));
|
|
54
50
|
statements.push(createImportDeclaration('../orm', ['createClient']));
|
|
55
51
|
statements.push(t.variableDeclaration('const', [
|
|
@@ -109,26 +105,12 @@ function generateExecutorFile(toolName, options) {
|
|
|
109
105
|
]))),
|
|
110
106
|
])),
|
|
111
107
|
])),
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
t.
|
|
116
|
-
t.objectExpression([
|
|
117
|
-
t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
|
|
118
|
-
t.memberExpression(t.identifier('ctx'), t.identifier('endpoint')),
|
|
119
|
-
t.identifier('headers'),
|
|
120
|
-
])),
|
|
121
|
-
]),
|
|
122
|
-
])),
|
|
123
|
-
]
|
|
124
|
-
: [
|
|
125
|
-
t.returnStatement(t.callExpression(t.identifier('createClient'), [
|
|
126
|
-
t.objectExpression([
|
|
127
|
-
t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
|
|
128
|
-
t.objectProperty(t.identifier('headers'), t.identifier('headers')),
|
|
129
|
-
]),
|
|
130
|
-
])),
|
|
108
|
+
t.returnStatement(t.callExpression(t.identifier('createClient'), [
|
|
109
|
+
t.objectExpression([
|
|
110
|
+
t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('ctx'), t.identifier('endpoint'))),
|
|
111
|
+
t.objectProperty(t.identifier('headers'), t.identifier('headers')),
|
|
131
112
|
]),
|
|
113
|
+
])),
|
|
132
114
|
]);
|
|
133
115
|
const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [contextNameParam], getClientBody);
|
|
134
116
|
statements.push(t.exportNamedDeclaration(getClientFunc));
|
|
@@ -139,12 +121,8 @@ function generateExecutorFile(toolName, options) {
|
|
|
139
121
|
content: header + '\n' + code,
|
|
140
122
|
};
|
|
141
123
|
}
|
|
142
|
-
function generateMultiTargetExecutorFile(toolName, targets
|
|
124
|
+
function generateMultiTargetExecutorFile(toolName, targets) {
|
|
143
125
|
const statements = [];
|
|
144
|
-
// Import NodeHttpAdapter for *.localhost subdomain routing
|
|
145
|
-
if (options?.nodeHttpAdapter) {
|
|
146
|
-
statements.push(createImportDeclaration('./node-fetch', ['NodeHttpAdapter']));
|
|
147
|
-
}
|
|
148
126
|
statements.push(createImportDeclaration('appstash', ['createConfigStore']));
|
|
149
127
|
for (const target of targets) {
|
|
150
128
|
const aliasName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}Client`;
|
|
@@ -235,26 +213,12 @@ function generateMultiTargetExecutorFile(toolName, targets, options) {
|
|
|
235
213
|
]), t.blockStatement([
|
|
236
214
|
t.expressionStatement(t.assignmentExpression('=', t.identifier('endpoint'), t.logicalExpression('||', t.memberExpression(t.identifier('defaultEndpoints'), t.identifier('targetName'), true), t.stringLiteral('')))),
|
|
237
215
|
])),
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
t.
|
|
242
|
-
t.objectExpression([
|
|
243
|
-
t.objectProperty(t.identifier('adapter'), t.newExpression(t.identifier('NodeHttpAdapter'), [
|
|
244
|
-
t.identifier('endpoint'),
|
|
245
|
-
t.identifier('headers'),
|
|
246
|
-
])),
|
|
247
|
-
]),
|
|
248
|
-
])),
|
|
249
|
-
]
|
|
250
|
-
: [
|
|
251
|
-
t.returnStatement(t.callExpression(t.identifier('createFn'), [
|
|
252
|
-
t.objectExpression([
|
|
253
|
-
t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
|
|
254
|
-
t.objectProperty(t.identifier('headers'), t.identifier('headers')),
|
|
255
|
-
]),
|
|
256
|
-
])),
|
|
216
|
+
t.returnStatement(t.callExpression(t.identifier('createFn'), [
|
|
217
|
+
t.objectExpression([
|
|
218
|
+
t.objectProperty(t.identifier('endpoint'), t.identifier('endpoint')),
|
|
219
|
+
t.objectProperty(t.identifier('headers'), t.identifier('headers')),
|
|
257
220
|
]),
|
|
221
|
+
])),
|
|
258
222
|
]);
|
|
259
223
|
const getClientFunc = t.functionDeclaration(t.identifier('getClient'), [targetNameParam, contextNameParam], getClientBody);
|
|
260
224
|
statements.push(t.exportNamedDeclaration(getClientFunc));
|
|
@@ -39,8 +39,6 @@ export interface GenerateMultiTargetCliOptions {
|
|
|
39
39
|
toolName: string;
|
|
40
40
|
builtinNames?: BuiltinNames;
|
|
41
41
|
targets: MultiTargetCliTarget[];
|
|
42
|
-
/** Enable NodeHttpAdapter for *.localhost subdomain routing */
|
|
43
|
-
nodeHttpAdapter?: boolean;
|
|
44
42
|
/** Generate a runnable index.ts entry point */
|
|
45
43
|
entryPoint?: boolean;
|
|
46
44
|
}
|
|
@@ -19,11 +19,7 @@ function generateCli(options) {
|
|
|
19
19
|
const toolName = typeof cliConfig === 'object' && cliConfig.toolName
|
|
20
20
|
? cliConfig.toolName
|
|
21
21
|
: 'app';
|
|
22
|
-
|
|
23
|
-
const useNodeHttpAdapter = !!config.nodeHttpAdapter;
|
|
24
|
-
const executorFile = (0, executor_generator_1.generateExecutorFile)(toolName, {
|
|
25
|
-
nodeHttpAdapter: useNodeHttpAdapter,
|
|
26
|
-
});
|
|
22
|
+
const executorFile = (0, executor_generator_1.generateExecutorFile)(toolName);
|
|
27
23
|
files.push(executorFile);
|
|
28
24
|
const utilsFile = (0, utils_generator_1.generateUtilsFile)();
|
|
29
25
|
files.push(utilsFile);
|
|
@@ -32,10 +28,6 @@ function generateCli(options) {
|
|
|
32
28
|
if (hasAnyEmbeddings) {
|
|
33
29
|
files.push((0, utils_generator_1.generateEmbedderFile)());
|
|
34
30
|
}
|
|
35
|
-
// Generate node HTTP adapter if configured (for *.localhost subdomain routing)
|
|
36
|
-
if (useNodeHttpAdapter) {
|
|
37
|
-
files.push((0, utils_generator_1.generateNodeFetchFile)());
|
|
38
|
-
}
|
|
39
31
|
const contextFile = (0, infra_generator_1.generateContextCommand)(toolName);
|
|
40
32
|
files.push(contextFile);
|
|
41
33
|
const authFile = (0, infra_generator_1.generateAuthCommand)(toolName);
|
|
@@ -97,9 +89,7 @@ function generateMultiTargetCli(options) {
|
|
|
97
89
|
endpoint: t.endpoint,
|
|
98
90
|
ormImportPath: t.ormImportPath,
|
|
99
91
|
}));
|
|
100
|
-
const executorFile = (0, executor_generator_1.generateMultiTargetExecutorFile)(toolName, executorInputs
|
|
101
|
-
nodeHttpAdapter: !!options.nodeHttpAdapter,
|
|
102
|
-
});
|
|
92
|
+
const executorFile = (0, executor_generator_1.generateMultiTargetExecutorFile)(toolName, executorInputs);
|
|
103
93
|
files.push(executorFile);
|
|
104
94
|
const utilsFile = (0, utils_generator_1.generateUtilsFile)();
|
|
105
95
|
files.push(utilsFile);
|
|
@@ -108,10 +98,6 @@ function generateMultiTargetCli(options) {
|
|
|
108
98
|
if (hasAnyMtEmbeddings) {
|
|
109
99
|
files.push((0, utils_generator_1.generateEmbedderFile)());
|
|
110
100
|
}
|
|
111
|
-
// Generate node HTTP adapter if configured (for *.localhost subdomain routing)
|
|
112
|
-
if (options.nodeHttpAdapter) {
|
|
113
|
-
files.push((0, utils_generator_1.generateNodeFetchFile)());
|
|
114
|
-
}
|
|
115
101
|
const contextFile = (0, infra_generator_1.generateMultiTargetContextCommand)(toolName, builtinNames.context, targets.map((t) => ({ name: t.name, endpoint: t.endpoint })));
|
|
116
102
|
files.push(contextFile);
|
|
117
103
|
const authFile = (0, infra_generator_1.generateAuthCommandWithName)(toolName, builtinNames.auth);
|
|
@@ -312,7 +312,7 @@ function buildFindManyArgsType(table) {
|
|
|
312
312
|
}
|
|
313
313
|
/**
|
|
314
314
|
* Build the FindFirstArgs type instantiation for a table:
|
|
315
|
-
* FindFirstArgs<SelectType, FilterType> & { select: SelectType }
|
|
315
|
+
* FindFirstArgs<SelectType, FilterType, OrderByType> & { select: SelectType }
|
|
316
316
|
*
|
|
317
317
|
* The intersection with { select: SelectType } makes select required,
|
|
318
318
|
* matching what the ORM's findFirst method expects.
|
|
@@ -321,9 +321,11 @@ function buildFindFirstArgsType(table) {
|
|
|
321
321
|
const { typeName } = (0, utils_1.getTableNames)(table);
|
|
322
322
|
const selectTypeName = `${typeName}Select`;
|
|
323
323
|
const whereTypeName = (0, utils_1.getFilterTypeName)(table);
|
|
324
|
+
const orderByTypeName = (0, utils_1.getOrderByTypeName)(table);
|
|
324
325
|
const findFirstType = t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation([
|
|
325
326
|
t.tsTypeReference(t.identifier(selectTypeName)),
|
|
326
327
|
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
328
|
+
t.tsTypeReference(t.identifier(orderByTypeName)),
|
|
327
329
|
]));
|
|
328
330
|
// Intersect with { select: SelectType } to make select required
|
|
329
331
|
return t.tsIntersectionType([
|
|
@@ -716,6 +718,114 @@ function buildMutationHandler(table, operation, vectorFieldNames, targetName, ty
|
|
|
716
718
|
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch(`Failed to ${operation} record.`)),
|
|
717
719
|
]), false, true);
|
|
718
720
|
}
|
|
721
|
+
function buildBulkMutationHandler(table, operation, targetName) {
|
|
722
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
723
|
+
const selectObj = buildSelectObject(table);
|
|
724
|
+
// Map CLI op name to ORM method name
|
|
725
|
+
const ormMethod = (() => {
|
|
726
|
+
switch (operation) {
|
|
727
|
+
case 'bulk-create': return 'bulkCreate';
|
|
728
|
+
case 'bulk-upsert': return 'bulkUpsert';
|
|
729
|
+
case 'bulk-update': return 'bulkUpdate';
|
|
730
|
+
case 'bulk-delete': return 'bulkDelete';
|
|
731
|
+
}
|
|
732
|
+
})();
|
|
733
|
+
const tryBody = [];
|
|
734
|
+
if (operation === 'bulk-create' || operation === 'bulk-upsert') {
|
|
735
|
+
// Parse --data (JSON array) from argv
|
|
736
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
737
|
+
t.variableDeclarator(t.identifier('dataRaw'), t.memberExpression(t.identifier('argv'), t.identifier('data'))),
|
|
738
|
+
]));
|
|
739
|
+
tryBody.push(t.ifStatement(t.unaryExpression('!', t.identifier('dataRaw')), t.blockStatement([
|
|
740
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [t.stringLiteral(`--data is required for ${operation}. Provide a JSON array.`)])),
|
|
741
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
742
|
+
])));
|
|
743
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
744
|
+
t.variableDeclarator(t.identifier('data'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.tsAsExpression(t.identifier('dataRaw'), t.tsStringKeyword())])),
|
|
745
|
+
]));
|
|
746
|
+
let ormArgs;
|
|
747
|
+
if (operation === 'bulk-upsert') {
|
|
748
|
+
// Also parse --on-conflict
|
|
749
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
750
|
+
t.variableDeclarator(t.identifier('onConflictRaw'), t.memberExpression(t.identifier('argv'), t.identifier('on-conflict'))),
|
|
751
|
+
]));
|
|
752
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
753
|
+
t.variableDeclarator(t.identifier('onConflict'), t.conditionalExpression(t.identifier('onConflictRaw'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.tsAsExpression(t.identifier('onConflictRaw'), t.tsStringKeyword())]), t.objectExpression([]))),
|
|
754
|
+
]));
|
|
755
|
+
ormArgs = t.objectExpression([
|
|
756
|
+
t.objectProperty(t.identifier('data'), t.identifier('data')),
|
|
757
|
+
t.objectProperty(t.identifier('onConflict'), t.identifier('onConflict')),
|
|
758
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
759
|
+
]);
|
|
760
|
+
}
|
|
761
|
+
else {
|
|
762
|
+
ormArgs = t.objectExpression([
|
|
763
|
+
t.objectProperty(t.identifier('data'), t.identifier('data')),
|
|
764
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
765
|
+
]);
|
|
766
|
+
}
|
|
767
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
768
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
769
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, ormMethod, ormArgs))),
|
|
770
|
+
]));
|
|
771
|
+
}
|
|
772
|
+
else if (operation === 'bulk-update') {
|
|
773
|
+
// Parse --where (JSON) and --data (JSON)
|
|
774
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
775
|
+
t.variableDeclarator(t.identifier('whereRaw'), t.memberExpression(t.identifier('argv'), t.identifier('where'))),
|
|
776
|
+
]));
|
|
777
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
778
|
+
t.variableDeclarator(t.identifier('dataRaw'), t.memberExpression(t.identifier('argv'), t.identifier('data'))),
|
|
779
|
+
]));
|
|
780
|
+
tryBody.push(t.ifStatement(t.logicalExpression('||', t.unaryExpression('!', t.identifier('whereRaw')), t.unaryExpression('!', t.identifier('dataRaw'))), t.blockStatement([
|
|
781
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [t.stringLiteral('--where and --data are required for bulk-update. Provide JSON objects.')])),
|
|
782
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
783
|
+
])));
|
|
784
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
785
|
+
t.variableDeclarator(t.identifier('where'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.tsAsExpression(t.identifier('whereRaw'), t.tsStringKeyword())])),
|
|
786
|
+
]));
|
|
787
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
788
|
+
t.variableDeclarator(t.identifier('data'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.tsAsExpression(t.identifier('dataRaw'), t.tsStringKeyword())])),
|
|
789
|
+
]));
|
|
790
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
791
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
792
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, ormMethod, t.objectExpression([
|
|
793
|
+
t.objectProperty(t.identifier('where'), t.identifier('where')),
|
|
794
|
+
t.objectProperty(t.identifier('data'), t.identifier('data')),
|
|
795
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
796
|
+
])))),
|
|
797
|
+
]));
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
// bulk-delete: parse --where (JSON)
|
|
801
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
802
|
+
t.variableDeclarator(t.identifier('whereRaw'), t.memberExpression(t.identifier('argv'), t.identifier('where'))),
|
|
803
|
+
]));
|
|
804
|
+
tryBody.push(t.ifStatement(t.unaryExpression('!', t.identifier('whereRaw')), t.blockStatement([
|
|
805
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [t.stringLiteral('--where is required for bulk-delete. Provide a JSON object.')])),
|
|
806
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
807
|
+
])));
|
|
808
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
809
|
+
t.variableDeclarator(t.identifier('where'), t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('parse')), [t.tsAsExpression(t.identifier('whereRaw'), t.tsStringKeyword())])),
|
|
810
|
+
]));
|
|
811
|
+
tryBody.push(buildGetClientStatement(targetName));
|
|
812
|
+
tryBody.push(t.variableDeclaration('const', [
|
|
813
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, ormMethod, t.objectExpression([
|
|
814
|
+
t.objectProperty(t.identifier('where'), t.identifier('where')),
|
|
815
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
816
|
+
])))),
|
|
817
|
+
]));
|
|
818
|
+
}
|
|
819
|
+
tryBody.push(buildJsonLog(t.identifier('result')));
|
|
820
|
+
const argvParam = t.identifier('argv');
|
|
821
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
822
|
+
const prompterParam = t.identifier('prompter');
|
|
823
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
824
|
+
const handlerName = `handle${(0, utils_1.toPascalCase)(operation)}`;
|
|
825
|
+
return t.functionDeclaration(t.identifier(handlerName), [argvParam, prompterParam], t.blockStatement([
|
|
826
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch(`Failed to ${operation}.`)),
|
|
827
|
+
]), false, true);
|
|
828
|
+
}
|
|
719
829
|
function generateTableCommand(table, options) {
|
|
720
830
|
const { singularName, typeName } = (0, utils_1.getTableNames)(table);
|
|
721
831
|
const commandName = (0, inflekt_1.toKebabCase)(singularName);
|
|
@@ -793,6 +903,11 @@ function generateTableCommand(table, options) {
|
|
|
793
903
|
const embedderPath = options?.targetName ? '../../embedder' : '../embedder';
|
|
794
904
|
statements.push(createImportDeclaration(embedderPath, ['resolveEmbedder', 'autoEmbedWhere', 'autoEmbedInput']));
|
|
795
905
|
}
|
|
906
|
+
// Detect bulk mutations
|
|
907
|
+
const hasBulkCreate = !!table.query?.bulkInsert;
|
|
908
|
+
const hasBulkUpsert = !!table.query?.bulkUpsert;
|
|
909
|
+
const hasBulkUpdate = !!table.query?.bulkUpdate;
|
|
910
|
+
const hasBulkDelete = !!table.query?.bulkDelete;
|
|
796
911
|
const subcommands = ['list', 'find-first'];
|
|
797
912
|
if (hasSearchFields)
|
|
798
913
|
subcommands.push('search');
|
|
@@ -803,6 +918,14 @@ function generateTableCommand(table, options) {
|
|
|
803
918
|
subcommands.push('update');
|
|
804
919
|
if (hasDelete)
|
|
805
920
|
subcommands.push('delete');
|
|
921
|
+
if (hasBulkCreate)
|
|
922
|
+
subcommands.push('bulk-create');
|
|
923
|
+
if (hasBulkUpsert)
|
|
924
|
+
subcommands.push('bulk-upsert');
|
|
925
|
+
if (hasBulkUpdate)
|
|
926
|
+
subcommands.push('bulk-update');
|
|
927
|
+
if (hasBulkDelete)
|
|
928
|
+
subcommands.push('bulk-delete');
|
|
806
929
|
const usageLines = [
|
|
807
930
|
'',
|
|
808
931
|
`${commandName} <command>`,
|
|
@@ -823,7 +946,15 @@ function generateTableCommand(table, options) {
|
|
|
823
946
|
}
|
|
824
947
|
if (hasDelete)
|
|
825
948
|
usageLines.push(` delete Delete a ${singularName}`);
|
|
826
|
-
|
|
949
|
+
if (hasBulkCreate)
|
|
950
|
+
usageLines.push(` bulk-create Bulk create ${singularName} records`);
|
|
951
|
+
if (hasBulkUpsert)
|
|
952
|
+
usageLines.push(` bulk-upsert Bulk upsert ${singularName} records`);
|
|
953
|
+
if (hasBulkUpdate)
|
|
954
|
+
usageLines.push(` bulk-update Bulk update ${singularName} records`);
|
|
955
|
+
if (hasBulkDelete)
|
|
956
|
+
usageLines.push(` bulk-delete Bulk delete ${singularName} records`);
|
|
957
|
+
usageLines.push('', 'List Options:', ' --limit <n> Max number of records to return (forward pagination)', ' --last <n> Number of records from the end (backward pagination)', ' --after <cursor> Cursor for forward pagination', ' --before <cursor> Cursor for backward pagination', ' --offset <n> Number of records to skip', ' --select <fields> Comma-separated list of fields to return', ' --where.<field>.<op> Filter (dot-notation, e.g. --where.name.equalTo foo)', ' --condition.<f>.<op> Condition filter (dot-notation)', ' --orderBy <values> Comma-separated ordering values (e.g. NAME_ASC,CREATED_AT_DESC)', '', 'Find-First Options:', ' --select <fields> Comma-separated list of fields to return', ' --where.<field>.<op> Filter (dot-notation, e.g. --where.status.equalTo active)', ' --condition.<f>.<op> Condition filter (dot-notation)', ' --orderBy <values> Comma-separated ordering values (e.g. NAME_ASC,CREATED_AT_DESC)', '');
|
|
827
958
|
if (hasSearchFields) {
|
|
828
959
|
usageLines.push('Search Options:', ' <query> Search query string (required)', ' --limit <n> Max number of records to return', ' --offset <n> Number of records to skip', ' --select <fields> Comma-separated list of fields to return', ' --orderBy <values> Comma-separated list of ordering values');
|
|
829
960
|
if (hasEmbeddings) {
|
|
@@ -906,6 +1037,14 @@ function generateTableCommand(table, options) {
|
|
|
906
1037
|
statements.push(buildMutationHandler(table, 'update', vectorFieldNames, tn, options?.typeRegistry, ormTypes));
|
|
907
1038
|
if (hasDelete)
|
|
908
1039
|
statements.push(buildMutationHandler(table, 'delete', vectorFieldNames, tn, options?.typeRegistry, ormTypes));
|
|
1040
|
+
if (hasBulkCreate)
|
|
1041
|
+
statements.push(buildBulkMutationHandler(table, 'bulk-create', tn));
|
|
1042
|
+
if (hasBulkUpsert)
|
|
1043
|
+
statements.push(buildBulkMutationHandler(table, 'bulk-upsert', tn));
|
|
1044
|
+
if (hasBulkUpdate)
|
|
1045
|
+
statements.push(buildBulkMutationHandler(table, 'bulk-update', tn));
|
|
1046
|
+
if (hasBulkDelete)
|
|
1047
|
+
statements.push(buildBulkMutationHandler(table, 'bulk-delete', tn));
|
|
909
1048
|
const header = (0, utils_1.getGeneratedFileHeader)(`CLI commands for ${table.name}`);
|
|
910
1049
|
const code = (0, babel_ast_1.generateCode)(statements);
|
|
911
1050
|
return {
|
|
@@ -8,14 +8,6 @@ import type { GeneratedFile } from './executor-generator';
|
|
|
8
8
|
* and mutation input parsing.
|
|
9
9
|
*/
|
|
10
10
|
export declare function generateUtilsFile(): GeneratedFile;
|
|
11
|
-
/**
|
|
12
|
-
* Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
|
|
13
|
-
*
|
|
14
|
-
* Provides a GraphQLAdapter implementation using node:http/node:https
|
|
15
|
-
* instead of the Fetch API. This cleanly handles *.localhost subdomain
|
|
16
|
-
* routing (DNS resolution + Host header) without any global patching.
|
|
17
|
-
*/
|
|
18
|
-
export declare function generateNodeFetchFile(): GeneratedFile;
|
|
19
11
|
/**
|
|
20
12
|
* Generate an index.ts entry point file for the CLI.
|
|
21
13
|
*
|
|
@@ -34,7 +34,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateUtilsFile = generateUtilsFile;
|
|
37
|
-
exports.generateNodeFetchFile = generateNodeFetchFile;
|
|
38
37
|
exports.generateEntryPointFile = generateEntryPointFile;
|
|
39
38
|
exports.generateEmbedderFile = generateEmbedderFile;
|
|
40
39
|
const fs = __importStar(require("fs"));
|
|
@@ -79,19 +78,6 @@ function generateUtilsFile() {
|
|
|
79
78
|
content: readTemplateFile('cli-utils.ts', 'CLI utility functions for type coercion and input handling'),
|
|
80
79
|
};
|
|
81
80
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Generate a node-fetch.ts file with NodeHttpAdapter for CLI.
|
|
84
|
-
*
|
|
85
|
-
* Provides a GraphQLAdapter implementation using node:http/node:https
|
|
86
|
-
* instead of the Fetch API. This cleanly handles *.localhost subdomain
|
|
87
|
-
* routing (DNS resolution + Host header) without any global patching.
|
|
88
|
-
*/
|
|
89
|
-
function generateNodeFetchFile() {
|
|
90
|
-
return {
|
|
91
|
-
fileName: 'node-fetch.ts',
|
|
92
|
-
content: readTemplateFile('node-fetch.ts', 'Node HTTP adapter for localhost subdomain routing'),
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
81
|
/**
|
|
96
82
|
* Generate an index.ts entry point file for the CLI.
|
|
97
83
|
*
|
|
@@ -113,6 +113,24 @@ function generateEntityMutationKeysDeclaration(table, relationships) {
|
|
|
113
113
|
const deleteProp = t.objectProperty(t.identifier('delete'), deleteArrowFn);
|
|
114
114
|
(0, babel_ast_1.addJSDocComment)(deleteProp, [`Delete ${singularName} mutation key`]);
|
|
115
115
|
properties.push(deleteProp);
|
|
116
|
+
// Bulk mutation keys (only if table has bulk operations)
|
|
117
|
+
const bulkOps = [
|
|
118
|
+
{ key: 'bulkCreate', queryField: table.query?.bulkInsert },
|
|
119
|
+
{ key: 'bulkUpsert', queryField: table.query?.bulkUpsert },
|
|
120
|
+
{ key: 'bulkUpdate', queryField: table.query?.bulkUpdate },
|
|
121
|
+
{ key: 'bulkDelete', queryField: table.query?.bulkDelete },
|
|
122
|
+
];
|
|
123
|
+
for (const { key, queryField } of bulkOps) {
|
|
124
|
+
if (!queryField)
|
|
125
|
+
continue;
|
|
126
|
+
const arrowFn = t.arrowFunctionExpression([], (0, babel_ast_1.constArray)([
|
|
127
|
+
t.stringLiteral('mutation'),
|
|
128
|
+
t.stringLiteral(entityKey),
|
|
129
|
+
t.stringLiteral(key),
|
|
130
|
+
]));
|
|
131
|
+
const prop = t.objectProperty(t.identifier(key), arrowFn);
|
|
132
|
+
properties.push(prop);
|
|
133
|
+
}
|
|
116
134
|
return t.exportNamedDeclaration(t.variableDeclaration('const', [
|
|
117
135
|
t.variableDeclarator(t.identifier(keysName), (0, babel_ast_1.asConst)(t.objectExpression(properties))),
|
|
118
136
|
]));
|
|
@@ -416,6 +416,185 @@ function generateDeleteMutationHook(table, options = {}) {
|
|
|
416
416
|
content: (0, hooks_ast_1.generateHookFileCode)(table.description || `Delete mutation hook for ${typeName}`, statements),
|
|
417
417
|
};
|
|
418
418
|
}
|
|
419
|
+
function generateBulkMutationHook(table, op, options = {}) {
|
|
420
|
+
const { reactQueryEnabled = true, useCentralizedKeys = true } = options;
|
|
421
|
+
if (!reactQueryEnabled)
|
|
422
|
+
return null;
|
|
423
|
+
const mutationFieldName = (() => {
|
|
424
|
+
switch (op) {
|
|
425
|
+
case 'bulkCreate': return table.query?.bulkInsert;
|
|
426
|
+
case 'bulkUpsert': return table.query?.bulkUpsert;
|
|
427
|
+
case 'bulkUpdate': return table.query?.bulkUpdate;
|
|
428
|
+
case 'bulkDelete': return table.query?.bulkDelete;
|
|
429
|
+
}
|
|
430
|
+
})();
|
|
431
|
+
if (!mutationFieldName)
|
|
432
|
+
return null;
|
|
433
|
+
const { typeName, singularName } = (0, utils_1.getTableNames)(table);
|
|
434
|
+
const hookName = (() => {
|
|
435
|
+
switch (op) {
|
|
436
|
+
case 'bulkCreate': return (0, utils_1.getBulkCreateMutationHookName)(table);
|
|
437
|
+
case 'bulkUpsert': return (0, utils_1.getBulkUpsertMutationHookName)(table);
|
|
438
|
+
case 'bulkUpdate': return (0, utils_1.getBulkUpdateMutationHookName)(table);
|
|
439
|
+
case 'bulkDelete': return (0, utils_1.getBulkDeleteMutationHookName)(table);
|
|
440
|
+
}
|
|
441
|
+
})();
|
|
442
|
+
const fileName = (() => {
|
|
443
|
+
switch (op) {
|
|
444
|
+
case 'bulkCreate': return (0, utils_1.getBulkCreateMutationFileName)(table);
|
|
445
|
+
case 'bulkUpsert': return (0, utils_1.getBulkUpsertMutationFileName)(table);
|
|
446
|
+
case 'bulkUpdate': return (0, utils_1.getBulkUpdateMutationFileName)(table);
|
|
447
|
+
case 'bulkDelete': return (0, utils_1.getBulkDeleteMutationFileName)(table);
|
|
448
|
+
}
|
|
449
|
+
})();
|
|
450
|
+
const keysName = `${(0, utils_1.lcFirst)(typeName)}Keys`;
|
|
451
|
+
const mutationKeysName = `${(0, utils_1.lcFirst)(typeName)}MutationKeys`;
|
|
452
|
+
const selectTypeName = `${typeName}Select`;
|
|
453
|
+
const relationTypeName = `${typeName}WithRelations`;
|
|
454
|
+
const createInputTypeName = `Create${typeName}Input`;
|
|
455
|
+
const patchTypeName = `${typeName}Patch`;
|
|
456
|
+
const filterTypeName = `${typeName}Filter`;
|
|
457
|
+
const statements = [];
|
|
458
|
+
// Imports
|
|
459
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', [
|
|
460
|
+
'useMutation',
|
|
461
|
+
'useQueryClient',
|
|
462
|
+
]));
|
|
463
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('@tanstack/react-query', ['UseMutationOptions', 'UseMutationResult'], true));
|
|
464
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../client', ['getClient']));
|
|
465
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['buildSelectionArgs']));
|
|
466
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../selection', ['SelectionConfig'], true));
|
|
467
|
+
if (useCentralizedKeys) {
|
|
468
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../query-keys', [keysName]));
|
|
469
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../mutation-keys', [mutationKeysName]));
|
|
470
|
+
}
|
|
471
|
+
// Determine which types to import
|
|
472
|
+
const typeImports = [selectTypeName, relationTypeName];
|
|
473
|
+
if (op === 'bulkCreate' || op === 'bulkUpsert') {
|
|
474
|
+
typeImports.push(createInputTypeName);
|
|
475
|
+
}
|
|
476
|
+
if (op === 'bulkUpdate') {
|
|
477
|
+
typeImports.push(patchTypeName);
|
|
478
|
+
typeImports.push(filterTypeName);
|
|
479
|
+
}
|
|
480
|
+
if (op === 'bulkDelete') {
|
|
481
|
+
typeImports.push(filterTypeName);
|
|
482
|
+
}
|
|
483
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/input-types', typeImports, true));
|
|
484
|
+
statements.push((0, hooks_ast_1.createImportDeclaration)('../../orm/select-types', ['InferSelectResult', 'BulkMutationResult', 'HookStrictSelect'], true));
|
|
485
|
+
// Re-exports
|
|
486
|
+
statements.push((0, hooks_ast_1.createTypeReExport)(typeImports, '../../orm/input-types'));
|
|
487
|
+
// Build the variable type for the mutationFn parameter
|
|
488
|
+
const varType = (() => {
|
|
489
|
+
switch (op) {
|
|
490
|
+
case 'bulkCreate':
|
|
491
|
+
return t.tsTypeLiteral([
|
|
492
|
+
t.tsPropertySignature(t.identifier('data'), t.tsTypeAnnotation(t.tsArrayType(t.tsIndexedAccessType((0, hooks_ast_1.typeRef)(createInputTypeName), t.tsLiteralType(t.stringLiteral(singularName)))))),
|
|
493
|
+
(() => {
|
|
494
|
+
const p = t.tsPropertySignature(t.identifier('onConflict'), t.tsTypeAnnotation(t.tsUnknownKeyword()));
|
|
495
|
+
p.optional = true;
|
|
496
|
+
return p;
|
|
497
|
+
})(),
|
|
498
|
+
]);
|
|
499
|
+
case 'bulkUpsert':
|
|
500
|
+
return t.tsTypeLiteral([
|
|
501
|
+
t.tsPropertySignature(t.identifier('data'), t.tsTypeAnnotation(t.tsArrayType(t.tsIndexedAccessType((0, hooks_ast_1.typeRef)(createInputTypeName), t.tsLiteralType(t.stringLiteral(singularName)))))),
|
|
502
|
+
t.tsPropertySignature(t.identifier('onConflict'), t.tsTypeAnnotation(t.tsUnknownKeyword())),
|
|
503
|
+
]);
|
|
504
|
+
case 'bulkUpdate':
|
|
505
|
+
return t.tsTypeLiteral([
|
|
506
|
+
t.tsPropertySignature(t.identifier('where'), t.tsTypeAnnotation((0, hooks_ast_1.typeRef)(filterTypeName))),
|
|
507
|
+
t.tsPropertySignature(t.identifier('data'), t.tsTypeAnnotation((0, hooks_ast_1.typeRef)(patchTypeName))),
|
|
508
|
+
]);
|
|
509
|
+
case 'bulkDelete':
|
|
510
|
+
return t.tsTypeLiteral([
|
|
511
|
+
t.tsPropertySignature(t.identifier('where'), t.tsTypeAnnotation((0, hooks_ast_1.typeRef)(filterTypeName))),
|
|
512
|
+
]);
|
|
513
|
+
}
|
|
514
|
+
})();
|
|
515
|
+
// Result type: BulkMutationResult<InferSelectResult<Relation, S>>
|
|
516
|
+
const bulkResultType = (sel) => (0, hooks_ast_1.typeRef)('BulkMutationResult', [(0, hooks_ast_1.inferSelectResultType)(relationTypeName, sel)]);
|
|
517
|
+
// Overload with fields
|
|
518
|
+
const o1ParamType = t.tsIntersectionType([
|
|
519
|
+
t.tsTypeLiteral([
|
|
520
|
+
t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation(buildFieldsSelectionType((0, hooks_ast_1.sRef)(), selectTypeName))),
|
|
521
|
+
]),
|
|
522
|
+
(0, hooks_ast_1.useMutationOptionsType)(bulkResultType((0, hooks_ast_1.sRef)()), varType),
|
|
523
|
+
]);
|
|
524
|
+
const o1 = (0, hooks_ast_1.exportDeclareFunction)(hookName, (0, hooks_ast_1.createSTypeParam)(selectTypeName), [(0, hooks_ast_1.createFunctionParam)('params', o1ParamType)], (0, hooks_ast_1.useMutationResultType)(bulkResultType((0, hooks_ast_1.sRef)()), varType));
|
|
525
|
+
(0, hooks_ast_1.addJSDocComment)(o1, [
|
|
526
|
+
table.description || `Bulk ${op.replace('bulk', '').toLowerCase()} mutation hook for ${typeName}`,
|
|
527
|
+
]);
|
|
528
|
+
statements.push(o1);
|
|
529
|
+
// Implementation
|
|
530
|
+
const implSelProp = t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation((0, hooks_ast_1.selectionConfigType)((0, hooks_ast_1.typeRef)(selectTypeName))));
|
|
531
|
+
const implParamType = t.tsIntersectionType([
|
|
532
|
+
t.tsTypeLiteral([implSelProp]),
|
|
533
|
+
(0, hooks_ast_1.omitType)((0, hooks_ast_1.typeRef)('UseMutationOptions', [
|
|
534
|
+
t.tsAnyKeyword(),
|
|
535
|
+
(0, hooks_ast_1.typeRef)('Error'),
|
|
536
|
+
varType,
|
|
537
|
+
]), ['mutationFn']),
|
|
538
|
+
]);
|
|
539
|
+
const body = [];
|
|
540
|
+
body.push((0, hooks_ast_1.buildSelectionArgsCall)(selectTypeName));
|
|
541
|
+
body.push((0, hooks_ast_1.destructureParamsWithSelection)('mutationOptions'));
|
|
542
|
+
body.push((0, hooks_ast_1.voidStatement)('_selection'));
|
|
543
|
+
body.push((0, hooks_ast_1.constDecl)('queryClient', (0, hooks_ast_1.callExpr)('useQueryClient', [])));
|
|
544
|
+
const mutationKeyExpr = useCentralizedKeys
|
|
545
|
+
? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier(mutationKeysName), t.identifier(op)), [])
|
|
546
|
+
: undefined;
|
|
547
|
+
// Build the ORM method call depending on the operation
|
|
548
|
+
const ormMethodName = op;
|
|
549
|
+
const mutationFnArgs = (() => {
|
|
550
|
+
switch (op) {
|
|
551
|
+
case 'bulkCreate':
|
|
552
|
+
return t.objectExpression([
|
|
553
|
+
(0, hooks_ast_1.shorthandProp)('data'),
|
|
554
|
+
(0, hooks_ast_1.objectProp)('onConflict', t.memberExpression(t.identifier('vars'), t.identifier('onConflict'))),
|
|
555
|
+
(0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
|
|
556
|
+
]);
|
|
557
|
+
case 'bulkUpsert':
|
|
558
|
+
return t.objectExpression([
|
|
559
|
+
(0, hooks_ast_1.shorthandProp)('data'),
|
|
560
|
+
(0, hooks_ast_1.objectProp)('onConflict', t.memberExpression(t.identifier('vars'), t.identifier('onConflict'))),
|
|
561
|
+
(0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
|
|
562
|
+
]);
|
|
563
|
+
case 'bulkUpdate':
|
|
564
|
+
return t.objectExpression([
|
|
565
|
+
(0, hooks_ast_1.objectProp)('where', t.memberExpression(t.identifier('vars'), t.identifier('where'))),
|
|
566
|
+
(0, hooks_ast_1.shorthandProp)('data'),
|
|
567
|
+
(0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
|
|
568
|
+
]);
|
|
569
|
+
case 'bulkDelete':
|
|
570
|
+
return t.objectExpression([
|
|
571
|
+
(0, hooks_ast_1.objectProp)('where', t.memberExpression(t.identifier('vars'), t.identifier('where'))),
|
|
572
|
+
(0, hooks_ast_1.objectProp)('select', t.memberExpression(t.identifier('args'), t.identifier('select'))),
|
|
573
|
+
]);
|
|
574
|
+
}
|
|
575
|
+
})();
|
|
576
|
+
const varsParam = (0, hooks_ast_1.createFunctionParam)('vars', varType);
|
|
577
|
+
const mutationFnExpr = t.arrowFunctionExpression([varsParam], (0, hooks_ast_1.getClientCallUnwrap)(singularName, ormMethodName, mutationFnArgs));
|
|
578
|
+
// onSuccess: invalidate lists
|
|
579
|
+
const listKeyExpr = useCentralizedKeys
|
|
580
|
+
? (0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier(keysName), t.identifier('lists')), [])
|
|
581
|
+
: t.arrayExpression([
|
|
582
|
+
t.stringLiteral(typeName.toLowerCase()),
|
|
583
|
+
t.stringLiteral('list'),
|
|
584
|
+
]);
|
|
585
|
+
const onSuccessFn = t.arrowFunctionExpression([], t.blockStatement([
|
|
586
|
+
t.expressionStatement((0, hooks_ast_1.callExpr)(t.memberExpression(t.identifier('queryClient'), t.identifier('invalidateQueries')), [t.objectExpression([(0, hooks_ast_1.objectProp)('queryKey', listKeyExpr)])])),
|
|
587
|
+
]));
|
|
588
|
+
body.push((0, hooks_ast_1.returnUseMutation)(mutationFnExpr, [
|
|
589
|
+
(0, hooks_ast_1.objectProp)('onSuccess', onSuccessFn),
|
|
590
|
+
(0, hooks_ast_1.spreadObj)(t.identifier('mutationOptions')),
|
|
591
|
+
], mutationKeyExpr));
|
|
592
|
+
statements.push((0, hooks_ast_1.exportFunction)(hookName, null, [(0, hooks_ast_1.createFunctionParam)('params', implParamType)], body));
|
|
593
|
+
return {
|
|
594
|
+
fileName,
|
|
595
|
+
content: (0, hooks_ast_1.generateHookFileCode)(table.description || `Bulk ${op.replace('bulk', '').toLowerCase()} mutation hook for ${typeName}`, statements),
|
|
596
|
+
};
|
|
597
|
+
}
|
|
419
598
|
function generateAllMutationHooks(tables, options = {}) {
|
|
420
599
|
const files = [];
|
|
421
600
|
for (const table of tables) {
|
|
@@ -431,6 +610,14 @@ function generateAllMutationHooks(tables, options = {}) {
|
|
|
431
610
|
if (deleteHook) {
|
|
432
611
|
files.push(deleteHook);
|
|
433
612
|
}
|
|
613
|
+
// Bulk mutation hooks
|
|
614
|
+
const bulkOps = ['bulkCreate', 'bulkUpsert', 'bulkUpdate', 'bulkDelete'];
|
|
615
|
+
for (const op of bulkOps) {
|
|
616
|
+
const hook = generateBulkMutationHook(table, op, options);
|
|
617
|
+
if (hook) {
|
|
618
|
+
files.push(hook);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
434
621
|
}
|
|
435
622
|
return files;
|
|
436
623
|
}
|
|
@@ -31,6 +31,4 @@ export declare function generateSelectTypesFile(): GeneratedClientFile;
|
|
|
31
31
|
/**
|
|
32
32
|
* Generate the main index.ts with createClient factory
|
|
33
33
|
*/
|
|
34
|
-
export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean
|
|
35
|
-
nodeHttpAdapter?: boolean;
|
|
36
|
-
}): GeneratedClientFile;
|
|
34
|
+
export declare function generateCreateClientFile(tables: Table[], hasCustomQueries: boolean, hasCustomMutations: boolean): GeneratedClientFile;
|