@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.cjs CHANGED
@@ -598,6 +598,203 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
598
598
  queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
599
599
  };
600
600
  };
601
+ var createMutationTxCtx = (options) => options ? { timeoutMs: options.timeoutMs, fieldNames: /* @__PURE__ */ new Set(), states: /* @__PURE__ */ new WeakMap() } : void 0;
602
+ var includedByDirectives = (node, variables) => {
603
+ for (const directive of node.directives ?? []) {
604
+ const name = directive.name.value;
605
+ if (name !== "skip" && name !== "include") {
606
+ continue;
607
+ }
608
+ const ifArg = directive.arguments?.find((arg) => arg.name.value === "if");
609
+ let value;
610
+ if (ifArg?.value.kind === "BooleanValue") {
611
+ value = ifArg.value.value;
612
+ } else if (ifArg?.value.kind === "Variable") {
613
+ value = variables?.[ifArg.value.name.value];
614
+ }
615
+ if (name === "skip" && value === true) {
616
+ return false;
617
+ }
618
+ if (name === "include" && value !== true) {
619
+ return false;
620
+ }
621
+ }
622
+ return true;
623
+ };
624
+ var collectRootMutationKeys = (selectionSet, fragments, variables, known, keys, visitedFragments) => {
625
+ for (const selection of selectionSet.selections) {
626
+ if (!includedByDirectives(selection, variables)) {
627
+ continue;
628
+ }
629
+ if (selection.kind === "Field") {
630
+ const name = selection.name.value;
631
+ if (name === "__typename") {
632
+ continue;
633
+ }
634
+ if (!known.has(name)) {
635
+ return false;
636
+ }
637
+ keys.add(selection.alias?.value ?? name);
638
+ } else if (selection.kind === "InlineFragment") {
639
+ if (!collectRootMutationKeys(selection.selectionSet, fragments, variables, known, keys, visitedFragments)) {
640
+ return false;
641
+ }
642
+ } else if (selection.kind === "FragmentSpread") {
643
+ const fragmentName = selection.name.value;
644
+ if (visitedFragments.has(fragmentName)) {
645
+ continue;
646
+ }
647
+ visitedFragments.add(fragmentName);
648
+ const fragment = fragments?.[fragmentName];
649
+ if (!fragment) {
650
+ return false;
651
+ }
652
+ if (!collectRootMutationKeys(fragment.selectionSet, fragments, variables, known, keys, visitedFragments)) {
653
+ return false;
654
+ }
655
+ }
656
+ }
657
+ return true;
658
+ };
659
+ var abortedBatchError = () => new import_graphql4.GraphQLError(
660
+ "Drizzle-GraphQL Error: Mutation was not executed because an earlier mutation in the same request failed and the shared transaction was rolled back."
661
+ );
662
+ var openSharedTx = (db, context, txCtx, stateKey, expected) => {
663
+ let release;
664
+ let rejectLatch;
665
+ const latch = new Promise((resolve, reject) => {
666
+ release = resolve;
667
+ rejectLatch = reject;
668
+ });
669
+ let readyResolve;
670
+ let readyReject;
671
+ const ready = new Promise((resolve, reject) => {
672
+ readyResolve = resolve;
673
+ readyReject = reject;
674
+ });
675
+ ready.catch(() => {
676
+ });
677
+ const canStash = context !== null && typeof context === "object" && !Object.isFrozen(context);
678
+ const settled = db.transaction(async (tx) => {
679
+ if (canStash) {
680
+ context[drizzleExecutorKey] = tx;
681
+ }
682
+ readyResolve(tx);
683
+ await latch;
684
+ });
685
+ let timer;
686
+ const clearTimer = () => {
687
+ if (timer !== void 0) {
688
+ clearTimeout(timer);
689
+ timer = void 0;
690
+ }
691
+ };
692
+ const state = {
693
+ kind: "shared",
694
+ expected,
695
+ completed: 0,
696
+ failure: void 0,
697
+ aborted: false,
698
+ done: false,
699
+ ready,
700
+ settled,
701
+ release,
702
+ abort: (e) => {
703
+ if (!state.aborted) {
704
+ state.aborted = true;
705
+ state.failure = e;
706
+ }
707
+ rejectLatch(e);
708
+ },
709
+ suspendTimer: clearTimer,
710
+ bumpTimer: () => {
711
+ clearTimer();
712
+ if (state.done) {
713
+ return;
714
+ }
715
+ timer = setTimeout(() => {
716
+ state.abort(
717
+ new import_graphql4.GraphQLError(
718
+ `Drizzle-GraphQL Error: Shared mutation transaction timed out after ${txCtx.timeoutMs}ms waiting for the remaining mutation fields; rolling back.`
719
+ )
720
+ );
721
+ }, txCtx.timeoutMs);
722
+ timer.unref?.();
723
+ }
724
+ };
725
+ const cleanup = () => {
726
+ state.done = true;
727
+ clearTimer();
728
+ if (canStash) {
729
+ delete context[drizzleExecutorKey];
730
+ }
731
+ if (!state.aborted) {
732
+ txCtx.states.delete(stateKey);
733
+ }
734
+ };
735
+ settled.then(cleanup, (e) => {
736
+ cleanup();
737
+ readyReject(e);
738
+ });
739
+ state.bumpTimer();
740
+ return state;
741
+ };
742
+ var runOnSharedTx = async (state, body) => {
743
+ if (state.aborted) {
744
+ await state.settled.catch(() => {
745
+ });
746
+ throw abortedBatchError();
747
+ }
748
+ state.suspendTimer();
749
+ const tx = await state.ready;
750
+ try {
751
+ if (state.aborted) {
752
+ throw abortedBatchError();
753
+ }
754
+ const result = await body(tx);
755
+ state.completed += 1;
756
+ if (state.completed >= state.expected) {
757
+ state.release();
758
+ await state.settled;
759
+ } else {
760
+ state.bumpTimer();
761
+ }
762
+ return result;
763
+ } catch (e) {
764
+ state.abort(e);
765
+ await state.settled.catch(() => {
766
+ });
767
+ throw e;
768
+ }
769
+ };
770
+ var runMutation = async (db, context, info, txCtx, body) => {
771
+ const contextIsObject = context !== null && (typeof context === "object" || typeof context === "function");
772
+ const stateKey = contextIsObject ? context : info.operation;
773
+ let state = txCtx?.states.get(stateKey);
774
+ if (!state) {
775
+ if (contextIsObject && context[drizzleExecutorKey]) {
776
+ return body(context[drizzleExecutorKey]);
777
+ }
778
+ if (!txCtx || info.operation.operation !== "mutation") {
779
+ return body(db);
780
+ }
781
+ const keys = /* @__PURE__ */ new Set();
782
+ const allKnown = collectRootMutationKeys(
783
+ info.operation.selectionSet,
784
+ info.fragments,
785
+ info.variableValues,
786
+ txCtx.fieldNames,
787
+ keys,
788
+ /* @__PURE__ */ new Set()
789
+ );
790
+ state = !allKnown || keys.size <= 1 ? { kind: "passthrough" } : openSharedTx(db, context, txCtx, stateKey, keys.size);
791
+ txCtx.states.set(stateKey, state);
792
+ }
793
+ if (state.kind === "passthrough") {
794
+ return body(resolveExecutor(db, context));
795
+ }
796
+ return runOnSharedTx(state, body);
797
+ };
601
798
  var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
602
799
  const cols = (0, import_drizzle_orm3.getColumns)(targetTable);
603
800
  const orderExprs = [
@@ -2244,6 +2441,7 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2244
2441
  const upsertArrayFieldName = `${upsertPrefix}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
2245
2442
  const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
2246
2443
  const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2444
+ const updateManyFieldName = `${prefixes.update}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}Many`;
2247
2445
  const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2248
2446
  const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
2249
2447
  const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
@@ -2259,11 +2457,28 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2259
2457
  upsertArrayFieldName,
2260
2458
  upsertSingleFieldName,
2261
2459
  updateFieldName,
2460
+ updateManyFieldName,
2262
2461
  updateSingleFieldName,
2263
2462
  deleteFieldName,
2264
2463
  deleteSingleFieldName
2265
2464
  };
2266
2465
  };
2466
+ var generateUpdateManyInput = (params) => {
2467
+ const { typeName, updatePrefix, updateInput, tableFilters } = params;
2468
+ return new import_graphql4.GraphQLInputObjectType({
2469
+ name: `${capitalize(updatePrefix)}${typeName}ManyInput`,
2470
+ description: `One entry of a batch update of ${typeName}: the rows \`where\` matches get this entry's \`set\` applied.`,
2471
+ fields: {
2472
+ where: {
2473
+ type: tableFilters,
2474
+ description: "Rows this entry updates. An omitted filter updates every row."
2475
+ },
2476
+ set: {
2477
+ type: new import_graphql4.GraphQLNonNull(updateInput)
2478
+ }
2479
+ }
2480
+ });
2481
+ };
2267
2482
  var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
