@vantreeseba/drizzle-graphql 5.3.0 → 5.5.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/dist/index.js CHANGED
@@ -605,6 +605,203 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
605
605
  queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
606
606
  };
607
607
  };
608
+ var createMutationTxCtx = (options) => options ? { timeoutMs: options.timeoutMs, fieldNames: /* @__PURE__ */ new Set(), states: /* @__PURE__ */ new WeakMap() } : void 0;
609
+ var includedByDirectives = (node, variables) => {
610
+ for (const directive of node.directives ?? []) {
611
+ const name = directive.name.value;
612
+ if (name !== "skip" && name !== "include") {
613
+ continue;
614
+ }
615
+ const ifArg = directive.arguments?.find((arg) => arg.name.value === "if");
616
+ let value;
617
+ if (ifArg?.value.kind === "BooleanValue") {
618
+ value = ifArg.value.value;
619
+ } else if (ifArg?.value.kind === "Variable") {
620
+ value = variables?.[ifArg.value.name.value];
621
+ }
622
+ if (name === "skip" && value === true) {
623
+ return false;
624
+ }
625
+ if (name === "include" && value !== true) {
626
+ return false;
627
+ }
628
+ }
629
+ return true;
630
+ };
631
+ var collectRootMutationKeys = (selectionSet, fragments, variables, known, keys, visitedFragments) => {
632
+ for (const selection of selectionSet.selections) {
633
+ if (!includedByDirectives(selection, variables)) {
634
+ continue;
635
+ }
636
+ if (selection.kind === "Field") {
637
+ const name = selection.name.value;
638
+ if (name === "__typename") {
639
+ continue;
640
+ }
641
+ if (!known.has(name)) {
642
+ return false;
643
+ }
644
+ keys.add(selection.alias?.value ?? name);
645
+ } else if (selection.kind === "InlineFragment") {
646
+ if (!collectRootMutationKeys(selection.selectionSet, fragments, variables, known, keys, visitedFragments)) {
647
+ return false;
648
+ }
649
+ } else if (selection.kind === "FragmentSpread") {
650
+ const fragmentName = selection.name.value;
651
+ if (visitedFragments.has(fragmentName)) {
652
+ continue;
653
+ }
654
+ visitedFragments.add(fragmentName);
655
+ const fragment = fragments?.[fragmentName];
656
+ if (!fragment) {
657
+ return false;
658
+ }
659
+ if (!collectRootMutationKeys(fragment.selectionSet, fragments, variables, known, keys, visitedFragments)) {
660
+ return false;
661
+ }
662
+ }
663
+ }
664
+ return true;
665
+ };
666
+ var abortedBatchError = () => new GraphQLError3(
667
+ "Drizzle-GraphQL Error: Mutation was not executed because an earlier mutation in the same request failed and the shared transaction was rolled back."
668
+ );
669
+ var openSharedTx = (db, context, txCtx, stateKey, expected) => {
670
+ let release;
671
+ let rejectLatch;
672
+ const latch = new Promise((resolve, reject) => {
673
+ release = resolve;
674
+ rejectLatch = reject;
675
+ });
676
+ let readyResolve;
677
+ let readyReject;
678
+ const ready = new Promise((resolve, reject) => {
679
+ readyResolve = resolve;
680
+ readyReject = reject;
681
+ });
682
+ ready.catch(() => {
683
+ });
684
+ const canStash = context !== null && typeof context === "object" && !Object.isFrozen(context);
685
+ const settled = db.transaction(async (tx) => {
686
+ if (canStash) {
687
+ context[drizzleExecutorKey] = tx;
688
+ }
689
+ readyResolve(tx);
690
+ await latch;
691
+ });
692
+ let timer;
693
+ const clearTimer = () => {
694
+ if (timer !== void 0) {
695
+ clearTimeout(timer);
696
+ timer = void 0;
697
+ }
698
+ };
699
+ const state = {
700
+ kind: "shared",
701
+ expected,
702
+ completed: 0,
703
+ failure: void 0,
704
+ aborted: false,
705
+ done: false,
706
+ ready,
707
+ settled,
708
+ release,
709
+ abort: (e) => {
710
+ if (!state.aborted) {
711
+ state.aborted = true;
712
+ state.failure = e;
713
+ }
714
+ rejectLatch(e);
715
+ },
716
+ suspendTimer: clearTimer,
717
+ bumpTimer: () => {
718
+ clearTimer();
719
+ if (state.done) {
720
+ return;
721
+ }
722
+ timer = setTimeout(() => {
723
+ state.abort(
724
+ new GraphQLError3(
725
+ `Drizzle-GraphQL Error: Shared mutation transaction timed out after ${txCtx.timeoutMs}ms waiting for the remaining mutation fields; rolling back.`
726
+ )
727
+ );
728
+ }, txCtx.timeoutMs);
729
+ timer.unref?.();
730
+ }
731
+ };
732
+ const cleanup = () => {
733
+ state.done = true;
734
+ clearTimer();
735
+ if (canStash) {
736
+ delete context[drizzleExecutorKey];
737
+ }
738
+ if (!state.aborted) {
739
+ txCtx.states.delete(stateKey);
740
+ }
741
+ };
742
+ settled.then(cleanup, (e) => {
743
+ cleanup();
744
+ readyReject(e);
745
+ });
746
+ state.bumpTimer();
747
+ return state;
748
+ };
749
+ var runOnSharedTx = async (state, body) => {
750
+ if (state.aborted) {
751
+ await state.settled.catch(() => {
752
+ });
753
+ throw abortedBatchError();
754
+ }
755
+ state.suspendTimer();
756
+ const tx = await state.ready;
757
+ try {
758
+ if (state.aborted) {
759
+ throw abortedBatchError();
760
+ }
761
+ const result = await body(tx);
762
+ state.completed += 1;
763
+ if (state.completed >= state.expected) {
764
+ state.release();
765
+ await state.settled;
766
+ } else {
767
+ state.bumpTimer();
768
+ }
769
+ return result;
770
+ } catch (e) {
771
+ state.abort(e);
772
+ await state.settled.catch(() => {
773
+ });
774
+ throw e;
775
+ }
776
+ };
777
+ var runMutation = async (db, context, info, txCtx, body) => {
778
+ const contextIsObject = context !== null && (typeof context === "object" || typeof context === "function");
779
+ const stateKey = contextIsObject ? context : info.operation;
780
+ let state = txCtx?.states.get(stateKey);
781
+ if (!state) {
782
+ if (contextIsObject && context[drizzleExecutorKey]) {
783
+ return body(context[drizzleExecutorKey]);
784
+ }
785
+ if (!txCtx || info.operation.operation !== "mutation") {
786
+ return body(db);
787
+ }
788
+ const keys = /* @__PURE__ */ new Set();
789
+ const allKnown = collectRootMutationKeys(
790
+ info.operation.selectionSet,
791
+ info.fragments,
792
+ info.variableValues,
793
+ txCtx.fieldNames,
794
+ keys,
795
+ /* @__PURE__ */ new Set()
796
+ );
797
+ state = !allKnown || keys.size <= 1 ? { kind: "passthrough" } : openSharedTx(db, context, txCtx, stateKey, keys.size);
798
+ txCtx.states.set(stateKey, state);
799
+ }
800
+ if (state.kind === "passthrough") {
801
+ return body(resolveExecutor(db, context));
802
+ }
803
+ return runOnSharedTx(state, body);
804
+ };
608
805
  var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
609
806
  const cols = getColumns(targetTable);
610
807
  const orderExprs = [
@@ -2251,6 +2448,7 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2251
2448
  const upsertArrayFieldName = `${upsertPrefix}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
2252
2449
  const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
2253
2450
  const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2451
+ const updateManyFieldName = `${prefixes.update}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}Many`;
2254
2452
  const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2255
2453
  const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
2256
2454
  const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
@@ -2266,11 +2464,28 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2266
2464
  upsertArrayFieldName,
2267
2465
  upsertSingleFieldName,
2268
2466
  updateFieldName,
2467
+ updateManyFieldName,
2269
2468
  updateSingleFieldName,
2270
2469
  deleteFieldName,
2271
2470
  deleteSingleFieldName
2272
2471
  };
2273
2472
  };
2473
+ var generateUpdateManyInput = (params) => {
2474
+ const { typeName, updatePrefix, updateInput, tableFilters } = params;
2475
+ return new GraphQLInputObjectType2({
2476
+ name: `${capitalize(updatePrefix)}${typeName}ManyInput`,
2477
+ description: `One entry of a batch update of ${typeName}: the rows \`where\` matches get this entry's \`set\` applied.`,
2478
+ fields: {
2479
+ where: {
2480
+ type: tableFilters,
2481
+ description: "Rows this entry updates. An omitted filter updates every row."
2482
+ },
2483
+ set: {
2484
+ type: new GraphQLNonNull2(updateInput)
2485
+ }
2486
+ }
2487
+ });
2488
+ };
2274
2489
  var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
