@constructive-io/graphql-codegen 4.40.5 → 4.41.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/core/codegen/cli/table-command-generator.js +141 -2
- package/core/codegen/mutation-keys.js +18 -0
- package/core/codegen/mutations.js +187 -0
- package/core/codegen/orm/client-generator.js +0 -6
- 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/esm/core/codegen/cli/table-command-generator.js +141 -2
- package/esm/core/codegen/mutation-keys.js +18 -0
- package/esm/core/codegen/mutations.js +188 -1
- package/esm/core/codegen/orm/client-generator.js +0 -6
- 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/types/schema.d.ts +8 -0
- package/package.json +4 -4
- package/types/schema.d.ts +8 -0
|
@@ -120,7 +120,10 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
120
120
|
const pkField = pkFields[0];
|
|
121
121
|
const pluralQueryName = table.query?.all ?? pluralName;
|
|
122
122
|
const singleQueryName = table.query?.one;
|
|
123
|
-
|
|
123
|
+
// The unwrapped result key for findFirst/findOne — must be the friendly
|
|
124
|
+
// singular noun (e.g. "animal"), NOT the GraphQL by-id query name (e.g.
|
|
125
|
+
// "animalById"), so the surface aligns with the rest of the SDK.
|
|
126
|
+
const singleResultFieldName = singularName;
|
|
124
127
|
const createMutationName = table.query?.create ?? `create${typeName}`;
|
|
125
128
|
const updateMutationName = table.query?.update;
|
|
126
129
|
const deleteMutationName = table.query?.delete;
|
|
@@ -133,6 +136,12 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
133
136
|
const jt = allTables?.find((tb) => tb.name === r.junctionTable);
|
|
134
137
|
return jt?.query?.delete != null;
|
|
135
138
|
});
|
|
139
|
+
// Detect which bulk mutations are available for this table
|
|
140
|
+
const bulkInsertMutationName = table.query?.bulkInsert ?? null;
|
|
141
|
+
const bulkUpsertMutationName = table.query?.bulkUpsert ?? null;
|
|
142
|
+
const bulkUpdateMutationName = table.query?.bulkUpdate ?? null;
|
|
143
|
+
const bulkDeleteMutationName = table.query?.bulkDelete ?? null;
|
|
144
|
+
const hasBulk = !!(bulkInsertMutationName || bulkUpsertMutationName || bulkUpdateMutationName || bulkDeleteMutationName);
|
|
136
145
|
const queryBuilderImports = [
|
|
137
146
|
'QueryBuilder',
|
|
138
147
|
'buildFindManyDocument',
|
|
@@ -142,6 +151,10 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
142
151
|
'buildUpdateByPkDocument',
|
|
143
152
|
'buildDeleteByPkDocument',
|
|
144
153
|
...(needsJunctionRemove ? ['buildJunctionRemoveDocument'] : []),
|
|
154
|
+
...(bulkInsertMutationName ? ['buildBulkInsertDocument'] : []),
|
|
155
|
+
...(bulkUpsertMutationName ? ['buildBulkUpsertDocument'] : []),
|
|
156
|
+
...(bulkUpdateMutationName ? ['buildBulkUpdateDocument'] : []),
|
|
157
|
+
...(bulkDeleteMutationName ? ['buildBulkDeleteDocument'] : []),
|
|
145
158
|
];
|
|
146
159
|
statements.push(createImportDeclaration('../query-builder', queryBuilderImports));
|
|
147
160
|
statements.push(createImportDeclaration('../select-types', [
|
|
@@ -151,6 +164,7 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
151
164
|
'CreateArgs',
|
|
152
165
|
'UpdateArgs',
|
|
153
166
|
'DeleteArgs',
|
|
167
|
+
...(hasBulk ? ['BulkInsertArgs', 'BulkUpsertArgs', 'BulkUpdateArgs', 'BulkDeleteArgs', 'BulkMutationResult'] : []),
|
|
154
168
|
'InferSelectResult',
|
|
155
169
|
'StrictSelect',
|
|
156
170
|
], true));
|
|
@@ -229,15 +243,17 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
229
243
|
const findFirstTypeArgs = [
|
|
230
244
|
(sel) => sel,
|
|
231
245
|
() => t.tsTypeReference(t.identifier(whereTypeName)),
|
|
246
|
+
() => t.tsTypeReference(t.identifier(orderByTypeName)),
|
|
232
247
|
];
|
|
233
248
|
const argsType = (sel) => t.tsTypeReference(t.identifier('FindFirstArgs'), t.tsTypeParameterInstantiation(findFirstTypeArgs.map(fn => fn(sel))));
|
|
234
249
|
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
235
250
|
t.tsTypeLiteral([
|
|
236
|
-
t.tsPropertySignature(t.identifier(
|
|
237
|
-
t.
|
|
251
|
+
t.tsPropertySignature(t.identifier(singleResultFieldName), t.tsTypeAnnotation(t.tsUnionType([
|
|
252
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
238
253
|
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
239
254
|
sel,
|
|
240
|
-
]))
|
|
255
|
+
])),
|
|
256
|
+
t.tsNullKeyword(),
|
|
241
257
|
]))),
|
|
242
258
|
]),
|
|
243
259
|
])));
|
|
@@ -250,6 +266,10 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
250
266
|
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
251
267
|
const findFirstObjProps = [
|
|
252
268
|
t.objectProperty(t.identifier('where'), t.optionalMemberExpression(t.identifier('args'), t.identifier('where'), false, true)),
|
|
269
|
+
t.objectProperty(t.identifier('orderBy'), t.tsAsExpression(t.optionalMemberExpression(t.identifier('args'), t.identifier('orderBy'), false, true), t.tsUnionType([
|
|
270
|
+
t.tsArrayType(t.tsStringKeyword()),
|
|
271
|
+
t.tsUndefinedKeyword(),
|
|
272
|
+
]))),
|
|
253
273
|
];
|
|
254
274
|
const bodyArgs = [
|
|
255
275
|
t.stringLiteral(typeName),
|
|
@@ -257,9 +277,23 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
257
277
|
selectExpr,
|
|
258
278
|
t.objectExpression(findFirstObjProps),
|
|
259
279
|
t.stringLiteral(whereTypeName),
|
|
280
|
+
t.stringLiteral(orderByTypeName),
|
|
260
281
|
t.identifier('connectionFieldsMap'),
|
|
261
282
|
];
|
|
262
|
-
|
|
283
|
+
const transformDataParam = t.identifier('data');
|
|
284
|
+
const transformedNodesProp = t.tsPropertySignature(t.identifier('nodes'), t.tsTypeAnnotation(t.tsArrayType(t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
285
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
286
|
+
sRef(),
|
|
287
|
+
])))));
|
|
288
|
+
transformedNodesProp.optional = true;
|
|
289
|
+
const transformedCollectionProp = t.tsPropertySignature(t.identifier(pluralQueryName), t.tsTypeAnnotation(t.tsTypeLiteral([transformedNodesProp])));
|
|
290
|
+
transformedCollectionProp.optional = true;
|
|
291
|
+
transformDataParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeLiteral([transformedCollectionProp]));
|
|
292
|
+
const firstNodeExpr = t.optionalMemberExpression(t.optionalMemberExpression(t.memberExpression(t.identifier('data'), t.identifier(pluralQueryName)), t.identifier('nodes'), false, true), t.numericLiteral(0), true, true);
|
|
293
|
+
const transformFn = t.arrowFunctionExpression([transformDataParam], t.objectExpression([
|
|
294
|
+
t.objectProperty(t.stringLiteral(singleResultFieldName), t.logicalExpression('??', firstNodeExpr, t.nullLiteral())),
|
|
295
|
+
]));
|
|
296
|
+
classBody.push(createClassMethod('findFirst', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildFindFirstDocument', bodyArgs, 'query', typeName, singleResultFieldName, [t.objectProperty(t.identifier('transform'), transformFn)])));
|
|
263
297
|
}
|
|
264
298
|
// ── findOne ────────────────────────────────────────────────────────────
|
|
265
299
|
if ((0, utils_1.hasValidPrimaryKey)(table)) {
|
|
@@ -450,6 +484,134 @@ function generateModelFile(table, _useSharedTypes, options, allTables) {
|
|
|
450
484
|
];
|
|
451
485
|
classBody.push(createClassMethod('delete', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildDeleteByPkDocument', bodyArgs, 'mutation', typeName, deleteMutationName)));
|
|
452
486
|
}
|
|
487
|
+
// ── bulkCreate ──────────────────────────────────────────────────────────
|
|
488
|
+
if (bulkInsertMutationName) {
|
|
489
|
+
const bulkInsertInputTypeName = `BulkCreate${typeName}Input`;
|
|
490
|
+
const dataType = () => t.tsIndexedAccessType(t.tsTypeReference(t.identifier(createInputTypeName)), t.tsLiteralType(t.stringLiteral(singularName)));
|
|
491
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('BulkInsertArgs'), t.tsTypeParameterInstantiation([sel, dataType()]));
|
|
492
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
493
|
+
t.tsTypeReference(t.identifier('BulkMutationResult'), t.tsTypeParameterInstantiation([
|
|
494
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
495
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
496
|
+
sel,
|
|
497
|
+
])),
|
|
498
|
+
])),
|
|
499
|
+
])));
|
|
500
|
+
const implParam = t.identifier('args');
|
|
501
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
502
|
+
argsType(sRef()),
|
|
503
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
504
|
+
strictSelectGuard(selectTypeName),
|
|
505
|
+
]));
|
|
506
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
507
|
+
const bodyArgs = [
|
|
508
|
+
t.stringLiteral(typeName),
|
|
509
|
+
t.stringLiteral(bulkInsertMutationName),
|
|
510
|
+
selectExpr,
|
|
511
|
+
t.memberExpression(t.identifier('args'), t.identifier('data')),
|
|
512
|
+
t.stringLiteral(bulkInsertInputTypeName),
|
|
513
|
+
t.memberExpression(t.identifier('args'), t.identifier('onConflict')),
|
|
514
|
+
t.identifier('connectionFieldsMap'),
|
|
515
|
+
];
|
|
516
|
+
classBody.push(createClassMethod('bulkCreate', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildBulkInsertDocument', bodyArgs, 'mutation', typeName, bulkInsertMutationName)));
|
|
517
|
+
}
|
|
518
|
+
// ── bulkUpsert ─────────────────────────────────────────────────────────
|
|
519
|
+
if (bulkUpsertMutationName) {
|
|
520
|
+
const bulkUpsertInputTypeName = `BulkUpsert${typeName}Input`;
|
|
521
|
+
const dataType = () => t.tsIndexedAccessType(t.tsTypeReference(t.identifier(createInputTypeName)), t.tsLiteralType(t.stringLiteral(singularName)));
|
|
522
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('BulkUpsertArgs'), t.tsTypeParameterInstantiation([sel, dataType()]));
|
|
523
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
524
|
+
t.tsTypeReference(t.identifier('BulkMutationResult'), t.tsTypeParameterInstantiation([
|
|
525
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
526
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
527
|
+
sel,
|
|
528
|
+
])),
|
|
529
|
+
])),
|
|
530
|
+
])));
|
|
531
|
+
const implParam = t.identifier('args');
|
|
532
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
533
|
+
argsType(sRef()),
|
|
534
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
535
|
+
strictSelectGuard(selectTypeName),
|
|
536
|
+
]));
|
|
537
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
538
|
+
const bodyArgs = [
|
|
539
|
+
t.stringLiteral(typeName),
|
|
540
|
+
t.stringLiteral(bulkUpsertMutationName),
|
|
541
|
+
selectExpr,
|
|
542
|
+
t.memberExpression(t.identifier('args'), t.identifier('data')),
|
|
543
|
+
t.stringLiteral(bulkUpsertInputTypeName),
|
|
544
|
+
t.memberExpression(t.identifier('args'), t.identifier('onConflict')),
|
|
545
|
+
t.identifier('connectionFieldsMap'),
|
|
546
|
+
];
|
|
547
|
+
classBody.push(createClassMethod('bulkUpsert', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildBulkUpsertDocument', bodyArgs, 'mutation', typeName, bulkUpsertMutationName)));
|
|
548
|
+
}
|
|
549
|
+
// ── bulkUpdate ─────────────────────────────────────────────────────────
|
|
550
|
+
if (bulkUpdateMutationName) {
|
|
551
|
+
const bulkUpdateInputTypeName = `BulkUpdate${typeName}Input`;
|
|
552
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('BulkUpdateArgs'), t.tsTypeParameterInstantiation([
|
|
553
|
+
sel,
|
|
554
|
+
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
555
|
+
t.tsTypeReference(t.identifier(patchTypeName)),
|
|
556
|
+
]));
|
|
557
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
558
|
+
t.tsTypeReference(t.identifier('BulkMutationResult'), t.tsTypeParameterInstantiation([
|
|
559
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
560
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
561
|
+
sel,
|
|
562
|
+
])),
|
|
563
|
+
])),
|
|
564
|
+
])));
|
|
565
|
+
const implParam = t.identifier('args');
|
|
566
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
567
|
+
argsType(sRef()),
|
|
568
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
569
|
+
strictSelectGuard(selectTypeName),
|
|
570
|
+
]));
|
|
571
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
572
|
+
const bodyArgs = [
|
|
573
|
+
t.stringLiteral(typeName),
|
|
574
|
+
t.stringLiteral(bulkUpdateMutationName),
|
|
575
|
+
selectExpr,
|
|
576
|
+
t.memberExpression(t.identifier('args'), t.identifier('where')),
|
|
577
|
+
t.memberExpression(t.identifier('args'), t.identifier('data')),
|
|
578
|
+
t.stringLiteral(bulkUpdateInputTypeName),
|
|
579
|
+
t.identifier('connectionFieldsMap'),
|
|
580
|
+
];
|
|
581
|
+
classBody.push(createClassMethod('bulkUpdate', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildBulkUpdateDocument', bodyArgs, 'mutation', typeName, bulkUpdateMutationName)));
|
|
582
|
+
}
|
|
583
|
+
// ── bulkDelete ─────────────────────────────────────────────────────────
|
|
584
|
+
if (bulkDeleteMutationName) {
|
|
585
|
+
const bulkDeleteInputTypeName = `BulkDelete${typeName}Input`;
|
|
586
|
+
const argsType = (sel) => t.tsTypeReference(t.identifier('BulkDeleteArgs'), t.tsTypeParameterInstantiation([
|
|
587
|
+
sel,
|
|
588
|
+
t.tsTypeReference(t.identifier(whereTypeName)),
|
|
589
|
+
]));
|
|
590
|
+
const retType = (sel) => t.tsTypeAnnotation(t.tsTypeReference(t.identifier('QueryBuilder'), t.tsTypeParameterInstantiation([
|
|
591
|
+
t.tsTypeReference(t.identifier('BulkMutationResult'), t.tsTypeParameterInstantiation([
|
|
592
|
+
t.tsTypeReference(t.identifier('InferSelectResult'), t.tsTypeParameterInstantiation([
|
|
593
|
+
t.tsTypeReference(t.identifier(relationTypeName)),
|
|
594
|
+
sel,
|
|
595
|
+
])),
|
|
596
|
+
])),
|
|
597
|
+
])));
|
|
598
|
+
const implParam = t.identifier('args');
|
|
599
|
+
implParam.typeAnnotation = t.tsTypeAnnotation(t.tsIntersectionType([
|
|
600
|
+
argsType(sRef()),
|
|
601
|
+
t.tsTypeLiteral([requiredSelectProp()]),
|
|
602
|
+
strictSelectGuard(selectTypeName),
|
|
603
|
+
]));
|
|
604
|
+
const selectExpr = t.memberExpression(t.identifier('args'), t.identifier('select'));
|
|
605
|
+
const bodyArgs = [
|
|
606
|
+
t.stringLiteral(typeName),
|
|
607
|
+
t.stringLiteral(bulkDeleteMutationName),
|
|
608
|
+
selectExpr,
|
|
609
|
+
t.memberExpression(t.identifier('args'), t.identifier('where')),
|
|
610
|
+
t.stringLiteral(bulkDeleteInputTypeName),
|
|
611
|
+
t.identifier('connectionFieldsMap'),
|
|
612
|
+
];
|
|
613
|
+
classBody.push(createClassMethod('bulkDelete', createTypeParam(selectTypeName), [implParam], retType(sRef()), buildMethodBody('buildBulkDeleteDocument', bodyArgs, 'mutation', typeName, bulkDeleteMutationName)));
|
|
614
|
+
}
|
|
453
615
|
// ── M:N add/remove methods ────────────────────────────────────────────
|
|
454
616
|
for (const rel of m2nRels) {
|
|
455
617
|
if (!rel.fieldName)
|
|
@@ -167,9 +167,10 @@ export interface FindManyArgs<TSelect, TWhere, TOrderBy> {
|
|
|
167
167
|
/**
|
|
168
168
|
* Arguments for findFirst/findUnique operations
|
|
169
169
|
*/
|
|
170
|
-
export interface FindFirstArgs<TSelect, TWhere> {
|
|
170
|
+
export interface FindFirstArgs<TSelect, TWhere, TOrderBy> {
|
|
171
171
|
select?: TSelect;
|
|
172
172
|
where?: TWhere;
|
|
173
|
+
orderBy?: TOrderBy[];
|
|
173
174
|
}
|
|
174
175
|
/**
|
|
175
176
|
* Arguments for create operations
|
package/core/codegen/queries.js
CHANGED
|
@@ -471,7 +471,7 @@ function generateSingleQueryHook(table, options = {}) {
|
|
|
471
471
|
t.tsPropertySignature(t.identifier(pkFieldName), t.tsTypeAnnotation(pkTsType)),
|
|
472
472
|
t.tsPropertySignature(t.identifier('selection'), t.tsTypeAnnotation((0, hooks_ast_1.selectionConfigType)((0, hooks_ast_1.typeRef)(selectTypeName)))),
|
|
473
473
|
];
|
|
474
|
-
statements.push((0, hooks_ast_1.exportAsyncFunction)(fetchFnName, null, [(0, hooks_ast_1.createFunctionParam)('params', t.tsTypeLiteral(fImplProps))], fBody));
|
|
474
|
+
statements.push((0, hooks_ast_1.exportAsyncFunction)(fetchFnName, null, [(0, hooks_ast_1.createFunctionParam)('params', t.tsTypeLiteral(fImplProps))], fBody, (0, hooks_ast_1.typeRef)('Promise', [t.tsAnyKeyword()])));
|
|
475
475
|
}
|
|
476
476
|
// Prefetch function
|
|
477
477
|
if (reactQueryEnabled) {
|
|
@@ -283,8 +283,8 @@ export function parseFindManyArgs<T = Record<string, unknown>>(
|
|
|
283
283
|
|
|
284
284
|
/**
|
|
285
285
|
* Build findFirst args from CLI argv.
|
|
286
|
-
* Like parseFindManyArgs but
|
|
287
|
-
*
|
|
286
|
+
* Like parseFindManyArgs but without pagination flags (no limit/offset/after/before/last)
|
|
287
|
+
* — findFirst returns the first matching record. Supports select, where, and orderBy.
|
|
288
288
|
*/
|
|
289
289
|
export function parseFindFirstArgs<T = Record<string, unknown>>(
|
|
290
290
|
argv: Record<string, unknown>,
|
|
@@ -293,10 +293,12 @@ export function parseFindFirstArgs<T = Record<string, unknown>>(
|
|
|
293
293
|
const select = parseSelectFlag(argv, defaultSelect);
|
|
294
294
|
const parsed = unflattenDotNotation(argv);
|
|
295
295
|
const where = parsed.where;
|
|
296
|
+
const orderBy = parseOrderByFlag(argv);
|
|
296
297
|
|
|
297
298
|
return {
|
|
298
299
|
select,
|
|
299
300
|
...(where !== undefined ? { where } : {}),
|
|
301
|
+
...(orderBy !== undefined ? { orderBy } : {}),
|
|
300
302
|
} as unknown as T;
|
|
301
303
|
}
|
|
302
304
|
|
|
@@ -343,8 +343,9 @@ export function buildFindFirstDocument<TSelect, TWhere>(
|
|
|
343
343
|
operationName: string,
|
|
344
344
|
queryField: string,
|
|
345
345
|
select: TSelect,
|
|
346
|
-
args: { where?: TWhere },
|
|
346
|
+
args: { where?: TWhere; orderBy?: string[] },
|
|
347
347
|
filterTypeName: string,
|
|
348
|
+
orderByTypeName: string,
|
|
348
349
|
connectionFieldsMap?: Record<string, Record<string, string>>,
|
|
349
350
|
): { document: string; variables: Record<string, unknown> } {
|
|
350
351
|
const selections = select
|
|
@@ -376,6 +377,16 @@ export function buildFindFirstDocument<TSelect, TWhere>(
|
|
|
376
377
|
queryArgs,
|
|
377
378
|
variables,
|
|
378
379
|
);
|
|
380
|
+
addVariable(
|
|
381
|
+
{
|
|
382
|
+
varName: 'orderBy',
|
|
383
|
+
typeName: '[' + orderByTypeName + '!]',
|
|
384
|
+
value: args.orderBy?.length ? args.orderBy : undefined,
|
|
385
|
+
},
|
|
386
|
+
variableDefinitions,
|
|
387
|
+
queryArgs,
|
|
388
|
+
variables,
|
|
389
|
+
);
|
|
379
390
|
|
|
380
391
|
const document = t.document({
|
|
381
392
|
definitions: [
|
|
@@ -962,3 +973,161 @@ function buildValueAst(
|
|
|
962
973
|
|
|
963
974
|
throw new Error('Unsupported value type: ' + typeof value);
|
|
964
975
|
}
|
|
976
|
+
|
|
977
|
+
// ============================================================================
|
|
978
|
+
// Bulk Mutation Document Builders
|
|
979
|
+
// ============================================================================
|
|
980
|
+
|
|
981
|
+
export function buildBulkInsertDocument<TSelect, TData>(
|
|
982
|
+
operationName: string,
|
|
983
|
+
mutationField: string,
|
|
984
|
+
select: TSelect,
|
|
985
|
+
data: TData[],
|
|
986
|
+
inputTypeName: string,
|
|
987
|
+
onConflict?: unknown,
|
|
988
|
+
connectionFieldsMap?: Record<string, Record<string, string>>,
|
|
989
|
+
): { document: string; variables: Record<string, unknown> } {
|
|
990
|
+
const selections = select
|
|
991
|
+
? buildSelections(
|
|
992
|
+
select as Record<string, unknown>,
|
|
993
|
+
connectionFieldsMap,
|
|
994
|
+
operationName,
|
|
995
|
+
)
|
|
996
|
+
: [t.field({ name: 'id' })];
|
|
997
|
+
|
|
998
|
+
return {
|
|
999
|
+
document: buildInputMutationDocument({
|
|
1000
|
+
operationName,
|
|
1001
|
+
mutationField,
|
|
1002
|
+
inputTypeName,
|
|
1003
|
+
resultSelections: [
|
|
1004
|
+
t.field({ name: 'affectedCount' }),
|
|
1005
|
+
t.field({
|
|
1006
|
+
name: 'returning',
|
|
1007
|
+
selectionSet: t.selectionSet({ selections }),
|
|
1008
|
+
}),
|
|
1009
|
+
],
|
|
1010
|
+
}),
|
|
1011
|
+
variables: {
|
|
1012
|
+
input: {
|
|
1013
|
+
values: data,
|
|
1014
|
+
...(onConflict ? { onConflict } : {}),
|
|
1015
|
+
},
|
|
1016
|
+
},
|
|
1017
|
+
};
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
export function buildBulkUpsertDocument<TSelect, TData>(
|
|
1021
|
+
operationName: string,
|
|
1022
|
+
mutationField: string,
|
|
1023
|
+
select: TSelect,
|
|
1024
|
+
data: TData[],
|
|
1025
|
+
inputTypeName: string,
|
|
1026
|
+
onConflict: unknown,
|
|
1027
|
+
connectionFieldsMap?: Record<string, Record<string, string>>,
|
|
1028
|
+
): { document: string; variables: Record<string, unknown> } {
|
|
1029
|
+
const selections = select
|
|
1030
|
+
? buildSelections(
|
|
1031
|
+
select as Record<string, unknown>,
|
|
1032
|
+
connectionFieldsMap,
|
|
1033
|
+
operationName,
|
|
1034
|
+
)
|
|
1035
|
+
: [t.field({ name: 'id' })];
|
|
1036
|
+
|
|
1037
|
+
return {
|
|
1038
|
+
document: buildInputMutationDocument({
|
|
1039
|
+
operationName,
|
|
1040
|
+
mutationField,
|
|
1041
|
+
inputTypeName,
|
|
1042
|
+
resultSelections: [
|
|
1043
|
+
t.field({ name: 'affectedCount' }),
|
|
1044
|
+
t.field({
|
|
1045
|
+
name: 'returning',
|
|
1046
|
+
selectionSet: t.selectionSet({ selections }),
|
|
1047
|
+
}),
|
|
1048
|
+
],
|
|
1049
|
+
}),
|
|
1050
|
+
variables: {
|
|
1051
|
+
input: {
|
|
1052
|
+
values: data,
|
|
1053
|
+
onConflict,
|
|
1054
|
+
},
|
|
1055
|
+
},
|
|
1056
|
+
};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
export function buildBulkUpdateDocument<TSelect, TWhere, TData>(
|
|
1060
|
+
operationName: string,
|
|
1061
|
+
mutationField: string,
|
|
1062
|
+
select: TSelect,
|
|
1063
|
+
where: TWhere,
|
|
1064
|
+
data: TData,
|
|
1065
|
+
inputTypeName: string,
|
|
1066
|
+
connectionFieldsMap?: Record<string, Record<string, string>>,
|
|
1067
|
+
): { document: string; variables: Record<string, unknown> } {
|
|
1068
|
+
const selections = select
|
|
1069
|
+
? buildSelections(
|
|
1070
|
+
select as Record<string, unknown>,
|
|
1071
|
+
connectionFieldsMap,
|
|
1072
|
+
operationName,
|
|
1073
|
+
)
|
|
1074
|
+
: [t.field({ name: 'id' })];
|
|
1075
|
+
|
|
1076
|
+
return {
|
|
1077
|
+
document: buildInputMutationDocument({
|
|
1078
|
+
operationName,
|
|
1079
|
+
mutationField,
|
|
1080
|
+
inputTypeName,
|
|
1081
|
+
resultSelections: [
|
|
1082
|
+
t.field({ name: 'affectedCount' }),
|
|
1083
|
+
t.field({
|
|
1084
|
+
name: 'returning',
|
|
1085
|
+
selectionSet: t.selectionSet({ selections }),
|
|
1086
|
+
}),
|
|
1087
|
+
],
|
|
1088
|
+
}),
|
|
1089
|
+
variables: {
|
|
1090
|
+
input: {
|
|
1091
|
+
where,
|
|
1092
|
+
patch: data,
|
|
1093
|
+
},
|
|
1094
|
+
},
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
export function buildBulkDeleteDocument<TSelect, TWhere>(
|
|
1099
|
+
operationName: string,
|
|
1100
|
+
mutationField: string,
|
|
1101
|
+
select: TSelect,
|
|
1102
|
+
where: TWhere,
|
|
1103
|
+
inputTypeName: string,
|
|
1104
|
+
connectionFieldsMap?: Record<string, Record<string, string>>,
|
|
1105
|
+
): { document: string; variables: Record<string, unknown> } {
|
|
1106
|
+
const selections = select
|
|
1107
|
+
? buildSelections(
|
|
1108
|
+
select as Record<string, unknown>,
|
|
1109
|
+
connectionFieldsMap,
|
|
1110
|
+
operationName,
|
|
1111
|
+
)
|
|
1112
|
+
: [t.field({ name: 'id' })];
|
|
1113
|
+
|
|
1114
|
+
return {
|
|
1115
|
+
document: buildInputMutationDocument({
|
|
1116
|
+
operationName,
|
|
1117
|
+
mutationField,
|
|
1118
|
+
inputTypeName,
|
|
1119
|
+
resultSelections: [
|
|
1120
|
+
t.field({ name: 'affectedCount' }),
|
|
1121
|
+
t.field({
|
|
1122
|
+
name: 'returning',
|
|
1123
|
+
selectionSet: t.selectionSet({ selections }),
|
|
1124
|
+
}),
|
|
1125
|
+
],
|
|
1126
|
+
}),
|
|
1127
|
+
variables: {
|
|
1128
|
+
input: {
|
|
1129
|
+
where,
|
|
1130
|
+
},
|
|
1131
|
+
},
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
@@ -32,9 +32,10 @@ export interface FindManyArgs<TSelect, TWhere, TOrderBy = never> {
|
|
|
32
32
|
offset?: number;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
export interface FindFirstArgs<TSelect, TWhere> {
|
|
35
|
+
export interface FindFirstArgs<TSelect, TWhere, TOrderBy> {
|
|
36
36
|
select?: TSelect;
|
|
37
37
|
where?: TWhere;
|
|
38
|
+
orderBy?: TOrderBy[];
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
export interface CreateArgs<TSelect, TData> {
|
|
@@ -61,6 +62,34 @@ export interface DeleteArgs<TWhere, TSelect = undefined> {
|
|
|
61
62
|
select?: TSelect;
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
export interface BulkInsertArgs<TSelect, TData, TOnConflict = unknown> {
|
|
66
|
+
data: TData[];
|
|
67
|
+
select?: TSelect;
|
|
68
|
+
onConflict?: TOnConflict;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface BulkUpsertArgs<TSelect, TData, TOnConflict = unknown> {
|
|
72
|
+
data: TData[];
|
|
73
|
+
select?: TSelect;
|
|
74
|
+
onConflict: TOnConflict;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface BulkUpdateArgs<TSelect, TWhere, TData> {
|
|
78
|
+
where: TWhere;
|
|
79
|
+
data: TData;
|
|
80
|
+
select?: TSelect;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface BulkDeleteArgs<TSelect, TWhere> {
|
|
84
|
+
where: TWhere;
|
|
85
|
+
select?: TSelect;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface BulkMutationResult<T> {
|
|
89
|
+
affectedCount: number;
|
|
90
|
+
returning: T[];
|
|
91
|
+
}
|
|
92
|
+
|
|
64
93
|
type DepthLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
|
65
94
|
type DecrementDepth = {
|
|
66
95
|
0: 0;
|
package/core/codegen/utils.d.ts
CHANGED
|
@@ -101,6 +101,14 @@ export declare function getUpdateMutationName(table: Table): string;
|
|
|
101
101
|
* Get the GraphQL mutation name for deleting
|
|
102
102
|
*/
|
|
103
103
|
export declare function getDeleteMutationName(table: Table): string;
|
|
104
|
+
export declare function getBulkCreateMutationHookName(table: Table): string;
|
|
105
|
+
export declare function getBulkUpsertMutationHookName(table: Table): string;
|
|
106
|
+
export declare function getBulkUpdateMutationHookName(table: Table): string;
|
|
107
|
+
export declare function getBulkDeleteMutationHookName(table: Table): string;
|
|
108
|
+
export declare function getBulkCreateMutationFileName(table: Table): string;
|
|
109
|
+
export declare function getBulkUpsertMutationFileName(table: Table): string;
|
|
110
|
+
export declare function getBulkUpdateMutationFileName(table: Table): string;
|
|
111
|
+
export declare function getBulkDeleteMutationFileName(table: Table): string;
|
|
104
112
|
/**
|
|
105
113
|
* Get PostGraphile filter type name
|
|
106
114
|
* e.g., "CarFilter"
|
package/core/codegen/utils.js
CHANGED
|
@@ -20,6 +20,14 @@ exports.getSingleRowQueryName = getSingleRowQueryName;
|
|
|
20
20
|
exports.getCreateMutationName = getCreateMutationName;
|
|
21
21
|
exports.getUpdateMutationName = getUpdateMutationName;
|
|
22
22
|
exports.getDeleteMutationName = getDeleteMutationName;
|
|
23
|
+
exports.getBulkCreateMutationHookName = getBulkCreateMutationHookName;
|
|
24
|
+
exports.getBulkUpsertMutationHookName = getBulkUpsertMutationHookName;
|
|
25
|
+
exports.getBulkUpdateMutationHookName = getBulkUpdateMutationHookName;
|
|
26
|
+
exports.getBulkDeleteMutationHookName = getBulkDeleteMutationHookName;
|
|
27
|
+
exports.getBulkCreateMutationFileName = getBulkCreateMutationFileName;
|
|
28
|
+
exports.getBulkUpsertMutationFileName = getBulkUpsertMutationFileName;
|
|
29
|
+
exports.getBulkUpdateMutationFileName = getBulkUpdateMutationFileName;
|
|
30
|
+
exports.getBulkDeleteMutationFileName = getBulkDeleteMutationFileName;
|
|
23
31
|
exports.getFilterTypeName = getFilterTypeName;
|
|
24
32
|
exports.getOrderByTypeName = getOrderByTypeName;
|
|
25
33
|
exports.getConditionTypeName = getConditionTypeName;
|
|
@@ -201,6 +209,37 @@ function getDeleteMutationName(table) {
|
|
|
201
209
|
return table.query?.delete || `delete${table.name}`;
|
|
202
210
|
}
|
|
203
211
|
// ============================================================================
|
|
212
|
+
// Bulk mutation naming helpers
|
|
213
|
+
// ============================================================================
|
|
214
|
+
function getBulkCreateMutationHookName(table) {
|
|
215
|
+
const { typeName } = getTableNames(table);
|
|
216
|
+
return `useBulkCreate${typeName}Mutation`;
|
|
217
|
+
}
|
|
218
|
+
function getBulkUpsertMutationHookName(table) {
|
|
219
|
+
const { typeName } = getTableNames(table);
|
|
220
|
+
return `useBulkUpsert${typeName}Mutation`;
|
|
221
|
+
}
|
|
222
|
+
function getBulkUpdateMutationHookName(table) {
|
|
223
|
+
const { typeName } = getTableNames(table);
|
|
224
|
+
return `useBulkUpdate${typeName}Mutation`;
|
|
225
|
+
}
|
|
226
|
+
function getBulkDeleteMutationHookName(table) {
|
|
227
|
+
const { typeName } = getTableNames(table);
|
|
228
|
+
return `useBulkDelete${typeName}Mutation`;
|
|
229
|
+
}
|
|
230
|
+
function getBulkCreateMutationFileName(table) {
|
|
231
|
+
return `${getBulkCreateMutationHookName(table)}.ts`;
|
|
232
|
+
}
|
|
233
|
+
function getBulkUpsertMutationFileName(table) {
|
|
234
|
+
return `${getBulkUpsertMutationHookName(table)}.ts`;
|
|
235
|
+
}
|
|
236
|
+
function getBulkUpdateMutationFileName(table) {
|
|
237
|
+
return `${getBulkUpdateMutationHookName(table)}.ts`;
|
|
238
|
+
}
|
|
239
|
+
function getBulkDeleteMutationFileName(table) {
|
|
240
|
+
return `${getBulkDeleteMutationHookName(table)}.ts`;
|
|
241
|
+
}
|
|
242
|
+
// ============================================================================
|
|
204
243
|
// Type names
|
|
205
244
|
// ============================================================================
|
|
206
245
|
/**
|