2268
2483
  const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2269
2484
  if (!filters) {
@@ -2991,7 +3206,7 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
2991
3206
  args: queryArgs
2992
3207
  };
2993
3208
  };
2994
- var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
3209
+ var generateInsertArray = (db, _tableName, table, baseType, fieldName, txCtx) => {
2995
3210
  const queryArgs = {
2996
3211
  values: {
2997
3212
  type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(baseType)))
@@ -2999,14 +3214,16 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
2999
3214
  };
3000
3215
  return {
3001
3216
  name: fieldName,
3002
- resolver: async (_source, args, context, _info) => {
3217
+ resolver: async (_source, args, context, info) => {
3003
3218
  try {
3004
- const input = remapFromGraphQLArrayInput(args.values, table);
3005
- if (!input.length) {
3006
- throw new import_graphql6.GraphQLError("No values were provided!");
3007
- }
3008
- await resolveExecutor(db, context).insert(table).values(input);
3009
- return { isSuccess: true };
3219
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3220
+ const input = remapFromGraphQLArrayInput(args.values, table);
3221
+ if (!input.length) {
3222
+ throw new import_graphql6.GraphQLError("No values were provided!");
3223
+ }
3224
+ await executor.insert(table).values(input);
3225
+ return { isSuccess: true };
3226
+ });
3010
3227
  } catch (e) {
3011
3228
  throw toGraphQLError(e);
3012
3229
  }
@@ -3014,7 +3231,7 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
3014
3231
  args: queryArgs
3015
3232
  };
3016
3233
  };
3017
- var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3234
+ var generateInsertSingle = (db, _tableName, table, baseType, fieldName, txCtx) => {
3018
3235
  const queryArgs = {
3019
3236
  values: {
3020
3237
  type: new import_graphql6.GraphQLNonNull(baseType)
@@ -3022,11 +3239,13 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3022
3239
  };
3023
3240
  return {
3024
3241
  name: fieldName,
3025
- resolver: async (_source, args, context, _info) => {
3242
+ resolver: async (_source, args, context, info) => {
3026
3243
  try {
3027
- const input = remapFromGraphQLSingleInput(args.values, table);
3028
- await resolveExecutor(db, context).insert(table).values(input);
3029
- return { isSuccess: true };
3244
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3245
+ const input = remapFromGraphQLSingleInput(args.values, table);
3246
+ await executor.insert(table).values(input);
3247
+ return { isSuccess: true };
3248
+ });
3030
3249
  } catch (e) {
3031
3250
  throw toGraphQLError(e);
3032
3251
  }
@@ -3034,7 +3253,7 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
3034
3253
  args: queryArgs
3035
3254
  };
3036
3255
  };
3037
- var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) => {
3256
+ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single, txCtx) => {
3038
3257
  const queryArgs = {
3039
3258
  values: {
3040
3259
  type: single ? new import_graphql6.GraphQLNonNull(baseType) : new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(baseType)))
@@ -3047,28 +3266,29 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
3047
3266
  const pkNames = mysqlPrimaryKeyPropNames(table);
3048
3267
  return {
3049
3268
  name: fieldName,
3050
- resolver: async (_source, args, context, _info) => {
3269
+ resolver: async (_source, args, context, info) => {
3051
3270
  try {
3052
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3053
- if (!input.length) {
3054
- throw new import_graphql6.GraphQLError("No values were provided!");
3055
- }
3056
- const plan = resolveConflictPlan({
3057
- table,
3058
- values: input,
3059
- onConflict: args.onConflict,
3060
- pkNames,
3061
- uniqueSets: [],
3062
- excludedRef: mysqlValuesColumnRef,
3063
- withTarget: false
3271
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3272
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3273
+ if (!input.length) {
3274
+ throw new import_graphql6.GraphQLError("No values were provided!");
3275
+ }
3276
+ const plan = resolveConflictPlan({
3277
+ table,
3278
+ values: input,
3279
+ onConflict: args.onConflict,
3280
+ pkNames,
3281
+ uniqueSets: [],
3282
+ excludedRef: mysqlValuesColumnRef,
3283
+ withTarget: false
3284
+ });
3285
+ if (plan.action === "NOTHING") {
3286
+ await executor.insert(table).ignore().values(input);
3287
+ } else {
3288
+ await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
3289
+ }
3290
+ return { isSuccess: true };
3064
3291
  });
3065
- const executor = resolveExecutor(db, context);
3066
- if (plan.action === "NOTHING") {
3067
- await executor.insert(table).ignore().values(input);
3068
- } else {
3069
- await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
3070
- }
3071
- return { isSuccess: true };
3072
3292
  } catch (e) {
3073
3293
  throw toGraphQLError(e);
3074
3294
  }
@@ -3076,7 +3296,7 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
3076
3296
  args: queryArgs
3077
3297
  };
3078
3298
  };
3079
- var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
3299
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3080
3300
  const queryArgs = {
3081
3301
  set: {
3082
3302
  type: new import_graphql6.GraphQLNonNull(setArgs)
@@ -3087,25 +3307,69 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3087
3307
  };
3088
3308
  return {
3089
3309
  name: fieldName,
3090
- resolver: async (_source, args, context, _info) => {
3310
+ resolver: async (_source, args, context, info) => {
3091
3311
  try {
3092
- const { where, set } = args;
3093
- const input = remapFromGraphQLSingleInput(set, table);
3094
- if (!Object.keys(input).length) {
3095
- throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
3096
- }
3097
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3098
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3099
- const executor = resolveExecutor(db, context);
3100
- if (single) {
3101
- await assertSingleMatch(executor, table, filters, fieldName);
3102
- }
3103
- let query = executor.update(table).set(input);
3104
- if (filters) {
3105
- query = query.where(filters);
3106
- }
3107
- await query;
3108
- return { isSuccess: true };
3312
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3313
+ const { where, set } = args;
3314
+ const input = remapFromGraphQLSingleInput(set, table);
3315
+ if (!Object.keys(input).length) {
3316
+ throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
3317
+ }
3318
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3319
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3320
+ if (single) {
3321
+ await assertSingleMatch(executor, table, filters, fieldName);
3322
+ }
3323
+ let query = executor.update(table).set(input);
3324
+ if (filters) {
3325
+ query = query.where(filters);
3326
+ }
3327
+ await query;
3328
+ return { isSuccess: true };
3329
+ });
3330
+ } catch (e) {
3331
+ throw toGraphQLError(e);
3332
+ }
3333
+ },
3334
+ args: queryArgs
3335
+ };
3336
+ };
3337
+ var generateUpdateMany = (db, tableName, table, updateManyInput, fieldName, filterCtx, txCtx) => {
3338
+ const queryArgs = {
3339
+ updates: {
3340
+ type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(updateManyInput)))
3341
+ }
3342
+ };
3343
+ return {
3344
+ name: fieldName,
3345
+ resolver: async (_source, args, context, info) => {
3346
+ try {
3347
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3348
+ const { updates } = args;
3349
+ if (!updates.length) {
3350
+ throw new import_graphql6.GraphQLError("No updates were provided!");
3351
+ }
3352
+ const entries = updates.map(({ where, set }) => {
3353
+ const input = remapFromGraphQLSingleInput(set, table);
3354
+ if (!Object.keys(input).length) {
3355
+ throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
3356
+ }
3357
+ return {
3358
+ set: input,
3359
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
3360
+ };
3361
+ });
3362
+ await executor.transaction(async (tx) => {
3363
+ for (const entry of entries) {
3364
+ let query = tx.update(table).set(entry.set);
3365
+ if (entry.filters) {
3366
+ query = query.where(entry.filters);
3367
+ }
3368
+ await query;
3369
+ }
3370
+ });
3371
+ return { isSuccess: true };
3372
+ });
3109
3373
  } catch (e) {
3110
3374
  throw toGraphQLError(e);
3111
3375
  }