2275
2490
  const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2276
2491
  if (!filters) {
@@ -3029,7 +3244,7 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
3029
3244
  args: queryArgs
3030
3245
  };
3031
3246
  };
3032
- var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
3247
+ var generateInsertArray = (db, _tableName, table, baseType, fieldName, txCtx) => {
3033
3248
  const queryArgs = {
3034
3249
  values: {
3035
3250
  type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
@@ -3037,14 +3252,16 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
3037
3252
  };
3038
3253
  return {
3039
3254
  name: fieldName,
3040
- resolver: async (_source, args, context, _info) => {
3255
+ resolver: async (_source, args, context, info) => {
3041
3256
  try {
3042
- const input = remapFromGraphQLArrayInput(args.values, table);
3043
- if (!input.length) {
3044
- throw new GraphQLError5("No values were provided!");
3045
- }
3046
- await resolveExecutor(db, context).insert(table).values(input);
3047
- return { isSuccess: true };
3257
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3258
+ const input = remapFromGraphQLArrayInput(args.values, table);
3259
+ if (!input.length) {
3260
+ throw new GraphQLError5("No values were provided!");
3261
+ }
3262
+ await executor.insert(table).values(input);
3263
+ return { isSuccess: true };
3264
+ });
3048
3265
  } catch (e) {
3049
3266
  throw toGraphQLError(e);
3050
3267
  }
@@ -3052,7 +3269,7 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
3052
3269
  args: queryArgs
3053
3270
  };
3054
3271
  };
3055
- var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3272
+ var generateInsertSingle = (db, _tableName, table, baseType, fieldName, txCtx) => {
3056
3273
  const queryArgs = {
3057
3274
  values: {
3058
3275
  type: new GraphQLNonNull4(baseType)
@@ -3060,11 +3277,13 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3060
3277
  };
3061
3278
  return {
3062
3279
  name: fieldName,
3063
- resolver: async (_source, args, context, _info) => {
3280
+ resolver: async (_source, args, context, info) => {
3064
3281
  try {
3065
- const input = remapFromGraphQLSingleInput(args.values, table);
3066
- await resolveExecutor(db, context).insert(table).values(input);
3067
- return { isSuccess: true };
3282
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3283
+ const input = remapFromGraphQLSingleInput(args.values, table);
3284
+ await executor.insert(table).values(input);
3285
+ return { isSuccess: true };
3286
+ });
3068
3287
  } catch (e) {
3069
3288
  throw toGraphQLError(e);
3070
3289
  }
@@ -3072,7 +3291,7 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3072
3291
  args: queryArgs
3073
3292
  };
3074
3293
  };
3075
- var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) => {
3294
+ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single, txCtx) => {
3076
3295
  const queryArgs = {
3077
3296
  values: {
3078
3297
  type: single ? new GraphQLNonNull4(baseType) : new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
@@ -3085,28 +3304,29 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
3085
3304
  const pkNames = mysqlPrimaryKeyPropNames(table);
3086
3305
  return {
3087
3306
  name: fieldName,
3088
- resolver: async (_source, args, context, _info) => {
3307
+ resolver: async (_source, args, context, info) => {
3089
3308
  try {
3090
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3091
- if (!input.length) {
3092
- throw new GraphQLError5("No values were provided!");
3093
- }
3094
- const plan = resolveConflictPlan({
3095
- table,
3096
- values: input,
3097
- onConflict: args.onConflict,
3098
- pkNames,
3099
- uniqueSets: [],
3100
- excludedRef: mysqlValuesColumnRef,
3101
- withTarget: false
3309
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3310
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3311
+ if (!input.length) {
3312
+ throw new GraphQLError5("No values were provided!");
3313
+ }
3314
+ const plan = resolveConflictPlan({
3315
+ table,
3316
+ values: input,
3317
+ onConflict: args.onConflict,
3318
+ pkNames,
3319
+ uniqueSets: [],
3320
+ excludedRef: mysqlValuesColumnRef,
3321
+ withTarget: false
3322
+ });
3323
+ if (plan.action === "NOTHING") {
3324
+ await executor.insert(table).ignore().values(input);
3325
+ } else {
3326
+ await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
3327
+ }
3328
+ return { isSuccess: true };
3102
3329
  });
3103
- const executor = resolveExecutor(db, context);
3104
- if (plan.action === "NOTHING") {
3105
- await executor.insert(table).ignore().values(input);
3106
- } else {
3107
- await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
3108
- }
3109
- return { isSuccess: true };
3110
3330
  } catch (e) {
3111
3331
  throw toGraphQLError(e);
3112
3332
  }
@@ -3114,7 +3334,7 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
3114
3334
  args: queryArgs
3115
3335
  };
3116
3336
  };
3117
- var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
3337
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3118
3338
  const queryArgs = {
3119
3339
  set: {
3120
3340
  type: new GraphQLNonNull4(setArgs)
@@ -3125,25 +3345,69 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3125
3345
  };
3126
3346
  return {
3127
3347
  name: fieldName,
3128
- resolver: async (_source, args, context, _info) => {
3348
+ resolver: async (_source, args, context, info) => {
3129
3349
  try {
3130
- const { where, set } = args;
3131
- const input = remapFromGraphQLSingleInput(set, table);
3132
- if (!Object.keys(input).length) {
3133
- throw new GraphQLError5("Unable to update with no values specified!");
3134
- }
3135
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3136
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3137
- const executor = resolveExecutor(db, context);
3138
- if (single) {
3139
- await assertSingleMatch(executor, table, filters, fieldName);
3140
- }
3141
- let query = executor.update(table).set(input);
3142
- if (filters) {
3143
- query = query.where(filters);
3144
- }
3145
- await query;
3146
- return { isSuccess: true };
3350
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3351
+ const { where, set } = args;
3352
+ const input = remapFromGraphQLSingleInput(set, table);
3353
+ if (!Object.keys(input).length) {
3354
+ throw new GraphQLError5("Unable to update with no values specified!");
3355
+ }
3356
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3357
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3358
+ if (single) {
3359
+ await assertSingleMatch(executor, table, filters, fieldName);
3360
+ }
3361
+ let query = executor.update(table).set(input);
3362
+ if (filters) {
3363
+ query = query.where(filters);
3364
+ }
3365
+ await query;
3366
+ return { isSuccess: true };
3367
+ });
3368
+ } catch (e) {
3369
+ throw toGraphQLError(e);
3370
+ }
3371
+ },
3372
+ args: queryArgs
3373
+ };
3374
+ };
3375
+ var generateUpdateMany = (db, tableName, table, updateManyInput, fieldName, filterCtx, txCtx) => {
3376
+ const queryArgs = {
3377
+ updates: {
3378
+ type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(updateManyInput)))
3379
+ }
3380
+ };
3381
+ return {
3382
+ name: fieldName,
3383
+ resolver: async (_source, args, context, info) => {
3384
+ try {
3385
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3386
+ const { updates } = args;
3387
+ if (!updates.length) {
3388
+ throw new GraphQLError5("No updates were provided!");
3389
+ }
3390
+ const entries = updates.map(({ where, set }) => {
3391
+ const input = remapFromGraphQLSingleInput(set, table);
3392
+ if (!Object.keys(input).length) {
3393
+ throw new GraphQLError5("Unable to update with no values specified!");
3394
+ }
3395
+ return {
3396
+ set: input,
3397
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
3398
+ };
3399
+ });
3400
+ await executor.transaction(async (tx) => {
3401
+ for (const entry of entries) {
3402
+ let query = tx.update(table).set(entry.set);
3403
+ if (entry.filters) {
3404
+ query = query.where(entry.filters);
3405
+ }
3406
+ await query;
3407
+ }
3408
+ });
3409
+ return { isSuccess: true };
3410
+ });
3147
3411
  } catch (e) {
3148
3412
  throw toGraphQLError(e);
3149
3413
  }
@@ -3151,7 +3415,7 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3151
3415
  args: queryArgs
3152
3416
  };
3153
3417
  };
3154
- var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
3418
+ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3155
3419
  const queryArgs = {
3156
3420
  where: {
3157
3421
  type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
@@ -3159,21 +3423,22 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requi
3159
3423
  };
3160
3424
  return {
3161
3425
  name: fieldName,
3162
- resolver: async (_source, args, context, _info) => {
3426
+ resolver: async (_source, args, context, info) => {
3163
3427
  try {
3164
- const { where } = args;
3165
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3166
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3167
- const executor = resolveExecutor(db, context);
3168
- if (single) {
3169
- await assertSingleMatch(executor, table, filters, fieldName);
3170
- }
3171
- let query = executor.delete(table);
3172
- if (filters) {
3173
- query = query.where(filters);
3174
- }
3175
- await query;
3176
- return { isSuccess: true };
3428
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3429
+ const { where } = args;
3430
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3431
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3432
+ if (single) {
3433
+ await assertSingleMatch(executor, table, filters, fieldName);
3434
+ }
3435
+ let query = executor.delete(table);
3436
+ if (filters) {
3437
+ query = query.where(filters);
3438
+ }
3439
+ await query;
3440
+ return { isSuccess: true };
3441
+ });
3177
3442
  } catch (e) {
3178
3443
  throw toGraphQLError(e);
3179
3444
  }
@@ -3213,6 +3478,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3213
3478
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3214
3479
  const queries = {};
3215
3480
  const mutations = {};
3481
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
3216
3482
  const gqlSchemaTypes = Object.fromEntries(
3217
3483
  Object.entries(tables).map(([tableName, _table]) => [
3218
3484
  tableName,
@@ -3258,6 +3524,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3258
3524
  upsertArrayFieldName,
3259
3525
  upsertSingleFieldName,
3260
3526
  updateFieldName,
3527
+ updateManyFieldName,
3261
3528
  updateSingleFieldName,
3262
3529
  deleteFieldName,
3263
3530
  deleteSingleFieldName
@@ -3287,8 +3554,22 @@ var generateSchemaData = (db, schema, relations, options) => {
3287
3554
  typeNameMapper,
3288
3555
  filterCtx
3289
3556
  );
3290
- const insertArrGenerated = features.insert ? generateInsertArray(db, tableName, schema[tableName], insertInput, createArrayFieldName) : void 0;
3291
- const insertSingleGenerated = features.insert ? generateInsertSingle(db, tableName, schema[tableName], insertInput, createSingleFieldName) : void 0;
3557
+ const insertArrGenerated = features.insert ? generateInsertArray(
3558
+ db,
3559
+ tableName,
3560
+ schema[tableName],
3561
+ insertInput,
3562
+ createArrayFieldName,
3563
+ mutationTxCtx
3564
+ ) : void 0;
3565
+ const insertSingleGenerated = features.insert ? generateInsertSingle(
3566
+ db,
3567
+ tableName,
3568
+ schema[tableName],
3569
+ insertInput,
3570
+ createSingleFieldName,
3571
+ mutationTxCtx
3572
+ ) : void 0;
3292
3573
  const onConflictInput = features.upsert ? generateOnConflictInput({
3293
3574
  table: schema[tableName],
3294
3575
  typeName,
@@ -3296,8 +3577,24 @@ var generateSchemaData = (db, schema, relations, options) => {
3296
3577
  tableFilters,
3297
3578
  withTarget: false
3298
3579
  }) : void 0;
3299
- const upsertArrGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertArrayFieldName, false) : void 0;
3300
- const upsertSingleGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertSingleFieldName, true) : void 0;
3580
+ const upsertArrGenerated = onConflictInput ? generateUpsert(
3581
+ db,
3582
+ schema[tableName],
3583
+ insertInput,
3584
+ onConflictInput,
3585
+ upsertArrayFieldName,
3586
+ false,
3587
+ mutationTxCtx
3588
+ ) : void 0;
3589
+ const upsertSingleGenerated = onConflictInput ? generateUpsert(
3590
+ db,
3591
+ schema[tableName],
3592
+ insertInput,
3593
+ onConflictInput,
3594
+ upsertSingleFieldName,
3595
+ true,
3596
+ mutationTxCtx
3597
+ ) : void 0;
3301
3598
  const updateGenerated = features.update ? generateUpdate(
3302
3599
  db,
3303
3600
  tableName,
@@ -3307,7 +3604,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3307
3604
  updateFieldName,
3308
3605
  false,
3309
3606
  features.requireWhere,
3310
- filterCtx
3607
+ filterCtx,
3608
+ mutationTxCtx
3311
3609
  ) : void 0;
3312
3610
  const updateSingleGenerated = features.update ? generateUpdate(
3313
3611
  db,
@@ -3318,7 +3616,18 @@ var generateSchemaData = (db, schema, relations, options) => {
3318
3616
  updateSingleFieldName,
3319
3617
  true,
3320
3618
  features.requireWhere,
3321
- filterCtx
3619
+ filterCtx,
3620
+ mutationTxCtx
3621
+ ) : void 0;
3622
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
3623
+ const updateManyGenerated = updateManyInput ? generateUpdateMany(
3624
+ db,
3625
+ tableName,
3626
+ schema[tableName],
3627
+ updateManyInput,
3628
+ updateManyFieldName,
3629
+ filterCtx,
3630
+ mutationTxCtx
3322
3631
  ) : void 0;
3323
3632
  const deleteGenerated = features.delete ? generateDelete(
3324
3633
  db,
@@ -3328,7 +3637,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3328
3637
  deleteFieldName,
3329
3638
  false,
3330
3639
  features.requireWhere,
3331
- filterCtx
3640
+ filterCtx,
3641
+ mutationTxCtx
3332
3642
  ) : void 0;
3333
3643
  const deleteSingleGenerated = features.delete ? generateDelete(
3334
3644
  db,
@@ -3338,7 +3648,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3338
3648
  deleteSingleFieldName,
3339
3649
  true,
3340
3650
  features.requireWhere,
3341
- filterCtx
3651
+ filterCtx,
3652
+ mutationTxCtx
3342
3653
  ) : void 0;
3343
3654
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3344
3655
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -3397,6 +3708,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3397
3708
  upsertArrGenerated,
3398
3709
  upsertSingleGenerated,
3399
3710
  updateGenerated,
3711
+ updateManyGenerated,
3400
3712
  updateSingleGenerated,
3401
3713
  deleteGenerated,
3402
3714
  deleteSingleGenerated
@@ -3414,6 +3726,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3414
3726
  ...features.insert || onConflictInput ? [insertInput] : [],
3415
3727
  ...onConflictInput ? [onConflictInput] : [],
3416
3728
  ...features.update ? [updateInput] : [],
3729
+ ...updateManyInput ? [updateManyInput] : [],
3417
3730
  tableFilters,
3418
3731
  tableOrder
3419
3732
  ];
@@ -3429,6 +3742,11 @@ var generateSchemaData = (db, schema, relations, options) => {
3429
3742
  inputs[havingInput.name] = havingInput;
3430
3743
  }
3431
3744
  }
3745
+ if (mutationTxCtx) {
3746
+ for (const name of Object.keys(mutations)) {
3747
+ mutationTxCtx.fieldNames.add(name);
3748
+ }
3749
+ }
3432
3750
  const fieldResolvers = {};
3433
3751
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
3434
3752
  const relResolvers = {};
@@ -3636,7 +3954,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
3636
3954
  };
3637
3955
  };
3638
3956
  var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig2);
3639
- var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
3957
+ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
3640
3958
  const queryArgs = {
3641
3959
  values: {
3642
3960
  type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
@@ -3647,31 +3965,32 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
3647
3965
  name: fieldName,
3648
3966
  resolver: async (_source, args, context, info) => {
3649
3967
  try {
3650
- const input = remapFromGraphQLArrayInput(args.values, table);
3651
- if (!input.length) {
3652
- throw new GraphQLError6("No values were provided!");
3653
- }
3654
- const parsedInfo = parseResolveInfo3(info, {
3655
- deep: true
3656
- });
3657
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3658
- relationMap,
3659
- tables,
3660
- tableName,
3661
- typeName,
3662
- typeNameMapper,
3663
- table,
3664
- pkNames,
3665
- parsedInfo
3968
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3969
+ const input = remapFromGraphQLArrayInput(args.values, table);
3970
+ if (!input.length) {
3971
+ throw new GraphQLError6("No values were provided!");
3972
+ }
3973
+ const parsedInfo = parseResolveInfo3(info, {
3974
+ deep: true
3975
+ });
3976
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3977
+ relationMap,
3978
+ tables,
3979
+ tableName,
3980
+ typeName,
3981
+ typeNameMapper,
3982
+ table,
3983
+ pkNames,
3984
+ parsedInfo
3985
+ });
3986
+ let query = executor.insert(table).values(input).returning(columns);
3987
+ if (conflictDoNothing) {
3988
+ query = query.onConflictDoNothing();
3989
+ }
3990
+ const result = await query;
3991
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3992
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3666
3993
  });
3667
- const executor = resolveExecutor(db, context);
3668
- let query = executor.insert(table).values(input).returning(columns);
3669
- if (conflictDoNothing) {
3670
- query = query.onConflictDoNothing();
3671
- }
3672
- const result = await query;
3673
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3674
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3675
3994
  } catch (e) {
3676
3995
  throw toGraphQLError(e);
3677
3996
  }