@@ -3113,7 +3377,7 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3113
3377
  args: queryArgs
3114
3378
  };
3115
3379
  };
3116
- var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
3380
+ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3117
3381
  const queryArgs = {
3118
3382
  where: {
3119
3383
  type: single || requireWhere ? new import_graphql6.GraphQLNonNull(filterArgs) : filterArgs
@@ -3121,21 +3385,22 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requi
3121
3385
  };
3122
3386
  return {
3123
3387
  name: fieldName,
3124
- resolver: async (_source, args, context, _info) => {
3388
+ resolver: async (_source, args, context, info) => {
3125
3389
  try {
3126
- const { where } = args;
3127
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3128
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3129
- const executor = resolveExecutor(db, context);
3130
- if (single) {
3131
- await assertSingleMatch(executor, table, filters, fieldName);
3132
- }
3133
- let query = executor.delete(table);
3134
- if (filters) {
3135
- query = query.where(filters);
3136
- }
3137
- await query;
3138
- return { isSuccess: true };
3390
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3391
+ const { where } = args;
3392
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3393
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3394
+ if (single) {
3395
+ await assertSingleMatch(executor, table, filters, fieldName);
3396
+ }
3397
+ let query = executor.delete(table);
3398
+ if (filters) {
3399
+ query = query.where(filters);
3400
+ }
3401
+ await query;
3402
+ return { isSuccess: true };
3403
+ });
3139
3404
  } catch (e) {
3140
3405
  throw toGraphQLError(e);
3141
3406
  }
@@ -3175,6 +3440,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3175
3440
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3176
3441
  const queries = {};
3177
3442
  const mutations = {};
3443
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
3178
3444
  const gqlSchemaTypes = Object.fromEntries(
3179
3445
  Object.entries(tables).map(([tableName, _table]) => [
3180
3446
  tableName,
@@ -3220,6 +3486,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3220
3486
  upsertArrayFieldName,
3221
3487
  upsertSingleFieldName,
3222
3488
  updateFieldName,
3489
+ updateManyFieldName,
3223
3490
  updateSingleFieldName,
3224
3491
  deleteFieldName,
3225
3492
  deleteSingleFieldName
@@ -3249,8 +3516,22 @@ var generateSchemaData = (db, schema, relations, options) => {
3249
3516
  typeNameMapper,
3250
3517
  filterCtx
3251
3518
  );
3252
- const insertArrGenerated = features.insert ? generateInsertArray(db, tableName, schema[tableName], insertInput, createArrayFieldName) : void 0;
3253
- const insertSingleGenerated = features.insert ? generateInsertSingle(db, tableName, schema[tableName], insertInput, createSingleFieldName) : void 0;
3519
+ const insertArrGenerated = features.insert ? generateInsertArray(
3520
+ db,
3521
+ tableName,
3522
+ schema[tableName],
3523
+ insertInput,
3524
+ createArrayFieldName,
3525
+ mutationTxCtx
3526
+ ) : void 0;
3527
+ const insertSingleGenerated = features.insert ? generateInsertSingle(
3528
+ db,
3529
+ tableName,
3530
+ schema[tableName],
3531
+ insertInput,
3532
+ createSingleFieldName,
3533
+ mutationTxCtx
3534
+ ) : void 0;
3254
3535
  const onConflictInput = features.upsert ? generateOnConflictInput({
3255
3536
  table: schema[tableName],
3256
3537
  typeName,
@@ -3258,8 +3539,24 @@ var generateSchemaData = (db, schema, relations, options) => {
3258
3539
  tableFilters,
3259
3540
  withTarget: false
3260
3541
  }) : void 0;
3261
- const upsertArrGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertArrayFieldName, false) : void 0;
3262
- const upsertSingleGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertSingleFieldName, true) : void 0;
3542
+ const upsertArrGenerated = onConflictInput ? generateUpsert(
3543
+ db,
3544
+ schema[tableName],
3545
+ insertInput,
3546
+ onConflictInput,
3547
+ upsertArrayFieldName,
3548
+ false,
3549
+ mutationTxCtx
3550
+ ) : void 0;
3551
+ const upsertSingleGenerated = onConflictInput ? generateUpsert(
3552
+ db,
3553
+ schema[tableName],
3554
+ insertInput,
3555
+ onConflictInput,
3556
+ upsertSingleFieldName,
3557
+ true,
3558
+ mutationTxCtx
3559
+ ) : void 0;
3263
3560
  const updateGenerated = features.update ? generateUpdate(
3264
3561
  db,
3265
3562
  tableName,
@@ -3269,7 +3566,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3269
3566
  updateFieldName,
3270
3567
  false,
3271
3568
  features.requireWhere,
3272
- filterCtx
3569
+ filterCtx,
3570
+ mutationTxCtx
3273
3571
  ) : void 0;
3274
3572
  const updateSingleGenerated = features.update ? generateUpdate(
3275
3573
  db,
@@ -3280,7 +3578,18 @@ var generateSchemaData = (db, schema, relations, options) => {
3280
3578
  updateSingleFieldName,
3281
3579
  true,
3282
3580
  features.requireWhere,
3283
- filterCtx
3581
+ filterCtx,
3582
+ mutationTxCtx
3583
+ ) : void 0;
3584
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
3585
+ const updateManyGenerated = updateManyInput ? generateUpdateMany(
3586
+ db,
3587
+ tableName,
3588
+ schema[tableName],
3589
+ updateManyInput,
3590
+ updateManyFieldName,
3591
+ filterCtx,
3592
+ mutationTxCtx
3284
3593
  ) : void 0;
3285
3594
  const deleteGenerated = features.delete ? generateDelete(
3286
3595
  db,
@@ -3290,7 +3599,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3290
3599
  deleteFieldName,
3291
3600
  false,
3292
3601
  features.requireWhere,
3293
- filterCtx
3602
+ filterCtx,
3603
+ mutationTxCtx
3294
3604
  ) : void 0;
3295
3605
  const deleteSingleGenerated = features.delete ? generateDelete(
3296
3606
  db,
@@ -3300,7 +3610,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3300
3610
  deleteSingleFieldName,
3301
3611
  true,
3302
3612
  features.requireWhere,
3303
- filterCtx
3613
+ filterCtx,
3614
+ mutationTxCtx
3304
3615
  ) : void 0;
3305
3616
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3306
3617
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -3359,6 +3670,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3359
3670
  upsertArrGenerated,
3360
3671
  upsertSingleGenerated,
3361
3672
  updateGenerated,
3673
+ updateManyGenerated,
3362
3674
  updateSingleGenerated,
3363
3675
  deleteGenerated,
3364
3676
  deleteSingleGenerated
@@ -3376,6 +3688,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3376
3688
  ...features.insert || onConflictInput ? [insertInput] : [],
3377
3689
  ...onConflictInput ? [onConflictInput] : [],
3378
3690
  ...features.update ? [updateInput] : [],
3691
+ ...updateManyInput ? [updateManyInput] : [],
3379
3692
  tableFilters,
3380
3693
  tableOrder
3381
3694
  ];
@@ -3391,6 +3704,11 @@ var generateSchemaData = (db, schema, relations, options) => {
3391
3704
  inputs[havingInput.name] = havingInput;
3392
3705
  }
3393
3706
  }
3707
+ if (mutationTxCtx) {
3708
+ for (const name of Object.keys(mutations)) {
3709
+ mutationTxCtx.fieldNames.add(name);
3710
+ }
3711
+ }
3394
3712
  const fieldResolvers = {};
3395
3713
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
3396
3714
  const relResolvers = {};
@@ -3594,7 +3912,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
3594
3912
  };
3595
3913
  };
3596
3914
  var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_pg_core2.getTableConfig);
3597
- var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
3915
+ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
3598
3916
  const queryArgs = {
3599
3917
  values: {
3600
3918
  type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(baseType)))
@@ -3605,31 +3923,32 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
3605
3923
  name: fieldName,