@@ -3679,7 +3998,7 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
3679
3998
  args: queryArgs
3680
3999
  };
3681
4000
  };
3682
- var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
4001
+ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
3683
4002
  const queryArgs = {
3684
4003
  values: {
3685
4004
  type: new GraphQLNonNull5(baseType)
@@ -3690,31 +4009,32 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
3690
4009
  name: fieldName,
3691
4010
  resolver: async (_source, args, context, info) => {
3692
4011
  try {
3693
- const input = remapFromGraphQLSingleInput(args.values, table);
3694
- const parsedInfo = parseResolveInfo3(info, {
3695
- deep: true
3696
- });
3697
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3698
- relationMap,
3699
- tables,
3700
- tableName,
3701
- typeName,
3702
- typeNameMapper,
3703
- table,
3704
- pkNames,
3705
- parsedInfo
4012
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4013
+ const input = remapFromGraphQLSingleInput(args.values, table);
4014
+ const parsedInfo = parseResolveInfo3(info, {
4015
+ deep: true
4016
+ });
4017
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4018
+ relationMap,
4019
+ tables,
4020
+ tableName,
4021
+ typeName,
4022
+ typeNameMapper,
4023
+ table,
4024
+ pkNames,
4025
+ parsedInfo
4026
+ });
4027
+ let query = executor.insert(table).values(input).returning(columns);
4028
+ if (conflictDoNothing) {
4029
+ query = query.onConflictDoNothing();
4030
+ }
4031
+ const result = await query;
4032
+ if (!result[0]) {
4033
+ return void 0;
4034
+ }
4035
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4036
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
3706
4037
  });
3707
- const executor = resolveExecutor(db, context);
3708
- let query = executor.insert(table).values(input).returning(columns);
3709
- if (conflictDoNothing) {
3710
- query = query.onConflictDoNothing();
3711
- }
3712
- const result = await query;
3713
- if (!result[0]) {
3714
- return void 0;
3715
- }
3716
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3717
- return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
3718
4038
  } catch (e) {
3719
4039
  throw toGraphQLError(e);
3720
4040
  }
@@ -3722,7 +4042,7 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
3722
4042
  args: queryArgs
3723
4043
  };
3724
4044
  };
3725
- var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
4045
+ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
3726
4046
  const queryArgs = {
3727
4047
  values: {
3728
4048
  type: single ? new GraphQLNonNull5(baseType) : new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
@@ -3737,40 +4057,41 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3737
4057
  name: fieldName,
3738
4058
  resolver: async (_source, args, context, info) => {
3739
4059
  try {
3740
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3741
- if (!input.length) {
3742
- throw new GraphQLError6("No values were provided!");
3743
- }
3744
- const parsedInfo = parseResolveInfo3(info, { deep: true });
3745
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3746
- relationMap,
3747
- tables,
3748
- tableName,
3749
- typeName,
3750
- typeNameMapper,
3751
- table,
3752
- pkNames,
3753
- parsedInfo
3754
- });
3755
- const plan = resolveConflictPlan({
3756
- table,
3757
- values: input,
3758
- onConflict: args.onConflict,
3759
- pkNames,
3760
- uniqueSets,
3761
- excludedRef: excludedColumnRef,
3762
- withTarget: true,
3763
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4060
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4061
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4062
+ if (!input.length) {
4063
+ throw new GraphQLError6("No values were provided!");
4064
+ }
4065
+ const parsedInfo = parseResolveInfo3(info, { deep: true });
4066
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4067
+ relationMap,
4068
+ tables,
4069
+ tableName,
4070
+ typeName,
4071
+ typeNameMapper,
4072
+ table,
4073
+ pkNames,
4074
+ parsedInfo
4075
+ });
4076
+ const plan = resolveConflictPlan({
4077
+ table,
4078
+ values: input,
4079
+ onConflict: args.onConflict,
4080
+ pkNames,
4081
+ uniqueSets,
4082
+ excludedRef: excludedColumnRef,
4083
+ withTarget: true,
4084
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4085
+ });
4086
+ let query = executor.insert(table).values(input).returning(columns);
4087
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4088
+ const result = await query;
4089
+ if (single && !result[0]) {
4090
+ return void 0;
4091
+ }
4092
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4093
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3764
4094
  });
3765
- const executor = resolveExecutor(db, context);
3766
- let query = executor.insert(table).values(input).returning(columns);
3767
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
3768
- const result = await query;
3769
- if (single && !result[0]) {
3770
- return void 0;
3771
- }
3772
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3773
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3774
4095
  } catch (e) {
3775
4096
  throw toGraphQLError(e);
3776
4097
  }
@@ -3778,7 +4099,7 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3778
4099
  args: queryArgs
3779
4100
  };
3780
4101
  };
3781
- var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
4102
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
3782
4103
  const queryArgs = {
3783
4104
  set: {
3784
4105
  type: new GraphQLNonNull5(setArgs)
@@ -3792,44 +4113,118 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3792
4113
  name: fieldName,
3793
4114
  resolver: async (_source, args, context, info) => {
3794
4115
  try {
3795
- const { where, set } = args;
3796
- const parsedInfo = parseResolveInfo3(info, {
3797
- deep: true
4116
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4117
+ const { where, set } = args;
4118
+ const parsedInfo = parseResolveInfo3(info, {
4119
+ deep: true
4120
+ });
4121
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4122
+ relationMap,
4123
+ tables,
4124
+ tableName,
4125
+ typeName,
4126
+ typeNameMapper,
4127
+ table,
4128
+ pkNames,
4129
+ parsedInfo
4130
+ });
4131
+ const input = remapFromGraphQLSingleInput(set, table);
4132
+ if (!Object.keys(input).length) {
4133
+ throw new GraphQLError6("Unable to update with no values specified!");
4134
+ }
4135
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4136
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4137
+ if (single) {
4138
+ await assertSingleMatch(executor, table, filters, fieldName);
4139
+ }
4140
+ let query = executor.update(table).set(input);
4141
+ if (filters) {
4142
+ query = query.where(filters);
4143
+ }
4144
+ query = query.returning(columns);
4145
+ const result = await query;
4146
+ if (single && result.length > 1) {
4147
+ throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
4148
+ }
4149
+ if (single && !result[0]) {
4150
+ return void 0;
4151
+ }
4152
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4153
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3798
4154
  });
3799
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3800
- relationMap,
3801
- tables,
3802
- tableName,
3803
- typeName,
3804
- typeNameMapper,
3805
- table,
3806
- pkNames,
3807
- parsedInfo
4155
+ } catch (e) {
4156
+ throw toGraphQLError(e);
4157
+ }
4158
+ },
4159
+ args: queryArgs
4160
+ };
4161
+ };
4162
+ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
4163
+ const queryArgs = {
4164
+ updates: {
4165
+ type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(updateManyInput)))
4166
+ }
4167
+ };
4168
+ const pkNames = pgPrimaryKeyPropNames(table);
4169
+ return {
4170
+ name: fieldName,
4171
+ resolver: async (_source, args, context, info) => {
4172
+ try {
4173
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4174
+ const { updates } = args;
4175
+ if (!updates.length) {
4176
+ throw new GraphQLError6("No updates were provided!");
4177
+ }
4178
+ const parsedInfo = parseResolveInfo3(info, {
4179
+ deep: true
4180
+ });
4181
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4182
+ relationMap,
4183
+ tables,
4184
+ tableName,
4185
+ typeName,
4186
+ typeNameMapper,
4187
+ table,
4188
+ pkNames,
4189
+ parsedInfo
4190
+ });
4191
+ const entries = updates.map(({ where, set }) => {
4192
+ const input = remapFromGraphQLSingleInput(set, table);
4193
+ if (!Object.keys(input).length) {
4194
+ throw new GraphQLError6("Unable to update with no values specified!");
4195
+ }
4196
+ return {
4197
+ set: input,
4198
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
4199
+ };
4200
+ });
4201
+ const perEntry = await executor.transaction(async (tx) => {
4202
+ const results = [];
4203
+ for (const entry of entries) {
4204
+ let query = tx.update(table).set(entry.set);
4205
+ if (entry.filters) {
4206
+ query = query.where(entry.filters);
4207
+ }
4208
+ results.push(await query.returning(columns));
4209
+ }
4210
+ return results;
4211
+ });
4212
+ const flatRows = perEntry.flat();
4213
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, flatRows, pkNames, withParams) : flatRows;
4214
+ const output = [];
4215
+ let offset = 0;
4216
+ for (const rows of perEntry) {
4217
+ if (!rows.length) {
4218
+ output.push(null);
4219
+ continue;
4220
+ }
4221
+ for (let i = 0; i < rows.length; i++) {
4222
+ output.push(remapToGraphQLSingleOutput(enriched[offset + i], tableName, table, relationMap));
4223
+ }
4224
+ offset += rows.length;
4225
+ }
4226
+ return output;
3808
4227
  });