3606
3924
  resolver: async (_source, args, context, info) => {
3607
3925
  try {
3608
- const input = remapFromGraphQLArrayInput(args.values, table);
3609
- if (!input.length) {
3610
- throw new import_graphql7.GraphQLError("No values were provided!");
3611
- }
3612
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3613
- deep: true
3614
- });
3615
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3616
- relationMap,
3617
- tables,
3618
- tableName,
3619
- typeName,
3620
- typeNameMapper,
3621
- table,
3622
- pkNames,
3623
- parsedInfo
3926
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3927
+ const input = remapFromGraphQLArrayInput(args.values, table);
3928
+ if (!input.length) {
3929
+ throw new import_graphql7.GraphQLError("No values were provided!");
3930
+ }
3931
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3932
+ deep: true
3933
+ });
3934
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3935
+ relationMap,
3936
+ tables,
3937
+ tableName,
3938
+ typeName,
3939
+ typeNameMapper,
3940
+ table,
3941
+ pkNames,
3942
+ parsedInfo
3943
+ });
3944
+ let query = executor.insert(table).values(input).returning(columns);
3945
+ if (conflictDoNothing) {
3946
+ query = query.onConflictDoNothing();
3947
+ }
3948
+ const result = await query;
3949
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3950
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3624
3951
  });
3625
- const executor = resolveExecutor(db, context);
3626
- let query = executor.insert(table).values(input).returning(columns);
3627
- if (conflictDoNothing) {
3628
- query = query.onConflictDoNothing();
3629
- }
3630
- const result = await query;
3631
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3632
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3633
3952
  } catch (e) {
3634
3953
  throw toGraphQLError(e);
3635
3954
  }
@@ -3637,7 +3956,7 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
3637
3956
  args: queryArgs
3638
3957
  };
3639
3958
  };
3640
- var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
3959
+ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
3641
3960
  const queryArgs = {
3642
3961
  values: {
3643
3962
  type: new import_graphql7.GraphQLNonNull(baseType)
@@ -3648,31 +3967,32 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
3648
3967
  name: fieldName,
3649
3968
  resolver: async (_source, args, context, info) => {
3650
3969
  try {
3651
- const input = remapFromGraphQLSingleInput(args.values, table);
3652
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3653
- deep: true
3654
- });
3655
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3656
- relationMap,
3657
- tables,
3658
- tableName,
3659
- typeName,
3660
- typeNameMapper,
3661
- table,
3662
- pkNames,
3663
- parsedInfo
3970
+ return await runMutation(db, context, info, txCtx, async (executor) => {
3971
+ const input = remapFromGraphQLSingleInput(args.values, table);
3972
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3973
+ deep: true
3974
+ });
3975
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3976
+ relationMap,
3977
+ tables,
3978
+ tableName,
3979
+ typeName,
3980
+ typeNameMapper,
3981
+ table,
3982
+ pkNames,
3983
+ parsedInfo
3984
+ });
3985
+ let query = executor.insert(table).values(input).returning(columns);
3986
+ if (conflictDoNothing) {
3987
+ query = query.onConflictDoNothing();
3988
+ }
3989
+ const result = await query;
3990
+ if (!result[0]) {
3991
+ return void 0;
3992
+ }
3993
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3994
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
3664
3995
  });
3665
- const executor = resolveExecutor(db, context);
3666
- let query = executor.insert(table).values(input).returning(columns);
3667
- if (conflictDoNothing) {
3668
- query = query.onConflictDoNothing();
3669
- }
3670
- const result = await query;
3671
- if (!result[0]) {
3672
- return void 0;
3673
- }
3674
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3675
- return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
3676
3996
  } catch (e) {
3677
3997
  throw toGraphQLError(e);
3678
3998
  }
@@ -3680,7 +4000,7 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
3680
4000
  args: queryArgs
3681
4001
  };
3682
4002
  };
3683
- var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
4003
+ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
3684
4004
  const queryArgs = {
3685
4005
  values: {
3686
4006
  type: single ? new import_graphql7.GraphQLNonNull(baseType) : new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(baseType)))
@@ -3695,40 +4015,41 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3695
4015
  name: fieldName,
3696
4016
  resolver: async (_source, args, context, info) => {
3697
4017
  try {
3698
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3699
- if (!input.length) {
3700
- throw new import_graphql7.GraphQLError("No values were provided!");
3701
- }
3702
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
3703
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3704
- relationMap,
3705
- tables,
3706
- tableName,
3707
- typeName,
3708
- typeNameMapper,
3709
- table,
3710
- pkNames,
3711
- parsedInfo
3712
- });
3713
- const plan = resolveConflictPlan({
3714
- table,
3715
- values: input,
3716
- onConflict: args.onConflict,
3717
- pkNames,
3718
- uniqueSets,
3719
- excludedRef: excludedColumnRef,
3720
- withTarget: true,
3721
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4018
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4019
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4020
+ if (!input.length) {
4021
+ throw new import_graphql7.GraphQLError("No values were provided!");
4022
+ }
4023
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
4024
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4025
+ relationMap,
4026
+ tables,
4027
+ tableName,
4028
+ typeName,
4029
+ typeNameMapper,
4030
+ table,
4031
+ pkNames,
4032
+ parsedInfo
4033
+ });
4034
+ const plan = resolveConflictPlan({
4035
+ table,
4036
+ values: input,
4037
+ onConflict: args.onConflict,
4038
+ pkNames,
4039
+ uniqueSets,
4040
+ excludedRef: excludedColumnRef,
4041
+ withTarget: true,
4042
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4043
+ });
4044
+ let query = executor.insert(table).values(input).returning(columns);
4045
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4046
+ const result = await query;
4047
+ if (single && !result[0]) {
4048
+ return void 0;
4049
+ }
4050
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4051
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3722
4052
  });
3723
- const executor = resolveExecutor(db, context);
3724
- let query = executor.insert(table).values(input).returning(columns);
3725
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
3726
- const result = await query;
3727
- if (single && !result[0]) {
3728
- return void 0;
3729
- }
3730
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3731
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3732
4053
  } catch (e) {
3733
4054
  throw toGraphQLError(e);
3734
4055
  }
@@ -3736,7 +4057,7 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3736
4057
  args: queryArgs
3737
4058
  };
3738
4059
  };
3739
- var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
4060
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
3740
4061
  const queryArgs = {
3741
4062
  set: {
3742
4063
  type: new import_graphql7.GraphQLNonNull(setArgs)
@@ -3750,44 +4071,118 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3750
4071
  name: fieldName,
3751
4072
  resolver: async (_source, args, context, info) => {
3752
4073
  try {
3753
- const { where, set } = args;
3754
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3755
- deep: true
4074
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4075
+ const { where, set } = args;
4076
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
4077
+ deep: true
4078
+ });
4079
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4080
+ relationMap,
4081
+ tables,
4082
+ tableName,
4083
+ typeName,
4084
+ typeNameMapper,
4085
+ table,
4086
+ pkNames,
4087
+ parsedInfo
4088
+ });
4089
+ const input = remapFromGraphQLSingleInput(set, table);
4090
+ if (!Object.keys(input).length) {
4091
+ throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
4092
+ }
4093
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4094
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4095
+ if (single) {
4096
+ await assertSingleMatch(executor, table, filters, fieldName);
4097
+ }
4098
+ let query = executor.update(table).set(input);
4099
+ if (filters) {
4100
+ query = query.where(filters);
4101
+ }
4102
+ query = query.returning(columns);
4103
+ const result = await query;
4104
+ if (single && result.length > 1) {
4105
+ throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4106
+ }
4107
+ if (single && !result[0]) {
4108
+ return void 0;
4109
+ }
4110
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4111
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3756
4112
  });