3809
- const input = remapFromGraphQLSingleInput(set, table);
3810
- if (!Object.keys(input).length) {
3811
- throw new GraphQLError6("Unable to update with no values specified!");
3812
- }
3813
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3814
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3815
- const executor = resolveExecutor(db, context);
3816
- if (single) {
3817
- await assertSingleMatch(executor, table, filters, fieldName);
3818
- }
3819
- let query = executor.update(table).set(input);
3820
- if (filters) {
3821
- query = query.where(filters);
3822
- }
3823
- query = query.returning(columns);
3824
- const result = await query;
3825
- if (single && result.length > 1) {
3826
- throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
3827
- }
3828
- if (single && !result[0]) {
3829
- return void 0;
3830
- }
3831
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3832
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3833
4228
  } catch (e) {
3834
4229
  throw toGraphQLError(e);
3835
4230
  }
@@ -3837,7 +4232,7 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3837
4232
  args: queryArgs
3838
4233
  };
3839
4234
  };
3840
- var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
4235
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
3841
4236
  const queryArgs = {
3842
4237
  where: {
3843
4238
  type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
@@ -3847,34 +4242,35 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, si
3847
4242
  name: fieldName,
3848
4243
  resolver: async (_source, args, context, info) => {
3849
4244
  try {
3850
- const { where } = args;
3851
- const parsedInfo = parseResolveInfo3(info, {
3852
- deep: true
4245
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4246
+ const { where } = args;
4247
+ const parsedInfo = parseResolveInfo3(info, {
4248
+ deep: true
4249
+ });
4250
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
4251
+ parsedInfo.fieldsByTypeName[typeName],
4252
+ table,
4253
+ selectionCtx
4254
+ );
4255
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4256
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4257
+ if (single) {
4258
+ await assertSingleMatch(executor, table, filters, fieldName);
4259
+ }
4260
+ let query = executor.delete(table);
4261
+ if (filters) {
4262
+ query = query.where(filters);
4263
+ }
4264
+ query = query.returning(columns);
4265
+ const result = await query;
4266
+ if (single && result.length > 1) {
4267
+ throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
4268
+ }
4269
+ if (single) {
4270
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4271
+ }
4272
+ return remapToGraphQLArrayOutput(result, tableName, table);
3853
4273
  });
3854
- const columns = extractSelectedColumnsFromTreeSQLFormat(
3855
- parsedInfo.fieldsByTypeName[typeName],
3856
- table,
3857
- selectionCtx
3858
- );
3859
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3860
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3861
- const executor = resolveExecutor(db, context);
3862
- if (single) {
3863
- await assertSingleMatch(executor, table, filters, fieldName);
3864
- }
3865
- let query = executor.delete(table);
3866
- if (filters) {
3867
- query = query.where(filters);
3868
- }
3869
- query = query.returning(columns);
3870
- const result = await query;
3871
- if (single && result.length > 1) {
3872
- throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
3873
- }
3874
- if (single) {
3875
- return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
3876
- }
3877
- return remapToGraphQLArrayOutput(result, tableName, table);
3878
4274
  } catch (e) {
3879
4275
  throw toGraphQLError(e);
3880
4276
  }
@@ -3921,6 +4317,7 @@ function generateSchemaData2(db, schema, relations, options) {
3921
4317
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3922
4318
  const queries = {};
3923
4319
  const mutations = {};
4320
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
3924
4321
  const gqlSchemaTypes = Object.fromEntries(
3925
4322
  Object.entries(tables).map(([tableName, _table]) => [
3926
4323
  tableName,
@@ -3955,6 +4352,7 @@ function generateSchemaData2(db, schema, relations, options) {
3955
4352
  upsertArrayFieldName,
3956
4353
  upsertSingleFieldName,
3957
4354
  updateFieldName,
4355
+ updateManyFieldName,
3958
4356
  updateSingleFieldName,
3959
4357
  deleteFieldName,
3960
4358
  deleteSingleFieldName
@@ -3994,7 +4392,8 @@ function generateSchemaData2(db, schema, relations, options) {
3994
4392
  createArrayFieldName,
3995
4393
  typeName,
3996
4394
  typeNameMapper,
3997
- conflictDoNothing
4395
+ conflictDoNothing,
4396
+ mutationTxCtx
3998
4397
  ) : void 0;
3999
4398
  const insertSingleGenerated = features.insert ? generateInsertSingle2(
4000
4399
  db,
@@ -4006,7 +4405,8 @@ function generateSchemaData2(db, schema, relations, options) {
4006
4405
  createSingleFieldName,
4007
4406
  typeName,
4008
4407
  typeNameMapper,
4009
- conflictDoNothing
4408
+ conflictDoNothing,
4409
+ mutationTxCtx
4010
4410
  ) : void 0;
4011
4411
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig2) : [];
4012
4412
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -4029,7 +4429,8 @@ function generateSchemaData2(db, schema, relations, options) {
4029
4429
  typeName,
4030
4430
  false,
4031
4431
  typeNameMapper,
4032
- filterCtx
4432
+ filterCtx,
4433
+ mutationTxCtx
4033
4434
  ) : void 0;
4034
4435
  const upsertSingleGenerated = onConflictInput ? generateUpsert2(
4035
4436
  db,
@@ -4044,7 +4445,8 @@ function generateSchemaData2(db, schema, relations, options) {
4044
4445
  typeName,
4045
4446
  true,
4046
4447
  typeNameMapper,
4047
- filterCtx
4448
+ filterCtx,
4449
+ mutationTxCtx
4048
4450
  ) : void 0;
4049
4451
  const updateGenerated = features.update ? generateUpdate2(
4050
4452
  db,
@@ -4059,7 +4461,8 @@ function generateSchemaData2(db, schema, relations, options) {
4059
4461
  false,
4060
4462
  features.requireWhere,
4061
4463
  typeNameMapper,
4062
- filterCtx
4464
+ filterCtx,
4465
+ mutationTxCtx
4063
4466
  ) : void 0;
4064
4467
  const updateSingleGenerated = features.update ? generateUpdate2(
4065
4468
  db,
@@ -4074,7 +4477,22 @@ function generateSchemaData2(db, schema, relations, options) {
4074
4477
  true,
4075
4478
  features.requireWhere,
4076
4479
  typeNameMapper,
4077
- filterCtx
4480
+ filterCtx,
4481
+ mutationTxCtx
4482
+ ) : void 0;
4483
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
4484
+ const updateManyGenerated = updateManyInput ? generateUpdateMany2(
4485
+ db,
4486
+ tableName,
4487
+ schema[tableName],
4488
+ tables,
4489
+ eagerRelations,
4490
+ updateManyInput,
4491
+ updateManyFieldName,
4492
+ typeName,
4493
+ typeNameMapper,
4494
+ filterCtx,
4495
+ mutationTxCtx
4078
4496
  ) : void 0;
4079
4497
  const deleteGenerated = features.delete ? generateDelete2(
4080
4498
  db,
@@ -4086,7 +4504,8 @@ function generateSchemaData2(db, schema, relations, options) {
4086
4504
  false,
4087
4505
  features.requireWhere,
4088
4506
  filterCtx,
4089
- { tableName, relationMap: namedRelations, tables }
4507
+ { tableName, relationMap: namedRelations, tables },
4508
+ mutationTxCtx
4090
4509
  ) : void 0;
4091
4510
  const deleteSingleGenerated = features.delete ? generateDelete2(
4092
4511
  db,
@@ -4098,7 +4517,8 @@ function generateSchemaData2(db, schema, relations, options) {
4098
4517
  true,
4099
4518
  features.requireWhere,
4100
4519
  filterCtx,
4101
- { tableName, relationMap: namedRelations, tables }
4520
+ { tableName, relationMap: namedRelations, tables },
4521
+ mutationTxCtx
4102
4522
  ) : void 0;
4103
4523
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4104
4524
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -4186,6 +4606,14 @@ function generateSchemaData2(db, schema, relations, options) {
4186
4606
  resolve: updateGenerated.resolver
4187
4607
  };
4188
4608
  }
4609
+ if (updateManyGenerated) {
4610
+ mutations[updateManyGenerated.name] = {
4611
+ // Nullable items: a no-match entry yields `null` in its slot.
4612
+ type: new GraphQLNonNull5(new GraphQLList5(singleTableItemOutput)),
4613
+ args: updateManyGenerated.args,
4614
+ resolve: updateManyGenerated.resolver
4615
+ };
4616
+ }
4189
4617
  if (updateSingleGenerated) {
4190
4618
  mutations[updateSingleGenerated.name] = {
4191
4619
  type: singleTableItemOutput,
@@ -4212,6 +4640,7 @@ function generateSchemaData2(db, schema, relations, options) {
4212
4640
  ...features.insert || onConflictInput ? [insertInput] : [],
4213
4641
  ...onConflictInput ? [onConflictInput] : [],
4214
4642
  ...features.update ? [updateInput] : [],
4643
+ ...updateManyInput ? [updateManyInput] : [],
4215
4644
  tableFilters,
4216
4645
  tableOrder
4217
4646
  ];
@@ -4228,6 +4657,11 @@ function generateSchemaData2(db, schema, relations, options) {
4228
4657
  inputs[havingInput.name] = havingInput;
4229
4658
  }
4230
4659
  }
4660
+ if (mutationTxCtx) {
4661
+ for (const name of Object.keys(mutations)) {
4662
+ mutationTxCtx.fieldNames.add(name);
4663
+ }
4664
+ }
4231
4665
  const fieldResolvers = {};
4232
4666
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
4233
4667
  const relResolvers = {};
@@ -4337,7 +4771,7 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
4337
4771
  };
4338
4772
  };
4339
4773
  var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig3);
4340
- var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
4774
+ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4341
4775
  const queryArgs = {
4342
4776
  values: {
4343
4777
  type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
@@ -4348,31 +4782,32 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4348
4782
  name: fieldName,
4349
4783
  resolver: async (_source, args, context, info) => {
4350
4784
  try {
4351
- const input = remapFromGraphQLArrayInput(args.values, table);
4352
- if (!input.length) {
4353
- throw new GraphQLError7("No values were provided!");
4354
- }
4355
- const parsedInfo = parseResolveInfo4(info, {
4356
- deep: true
4357
- });
4358
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4359
- relationMap,
4360
- tables,
4361
- tableName,
4362
- typeName,
4363
- typeNameMapper,
4364
- table,
4365
- pkNames,
4366
- parsedInfo
4785
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4786
+ const input = remapFromGraphQLArrayInput(args.values, table);
4787
+ if (!input.length) {
4788
+ throw new GraphQLError7("No values were provided!");
4789
+ }
4790
+ const parsedInfo = parseResolveInfo4(info, {
4791
+ deep: true
4792
+ });
4793
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4794
+ relationMap,
4795
+ tables,
4796
+ tableName,
4797
+ typeName,
4798
+ typeNameMapper,
4799
+ table,
4800
+ pkNames,
4801
+ parsedInfo
4802
+ });
4803
+ let query = executor.insert(table).values(input).returning(columns);
4804
+ if (conflictDoNothing) {
4805
+ query = query.onConflictDoNothing();
4806
+ }
4807
+ const result = await query;
4808
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4809
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4367
4810
  });
4368
- const executor = resolveExecutor(db, context);
4369
- let query = executor.insert(table).values(input).returning(columns);
4370
- if (conflictDoNothing) {
4371
- query = query.onConflictDoNothing();
4372
- }
4373
- const result = await query;
4374
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4375
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4376
4811
  } catch (e) {
4377
4812
  throw toGraphQLError(e);
4378
4813
  }
@@ -4380,7 +4815,7 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4380
4815
  args: queryArgs
4381
4816
  };
4382
4817
  };
4383
- var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
4818
+ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4384
4819
  const queryArgs = {
4385
4820
  values: {
4386
4821
  type: new GraphQLNonNull6(baseType)
@@ -4391,31 +4826,32 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4391
4826
  name: fieldName,
4392
4827
  resolver: async (_source, args, context, info) => {
4393
4828
  try {
4394
- const input = remapFromGraphQLSingleInput(args.values, table);
4395
- const parsedInfo = parseResolveInfo4(info, {
4396
- deep: true
4397
- });
4398
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4399
- relationMap,
4400
- tables,
4401
- tableName,
4402
- typeName,
4403
- typeNameMapper,
4404
- table,
4405
- pkNames,
4406
- parsedInfo
4829
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4830
+ const input = remapFromGraphQLSingleInput(args.values, table);
4831
+ const parsedInfo = parseResolveInfo4(info, {
4832
+ deep: true
4833
+ });
4834
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4835
+ relationMap,
4836
+ tables,
4837
+ tableName,
4838
+ typeName,
4839
+ typeNameMapper,
4840
+ table,
4841
+ pkNames,
4842
+ parsedInfo
4843
+ });
4844
+ let query = executor.insert(table).values(input).returning(columns);
4845
+ if (conflictDoNothing) {
4846
+ query = query.onConflictDoNothing();
4847
+ }
4848
+ const result = await query;
4849
+ if (!result[0]) {
4850
+ return void 0;
4851
+ }
4852
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4853
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
4407
4854
  });
4408
- const executor = resolveExecutor(db, context);
4409
- let query = executor.insert(table).values(input).returning(columns);
4410
- if (conflictDoNothing) {
4411
- query = query.onConflictDoNothing();
4412
- }
4413
- const result = await query;
4414
- if (!result[0]) {
4415
- return void 0;
4416
- }
4417
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4418
- return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
4419
4855
  } catch (e) {
4420
4856
  throw toGraphQLError(e);
4421
4857
  }
@@ -4423,7 +4859,7 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4423
4859
  args: queryArgs
4424
4860
  };
4425
4861
  };
4426
- var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
4862
+ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
4427
4863
  const queryArgs = {
4428
4864
  values: {
4429
4865
  type: single ? new GraphQLNonNull6(baseType) : new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
@@ -4438,40 +4874,41 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4438
4874
  name: fieldName,
4439
4875
  resolver: async (_source, args, context, info) => {
4440
4876
  try {
4441
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4442
- if (!input.length) {
4443
- throw new GraphQLError7("No values were provided!");
4444
- }
4445
- const parsedInfo = parseResolveInfo4(info, { deep: true });
4446
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4447
- relationMap,
4448
- tables,
4449
- tableName,
4450
- typeName,
4451
- typeNameMapper,
4452
- table,
4453
- pkNames,
4454
- parsedInfo
4455
- });
4456
- const plan = resolveConflictPlan({
4457
- table,
4458
- values: input,
4459
- onConflict: args.onConflict,
4460
- pkNames,
4461
- uniqueSets,
4462
- excludedRef: excludedColumnRef,
4463
- withTarget: true,
4464
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4877
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4878
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4879
+ if (!input.length) {
4880
+ throw new GraphQLError7("No values were provided!");
4881
+ }
4882
+ const parsedInfo = parseResolveInfo4(info, { deep: true });
4883
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4884
+ relationMap,
4885
+ tables,
4886
+ tableName,
4887
+ typeName,
4888
+ typeNameMapper,
4889
+ table,
4890
+ pkNames,
4891
+ parsedInfo
4892
+ });
4893
+ const plan = resolveConflictPlan({
4894
+ table,
4895
+ values: input,
4896
+ onConflict: args.onConflict,
4897
+ pkNames,
4898
+ uniqueSets,
4899
+ excludedRef: excludedColumnRef,
4900
+ withTarget: true,
4901
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4902
+ });
4903
+ let query = executor.insert(table).values(input).returning(columns);
4904
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4905
+ const result = await query;
4906
+ if (single && !result[0]) {
4907
+ return void 0;
4908
+ }
4909
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4910
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4465
4911
  });
4466
- const executor = resolveExecutor(db, context);
4467
- let query = executor.insert(table).values(input).returning(columns);
4468
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4469
- const result = await query;
4470
- if (single && !result[0]) {
4471
- return void 0;
4472
- }
4473
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4474
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4475
4912
  } catch (e) {
4476
4913
  throw toGraphQLError(e);
4477
4914
  }
@@ -4479,7 +4916,7 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4479
4916
  args: queryArgs
4480
4917
  };
4481
4918
  };