3757
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3758
- relationMap,
3759
- tables,
3760
- tableName,
3761
- typeName,
3762
- typeNameMapper,
3763
- table,
3764
- pkNames,
3765
- parsedInfo
4113
+ } catch (e) {
4114
+ throw toGraphQLError(e);
4115
+ }
4116
+ },
4117
+ args: queryArgs
4118
+ };
4119
+ };
4120
+ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
4121
+ const queryArgs = {
4122
+ updates: {
4123
+ type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(updateManyInput)))
4124
+ }
4125
+ };
4126
+ const pkNames = pgPrimaryKeyPropNames(table);
4127
+ return {
4128
+ name: fieldName,
4129
+ resolver: async (_source, args, context, info) => {
4130
+ try {
4131
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4132
+ const { updates } = args;
4133
+ if (!updates.length) {
4134
+ throw new import_graphql7.GraphQLError("No updates were provided!");
4135
+ }
4136
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
4137
+ deep: true
4138
+ });
4139
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4140
+ relationMap,
4141
+ tables,
4142
+ tableName,
4143
+ typeName,
4144
+ typeNameMapper,
4145
+ table,
4146
+ pkNames,
4147
+ parsedInfo
4148
+ });
4149
+ const entries = updates.map(({ where, set }) => {
4150
+ const input = remapFromGraphQLSingleInput(set, table);
4151
+ if (!Object.keys(input).length) {
4152
+ throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
4153
+ }
4154
+ return {
4155
+ set: input,
4156
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
4157
+ };
4158
+ });
4159
+ const perEntry = await executor.transaction(async (tx) => {
4160
+ const results = [];
4161
+ for (const entry of entries) {
4162
+ let query = tx.update(table).set(entry.set);
4163
+ if (entry.filters) {
4164
+ query = query.where(entry.filters);
4165
+ }
4166
+ results.push(await query.returning(columns));
4167
+ }
4168
+ return results;
4169
+ });
4170
+ const flatRows = perEntry.flat();
4171
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, flatRows, pkNames, withParams) : flatRows;
4172
+ const output = [];
4173
+ let offset = 0;
4174
+ for (const rows of perEntry) {
4175
+ if (!rows.length) {
4176
+ output.push(null);
4177
+ continue;
4178
+ }
4179
+ for (let i = 0; i < rows.length; i++) {
4180
+ output.push(remapToGraphQLSingleOutput(enriched[offset + i], tableName, table, relationMap));
4181
+ }
4182
+ offset += rows.length;
4183
+ }
4184
+ return output;
3766
4185
  });
3767
- const input = remapFromGraphQLSingleInput(set, table);
3768
- if (!Object.keys(input).length) {
3769
- throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
3770
- }
3771
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3772
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3773
- const executor = resolveExecutor(db, context);
3774
- if (single) {
3775
- await assertSingleMatch(executor, table, filters, fieldName);
3776
- }
3777
- let query = executor.update(table).set(input);
3778
- if (filters) {
3779
- query = query.where(filters);
3780
- }
3781
- query = query.returning(columns);
3782
- const result = await query;
3783
- if (single && result.length > 1) {
3784
- throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
3785
- }
3786
- if (single && !result[0]) {
3787
- return void 0;
3788
- }
3789
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3790
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3791
4186
  } catch (e) {
3792
4187
  throw toGraphQLError(e);
3793
4188
  }
@@ -3795,7 +4190,7 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3795
4190
  args: queryArgs
3796
4191
  };
3797
4192
  };
3798
- var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
4193
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
3799
4194
  const queryArgs = {
3800
4195
  where: {
3801
4196
  type: single || requireWhere ? new import_graphql7.GraphQLNonNull(filterArgs) : filterArgs
@@ -3805,34 +4200,35 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, si
3805
4200
  name: fieldName,
3806
4201
  resolver: async (_source, args, context, info) => {
3807
4202
  try {
3808
- const { where } = args;
3809
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3810
- deep: true
4203
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4204
+ const { where } = args;
4205
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
4206
+ deep: true
4207
+ });
4208
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
4209
+ parsedInfo.fieldsByTypeName[typeName],
4210
+ table,
4211
+ selectionCtx
4212
+ );
4213
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4214
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4215
+ if (single) {
4216
+ await assertSingleMatch(executor, table, filters, fieldName);
4217
+ }
4218
+ let query = executor.delete(table);
4219
+ if (filters) {
4220
+ query = query.where(filters);
4221
+ }
4222
+ query = query.returning(columns);
4223
+ const result = await query;
4224
+ if (single && result.length > 1) {
4225
+ throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4226
+ }
4227
+ if (single) {
4228
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4229
+ }
4230
+ return remapToGraphQLArrayOutput(result, tableName, table);
3811
4231
  });
3812
- const columns = extractSelectedColumnsFromTreeSQLFormat(
3813
- parsedInfo.fieldsByTypeName[typeName],
3814
- table,
3815
- selectionCtx
3816
- );
3817
- const relationCtx = relationFilterCtx(filterCtx, tableName);
3818
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3819
- const executor = resolveExecutor(db, context);
3820
- if (single) {
3821
- await assertSingleMatch(executor, table, filters, fieldName);
3822
- }
3823
- let query = executor.delete(table);
3824
- if (filters) {
3825
- query = query.where(filters);
3826
- }
3827
- query = query.returning(columns);
3828
- const result = await query;
3829
- if (single && result.length > 1) {
3830
- throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
3831
- }
3832
- if (single) {
3833
- return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
3834
- }
3835
- return remapToGraphQLArrayOutput(result, tableName, table);
3836
4232
  } catch (e) {
3837
4233
  throw toGraphQLError(e);
3838
4234
  }
@@ -3879,6 +4275,7 @@ function generateSchemaData2(db, schema, relations, options) {
3879
4275
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3880
4276
  const queries = {};
3881
4277
  const mutations = {};
4278
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
3882
4279
  const gqlSchemaTypes = Object.fromEntries(
3883
4280
  Object.entries(tables).map(([tableName, _table]) => [
3884
4281
  tableName,
@@ -3913,6 +4310,7 @@ function generateSchemaData2(db, schema, relations, options) {
3913
4310
  upsertArrayFieldName,
3914
4311
  upsertSingleFieldName,
3915
4312
  updateFieldName,
4313
+ updateManyFieldName,
3916
4314
  updateSingleFieldName,
3917
4315
  deleteFieldName,
3918
4316
  deleteSingleFieldName
@@ -3952,7 +4350,8 @@ function generateSchemaData2(db, schema, relations, options) {
3952
4350
  createArrayFieldName,
3953
4351
  typeName,
3954
4352
  typeNameMapper,
3955
- conflictDoNothing
4353
+ conflictDoNothing,
4354
+ mutationTxCtx
3956
4355
  ) : void 0;
3957
4356
  const insertSingleGenerated = features.insert ? generateInsertSingle2(
3958
4357
  db,
@@ -3964,7 +4363,8 @@ function generateSchemaData2(db, schema, relations, options) {
3964
4363
  createSingleFieldName,
3965
4364
  typeName,
3966
4365
  typeNameMapper,
3967
- conflictDoNothing
4366
+ conflictDoNothing,
4367
+ mutationTxCtx
3968
4368
  ) : void 0;
3969
4369
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_pg_core2.getTableConfig) : [];
3970
4370
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -3987,7 +4387,8 @@ function generateSchemaData2(db, schema, relations, options) {
3987
4387
  typeName,
3988
4388
  false,
3989
4389
  typeNameMapper,
3990
- filterCtx
4390
+ filterCtx,
4391
+ mutationTxCtx
3991
4392
  ) : void 0;
3992
4393
  const upsertSingleGenerated = onConflictInput ? generateUpsert2(
3993
4394
  db,
@@ -4002,7 +4403,8 @@ function generateSchemaData2(db, schema, relations, options) {
4002
4403
  typeName,
4003
4404
  true,
4004
4405
  typeNameMapper,
4005
- filterCtx
4406
+ filterCtx,
4407
+ mutationTxCtx
4006
4408
  ) : void 0;
4007
4409
  const updateGenerated = features.update ? generateUpdate2(
4008
4410
  db,
@@ -4017,7 +4419,8 @@ function generateSchemaData2(db, schema, relations, options) {
4017
4419
  false,
4018
4420
  features.requireWhere,
4019
4421
  typeNameMapper,
4020
- filterCtx
4422
+ filterCtx,
4423
+ mutationTxCtx
4021
4424
  ) : void 0;
4022
4425
  const updateSingleGenerated = features.update ? generateUpdate2(
4023
4426
  db,
@@ -4032,7 +4435,22 @@ function generateSchemaData2(db, schema, relations, options) {
4032
4435
  true,
4033
4436
  features.requireWhere,
4034
4437
  typeNameMapper,
4035
- filterCtx
4438
+ filterCtx,
4439
+ mutationTxCtx
4440
+ ) : void 0;
4441
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
4442
+ const updateManyGenerated = updateManyInput ? generateUpdateMany2(
4443
+ db,
4444
+ tableName,
4445
+ schema[tableName],
4446
+ tables,
4447
+ eagerRelations,
4448
+ updateManyInput,
4449
+ updateManyFieldName,
4450
+ typeName,
4451
+ typeNameMapper,
4452
+ filterCtx,
4453
+ mutationTxCtx
4036
4454
  ) : void 0;
4037
4455
  const deleteGenerated = features.delete ? generateDelete2(
4038
4456
  db,
@@ -4044,7 +4462,8 @@ function generateSchemaData2(db, schema, relations, options) {
4044
4462
  false,
4045
4463
  features.requireWhere,
4046
4464
  filterCtx,
4047
- { tableName, relationMap: namedRelations, tables }
4465
+ { tableName, relationMap: namedRelations, tables },
4466
+ mutationTxCtx
4048
4467
  ) : void 0;
4049
4468
  const deleteSingleGenerated = features.delete ? generateDelete2(
4050
4469
  db,
@@ -4056,7 +4475,8 @@ function generateSchemaData2(db, schema, relations, options) {
4056
4475
  true,
4057
4476
  features.requireWhere,
4058
4477
  filterCtx,
4059
- { tableName, relationMap: namedRelations, tables }
4478
+ { tableName, relationMap: namedRelations, tables },
4479
+ mutationTxCtx
4060
4480
  ) : void 0;
4061
4481
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4062
4482
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -4144,6 +4564,14 @@ function generateSchemaData2(db, schema, relations, options) {
4144
4564
  resolve: updateGenerated.resolver
4145
4565
  };
4146
4566
  }
4567
+ if (updateManyGenerated) {
4568
+ mutations[updateManyGenerated.name] = {
4569
+ // Nullable items: a no-match entry yields `null` in its slot.
4570
+ type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(singleTableItemOutput)),
4571
+ args: updateManyGenerated.args,
4572
+ resolve: updateManyGenerated.resolver
4573
+ };
4574
+ }
4147
4575
  if (updateSingleGenerated) {
4148
4576
  mutations[updateSingleGenerated.name] = {
4149
4577
  type: singleTableItemOutput,
@@ -4170,6 +4598,7 @@ function generateSchemaData2(db, schema, relations, options) {
4170
4598
  ...features.insert || onConflictInput ? [insertInput] : [],
4171
4599
  ...onConflictInput ? [onConflictInput] : [],
4172
4600
  ...features.update ? [updateInput] : [],
4601
+ ...updateManyInput ? [updateManyInput] : [],
4173
4602
  tableFilters,
4174
4603
  tableOrder
4175
4604
  ];
@@ -4186,6 +4615,11 @@ function generateSchemaData2(db, schema, relations, options) {
4186
4615
  inputs[havingInput.name] = havingInput;
4187
4616
  }
4188
4617
  }
4618
+ if (mutationTxCtx) {
4619
+ for (const name of Object.keys(mutations)) {
4620
+ mutationTxCtx.fieldNames.add(name);
4621
+ }
4622
+ }
4189
4623
  const fieldResolvers = {};
4190
4624
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
4191
4625
  const relResolvers = {};
@@ -4291,7 +4725,7 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
4291
4725
  };
4292
4726
  };
4293
4727
  var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_sqlite_core2.getTableConfig);
4294
- var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
4728
+ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4295
4729
  const queryArgs = {
4296
4730
  values: {
4297
4731
  type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(baseType)))
@@ -4302,31 +4736,32 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4302
4736
  name: fieldName,
4303
4737
  resolver: async (_source, args, context, info) => {
4304
4738
  try {
4305
- const input = remapFromGraphQLArrayInput(args.values, table);
4306
- if (!input.length) {
4307
- throw new import_graphql8.GraphQLError("No values were provided!");
4308
- }
4309
- const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4310
- deep: true
4311
- });
4312
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4313
- relationMap,
4314
- tables,
4315
- tableName,
4316
- typeName,
4317
- typeNameMapper,
4318
- table,
4319
- pkNames,
4320
- parsedInfo
4739
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4740
+ const input = remapFromGraphQLArrayInput(args.values, table);
4741
+ if (!input.length) {
4742
+ throw new import_graphql8.GraphQLError("No values were provided!");
4743
+ }
4744
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4745
+ deep: true
4746
+ });
4747
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4748
+ relationMap,
4749
+ tables,
4750
+ tableName,
4751
+ typeName,
4752
+ typeNameMapper,
4753
+ table,
4754
+ pkNames,
4755
+ parsedInfo
4756
+ });
4757
+ let query = executor.insert(table).values(input).returning(columns);
4758
+ if (conflictDoNothing) {
4759
+ query = query.onConflictDoNothing();
4760
+ }
4761
+ const result = await query;
4762
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4763
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4321
4764
  });
4322
- const executor = resolveExecutor(db, context);
4323
- let query = executor.insert(table).values(input).returning(columns);
4324
- if (conflictDoNothing) {
4325
- query = query.onConflictDoNothing();
4326
- }
4327
- const result = await query;
4328
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4329
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4330
4765
  } catch (e) {
4331
4766
  throw toGraphQLError(e);
4332
4767
  }
@@ -4334,7 +4769,7 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4334
4769
  args: queryArgs
4335
4770
  };
4336
4771
  };
4337
- var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
4772
+ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4338
4773
  const queryArgs = {
4339
4774
  values: {
4340
4775
  type: new import_graphql8.GraphQLNonNull(baseType)
@@ -4345,31 +4780,32 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4345
4780
  name: fieldName,
4346
4781
  resolver: async (_source, args, context, info) => {
4347
4782
  try {
4348
- const input = remapFromGraphQLSingleInput(args.values, table);
4349
- const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4350
- deep: true
4351
- });
4352
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4353
- relationMap,
4354
- tables,
4355
- tableName,
4356
- typeName,
4357
- typeNameMapper,
4358
- table,
4359
- pkNames,
4360
- parsedInfo
4783
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4784
+ const input = remapFromGraphQLSingleInput(args.values, table);
4785
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4786
+ deep: true
4787
+ });
4788
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4789
+ relationMap,
4790
+ tables,
4791
+ tableName,
4792
+ typeName,
4793
+ typeNameMapper,
4794
+ table,
4795
+ pkNames,
4796
+ parsedInfo
4797
+ });
4798
+ let query = executor.insert(table).values(input).returning(columns);
4799
+ if (conflictDoNothing) {
4800
+ query = query.onConflictDoNothing();
4801
+ }
4802
+ const result = await query;
4803
+ if (!result[0]) {
4804
+ return void 0;
4805
+ }
4806
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4807
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
4361
4808
  });
4362
- const executor = resolveExecutor(db, context);
4363
- let query = executor.insert(table).values(input).returning(columns);
4364
- if (conflictDoNothing) {
4365
- query = query.onConflictDoNothing();
4366
- }
4367
- const result = await query;
4368
- if (!result[0]) {
4369
- return void 0;
4370
- }
4371
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4372
- return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
4373
4809
  } catch (e) {
4374
4810
  throw toGraphQLError(e);
4375
4811
  }
@@ -4377,7 +4813,7 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4377
4813
  args: queryArgs
4378
4814
  };
4379
4815
  };
4380
- var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
4816
+ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
4381
4817
  const queryArgs = {
4382
4818
  values: {
4383
4819
  type: single ? new import_graphql8.GraphQLNonNull(baseType) : new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(baseType)))
@@ -4392,40 +4828,41 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4392
4828
  name: fieldName,
4393
4829
  resolver: async (_source, args, context, info) => {
4394
4830
  try {
4395
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4396
- if (!input.length) {
4397
- throw new import_graphql8.GraphQLError("No values were provided!");
4398
- }
4399
- const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
4400
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4401
- relationMap,
4402
- tables,
4403
- tableName,
4404
- typeName,
4405
- typeNameMapper,
4406
- table,
4407
- pkNames,
4408
- parsedInfo
4409
- });
4410
- const plan = resolveConflictPlan({
4411
- table,
4412
- values: input,
4413
- onConflict: args.onConflict,
4414
- pkNames,
4415
- uniqueSets,
4416
- excludedRef: excludedColumnRef,
4417
- withTarget: true,
4418
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4831
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4832
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4833
+ if (!input.length) {
4834
+ throw new import_graphql8.GraphQLError("No values were provided!");
4835
+ }
4836
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
4837
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4838
+ relationMap,
4839
+ tables,
4840
+ tableName,
4841
+ typeName,
4842
+ typeNameMapper,
4843
+ table,
4844
+ pkNames,
4845
+ parsedInfo
4846
+ });
4847
+ const plan = resolveConflictPlan({
4848
+ table,
4849
+ values: input,
4850
+ onConflict: args.onConflict,
4851
+ pkNames,
4852
+ uniqueSets,
4853
+ excludedRef: excludedColumnRef,
4854
+ withTarget: true,
4855
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4856
+ });
4857
+ let query = executor.insert(table).values(input).returning(columns);
4858
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4859
+ const result = await query;
4860
+ if (single && !result[0]) {
4861
+ return void 0;
4862
+ }
4863
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4864
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4419
4865
  });