4482
- var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
4919
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
4483
4920
  const queryArgs = {
4484
4921
  set: {
4485
4922
  type: new GraphQLNonNull6(setArgs)
@@ -4493,44 +4930,131 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
4493
4930
  name: fieldName,
4494
4931
  resolver: async (_source, args, context, info) => {
4495
4932
  try {
4496
- const { where, set } = args;
4497
- const parsedInfo = parseResolveInfo4(info, {
4498
- deep: true
4933
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4934
+ const { where, set } = args;
4935
+ const parsedInfo = parseResolveInfo4(info, {
4936
+ deep: true
4937
+ });
4938
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4939
+ relationMap,
4940
+ tables,
4941
+ tableName,
4942
+ typeName,
4943
+ typeNameMapper,
4944
+ table,
4945
+ pkNames,
4946
+ parsedInfo
4947
+ });
4948
+ const input = remapFromGraphQLSingleInput(set, table);
4949
+ if (!Object.keys(input).length) {
4950
+ throw new GraphQLError7("Unable to update with no values specified!");
4951
+ }
4952
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4953
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4954
+ if (single) {
4955
+ await assertSingleMatch(executor, table, filters, fieldName);
4956
+ }
4957
+ let query = executor.update(table).set(input);
4958
+ if (filters) {
4959
+ query = query.where(filters);
4960
+ }
4961
+ query = query.returning(columns);
4962
+ const result = await query;
4963
+ if (single && result.length > 1) {
4964
+ throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
4965
+ }
4966
+ if (single && !result[0]) {
4967
+ return void 0;
4968
+ }
4969
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4970
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4499
4971
  });
4500
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4501
- relationMap,
4502
- tables,
4503
- tableName,
4504
- typeName,
4505
- typeNameMapper,
4506
- table,
4507
- pkNames,
4508
- parsedInfo
4972
+ } catch (e) {
4973
+ throw toGraphQLError(e);
4974
+ }
4975
+ },
4976
+ args: queryArgs
4977
+ };
4978
+ };
4979
+ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
4980
+ const queryArgs = {
4981
+ updates: {
4982
+ type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(updateManyInput)))
4983
+ }
4984
+ };
4985
+ const pkNames = sqlitePrimaryKeyPropNames(table);
4986
+ return {
4987
+ name: fieldName,
4988
+ resolver: async (_source, args, context, info) => {
4989
+ try {
4990
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4991
+ const { updates } = args;
4992
+ if (!updates.length) {
4993
+ throw new GraphQLError7("No updates were provided!");
4994
+ }
4995
+ const parsedInfo = parseResolveInfo4(info, {
4996
+ deep: true
4997
+ });
4998
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4999
+ relationMap,
5000
+ tables,
5001
+ tableName,
5002
+ typeName,
5003
+ typeNameMapper,
5004
+ table,
5005
+ pkNames,
5006
+ parsedInfo
5007
+ });
5008
+ const entries = updates.map(({ where, set }) => {
5009
+ const input = remapFromGraphQLSingleInput(set, table);
5010
+ if (!Object.keys(input).length) {
5011
+ throw new GraphQLError7("Unable to update with no values specified!");
5012
+ }
5013
+ return {
5014
+ set: input,
5015
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
5016
+ };
5017
+ });
5018
+ const runEntry = (tx, entry) => {
5019
+ let query = tx.update(table).set(entry.set);
5020
+ if (entry.filters) {
5021
+ query = query.where(entry.filters);
5022
+ }
5023
+ return query.returning(columns).all();
5024
+ };
5025
+ const perEntry = await executor.transaction((tx) => {
5026
+ const first = runEntry(tx, entries[0]);
5027
+ if (typeof first?.then === "function") {
5028
+ return (async () => {
5029
+ const results2 = [await first];
5030
+ for (let i = 1; i < entries.length; i++) {
5031
+ results2.push(await runEntry(tx, entries[i]));
5032
+ }
5033
+ return results2;
5034
+ })();
5035
+ }
5036
+ const results = [first];
5037
+ for (let i = 1; i < entries.length; i++) {
5038
+ results.push(runEntry(tx, entries[i]));
5039
+ }
5040
+ return results;
5041
+ });
5042
+ const flatRows = perEntry.flat();
5043
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, flatRows, pkNames, withParams) : flatRows;
5044
+ const output = [];
5045
+ let offset = 0;
5046
+ for (const rows of perEntry) {
5047
+ if (!rows.length) {
5048
+ output.push(null);
5049
+ continue;
5050
+ }
5051
+ for (let i = 0; i < rows.length; i++) {
5052
+ output.push(remapToGraphQLSingleOutput(enriched[offset + i], tableName, table, relationMap));
5053
+ }
5054
+ offset += rows.length;
5055
+ }
5056
+ return output;
4509
5057
  });