4420
- const executor = resolveExecutor(db, context);
4421
- let query = executor.insert(table).values(input).returning(columns);
4422
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4423
- const result = await query;
4424
- if (single && !result[0]) {
4425
- return void 0;
4426
- }
4427
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4428
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4429
4866
  } catch (e) {
4430
4867
  throw toGraphQLError(e);
4431
4868
  }
@@ -4433,7 +4870,7 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4433
4870
  args: queryArgs
4434
4871
  };
4435
4872
  };
4436
- var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
4873
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
4437
4874
  const queryArgs = {
4438
4875
  set: {
4439
4876
  type: new import_graphql8.GraphQLNonNull(setArgs)
@@ -4447,44 +4884,131 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
4447
4884
  name: fieldName,
4448
4885
  resolver: async (_source, args, context, info) => {
4449
4886
  try {
4450
- const { where, set } = args;
4451
- const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4452
- deep: true
4887
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4888
+ const { where, set } = args;
4889
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4890
+ deep: true
4891
+ });
4892
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4893
+ relationMap,
4894
+ tables,
4895
+ tableName,
4896
+ typeName,
4897
+ typeNameMapper,
4898
+ table,
4899
+ pkNames,
4900
+ parsedInfo
4901
+ });
4902
+ const input = remapFromGraphQLSingleInput(set, table);
4903
+ if (!Object.keys(input).length) {
4904
+ throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
4905
+ }
4906
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4907
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4908
+ if (single) {
4909
+ await assertSingleMatch(executor, table, filters, fieldName);
4910
+ }
4911
+ let query = executor.update(table).set(input);
4912
+ if (filters) {
4913
+ query = query.where(filters);
4914
+ }
4915
+ query = query.returning(columns);
4916
+ const result = await query;
4917
+ if (single && result.length > 1) {
4918
+ throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4919
+ }
4920
+ if (single && !result[0]) {
4921
+ return void 0;
4922
+ }
4923
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4924
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4453
4925
  });
4454
- const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4455
- relationMap,
4456
- tables,
4457
- tableName,
4458
- typeName,
4459
- typeNameMapper,
4460
- table,
4461
- pkNames,
4462
- parsedInfo
4926
+ } catch (e) {
4927
+ throw toGraphQLError(e);
4928
+ }
4929
+ },
4930
+ args: queryArgs
4931
+ };
4932
+ };
4933
+ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
4934
+ const queryArgs = {
4935
+ updates: {
4936
+ type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(updateManyInput)))
4937
+ }
4938
+ };
4939
+ const pkNames = sqlitePrimaryKeyPropNames(table);
4940
+ return {
4941
+ name: fieldName,
4942
+ resolver: async (_source, args, context, info) => {
4943
+ try {
4944
+ return await runMutation(db, context, info, txCtx, async (executor) => {
4945
+ const { updates } = args;
4946
+ if (!updates.length) {
4947
+ throw new import_graphql8.GraphQLError("No updates were provided!");
4948
+ }
4949
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4950
+ deep: true
4951
+ });
4952
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4953
+ relationMap,
4954
+ tables,
4955
+ tableName,
4956
+ typeName,
4957
+ typeNameMapper,
4958
+ table,
4959
+ pkNames,
4960
+ parsedInfo
4961
+ });
4962
+ const entries = updates.map(({ where, set }) => {
4963
+ const input = remapFromGraphQLSingleInput(set, table);
4964
+ if (!Object.keys(input).length) {
4965
+ throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
4966
+ }
4967
+ return {
4968
+ set: input,
4969
+ filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
4970
+ };
4971
+ });
4972
+ const runEntry = (tx, entry) => {
4973
+ let query = tx.update(table).set(entry.set);
4974
+ if (entry.filters) {
4975
+ query = query.where(entry.filters);
4976
+ }
4977
+ return query.returning(columns).all();
4978
+ };
4979
+ const perEntry = await executor.transaction((tx) => {
4980
+ const first = runEntry(tx, entries[0]);
4981
+ if (typeof first?.then === "function") {
4982
+ return (async () => {
4983
+ const results2 = [await first];
4984
+ for (let i = 1; i < entries.length; i++) {
4985
+ results2.push(await runEntry(tx, entries[i]));
4986
+ }
4987
+ return results2;
4988
+ })();
4989
+ }
4990
+ const results = [first];
4991
+ for (let i = 1; i < entries.length; i++) {
4992
+ results.push(runEntry(tx, entries[i]));
4993
+ }
4994
+ return results;
4995
+ });
4996
+ const flatRows = perEntry.flat();
4997
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, flatRows, pkNames, withParams) : flatRows;
4998
+ const output = [];
4999
+ let offset = 0;
5000
+ for (const rows of perEntry) {
5001
+ if (!rows.length) {
5002
+ output.push(null);
5003
+ continue;
5004
+ }
5005
+ for (let i = 0; i < rows.length; i++) {
5006
+ output.push(remapToGraphQLSingleOutput(enriched[offset + i], tableName, table, relationMap));
5007
+ }
5008
+ offset += rows.length;
5009
+ }
5010
+ return output;
4463
5011
  });
4464
- const input = remapFromGraphQLSingleInput(set, table);
4465
- if (!Object.keys(input).length) {
4466
- throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
4467
- }
4468
- const relationCtx = relationFilterCtx(filterCtx, tableName);
4469
- const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4470
- const executor = resolveExecutor(db, context);
4471
- if (single) {
4472
- await assertSingleMatch(executor, table, filters, fieldName);
4473
- }
4474
- let query = executor.update(table).set(input);
4475
- if (filters) {
4476
- query = query.where(filters);
4477
- }
4478
- query = query.returning(columns);
4479
- const result = await query;
4480
- if (single && result.length > 1) {
4481
- throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4482
- }
4483
- if (single && !result[0]) {
4484
- return void 0;
4485
- }
4486
- const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4487
- return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4488
5012
  } catch (e) {
4489
5013
  throw toGraphQLError(e);
4490
5014
  }
@@ -4492,7 +5016,7 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
4492
5016
  args: queryArgs
4493
5017
  };
4494
5018
  };