4510
- const input = remapFromGraphQLSingleInput(set, table);
4511
- if (!Object.keys(input).length) {
4512
- throw new GraphQLError7("Unable to update with no values specified!");
4513
- }
4514
- const relationCtx = relationFilterCtx(filterCtx, tableName);
4515
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4516
- const executor = resolveExecutor(db, context);
4517
- if (single) {
4518
- await assertSingleMatch(executor, table, filters, fieldName);
4519
- }
4520
- let query = executor.update(table).set(input);
4521
- if (filters) {
4522
- query = query.where(filters);
4523
- }
4524
- query = query.returning(columns);
4525
- const result = await query;
4526
- if (single && result.length > 1) {
4527
- throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
4528
- }
4529
- if (single && !result[0]) {
4530
- return void 0;
4531
- }
4532
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4533
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4534
5058
  } catch (e) {
4535
5059
  throw toGraphQLError(e);
4536
5060
  }
@@ -4538,7 +5062,7 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
4538
5062
  args: queryArgs
4539
5063
  };
4540
5064
  };
4541
- var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
5065
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
4542
5066
  const queryArgs = {
4543
5067
  where: {
4544
5068
  type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
@@ -4548,34 +5072,35 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, si
4548
5072
  name: fieldName,
4549
5073
  resolver: async (_source, args, context, info) => {
4550
5074
  try {
4551
- const { where } = args;
4552
- const parsedInfo = parseResolveInfo4(info, {
4553
- deep: true
5075
+ return await runMutation(db, context, info, txCtx, async (executor) => {
5076
+ const { where } = args;
5077
+ const parsedInfo = parseResolveInfo4(info, {
5078
+ deep: true
5079
+ });
5080
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
5081
+ parsedInfo.fieldsByTypeName[typeName],
5082
+ table,
5083
+ selectionCtx
5084
+ );
5085
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
5086
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
5087
+ if (single) {
5088
+ await assertSingleMatch(executor, table, filters, fieldName);
5089
+ }
5090
+ let query = executor.delete(table);
5091
+ if (filters) {
5092
+ query = query.where(filters);
5093
+ }
5094
+ query = query.returning(columns);
5095
+ const result = await query;
5096
+ if (single && result.length > 1) {
5097
+ throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
5098
+ }
5099
+ if (single) {
5100
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
5101
+ }
5102
+ return remapToGraphQLArrayOutput(result, tableName, table);
4554
5103
  });
4555
- const columns = extractSelectedColumnsFromTreeSQLFormat(
4556
- parsedInfo.fieldsByTypeName[typeName],
4557
- table,
4558
- selectionCtx
4559
- );
4560
- const relationCtx = relationFilterCtx(filterCtx, tableName);
4561
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4562
- const executor = resolveExecutor(db, context);
4563
- if (single) {
4564
- await assertSingleMatch(executor, table, filters, fieldName);
4565
- }
4566
- let query = executor.delete(table);
4567
- if (filters) {
4568
- query = query.where(filters);
4569
- }
4570
- query = query.returning(columns);
4571
- const result = await query;
4572
- if (single && result.length > 1) {
4573
- throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
4574
- }
4575
- if (single) {
4576
- return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4577
- }
4578
- return remapToGraphQLArrayOutput(result, tableName, table);
4579
5104
  } catch (e) {
4580
5105
  throw toGraphQLError(e);
4581
5106
  }
@@ -4623,6 +5148,12 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4623
5148
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
4624
5149
  const queries = {};
4625
5150
  const mutations = {};
5151
+ if (options.transactions && db.resultKind === "sync") {
5152
+ throw new Error(
5153
+ "Drizzle-GraphQL Error: transactions: 'auto' requires an asynchronous SQLite driver (e.g. libsql). Synchronous drivers cannot hold a transaction open across resolvers."
5154
+ );
5155
+ }
5156
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
4626
5157
  const gqlSchemaTypes = Object.fromEntries(
4627
5158
  Object.entries(tables).map(([tableName, _table]) => [
4628
5159
  tableName,
@@ -4657,6 +5188,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4657
5188
  upsertArrayFieldName,
4658
5189
  upsertSingleFieldName,
4659
5190
  updateFieldName,
5191
+ updateManyFieldName,
4660
5192
  updateSingleFieldName,
4661
5193
  deleteFieldName,
4662
5194
  deleteSingleFieldName
@@ -4696,7 +5228,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4696
5228
  createArrayFieldName,
4697
5229
  typeName,
4698
5230
  typeNameMapper,
4699
- conflictDoNothing
5231
+ conflictDoNothing,
5232
+ mutationTxCtx
4700
5233
  ) : void 0;
4701
5234
  const insertSingleGenerated = features.insert ? generateInsertSingle3(
4702
5235
  db,
@@ -4708,7 +5241,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4708
5241
  createSingleFieldName,
4709
5242
  typeName,
4710
5243
  typeNameMapper,
4711
- conflictDoNothing
5244
+ conflictDoNothing,
5245
+ mutationTxCtx
4712
5246
  ) : void 0;
4713
5247
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig3) : [];
4714
5248
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -4731,7 +5265,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4731
5265
  typeName,
4732
5266
  false,
4733
5267
  typeNameMapper,
4734
- filterCtx
5268
+ filterCtx,
5269
+ mutationTxCtx
4735
5270
  ) : void 0;
4736
5271
  const upsertSingleGenerated = onConflictInput ? generateUpsert3(
4737
5272
  db,
@@ -4746,7 +5281,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4746
5281
  typeName,
4747
5282
  true,
4748
5283
  typeNameMapper,
4749
- filterCtx
5284
+ filterCtx,
5285
+ mutationTxCtx
4750
5286
  ) : void 0;
4751
5287
  const updateGenerated = features.update ? generateUpdate3(
4752
5288
  db,
@@ -4761,7 +5297,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4761
5297
  false,
4762
5298
  features.requireWhere,
4763
5299
  typeNameMapper,
4764
- filterCtx
5300
+ filterCtx,
5301
+ mutationTxCtx
4765
5302
  ) : void 0;
4766
5303
  const updateSingleGenerated = features.update ? generateUpdate3(
4767
5304
  db,
@@ -4776,7 +5313,22 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4776
5313
  true,
4777
5314
  features.requireWhere,
4778
5315
  typeNameMapper,
4779
- filterCtx
5316
+ filterCtx,
5317
+ mutationTxCtx
5318
+ ) : void 0;
5319
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
5320
+ const updateManyGenerated = updateManyInput ? generateUpdateMany3(
5321
+ db,
5322
+ tableName,
5323
+ schema[tableName],
5324
+ tables,
5325
+ eagerRelations,
5326
+ updateManyInput,
5327
+ updateManyFieldName,
5328
+ typeName,
5329
+ typeNameMapper,
5330
+ filterCtx,
5331
+ mutationTxCtx
4780
5332
  ) : void 0;
4781
5333
  const deleteGenerated = features.delete ? generateDelete3(
4782
5334
  db,
@@ -4788,7 +5340,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4788
5340
  false,
4789
5341
  features.requireWhere,
4790
5342
  filterCtx,
4791
- { tableName, relationMap: namedRelations, tables }
5343
+ { tableName, relationMap: namedRelations, tables },
5344
+ mutationTxCtx
4792
5345
  ) : void 0;
4793
5346
  const deleteSingleGenerated = features.delete ? generateDelete3(
4794
5347
  db,
@@ -4800,7 +5353,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4800
5353
  true,
4801
5354
  features.requireWhere,
4802
5355
  filterCtx,
4803
- { tableName, relationMap: namedRelations, tables }
5356
+ { tableName, relationMap: namedRelations, tables },
5357
+ mutationTxCtx
4804
5358
  ) : void 0;
4805
5359
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4806
5360
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -4888,6 +5442,14 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4888
5442
  resolve: updateGenerated.resolver
4889
5443
  };
4890
5444
  }
5445
+ if (updateManyGenerated) {
5446
+ mutations[updateManyGenerated.name] = {
5447
+ // Nullable items: a no-match entry yields `null` in its slot.
5448
+ type: new GraphQLNonNull6(new GraphQLList6(singleTableItemOutput)),
5449
+ args: updateManyGenerated.args,
5450
+ resolve: updateManyGenerated.resolver
5451
+ };
5452
+ }
4891
5453
  if (updateSingleGenerated) {
4892
5454
  mutations[updateSingleGenerated.name] = {
4893
5455
  type: singleTableItemOutput,
@@ -4914,6 +5476,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4914
5476
  ...features.insert || onConflictInput ? [insertInput] : [],
4915
5477
  ...onConflictInput ? [onConflictInput] : [],
4916
5478
  ...features.update ? [updateInput] : [],
5479
+ ...updateManyInput ? [updateManyInput] : [],
4917
5480
  tableFilters,
4918
5481
  tableOrder
4919
5482
  ];
@@ -4930,6 +5493,11 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4930
5493
  inputs[havingInput.name] = havingInput;
4931
5494
  }
4932
5495
  }
5496
+ if (mutationTxCtx) {
5497
+ for (const name of Object.keys(mutations)) {
5498
+ mutationTxCtx.fieldNames.add(name);
5499
+ }
5500
+ }
4933
5501
  const fieldResolvers = {};
4934
5502
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
4935
5503
  const relResolvers = {};
@@ -4976,6 +5544,7 @@ var buildSchema = (db, config) => {
4976
5544
  distinct: config?.features?.distinct ?? true,
4977
5545
  insert: config?.features?.insert ?? true,
4978
5546
  update: config?.features?.update ?? true,
5547
+ updateMany: config?.features?.updateMany ?? true,
4979
5548
  delete: config?.features?.delete ?? true,
4980
5549
  upsert: config?.features?.upsert ?? false,
4981
5550
  requireWhere: config?.features?.requireWhere ?? false
@@ -4985,6 +5554,8 @@ var buildSchema = (db, config) => {
4985
5554
  defaultListSize: (complexityConfig === true ? void 0 : complexityConfig.defaultListSize) ?? 10,
4986
5555
  aggregateCost: (complexityConfig === true ? void 0 : complexityConfig.aggregateCost) ?? 10
4987
5556
  };
5557
+ const transactionsOpt = config?.transactions;
5558
+ const transactions = transactionsOpt === void 0 || transactionsOpt === "none" ? void 0 : { timeoutMs: (transactionsOpt === "auto" ? void 0 : transactionsOpt.timeoutMs) ?? 3e4 };
4988
5559
  const eagerOpt = config?.eagerLoadRelations;
4989
5560
  const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
4990
5561
  if (!typeNameMapper && suffixes.list === suffixes.single) {
@@ -5012,7 +5583,8 @@ var buildSchema = (db, config) => {
5012
5583
  typeNameMapper,
5013
5584
  shouldEagerLoad,
5014
5585
  features,
5015
- complexity
5586
+ complexity,
5587
+ transactions
5016
5588
  };
5017
5589
  let generatorOutput;
5018
5590
  if (is7(db, MySqlDatabase)) {