4495
- var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
5019
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
4496
5020
  const queryArgs = {
4497
5021
  where: {
4498
5022
  type: single || requireWhere ? new import_graphql8.GraphQLNonNull(filterArgs) : filterArgs
@@ -4502,34 +5026,35 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, si
4502
5026
  name: fieldName,
4503
5027
  resolver: async (_source, args, context, info) => {
4504
5028
  try {
4505
- const { where } = args;
4506
- const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
4507
- deep: true
5029
+ return await runMutation(db, context, info, txCtx, async (executor) => {
5030
+ const { where } = args;
5031
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
5032
+ deep: true
5033
+ });
5034
+ const columns = extractSelectedColumnsFromTreeSQLFormat(
5035
+ parsedInfo.fieldsByTypeName[typeName],
5036
+ table,
5037
+ selectionCtx
5038
+ );
5039
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
5040
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
5041
+ if (single) {
5042
+ await assertSingleMatch(executor, table, filters, fieldName);
5043
+ }
5044
+ let query = executor.delete(table);
5045
+ if (filters) {
5046
+ query = query.where(filters);
5047
+ }
5048
+ query = query.returning(columns);
5049
+ const result = await query;
5050
+ if (single && result.length > 1) {
5051
+ throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
5052
+ }
5053
+ if (single) {
5054
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
5055
+ }
5056
+ return remapToGraphQLArrayOutput(result, tableName, table);
4508
5057
  });
4509
- const columns = extractSelectedColumnsFromTreeSQLFormat(
4510
- parsedInfo.fieldsByTypeName[typeName],
4511
- table,
4512
- selectionCtx
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.delete(table);
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 import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4528
- }
4529
- if (single) {
4530
- return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4531
- }
4532
- return remapToGraphQLArrayOutput(result, tableName, table);
4533
5058
  } catch (e) {
4534
5059
  throw toGraphQLError(e);
4535
5060
  }
@@ -4577,6 +5102,12 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4577
5102
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
4578
5103
  const queries = {};
4579
5104
  const mutations = {};
5105
+ if (options.transactions && db.resultKind === "sync") {
5106
+ throw new Error(
5107
+ "Drizzle-GraphQL Error: transactions: 'auto' requires an asynchronous SQLite driver (e.g. libsql). Synchronous drivers cannot hold a transaction open across resolvers."
5108
+ );
5109
+ }
5110
+ const mutationTxCtx = createMutationTxCtx(options.transactions);
4580
5111
  const gqlSchemaTypes = Object.fromEntries(
4581
5112
  Object.entries(tables).map(([tableName, _table]) => [
4582
5113
  tableName,
@@ -4611,6 +5142,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4611
5142
  upsertArrayFieldName,
4612
5143
  upsertSingleFieldName,
4613
5144
  updateFieldName,
5145
+ updateManyFieldName,
4614
5146
  updateSingleFieldName,
4615
5147
  deleteFieldName,
4616
5148
  deleteSingleFieldName
@@ -4650,7 +5182,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4650
5182
  createArrayFieldName,
4651
5183
  typeName,
4652
5184
  typeNameMapper,
4653
- conflictDoNothing
5185
+ conflictDoNothing,
5186
+ mutationTxCtx
4654
5187
  ) : void 0;
4655
5188
  const insertSingleGenerated = features.insert ? generateInsertSingle3(
4656
5189
  db,
@@ -4662,7 +5195,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4662
5195
  createSingleFieldName,
4663
5196
  typeName,
4664
5197
  typeNameMapper,
4665
- conflictDoNothing
5198
+ conflictDoNothing,
5199
+ mutationTxCtx
4666
5200
  ) : void 0;
4667
5201
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_sqlite_core2.getTableConfig) : [];
4668
5202
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -4685,7 +5219,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4685
5219
  typeName,
4686
5220
  false,
4687
5221
  typeNameMapper,
4688
- filterCtx
5222
+ filterCtx,
5223
+ mutationTxCtx
4689
5224
  ) : void 0;
4690
5225
  const upsertSingleGenerated = onConflictInput ? generateUpsert3(
4691
5226
  db,
@@ -4700,7 +5235,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4700
5235
  typeName,
4701
5236
  true,
4702
5237
  typeNameMapper,
4703
- filterCtx
5238
+ filterCtx,
5239
+ mutationTxCtx
4704
5240
  ) : void 0;
4705
5241
  const updateGenerated = features.update ? generateUpdate3(
4706
5242
  db,
@@ -4715,7 +5251,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4715
5251
  false,
4716
5252
  features.requireWhere,
4717
5253
  typeNameMapper,
4718
- filterCtx
5254
+ filterCtx,
5255
+ mutationTxCtx
4719
5256
  ) : void 0;
4720
5257
  const updateSingleGenerated = features.update ? generateUpdate3(
4721
5258
  db,
@@ -4730,7 +5267,22 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4730
5267
  true,
4731
5268
  features.requireWhere,
4732
5269
  typeNameMapper,
4733
- filterCtx
5270
+ filterCtx,
5271
+ mutationTxCtx
5272
+ ) : void 0;
5273
+ const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
5274
+ const updateManyGenerated = updateManyInput ? generateUpdateMany3(
5275
+ db,
5276
+ tableName,
5277
+ schema[tableName],
5278
+ tables,
5279
+ eagerRelations,
5280
+ updateManyInput,
5281
+ updateManyFieldName,
5282
+ typeName,
5283
+ typeNameMapper,
5284
+ filterCtx,
5285
+ mutationTxCtx
4734
5286
  ) : void 0;
4735
5287
  const deleteGenerated = features.delete ? generateDelete3(
4736
5288
  db,
@@ -4742,7 +5294,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4742
5294
  false,
4743
5295
  features.requireWhere,
4744
5296
  filterCtx,
4745
- { tableName, relationMap: namedRelations, tables }
5297
+ { tableName, relationMap: namedRelations, tables },
5298
+ mutationTxCtx
4746
5299
  ) : void 0;
4747
5300
  const deleteSingleGenerated = features.delete ? generateDelete3(
4748
5301
  db,
@@ -4754,7 +5307,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4754
5307
  true,
4755
5308
  features.requireWhere,
4756
5309
  filterCtx,
4757
- { tableName, relationMap: namedRelations, tables }
5310
+ { tableName, relationMap: namedRelations, tables },
5311
+ mutationTxCtx
4758
5312
  ) : void 0;
4759
5313
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4760
5314
  const aggregateGenerated = features.aggregates ? generateAggregate(
@@ -4842,6 +5396,14 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4842
5396
  resolve: updateGenerated.resolver
4843
5397
  };
4844
5398
  }
5399
+ if (updateManyGenerated) {
5400
+ mutations[updateManyGenerated.name] = {
5401
+ // Nullable items: a no-match entry yields `null` in its slot.
5402
+ type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(singleTableItemOutput)),
5403
+ args: updateManyGenerated.args,
5404
+ resolve: updateManyGenerated.resolver
5405
+ };
5406
+ }
4845
5407
  if (updateSingleGenerated) {
4846
5408
  mutations[updateSingleGenerated.name] = {
4847
5409
  type: singleTableItemOutput,
@@ -4868,6 +5430,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4868
5430
  ...features.insert || onConflictInput ? [insertInput] : [],
4869
5431
  ...onConflictInput ? [onConflictInput] : [],
4870
5432
  ...features.update ? [updateInput] : [],
5433
+ ...updateManyInput ? [updateManyInput] : [],
4871
5434
  tableFilters,
4872
5435
  tableOrder
4873
5436
  ];
@@ -4884,6 +5447,11 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4884
5447
  inputs[havingInput.name] = havingInput;
4885
5448
  }
4886
5449
  }
5450
+ if (mutationTxCtx) {
5451
+ for (const name of Object.keys(mutations)) {
5452
+ mutationTxCtx.fieldNames.add(name);
5453
+ }
5454
+ }
4887
5455
  const fieldResolvers = {};
4888
5456
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
4889
5457
  const relResolvers = {};
@@ -4930,6 +5498,7 @@ var buildSchema = (db, config) => {
4930
5498
  distinct: config?.features?.distinct ?? true,
4931
5499
  insert: config?.features?.insert ?? true,
4932
5500
  update: config?.features?.update ?? true,
5501
+ updateMany: config?.features?.updateMany ?? true,
4933
5502
  delete: config?.features?.delete ?? true,
4934
5503
  upsert: config?.features?.upsert ?? false,
4935
5504
  requireWhere: config?.features?.requireWhere ?? false
@@ -4939,6 +5508,8 @@ var buildSchema = (db, config) => {
4939
5508
  defaultListSize: (complexityConfig === true ? void 0 : complexityConfig.defaultListSize) ?? 10,
4940
5509
  aggregateCost: (complexityConfig === true ? void 0 : complexityConfig.aggregateCost) ?? 10
4941
5510
  };
5511
+ const transactionsOpt = config?.transactions;
5512
+ const transactions = transactionsOpt === void 0 || transactionsOpt === "none" ? void 0 : { timeoutMs: (transactionsOpt === "auto" ? void 0 : transactionsOpt.timeoutMs) ?? 3e4 };
4942
5513
  const eagerOpt = config?.eagerLoadRelations;
4943
5514
  const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
4944
5515
  if (!typeNameMapper && suffixes.list === suffixes.single) {
@@ -4966,7 +5537,8 @@ var buildSchema = (db, config) => {
4966
5537
  typeNameMapper,
4967
5538
  shouldEagerLoad,
4968
5539
  features,
4969
- complexity
5540
+ complexity,
5541
+ transactions
4970
5542
  };
4971
5543
  let generatorOutput;
4972
5544
  if ((0, import_drizzle_orm8.is)(db, import_mysql_core3.MySqlDatabase)) {