@vantreeseba/drizzle-graphql 5.6.0 → 7.0.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
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import { is as is7 } from "drizzle-orm";
2
+ import { is as is8 } from "drizzle-orm";
3
3
  import { MySqlDatabase } from "drizzle-orm/mysql-core";
4
4
  import { PgAsyncDatabase } from "drizzle-orm/pg-core";
5
5
  import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core";
@@ -18,7 +18,7 @@ import {
18
18
  desc,
19
19
  eq,
20
20
  extractExtendedColumnType as extractExtendedColumnType2,
21
- getColumns,
21
+ getColumns as getColumns2,
22
22
  getTableAsAliasSQL,
23
23
  gt,
24
24
  gte,
@@ -38,17 +38,17 @@ import {
38
38
  One as One2,
39
39
  or,
40
40
  relationsFilterToSQL,
41
- sql
41
+ sql as sql2
42
42
  } from "drizzle-orm";
43
43
  import {
44
44
  GraphQLBoolean as GraphQLBoolean2,
45
45
  GraphQLEnumType as GraphQLEnumType2,
46
- GraphQLError as GraphQLError3,
47
- GraphQLFloat as GraphQLFloat2,
48
- GraphQLInputObjectType as GraphQLInputObjectType2,
49
- GraphQLInt as GraphQLInt2,
50
- GraphQLList as GraphQLList2,
51
- GraphQLNonNull as GraphQLNonNull2,
46
+ GraphQLError as GraphQLError4,
47
+ GraphQLFloat as GraphQLFloat3,
48
+ GraphQLInputObjectType as GraphQLInputObjectType3,
49
+ GraphQLInt as GraphQLInt3,
50
+ GraphQLList as GraphQLList3,
51
+ GraphQLNonNull as GraphQLNonNull3,
52
52
  GraphQLObjectType as GraphQLObjectType2,
53
53
  GraphQLString as GraphQLString2
54
54
  } from "graphql";
@@ -198,15 +198,42 @@ var GraphQLDecimalString = new GraphQLScalarType({
198
198
 
199
199
  // src/util/type-converter/index.ts
200
200
  var allowedNameChars = /^[a-zA-Z0-9_]+$/;
201
- var enumMap = /* @__PURE__ */ new WeakMap();
201
+ var declaredEnum = (column) => {
202
+ const declared = column.enum;
203
+ return typeof declared?.enumName === "string" ? { enumName: declared.enumName, schema: typeof declared.schema === "string" ? declared.schema : void 0 } : void 0;
204
+ };
205
+ var pascalize = (input) => input.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => capitalize(part)).join("");
206
+ var enumValuesKey = (values) => JSON.stringify(values);
207
+ var enumNamesInUse = /* @__PURE__ */ new Map();
208
+ var enumNameMapper;
209
+ var registerEnumConfig = (config) => {
210
+ enumNameMapper = config.enumNameMapper;
211
+ enumNamesInUse = /* @__PURE__ */ new Map();
212
+ };
202
213
  var generateEnumCached = (column, columnName, tableName) => {
203
- if (enumMap.has(column)) {
204
- return enumMap.get(column);
214
+ const declared = declaredEnum(column);
215
+ const values = column.enumValues;
216
+ const name = enumNameMapper?.({
217
+ enumName: declared?.enumName,
218
+ schema: declared?.schema,
219
+ tableName,
220
+ columnName,
221
+ values
222
+ }) ?? (declared ? `${pascalize(declared.enumName)}Enum` : `${capitalize(tableName)}${capitalize(columnName)}Enum`);
223
+ const valuesKey = enumValuesKey(values);
224
+ const claimed = enumNamesInUse.get(name);
225
+ if (claimed) {
226
+ if (claimed.valuesKey !== valuesKey) {
227
+ throw new Error(
228
+ `Drizzle-GraphQL Error: Two different enums both map to the GraphQL type name '${name}' (most recently '${tableName}.${columnName}'). Give one of them a different name via config.enumNameMapper.`
229
+ );
230
+ }
231
+ return claimed.type;
205
232
  }
206
233
  const gqlEnum = new GraphQLEnumType({
207
- name: `${capitalize(tableName)}${capitalize(columnName)}Enum`,
234
+ name,
208
235
  values: Object.fromEntries(
209
- column.enumValues.map((e, index) => [
236
+ values.map((e, index) => [
210
237
  allowedNameChars.test(e) ? e : `Option${index}`,
211
238
  {
212
239
  value: e,
@@ -215,7 +242,7 @@ var generateEnumCached = (column, columnName, tableName) => {
215
242
  ])
216
243
  )
217
244
  });
218
- enumMap.set(column, gqlEnum);
245
+ enumNamesInUse.set(name, { type: gqlEnum, valuesKey });
219
246
  return gqlEnum;
220
247
  };
221
248
  var geoXyType = new GraphQLObjectType({
@@ -236,14 +263,14 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
236
263
  const dimensions = column.dimensions;
237
264
  if (dimensions !== void 0 && dimensions > 0) {
238
265
  const inner = columnBaseToGraphQLCore(column, columnName, tableName, isInput);
239
- const innerDesc = inner.description ?? inner.type.name;
266
+ const innerLabel = inner.typeLabel ?? inner.type.name;
240
267
  let type = inner.type;
241
- let description = innerDesc;
268
+ let typeLabel = innerLabel;
242
269
  for (let i = 0; i < dimensions; i++) {
243
270
  type = new GraphQLList(new GraphQLNonNull(type));
244
- description = `Array<${description}>`;
271
+ typeLabel = `Array<${typeLabel}>`;
245
272
  }
246
- return { type, description };
273
+ return { type, typeLabel };
247
274
  }
248
275
  return columnBaseToGraphQLCore(column, columnName, tableName, isInput);
249
276
  };
@@ -251,51 +278,51 @@ var columnBaseToGraphQLCore = (column, columnName, tableName, isInput) => {
251
278
  const { type: baseType, constraint } = extractExtendedColumnType(column);
252
279
  switch (baseType) {
253
280
  case "boolean":
254
- return { type: GraphQLBoolean, description: "Boolean" };
281
+ return { type: GraphQLBoolean, typeLabel: "Boolean" };
255
282
  case "object":
256
283
  if (column instanceof PgTimestamp || column instanceof PgDate) {
257
- return { type: GraphQLDateTime, description: "DateTime" };
284
+ return { type: GraphQLDateTime, typeLabel: "DateTime" };
258
285
  }
259
286
  return column.columnType === "PgGeometryObject" ? {
260
287
  type: isInput ? geoXyInputType : geoXyType,
261
- description: "Geometry points XY"
288
+ typeLabel: "Geometry points XY"
262
289
  } : column.columnType === "PgBytea" ? {
263
290
  type: new GraphQLList(new GraphQLNonNull(GraphQLInt)),
264
- description: "Buffer"
265
- } : { type: GraphQLJSON, description: "JSON" };
291
+ typeLabel: "Buffer"
292
+ } : { type: GraphQLJSON, typeLabel: "JSON" };
266
293
  case "string":
267
294
  if (column.enumValues?.length) {
268
295
  return { type: generateEnumCached(column, columnName, tableName) };
269
296
  }
270
297
  if (constraint === "numeric" && !column.dimensions) {
271
- return { type: GraphQLDecimalString, description: "Decimal" };
298
+ return { type: GraphQLDecimalString, typeLabel: "Decimal" };
272
299
  }
273
300
  if (column instanceof PgTimestamp || column instanceof PgTimestampString) {
274
- return { type: GraphQLDateTime, description: "DateTime" };
301
+ return { type: GraphQLDateTime, typeLabel: "DateTime" };
275
302
  }
276
303
  if (column instanceof PgUUID) {
277
- return { type: GraphQLUUID, description: "UUID" };
304
+ return { type: GraphQLUUID, typeLabel: "UUID" };
278
305
  }
279
306
  if (column instanceof PgDateString) {
280
- return isInput ? { type: GraphQLString, description: "Date" } : { type: GraphQLDate, description: "Date" };
307
+ return isInput ? { type: GraphQLString, typeLabel: "Date" } : { type: GraphQLDate, typeLabel: "Date" };
281
308
  }
282
- return { type: GraphQLString, description: "String" };
309
+ return { type: GraphQLString, typeLabel: "String" };
283
310
  case "bigint":
284
- return { type: GraphQLBigIntString, description: "BigInt" };
311
+ return { type: GraphQLBigIntString, typeLabel: "BigInt" };
285
312
  case "number": {
286
- return is(column, PgInteger) || is(column, PgSerial) || is(column, MySqlInt) || is(column, MySqlSerial) || is(column, SQLiteInteger) ? { type: GraphQLInt, description: "Integer" } : { type: GraphQLFloat, description: "Float" };
313
+ return is(column, PgInteger) || is(column, PgSerial) || is(column, MySqlInt) || is(column, MySqlSerial) || is(column, SQLiteInteger) ? { type: GraphQLInt, typeLabel: "Integer" } : { type: GraphQLFloat, typeLabel: "Float" };
287
314
  }
288
315
  case "array": {
289
316
  if (column.columnType === "PgVector") {
290
317
  return {
291
318
  type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
292
- description: "Array<Float>"
319
+ typeLabel: "Array<Float>"
293
320
  };
294
321
  }
295
322
  if (column.columnType === "PgGeometry") {
296
323
  return {
297
324
  type: new GraphQLList(new GraphQLNonNull(GraphQLFloat)),
298
- description: "Tuple<[Float, Float]>"
325
+ typeLabel: "Tuple<[Float, Float]>"
299
326
  };
300
327
  }
301
328
  const innerType = columnToGraphQLCore(
@@ -306,7 +333,7 @@ var columnBaseToGraphQLCore = (column, columnName, tableName, isInput) => {
306
333
  );
307
334
  return {
308
335
  type: new GraphQLList(new GraphQLNonNull(innerType.type)),
309
- description: `Array<${innerType.description}>`
336
+ typeLabel: `Array<${innerType.typeLabel}>`
310
337
  };
311
338
  }
312
339
  default:
@@ -362,24 +389,14 @@ var registerScalarOverrides = (tables, config) => {
362
389
  };
363
390
  var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable = false, defaultIsNullable = false, isInput = false) => {
364
391
  const override = getColumnScalarOverride(column, isInput);
365
- let typeDesc;
366
- if (override) {
367
- typeDesc = { type: override, description: override.name };
368
- } else {
369
- typeDesc = columnToGraphQLCore(column, columnName, tableName, isInput);
370
- const noDesc = ["string", "boolean", "number"];
371
- const { type: baseType } = extractExtendedColumnType(column);
372
- if (noDesc.find((e) => e === baseType)) {
373
- delete typeDesc.description;
374
- }
375
- }
392
+ const typeDesc = override ? { type: override, typeLabel: override.name } : columnToGraphQLCore(column, columnName, tableName, isInput);
376
393
  if (forceNullable) {
377
394
  return typeDesc;
378
395
  }
379
396
  if (column.notNull && !(defaultIsNullable && (column.hasDefault || column.defaultFn))) {
380
397
  return {
381
398
  type: new GraphQLNonNull(typeDesc.type),
382
- description: typeDesc.description
399
+ typeLabel: typeDesc.typeLabel
383
400
  };
384
401
  }
385
402
  return typeDesc;
@@ -585,6 +602,131 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
585
602
  return queryInput;
586
603
  };
587
604
 
605
+ // src/util/builders/field-updates.ts
606
+ import { getColumns, sql } from "drizzle-orm";
607
+ import {
608
+ GraphQLError as GraphQLError3,
609
+ GraphQLFloat as GraphQLFloat2,
610
+ GraphQLInputObjectType as GraphQLInputObjectType2,
611
+ GraphQLInt as GraphQLInt2,
612
+ GraphQLList as GraphQLList2,
613
+ GraphQLNonNull as GraphQLNonNull2
614
+ } from "graphql";
615
+ var NUMERIC_SCALARS = /* @__PURE__ */ new Set([
616
+ GraphQLInt2,
617
+ GraphQLFloat2,
618
+ GraphQLBigIntString,
619
+ GraphQLDecimalString
620
+ ]);
621
+ var NON_LIST_ARRAY_COLUMNS = /* @__PURE__ */ new Set(["PgVector", "PgGeometry", "PgBytea"]);
622
+ var kindCache = /* @__PURE__ */ new WeakMap();
623
+ var fieldUpdateKind = (column, columnName, tableName) => {
624
+ const cached = kindCache.get(column);
625
+ if (cached) {
626
+ return cached;
627
+ }
628
+ let kind = "none";
629
+ if (!getColumnScalarOverride(column, true)) {
630
+ const { type } = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
631
+ if (NUMERIC_SCALARS.has(type)) {
632
+ kind = "numeric";
633
+ } else if (type instanceof GraphQLList2 && !NON_LIST_ARRAY_COLUMNS.has(column.columnType)) {
634
+ kind = "list";
635
+ }
636
+ }
637
+ kindCache.set(column, kind);
638
+ return kind;
639
+ };
640
+ var inputCache = /* @__PURE__ */ new Map();
641
+ var namedFieldUpdateInput = (name, fields, description) => {
642
+ const cached = inputCache.get(name);
643
+ if (cached) {
644
+ return cached;
645
+ }
646
+ const input = new GraphQLInputObjectType2({ name, description, fields: fields() });
647
+ inputCache.set(name, input);
648
+ return input;
649
+ };
650
+ var fieldUpdateInputType = (column, columnName, tableName) => {
651
+ const kind = fieldUpdateKind(column, columnName, tableName);
652
+ if (kind === "none") {
653
+ return void 0;
654
+ }
655
+ const { type } = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
656
+ if (kind === "numeric") {
657
+ const scalar = type;
658
+ return namedFieldUpdateInput(
659
+ `${scalar.name}FieldUpdate`,
660
+ () => ({
661
+ set: { type: scalar, description: "Replace the current value with this one" },
662
+ increment: { type: scalar, description: "Add this to the current value (SQL `column + value`)" },
663
+ decrement: { type: scalar, description: "Subtract this from the current value (SQL `column - value`)" },
664
+ multiply: { type: scalar, description: "Multiply the current value by this (SQL `column * value`)" },
665
+ divide: {
666
+ type: scalar,
667
+ description: "Divide the current value by this (SQL `column / value`), rounding as the database does"
668
+ }
669
+ }),
670
+ `An update to a ${scalar.name} column: exactly one of these operations`
671
+ );
672
+ }
673
+ const list = type;
674
+ const element = list.ofType;
675
+ const elementName = element instanceof GraphQLNonNull2 ? String(element.ofType) : String(element);
676
+ return namedFieldUpdateInput(
677
+ `${elementName}ListFieldUpdate`,
678
+ () => ({
679
+ set: { type: list, description: "Replace the current array with this one" },
680
+ push: { type: list, description: "Append these elements to the current array" }
681
+ }),
682
+ `An update to a ${elementName} array column: exactly one of these operations`
683
+ );
684
+ };
685
+ var OPERATIONS = ["set", "increment", "decrement", "multiply", "divide", "push"];
686
+ var singleOperation = (value, columnName) => {
687
+ const given = OPERATIONS.filter((operation) => value[operation] !== void 0);
688
+ if (given.length === 1) {
689
+ return [given[0], value[given[0]]];
690
+ }
691
+ throw new GraphQLError3(
692
+ given.length ? `Field '${columnName}' takes exactly one update operation, but ${given.length} were given (${given.join(", ")}).` : `Field '${columnName}' was given no update operation. Pass exactly one of ${OPERATIONS.join(", ")}.`
693
+ );
694
+ };
695
+ var splitFieldUpdateOperations = (values, table, tableName) => {
696
+ const cols = getColumns(table);
697
+ const columns = {};
698
+ const expressions = {};
699
+ for (const [columnName, value] of Object.entries(values)) {
700
+ const column = cols[columnName];
701
+ if (!column || value === null || value === void 0) {
702
+ columns[columnName] = value;
703
+ continue;
704
+ }
705
+ const isOperations = typeof value === "object" && !Array.isArray(value) && !(value instanceof Date);
706
+ if (!isOperations || fieldUpdateKind(column, columnName, tableName) === "none") {
707
+ columns[columnName] = value;
708
+ continue;
709
+ }
710
+ const [operation, operand] = singleOperation(value, columnName);
711
+ if (operation === "set") {
712
+ columns[columnName] = operand;
713
+ continue;
714
+ }
715
+ const param = sql.param(remapFromGraphQLCore(operand, column, columnName), column);
716
+ expressions[columnName] = operation === "increment" ? sql`${column} + ${param}` : operation === "decrement" ? sql`${column} - ${param}` : operation === "multiply" ? sql`${column} * ${param}` : operation === "divide" ? sql`${column} / ${param}` : (
717
+ // `push`: array concatenation, which is the only dialect-specific operation
718
+ // here — and arrays are a PostgreSQL column type to begin with.
719
+ sql`${column} || ${param}`
720
+ );
721
+ }
722
+ return { columns, expressions };
723
+ };
724
+ var remapUpdateInput = (values, table, tableName) => {
725
+ const { columns, expressions } = splitFieldUpdateOperations(values, table, tableName);
726
+ const remapped = remapFromGraphQLSingleInput(columns, table);
727
+ return Object.keys(expressions).length ? { ...remapped, ...expressions } : remapped;
728
+ };
729
+
588
730
  // src/util/builders/common.ts
589
731
  var rqbCrashTypes = ["SQLiteBigInt", "SQLiteBlobJson", "SQLiteBlobBuffer"];
590
732
  var resolveTypeName = (name, typeNameMapper) => {
@@ -647,9 +789,9 @@ var extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
647
789
  }
648
790
  const sourceCol = sourceColumns[0];
649
791
  const targetCol = targetColumns[0];
650
- const parentCols = getColumns(parentTable);
792
+ const parentCols = getColumns2(parentTable);
651
793
  const localColPropName = Object.entries(parentCols).find(([, c]) => c === sourceCol)?.[0];
652
- const targetCols = getColumns(targetTable);
794
+ const targetCols = getColumns2(targetTable);
653
795
  const foreignColPropName = Object.entries(targetCols).find(([, c]) => c === targetCol)?.[0];
654
796
  if (!localColPropName || !foreignColPropName) {
655
797
  return void 0;
@@ -731,7 +873,7 @@ var collectRootMutationKeys = (selectionSet, fragments, variables, known, keys,
731
873
  }
732
874
  return true;
733
875
  };
734
- var abortedBatchError = () => new GraphQLError3(
876
+ var abortedBatchError = () => new GraphQLError4(
735
877
  "Drizzle-GraphQL Error: Mutation was not executed because an earlier mutation in the same request failed and the shared transaction was rolled back."
736
878
  );
737
879
  var openSharedTx = (db, context, txCtx, stateKey, expected) => {
@@ -789,7 +931,7 @@ var openSharedTx = (db, context, txCtx, stateKey, expected) => {
789
931
  }
790
932
  timer = setTimeout(() => {
791
933
  state.abort(
792
- new GraphQLError3(
934
+ new GraphQLError4(
793
935
  `Drizzle-GraphQL Error: Shared mutation transaction timed out after ${txCtx.timeoutMs}ms waiting for the remaining mutation fields; rolling back.`
794
936
  )
795
937
  );
@@ -871,14 +1013,14 @@ var runMutation = async (db, context, info, txCtx, body) => {
871
1013
  return runOnSharedTx(state, body);
872
1014
  };
873
1015
  var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
874
- const cols = getColumns(targetTable);
1016
+ const cols = getColumns2(targetTable);
875
1017
  const orderExprs = [
876
1018
  ...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
877
1019
  ...primaryKeyOrderExprs(targetTable, pkNames)
878
1020
  ];
879
- const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
1021
+ const orderClause = orderExprs.length ? sql2` order by ${sql2.join(orderExprs, sql2`, `)}` : sql2``;
880
1022
  const RN = "__drizzle_graphql_rn";
881
- const rowNumber = sql`row_number() over (partition by ${foreignCol}${orderClause})`.as(RN);
1023
+ const rowNumber = sql2`row_number() over (partition by ${foreignCol}${orderClause})`.as(RN);
882
1024
  const sub = db.select({ ...cols, [RN]: rowNumber }).from(targetTable).where(whereCondition).as("__paginated");
883
1025
  const lower = offset ?? 0;
884
1026
  const windowConds = [gt(sub[RN], lower)];
@@ -891,7 +1033,7 @@ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCon
891
1033
  }
892
1034
  return rows;
893
1035
  };
894
- var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, relationName, relEntry, isOne }) => {
1036
+ var createRelationResolverFactory = (db, tables, nullOrdering, filterCtx) => ({ tableName, relationName, relEntry, isOne }) => {
895
1037
  const parentTable = tables[tableName];
896
1038
  const targetTableName = relEntry.targetTableName;
897
1039
  const targetTable = tables[targetTableName];
@@ -904,7 +1046,7 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
904
1046
  }
905
1047
  const { localColPropName, foreignCol, foreignColPropName } = joinCols;
906
1048
  const targetPkNames = relEntry.targetPkNames ?? [];
907
- return async (parent, args, context) => {
1049
+ return async (parent, args, context, info) => {
908
1050
  if (parent[relationName] !== void 0) {
909
1051
  return parent[relationName];
910
1052
  }
@@ -912,21 +1054,65 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
912
1054
  if (localValue == null) {
913
1055
  return isOne ? null : [];
914
1056
  }
915
- const { where: whereArg, orderBy: orderByArg, limit, offset } = args ?? {};
1057
+ const { where: whereArg, orderBy: orderByArg, limit, offset, after } = args ?? {};
1058
+ const distinct = (args ?? {}).distinct?.length ? (args ?? {}).distinct : void 0;
1059
+ const cursorSelected = !isOne && !!info && selectsCursorField(info, targetTable);
1060
+ let cursorEntries;
1061
+ if (!isOne && (after != null || cursorSelected)) {
1062
+ if (after != null && distinct) {
1063
+ throw new GraphQLError4("'after' cannot be combined with 'distinct'.");
1064
+ }
1065
+ if (orderByHasRelationEntry(orderByArg)) {
1066
+ if (after != null) {
1067
+ throw new GraphQLError4(
1068
+ "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor."
1069
+ );
1070
+ }
1071
+ } else if (!targetPkNames.length) {
1072
+ if (after != null) {
1073
+ throw new GraphQLError4(
1074
+ `Table ${targetTableName} has no primary key, so cursor pagination cannot be used on it.`
1075
+ );
1076
+ }
1077
+ } else {
1078
+ cursorEntries = cursorOrderingEntries(orderByArg, targetPkNames);
1079
+ }
1080
+ }
1081
+ const cursorValues = after != null && cursorEntries ? decodeCursor(after, cursorEntries) : void 0;
916
1082
  const argsKey = JSON.stringify({
917
1083
  where: whereArg ?? null,
918
1084
  orderBy: orderByArg ?? null,
919
1085
  limit: limit ?? null,
920
- offset: offset ?? null
1086
+ offset: offset ?? null,
1087
+ after: after ?? null,
1088
+ distinct: distinct ?? null,
1089
+ cursor: cursorEntries ? 1 : 0
921
1090
  });
922
1091
  const loaderKey = `${tableName}::${relationName}::${argsKey}`;
923
1092
  const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
924
1093
  const executor = resolveExecutor(db, context);
925
1094
  const uniqueIds = [...new Set(parentIds)];
926
- const whereCondition = and(
1095
+ let whereCondition = and(
927
1096
  inArray(foreignCol, uniqueIds),
928
- whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0
1097
+ whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0,
1098
+ cursorValues ? buildCursorCondition(targetTable, cursorEntries, cursorValues, nullOrdering) : void 0
929
1099
  );
1100
+ if (distinct) {
1101
+ const keys = await selectDistinctKeys({
1102
+ db: executor,
1103
+ table: targetTable,
1104
+ tableName: targetTableName,
1105
+ distinct,
1106
+ pkNames: targetPkNames,
1107
+ where: whereCondition,
1108
+ orderBy: orderByArg,
1109
+ partitionBy: [foreignCol]
1110
+ });
1111
+ if (!keys.length) {
1112
+ return parentIds.map(() => isOne ? null : []);
1113
+ }
1114
+ whereCondition = and(whereCondition, primaryKeyRestriction(targetTable, targetPkNames, keys));
1115
+ }
930
1116
  let rows;
931
1117
  if (limit != null || offset != null) {
932
1118
  rows = await batchedPaginatedRelationQuery(
@@ -942,11 +1128,15 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
942
1128
  );
943
1129
  } else {
944
1130
  let q = executor.select().from(targetTable).where(whereCondition);
945
- if (orderByArg) {
946
- q = q.orderBy(...extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)));
1131
+ const orderExprs = cursorEntries ? cursorOrderExprs(targetTable, cursorEntries) : orderByArg ? extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)) : [];
1132
+ if (orderExprs.length) {
1133
+ q = q.orderBy(...orderExprs);
947
1134
  }
948
1135
  rows = await q;
949
1136
  }
1137
+ if (cursorEntries) {
1138
+ attachRowCursors(rows, cursorEntries);
1139
+ }
950
1140
  if (isOne) {
951
1141
  const byKey = new Map(rows.map((row) => [String(row[foreignColPropName]), row]));
952
1142
  remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
@@ -962,6 +1152,22 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
962
1152
  return loader.load(localValue);
963
1153
  };
964
1154
  };
1155
+ var columnDocs = (docs, column, tableName, columnName) => {
1156
+ const description = docs.describeColumn?.(column, { tableName, columnName });
1157
+ const deprecationReason = docs.deprecateColumn?.(column, { tableName, columnName });
1158
+ return {
1159
+ ...description !== void 0 ? { description } : {},
1160
+ ...deprecationReason !== void 0 ? { deprecationReason } : {}
1161
+ };
1162
+ };
1163
+ var inputFieldDocs = (docs, column, tableName, columnName, fieldType) => {
1164
+ const resolved = columnDocs(docs, column, tableName, columnName);
1165
+ if (resolved.deprecationReason !== void 0 && fieldType instanceof GraphQLNonNull3) {
1166
+ const { deprecationReason: _dropped, ...rest } = resolved;
1167
+ return rest;
1168
+ }
1169
+ return resolved;
1170
+ };
965
1171
  var listFieldComplexity = (options) => ({ args, childComplexity }) => {
966
1172
  const limit = args["limit"];
967
1173
  const rows = typeof limit === "number" && limit > 0 ? limit : options.defaultListSize;
@@ -969,18 +1175,21 @@ var listFieldComplexity = (options) => ({ args, childComplexity }) => {
969
1175
  };
970
1176
  var aggregateFieldComplexity = (options) => ({ childComplexity }) => options.aggregateCost + childComplexity;
971
1177
  var AGGREGATE_FIELD_SUFFIX = "Aggregate";
972
- var relationAggregateJoinColumns = (tree, table, selectionCtx) => {
973
- const relations = selectionCtx?.relationMap[selectionCtx.tableName];
974
- if (!relations || !selectionCtx) {
1178
+ var relationJoinColumns = (tree, table, selectionCtx) => {
1179
+ if (!selectionCtx) {
1180
+ return [];
1181
+ }
1182
+ const relations = (selectionCtx.allRelations ?? selectionCtx.relationMap)[selectionCtx.tableName] ?? selectionCtx.relationMap[selectionCtx.tableName];
1183
+ if (!relations) {
975
1184
  return [];
976
1185
  }
977
- const tableColumns = getColumns(table);
1186
+ const tableColumns = getColumns2(table);
978
1187
  const needed = [];
979
1188
  for (const fieldData of Object.values(tree)) {
980
- if (tableColumns[fieldData.name] || !fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX)) {
1189
+ if (tableColumns[fieldData.name]) {
981
1190
  continue;
982
1191
  }
983
- const relEntry = relations[fieldData.name.slice(0, -AGGREGATE_FIELD_SUFFIX.length)];
1192
+ const relEntry = fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX) ? relations[fieldData.name.slice(0, -AGGREGATE_FIELD_SUFFIX.length)] : relations[fieldData.name];
984
1193
  const targetTable = relEntry ? selectionCtx.tables[relEntry.targetTableName] : void 0;
985
1194
  if (!relEntry || !targetTable) {
986
1195
  continue;
@@ -993,7 +1202,7 @@ var relationAggregateJoinColumns = (tree, table, selectionCtx) => {
993
1202
  return needed;
994
1203
  };
995
1204
  var extractSelectedColumnsFromTree = (tree, table, selectionCtx) => {
996
- const tableColumns = getColumns(table);
1205
+ const tableColumns = getColumns2(table);
997
1206
  const treeEntries = Object.entries(tree);
998
1207
  const selectedColumns = [];
999
1208
  for (const [_fieldName, fieldData] of treeEntries) {
@@ -1002,7 +1211,7 @@ var extractSelectedColumnsFromTree = (tree, table, selectionCtx) => {
1002
1211
  }
1003
1212
  selectedColumns.push([fieldData.name, true]);
1004
1213
  }
1005
- for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
1214
+ for (const columnName of relationJoinColumns(tree, table, selectionCtx)) {
1006
1215
  selectedColumns.push([columnName, true]);
1007
1216
  }
1008
1217
  if (!selectedColumns.length) {
@@ -1013,7 +1222,7 @@ var extractSelectedColumnsFromTree = (tree, table, selectionCtx) => {
1013
1222
  return Object.fromEntries(selectedColumns);
1014
1223
  };
1015
1224
  var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
1016
- const tableColumns = getColumns(table);
1225
+ const tableColumns = getColumns2(table);
1017
1226
  const treeEntries = Object.entries(tree);
1018
1227
  const selectedColumns = [];
1019
1228
  for (const [_fieldName, fieldData] of treeEntries) {
@@ -1022,7 +1231,7 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
1022
1231
  }
1023
1232
  selectedColumns.push([fieldData.name, tableColumns[fieldData.name]]);
1024
1233
  }
1025
- for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
1234
+ for (const columnName of relationJoinColumns(tree, table, selectionCtx)) {
1026
1235
  selectedColumns.push([columnName, tableColumns[columnName]]);
1027
1236
  }
1028
1237
  if (!selectedColumns.length) {
@@ -1046,11 +1255,11 @@ var orderNulls = new GraphQLEnumType2({
1046
1255
  }
1047
1256
  }
1048
1257
  });
1049
- var innerOrder = new GraphQLInputObjectType2({
1258
+ var innerOrder = new GraphQLInputObjectType3({
1050
1259
  name: "InnerOrder",
1051
1260
  fields: {
1052
1261
  direction: {
1053
- type: new GraphQLNonNull2(
1262
+ type: new GraphQLNonNull3(
1054
1263
  new GraphQLEnumType2({
1055
1264
  name: "OrderDirection",
1056
1265
  description: "Order by direction",
@@ -1068,7 +1277,7 @@ var innerOrder = new GraphQLInputObjectType2({
1068
1277
  )
1069
1278
  },
1070
1279
  priority: {
1071
- type: new GraphQLNonNull2(GraphQLInt2),
1280
+ type: new GraphQLNonNull3(GraphQLInt3),
1072
1281
  description: "Priority of current field"
1073
1282
  },
1074
1283
  nulls: {
@@ -1094,9 +1303,9 @@ var resolveGenericFilterDescriptor = (column, columnGraphQLType) => {
1094
1303
  if (columnGraphQLType.type === GraphQLJSON) {
1095
1304
  return { name: "JSON", kind: "json" };
1096
1305
  }
1097
- if (columnGraphQLType.type instanceof GraphQLList2) {
1306
+ if (columnGraphQLType.type instanceof GraphQLList3) {
1098
1307
  let element = columnGraphQLType.type.ofType;
1099
- if (element instanceof GraphQLNonNull2) {
1308
+ if (element instanceof GraphQLNonNull3) {
1100
1309
  element = element.ofType;
1101
1310
  }
1102
1311
  return { name: `${element.name}Array`, kind: "array" };
@@ -1120,10 +1329,10 @@ var resolveGenericFilterDescriptor = (column, columnGraphQLType) => {
1120
1329
  if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
1121
1330
  return { name: "DateTime", kind: "scalar" };
1122
1331
  }
1123
- if (columnGraphQLType.type === GraphQLInt2) {
1332
+ if (columnGraphQLType.type === GraphQLInt3) {
1124
1333
  return { name: "Int", kind: "scalar" };
1125
1334
  }
1126
- if (columnGraphQLType.type === GraphQLFloat2) {
1335
+ if (columnGraphQLType.type === GraphQLFloat3) {
1127
1336
  return { name: "Float", kind: "scalar" };
1128
1337
  }
1129
1338
  return { name: "String", kind: "scalar" };
@@ -1143,21 +1352,23 @@ var jsonFilterFields = (column, colType) => {
1143
1352
  isNotNull: { type: GraphQLBoolean2 }
1144
1353
  };
1145
1354
  };
1146
- var arrayFilterFields = (colType, colArr, colDesc) => {
1355
+ var IN_ARRAY_DESCRIPTION = "Matches any one of these values (SQL `IN`)";
1356
+ var NOT_IN_ARRAY_DESCRIPTION = "Matches none of these values (SQL `NOT IN`)";
1357
+ var arrayFilterFields = (colType, colArr) => {
1147
1358
  let element = colType.ofType;
1148
- if (element instanceof GraphQLNonNull2) {
1359
+ if (element instanceof GraphQLNonNull3) {
1149
1360
  element = element.ofType;
1150
1361
  }
1151
- const elementList = new GraphQLList2(new GraphQLNonNull2(element));
1362
+ const elementList = new GraphQLList3(new GraphQLNonNull3(element));
1152
1363
  return {
1153
- eq: { type: colType, description: colDesc },
1154
- ne: { type: colType, description: colDesc },
1364
+ eq: { type: colType, description: "The whole array equals this array" },
1365
+ ne: { type: colType, description: "The whole array differs from this array" },
1155
1366
  has: { type: element, description: "Array contains this element" },
1156
1367
  hasSome: { type: elementList, description: "Array contains at least one of these elements (overlap, `&&`)" },
1157
1368
  hasEvery: { type: elementList, description: "Array contains every one of these elements (containment, `@>`)" },
1158
1369
  isEmpty: { type: GraphQLBoolean2, description: "When true, matches arrays with no elements" },
1159
- inArray: { type: colArr, description: `Array<${colDesc}>` },
1160
- notInArray: { type: colArr, description: `Array<${colDesc}>` },
1370
+ inArray: { type: colArr, description: IN_ARRAY_DESCRIPTION },
1371
+ notInArray: { type: colArr, description: NOT_IN_ARRAY_DESCRIPTION },
1161
1372
  isNull: { type: GraphQLBoolean2 },
1162
1373
  isNotNull: { type: GraphQLBoolean2 }
1163
1374
  };
@@ -1165,8 +1376,8 @@ var arrayFilterFields = (colType, colArr, colDesc) => {
1165
1376
  var FILTERS_WITHOUT_STRING_OPS = /* @__PURE__ */ new Set(["Id", "Int", "Float", "BigInt", "Decimal"]);
1166
1377
  var BUILTIN_FILTER_SCALARS = /* @__PURE__ */ new Set([
1167
1378
  GraphQLString2,
1168
- GraphQLInt2,
1169
- GraphQLFloat2,
1379
+ GraphQLInt3,
1380
+ GraphQLFloat3,
1170
1381
  GraphQLBoolean2,
1171
1382
  GraphQLBigIntString,
1172
1383
  GraphQLDecimalString,
@@ -1193,18 +1404,17 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
1193
1404
  return cached;
1194
1405
  }
1195
1406
  const colType = columnGraphQLType.type;
1196
- const colDesc = columnGraphQLType.description;
1197
- const colArr = new GraphQLList2(new GraphQLNonNull2(colType));
1407
+ const colArr = new GraphQLList3(new GraphQLNonNull3(colType));
1198
1408
  const customOverrideFilter = inputOverride !== void 0 && !BUILTIN_FILTER_SCALARS.has(inputOverride);
1199
1409
  const underlying = extractExtendedColumnType2(column);
1200
1410
  const omitStringOps = customOverrideFilter ? underlying.type !== "string" || underlying.constraint === "numeric" : FILTERS_WITHOUT_STRING_OPS.has(genericName);
1201
- const baseFields = kind === "json" ? jsonFilterFields(column, colType) : kind === "array" ? arrayFilterFields(colType, colArr, colDesc) : {
1202
- eq: { type: colType, description: colDesc },
1203
- ne: { type: colType, description: colDesc },
1204
- lt: { type: colType, description: colDesc },
1205
- lte: { type: colType, description: colDesc },
1206
- gt: { type: colType, description: colDesc },
1207
- gte: { type: colType, description: colDesc },
1411
+ const baseFields = kind === "json" ? jsonFilterFields(column, colType) : kind === "array" ? arrayFilterFields(colType, colArr) : {
1412
+ eq: { type: colType, description: "Equal to" },
1413
+ ne: { type: colType, description: "Not equal to" },
1414
+ lt: { type: colType, description: "Less than" },
1415
+ lte: { type: colType, description: "Less than or equal to" },
1416
+ gt: { type: colType, description: "Greater than" },
1417
+ gte: { type: colType, description: "Greater than or equal to" },
1208
1418
  ...omitStringOps ? {} : {
1209
1419
  like: { type: GraphQLString2 },
1210
1420
  notLike: { type: GraphQLString2 },
@@ -1235,21 +1445,21 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
1235
1445
  description: "Case-insensitive `contains`."
1236
1446
  }
1237
1447
  },
1238
- inArray: { type: colArr, description: `Array<${colDesc}>` },
1239
- notInArray: { type: colArr, description: `Array<${colDesc}>` },
1240
- isNull: { type: GraphQLBoolean2 },
1241
- isNotNull: { type: GraphQLBoolean2 }
1448
+ inArray: { type: colArr, description: IN_ARRAY_DESCRIPTION },
1449
+ notInArray: { type: colArr, description: NOT_IN_ARRAY_DESCRIPTION },
1450
+ isNull: { type: GraphQLBoolean2, description: "When true, matches rows where the column is NULL" },
1451
+ isNotNull: { type: GraphQLBoolean2, description: "When true, matches rows where the column is not NULL" }
1242
1452
  };
1243
- const mainType = new GraphQLInputObjectType2({
1453
+ const mainType = new GraphQLInputObjectType3({
1244
1454
  name: `${genericName}Filter`,
1245
1455
  fields: () => ({
1246
1456
  ...baseFields,
1247
1457
  OR: {
1248
- type: new GraphQLList2(new GraphQLNonNull2(mainType)),
1458
+ type: new GraphQLList3(new GraphQLNonNull3(mainType)),
1249
1459
  description: "At least one branch matches; ANDed with any sibling operators"
1250
1460
  },
1251
1461
  AND: {
1252
- type: new GraphQLList2(new GraphQLNonNull2(mainType)),
1462
+ type: new GraphQLList3(new GraphQLNonNull3(mainType)),
1253
1463
  description: "Every branch matches"
1254
1464
  },
1255
1465
  NOT: {
@@ -1268,7 +1478,7 @@ var generateTableOrderCached = (table) => {
1268
1478
  }
1269
1479
  let remapped = {};
1270
1480
  try {
1271
- const columns = getColumns(table);
1481
+ const columns = getColumns2(table);
1272
1482
  const columnEntries = Object.entries(columns);
1273
1483
  remapped = Object.fromEntries(
1274
1484
  columnEntries.map(([columnName, _columnDescription]) => [columnName, { type: innerOrder }])
@@ -1282,13 +1492,17 @@ var generateTableFilterValuesCached = (table, tableName, cacheCtx) => {
1282
1492
  if (cacheCtx.filterFieldCache.has(table)) {
1283
1493
  return cacheCtx.filterFieldCache.get(table);
1284
1494
  }
1285
- const columns = getColumns(table);
1495
+ const columns = getColumns2(table);
1286
1496
  const columnEntries = Object.entries(columns);
1287
1497
  const remapped = Object.fromEntries(
1288
- columnEntries.map(([columnName, columnDescription]) => [
1498
+ columnEntries.map(([columnName, column]) => [
1289
1499
  columnName,
1290
1500
  {
1291
- type: generateColumnFilterValues(columnDescription, tableName, columnName, cacheCtx)
1501
+ type: generateColumnFilterValues(column, tableName, columnName, cacheCtx),
1502
+ // A filter field is the same column, so it carries the same documentation. Deprecation
1503
+ // is not propagated: filtering on a deprecated column is how a caller finds the rows
1504
+ // that still use it.
1505
+ ...cacheCtx.docs.describeColumn ? { description: cacheCtx.docs.describeColumn(column, { tableName, columnName }) } : {}
1292
1506
  }
1293
1507
  ])
1294
1508
  );
@@ -1299,12 +1513,15 @@ var generateTableSelectTypeFieldsCached = (table, tableName, cacheCtx) => {
1299
1513
  if (cacheCtx.selectFieldCache.has(table)) {
1300
1514
  return cacheCtx.selectFieldCache.get(table);
1301
1515
  }
1302
- const columns = getColumns(table);
1516
+ const columns = getColumns2(table);
1303
1517
  const columnEntries = Object.entries(columns);
1304
1518
  const remapped = Object.fromEntries(
1305
- columnEntries.map(([columnName, columnDescription]) => [
1519
+ columnEntries.map(([columnName, column]) => [
1306
1520
  columnName,
1307
- drizzleColumnToGraphQLType(columnDescription, columnName, tableName)
1521
+ {
1522
+ ...drizzleColumnToGraphQLType(column, columnName, tableName),
1523
+ ...columnDocs(cacheCtx.docs, column, tableName, columnName)
1524
+ }
1308
1525
  ])
1309
1526
  );
1310
1527
  if (!remapped[CURSOR_FIELD_NAME]) {
@@ -1351,7 +1568,7 @@ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx,
1351
1568
  if (cacheCtx.orderTypeCache.has(table)) {
1352
1569
  return cacheCtx.orderTypeCache.get(table);
1353
1570
  }
1354
- const order = new GraphQLInputObjectType2({
1571
+ const order = new GraphQLInputObjectType3({
1355
1572
  name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
1356
1573
  fields: () => {
1357
1574
  const orderColumns = generateTableOrderCached(table);
@@ -1369,7 +1586,7 @@ var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx,
1369
1586
  if (cached) {
1370
1587
  return cached;
1371
1588
  }
1372
- const listFilter = new GraphQLInputObjectType2({
1589
+ const listFilter = new GraphQLInputObjectType3({
1373
1590
  name: `${resolveTypeName(targetTableName, typeNameMapper)}ListRelationFilter`,
1374
1591
  fields: () => {
1375
1592
  const targetFilters = generateTableFilterTypeCached(
@@ -1439,16 +1656,16 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
1439
1656
  ...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
1440
1657
  };
1441
1658
  };
1442
- const filters = new GraphQLInputObjectType2({
1659
+ const filters = new GraphQLInputObjectType3({
1443
1660
  name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
1444
1661
  fields: () => ({
1445
1662
  ...buildFields(),
1446
1663
  OR: {
1447
- type: new GraphQLList2(new GraphQLNonNull2(filters)),
1664
+ type: new GraphQLList3(new GraphQLNonNull3(filters)),
1448
1665
  description: "At least one branch matches; ANDed with any sibling fields"
1449
1666
  },
1450
1667
  AND: {
1451
- type: new GraphQLList2(new GraphQLNonNull2(filters)),
1668
+ type: new GraphQLList3(new GraphQLNonNull3(filters)),
1452
1669
  description: "Every branch matches"
1453
1670
  },
1454
1671
  NOT: {
@@ -1501,6 +1718,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1501
1718
  const typeName = resolveTypeName(tableName, typeNameMapper);
1502
1719
  const shell = new GraphQLObjectType2({
1503
1720
  name: typeName,
1721
+ description: cacheCtx.docs.describeTable?.(tableName),
1504
1722
  fields: () => ({ ...tableFields, ...container.fields })
1505
1723
  });
1506
1724
  cacheCtx.objectTypeCache.set(tableName, shell);
@@ -1542,36 +1760,47 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1542
1760
  const capturedTargetContainer = targetContainer;
1543
1761
  relType = new GraphQLObjectType2({
1544
1762
  name: resolveTypeName(targetTableName, typeNameMapper),
1763
+ description: cacheCtx.docs.describeTable?.(targetTableName),
1545
1764
  fields: () => ({ ...targetTableFields, ...capturedTargetContainer.fields })
1546
1765
  });
1547
1766
  cacheCtx.objectTypeCache.set(targetTableName, relType);
1548
1767
  }
1549
1768
  const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
1769
+ const relationDescription = cacheCtx.docs.describeRelation?.(tableName, relationName);
1770
+ const relationDocs = relationDescription !== void 0 ? { description: relationDescription } : {};
1550
1771
  if (isOne) {
1551
1772
  const isRequired = relation.optional === false;
1552
1773
  rawRelationFields.push([
1553
1774
  relationName,
1554
1775
  {
1555
- type: isRequired ? new GraphQLNonNull2(relType) : relType,
1776
+ type: isRequired ? new GraphQLNonNull3(relType) : relType,
1556
1777
  args: {
1557
1778
  where: { type: relSelectData.filters }
1558
1779
  },
1559
- resolve
1780
+ resolve,
1781
+ ...relationDocs
1560
1782
  }
1561
1783
  ]);
1562
1784
  continue;
1563
1785
  }
1786
+ const targetDistinctEnum = cacheCtx.features.distinct ? generateDistinctEnum(tables[targetTableName], resolveTypeName(targetTableName, typeNameMapper)) : void 0;
1564
1787
  rawRelationFields.push([
1565
1788
  relationName,
1566
1789
  {
1567
- type: new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(relType))),
1790
+ type: new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(relType))),
1568
1791
  args: {
1569
1792
  where: { type: relSelectData.filters },
1570
1793
  orderBy: { type: relSelectData.order },
1571
- offset: { type: GraphQLInt2 },
1572
- limit: { type: GraphQLInt2 }
1794
+ offset: { type: GraphQLInt3 },
1795
+ limit: { type: GraphQLInt3 },
1796
+ after: {
1797
+ type: GraphQLString2,
1798
+ description: "Keyset pagination: only return related rows strictly after this cursor (a row's `cursor` field from a previous page of this relation, under the same orderBy)."
1799
+ },
1800
+ ...targetDistinctEnum ? { distinct: { type: new GraphQLList3(new GraphQLNonNull3(targetDistinctEnum)) } } : {}
1573
1801
  },
1574
1802
  resolve,
1803
+ ...relationDocs,
1575
1804
  ...cacheCtx.complexity ? { extensions: { complexity: listFieldComplexity(cacheCtx.complexity) } } : {}
1576
1805
  }
1577
1806
  ]);
@@ -1586,7 +1815,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1586
1815
  rawRelationFields.push([
1587
1816
  aggregateFieldName,
1588
1817
  {
1589
- type: new GraphQLNonNull2(relationAggregate.type),
1818
+ type: new GraphQLNonNull3(relationAggregate.type),
1590
1819
  args: {
1591
1820
  where: { type: relSelectData.filters }
1592
1821
  },
@@ -1619,7 +1848,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1619
1848
  relationFields: {}
1620
1849
  };
1621
1850
  };
1622
- var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory, relationAggregateFactory) => {
1851
+ var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory, relationAggregateFactory, nestedWrites) => {
1623
1852
  const { tableFields, relationFields, filters, order } = generateSelectFields(
1624
1853
  tables,
1625
1854
  tableName,
@@ -1638,36 +1867,51 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
1638
1867
  relationAggregateFactory
1639
1868
  );
1640
1869
  const table = tables[tableName];
1641
- const columns = getColumns(table);
1870
+ const columns = getColumns2(table);
1642
1871
  const columnEntries = Object.entries(columns);
1872
+ const relaxedColumns = nestedWrites?.relaxedColumns(tableName);
1643
1873
  const insertFields = Object.fromEntries(
1644
- columnEntries.map(([columnName, columnDescription]) => [
1645
- columnName,
1646
- drizzleColumnToGraphQLType(columnDescription, columnName, tableName, false, true, true)
1647
- ])
1874
+ columnEntries.map(([columnName, column]) => {
1875
+ const converted = drizzleColumnToGraphQLType(
1876
+ column,
1877
+ columnName,
1878
+ tableName,
1879
+ !!relaxedColumns?.has(columnName),
1880
+ true,
1881
+ true
1882
+ );
1883
+ return [
1884
+ columnName,
1885
+ { ...converted, ...inputFieldDocs(cacheCtx.docs, column, tableName, columnName, converted.type) }
1886
+ ];
1887
+ })
1648
1888
  );
1649
1889
  const updateFields = Object.fromEntries(
1650
- columnEntries.map(([columnName, columnDescription]) => [
1651
- columnName,
1652
- drizzleColumnToGraphQLType(columnDescription, columnName, tableName, true, false, true)
1653
- ])
1890
+ columnEntries.map(([columnName, column]) => {
1891
+ const converted = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
1892
+ const operations = cacheCtx.features.fieldUpdateOperations ? fieldUpdateInputType(column, columnName, tableName) : void 0;
1893
+ const field = operations ? { ...converted, type: operations } : converted;
1894
+ return [columnName, { ...field, ...inputFieldDocs(cacheCtx.docs, column, tableName, columnName, field.type) }];
1895
+ })
1654
1896
  );
1655
- const insertInput = new GraphQLInputObjectType2({
1656
- name: `${capitalize(insertPrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
1657
- fields: insertFields
1897
+ const typeName = resolveTypeName(tableName, typeNameMapper);
1898
+ const insertInput = new GraphQLInputObjectType3({
1899
+ name: `${capitalize(insertPrefix)}${typeName}Input`,
1900
+ fields: nestedWrites ? () => ({ ...insertFields, ...nestedWrites.createFields(tableName, typeName) }) : insertFields
1658
1901
  });
1659
- const updateInput = new GraphQLInputObjectType2({
1660
- name: `${capitalize(updatePrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
1661
- fields: updateFields
1902
+ const updateInput = new GraphQLInputObjectType3({
1903
+ name: `${capitalize(updatePrefix)}${typeName}Input`,
1904
+ fields: nestedWrites ? () => ({ ...updateFields, ...nestedWrites.updateFields(tableName, typeName) }) : updateFields
1662
1905
  });
1663
1906
  const selectSingleOutput = cacheCtx.objectTypeCache.get(tableName) ?? new GraphQLObjectType2({
1664
1907
  name: resolveTypeName(tableName, typeNameMapper),
1908
+ description: cacheCtx.docs.describeTable?.(tableName),
1665
1909
  fields: { ...tableFields, ...relationFields }
1666
1910
  });
1667
- const selectArrOutput = new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(selectSingleOutput)));
1911
+ const selectArrOutput = new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(selectSingleOutput)));
1668
1912
  const arrTableItemOutput = withReturning ? (
1669
1913
  // ? new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(singleTableItemOutput!)))
1670
- new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(selectSingleOutput)))
1914
+ new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(selectSingleOutput)))
1671
1915
  ) : void 0;
1672
1916
  const inputs = {
1673
1917
  insertInput,
@@ -1692,7 +1936,7 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
1692
1936
  };
1693
1937
  var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => {
1694
1938
  if (typeof config === "object" && config.direction === void 0) {
1695
- throw new GraphQLError3(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
1939
+ throw new GraphQLError4(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
1696
1940
  }
1697
1941
  return [column, config.direction, config.nulls ?? void 0];
1698
1942
  });
@@ -1703,16 +1947,16 @@ var orderExpressions = (expr, direction, nulls, dialectColumn) => {
1703
1947
  }
1704
1948
  const isMySql = (dialectColumn.columnType ?? "").startsWith("MySql");
1705
1949
  if (isMySql) {
1706
- const nullsKey = nulls === "first" ? desc(sql`(${expr} is null)`) : asc(sql`(${expr} is null)`);
1950
+ const nullsKey = nulls === "first" ? desc(sql2`(${expr} is null)`) : asc(sql2`(${expr} is null)`);
1707
1951
  return [nullsKey, directed];
1708
1952
  }
1709
- return [nulls === "first" ? sql`${directed} nulls first` : sql`${directed} nulls last`];
1953
+ return [nulls === "first" ? sql2`${directed} nulls first` : sql2`${directed} nulls last`];
1710
1954
  };
1711
1955
  var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain) => {
1712
1956
  const targetTable = ctx.tables[relEntry.targetTableName];
1713
1957
  const relation = relEntry.relation ?? relEntry;
1714
1958
  if (!targetTable || !is3(relation, One2) || !isFilterableRelation(relation)) {
1715
- throw new GraphQLError3(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
1959
+ throw new GraphQLError4(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
1716
1960
  }
1717
1961
  ctx.aliases ??= { n: 0 };
1718
1962
  const aliasedTarget = aliasedTable(targetTable, `dgql_ord_${ctx.aliases.n++}`);
@@ -1729,7 +1973,7 @@ var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain)
1729
1973
  };
1730
1974
  };
1731
1975
  var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
1732
- const columns = getColumns(table);
1976
+ const columns = getColumns2(table);
1733
1977
  const relations = ctx?.relationMap[tableKey];
1734
1978
  for (const [key, config] of Object.entries(orderArgs)) {
1735
1979
  if (config === null || config === void 0) {
@@ -1738,7 +1982,7 @@ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
1738
1982
  const column = columns[key];
1739
1983
  if (column) {
1740
1984
  out.push({
1741
- expression: chain ? sql`(select ${column} from ${sql.join(chain.fromParts, sql`, `)} where ${and(...chain.conditions)})` : column,
1985
+ expression: chain ? sql2`(select ${column} from ${sql2.join(chain.fromParts, sql2`, `)} where ${and(...chain.conditions)})` : column,
1742
1986
  column,
1743
1987
  direction: config.direction,
1744
1988
  nulls: config.nulls ?? void 0,
@@ -1748,7 +1992,7 @@ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
1748
1992
  }
1749
1993
  const relEntry = relations?.[key];
1750
1994
  if (!relEntry || !ctx) {
1751
- throw new GraphQLError3(`ORDER BY ${key}: Unknown column or relation`);
1995
+ throw new GraphQLError4(`ORDER BY ${key}: Unknown column or relation`);
1752
1996
  }
1753
1997
  const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
1754
1998
  collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
@@ -1771,21 +2015,21 @@ var safeLikeOps = {
1771
2015
  };
1772
2016
  var safeLikeCondition = (column, pattern, insensitive) => {
1773
2017
  if (!insensitive) {
1774
- return sql`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
2018
+ return sql2`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
1775
2019
  }
1776
2020
  const isPg = (column.columnType ?? "").startsWith("Pg");
1777
- return isPg ? sql`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : sql`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
2021
+ return isPg ? sql2`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : sql2`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
1778
2022
  };
1779
2023
  var isJsonColumn2 = (column) => (column.columnType ?? "").includes("Json");
1780
2024
  var jsonContains = (column, columnName, value) => {
1781
2025
  const serialized = JSON.stringify(value);
1782
2026
  switch (columnDialect(column)) {
1783
2027
  case "pg":
1784
- return column.columnType === "PgJson" ? sql`${column}::jsonb @> ${serialized}::jsonb` : sql`${column} @> ${serialized}::jsonb`;
2028
+ return column.columnType === "PgJson" ? sql2`${column}::jsonb @> ${serialized}::jsonb` : sql2`${column} @> ${serialized}::jsonb`;
1785
2029
  case "mysql":
1786
- return sql`json_contains(${column}, ${serialized})`;
2030
+ return sql2`json_contains(${column}, ${serialized})`;
1787
2031
  default:
1788
- throw new GraphQLError3(`WHERE ${columnName}: Operator 'contains' is not supported for this dialect!`);
2032
+ throw new GraphQLError4(`WHERE ${columnName}: Operator 'contains' is not supported for this dialect!`);
1789
2033
  }
1790
2034
  };
1791
2035
  var extractFiltersColumn = (column, columnName, operators) => {
@@ -1816,7 +2060,7 @@ var extractFiltersColumn = (column, columnName, operators) => {
1816
2060
  variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
1817
2061
  } else if (operatorName in arrayValueOps) {
1818
2062
  if (!operatorValue.length) {
1819
- throw new GraphQLError3(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
2063
+ throw new GraphQLError4(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
1820
2064
  }
1821
2065
  const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
1822
2066
  variants.push(arrayValueOps[operatorName](column, arrayValue));
@@ -1824,15 +2068,15 @@ var extractFiltersColumn = (column, columnName, operators) => {
1824
2068
  variants.push(arrayContains(column, [operatorValue]));
1825
2069
  } else if (operatorName in arrayMembershipOps) {
1826
2070
  if (!operatorValue.length) {
1827
- throw new GraphQLError3(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
2071
+ throw new GraphQLError4(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
1828
2072
  }
1829
2073
  variants.push(arrayMembershipOps[operatorName](column, operatorValue));
1830
2074
  } else if (operatorName === "isEmpty") {
1831
- variants.push(sql`cardinality(${column}) = 0`);
2075
+ variants.push(sql2`cardinality(${column}) = 0`);
1832
2076
  } else if (operatorName in nullableOps) {
1833
2077
  variants.push(nullableOps[operatorName](column));
1834
2078
  } else {
1835
- throw new GraphQLError3(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
2079
+ throw new GraphQLError4(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
1836
2080
  }
1837
2081
  }
1838
2082
  if (AND?.length) {
@@ -1868,23 +2112,23 @@ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relation
1868
2112
  const sourceColumns = relation.sourceColumns;
1869
2113
  const targetColumns = relation.targetColumns;
1870
2114
  if (!sourceColumns?.length || sourceColumns.length !== targetColumns?.length) {
1871
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2115
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1872
2116
  }
1873
- const parentColumns = Object.values(getColumns(parentTable));
1874
- const targetColumnsByName = Object.values(getColumns(aliasedTarget));
2117
+ const parentColumns = Object.values(getColumns2(parentTable));
2118
+ const targetColumnsByName = Object.values(getColumns2(aliasedTarget));
1875
2119
  const conditions = [];
1876
2120
  for (let i = 0; i < sourceColumns.length; i++) {
1877
2121
  const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
1878
2122
  const foreignColumn = targetColumnsByName.find((c) => c.name === targetColumns[i].name);
1879
2123
  if (!localColumn || !foreignColumn) {
1880
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2124
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1881
2125
  }
1882
2126
  conditions.push(eq(localColumn, foreignColumn));
1883
2127
  }
1884
2128
  return conditions.length > 1 ? and(...conditions) : conditions[0];
1885
2129
  };
1886
2130
  var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
1887
- const throughColumns = getColumns(aliasedThrough);
2131
+ const throughColumns = getColumns2(aliasedThrough);
1888
2132
  const key = junctionRef?._?.key;
1889
2133
  const byKey = key ? throughColumns[key] : void 0;
1890
2134
  if (byKey) {
@@ -1893,7 +2137,7 @@ var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
1893
2137
  const columnName = junctionRef?._?.column?.name;
1894
2138
  const byName = columnName ? Object.values(throughColumns).find((c) => c.name === columnName) : void 0;
1895
2139
  if (!byName) {
1896
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2140
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1897
2141
  }
1898
2142
  return byName;
1899
2143
  };
@@ -1902,15 +2146,15 @@ var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliased
1902
2146
  const targetColumns = relation.targetColumns;
1903
2147
  const through = relation.through;
1904
2148
  if (!sourceColumns?.length || !targetColumns?.length || through?.source.length !== sourceColumns.length || through.target.length !== targetColumns.length) {
1905
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2149
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1906
2150
  }
1907
- const parentColumns = Object.values(getColumns(parentTable));
1908
- const targetTableColumns = Object.values(getColumns(aliasedTarget));
2151
+ const parentColumns = Object.values(getColumns2(parentTable));
2152
+ const targetTableColumns = Object.values(getColumns2(aliasedTarget));
1909
2153
  const correlationConditions = [];
1910
2154
  for (let i = 0; i < sourceColumns.length; i++) {
1911
2155
  const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
1912
2156
  if (!localColumn) {
1913
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2157
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1914
2158
  }
1915
2159
  correlationConditions.push(eq(localColumn, resolveJunctionColumn(aliasedThrough, through.source[i], relationName)));
1916
2160
  }
@@ -1918,7 +2162,7 @@ var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliased
1918
2162
  for (let i = 0; i < targetColumns.length; i++) {
1919
2163
  const foreignColumn = targetTableColumns.find((c) => c.name === targetColumns[i].name);
1920
2164
  if (!foreignColumn) {
1921
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2165
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1922
2166
  }
1923
2167
  junctionJoinConditions.push(
1924
2168
  eq(resolveJunctionColumn(aliasedThrough, through.target[i], relationName), foreignColumn)
@@ -1934,7 +2178,7 @@ var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mo
1934
2178
  const targetTable = ctx.tables[targetTableName];
1935
2179
  const relation = relEntry.relation ?? relEntry;
1936
2180
  if (!targetTable) {
1937
- throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
2181
+ throw new GraphQLError4(`WHERE ${relationName}: Relation cannot be used as a filter`);
1938
2182
  }
1939
2183
  ctx.aliases ??= { n: 0 };
1940
2184
  const aliases = ctx.aliases;
@@ -1951,7 +2195,7 @@ var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mo
1951
2195
  aliasedTarget,
1952
2196
  relationName
1953
2197
  );
1954
- fromClause = sql`${getTableAsAliasSQL(aliasedTarget)} inner join ${getTableAsAliasSQL(aliasedThrough)} on ${junctionJoin}`;
2198
+ fromClause = sql2`${getTableAsAliasSQL(aliasedTarget)} inner join ${getTableAsAliasSQL(aliasedThrough)} on ${junctionJoin}`;
1955
2199
  joinCondition = correlation;
1956
2200
  } else {
1957
2201
  fromClause = getTableAsAliasSQL(aliasedTarget);
@@ -1963,10 +2207,10 @@ var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mo
1963
2207
  if (!inner) {
1964
2208
  return void 0;
1965
2209
  }
1966
- return sql`not exists (select 1 from ${fromClause} where ${and(joinCondition, relationWhere, not(inner))})`;
2210
+ return sql2`not exists (select 1 from ${fromClause} where ${and(joinCondition, relationWhere, not(inner))})`;
1967
2211
  }
1968
2212
  const condition = and(joinCondition, relationWhere, inner);
1969
- return mode === "none" ? sql`not exists (select 1 from ${fromClause} where ${condition})` : sql`exists (select 1 from ${fromClause} where ${condition})`;
2213
+ return mode === "none" ? sql2`not exists (select 1 from ${fromClause} where ${condition})` : sql2`exists (select 1 from ${fromClause} where ${condition})`;
1970
2214
  };
1971
2215
  var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
1972
2216
  const relation = relEntry.relation ?? relEntry;
@@ -1980,7 +2224,7 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
1980
2224
  continue;
1981
2225
  }
1982
2226
  if (!relationMatchModes.includes(mode)) {
1983
- throw new GraphQLError3(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
2227
+ throw new GraphQLError4(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
1984
2228
  }
1985
2229
  const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
1986
2230
  if (extracted) {
@@ -1992,7 +2236,7 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
1992
2236
  var extractFilters = (table, tableName, filters, relationCtx) => {
1993
2237
  const { OR, AND, NOT, ...fieldFilters } = filters;
1994
2238
  const entries = Object.entries(fieldFilters);
1995
- const columns = getColumns(table);
2239
+ const columns = getColumns2(table);
1996
2240
  const relations = relationCtx?.relationMap[relationCtx.tableKey];
1997
2241
  const variants = [];
1998
2242
  for (const [fieldName, operators] of entries) {
@@ -2001,7 +2245,7 @@ var extractFilters = (table, tableName, filters, relationCtx) => {
2001
2245
  }
2002
2246
  const column = columns[fieldName];
2003
2247
  if (!column && !(relations?.[fieldName] && relationCtx)) {
2004
- throw new GraphQLError3(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
2248
+ throw new GraphQLError4(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
2005
2249
  }
2006
2250
  const extracted = column ? extractFiltersColumn(column, fieldName, operators) : extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx);
2007
2251
  if (extracted) {
@@ -2053,15 +2297,27 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2053
2297
  if (!field) {
2054
2298
  continue;
2055
2299
  }
2300
+ const selectionCount = Object.values(baseField).reduce(
2301
+ (n, f) => n + (f.name === relName ? 1 : 0),
2302
+ 0
2303
+ );
2304
+ if (selectionCount > 1) {
2305
+ continue;
2306
+ }
2056
2307
  const relField = field?.fieldsByTypeName;
2057
2308
  const relFieldSelection = relField?.[relTypeName];
2058
2309
  if (!relFieldSelection) {
2059
2310
  continue;
2060
2311
  }
2312
+ const eagerArgs = field.args;
2313
+ if (!is3(relEntry.relation ?? relEntry, One2) && (eagerArgs?.after != null || !!eagerArgs?.distinct?.length || isCursorFieldSelected(relFieldSelection, tables[targetTableName]))) {
2314
+ continue;
2315
+ }
2061
2316
  const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName], {
2062
2317
  tableName: targetTableName,
2063
2318
  relationMap,
2064
- tables
2319
+ tables,
2320
+ allRelations: filterCtx?.relationMap
2065
2321
  });
2066
2322
  const thisRecord = {};
2067
2323
  thisRecord.columns = columns;
@@ -2109,7 +2365,7 @@ var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
2109
2365
  return out;
2110
2366
  };
2111
2367
  var getPrimaryKeyPropNames = (table, compositePkColumnNames) => {
2112
- const cols = getColumns(table);
2368
+ const cols = getColumns2(table);
2113
2369
  const entries = Object.entries(cols);
2114
2370
  const inlinePks = entries.filter(([, c]) => c.primary).map(([k]) => k);
2115
2371
  if (inlinePks.length) {
@@ -2125,7 +2381,7 @@ var getPrimaryKeyPropNames = (table, compositePkColumnNames) => {
2125
2381
  return [];
2126
2382
  };
2127
2383
  var withPrimaryKeyColumns = (columns, table, pkNames) => {
2128
- const allCols = getColumns(table);
2384
+ const allCols = getColumns2(table);
2129
2385
  for (const pk of pkNames) {
2130
2386
  if (!(pk in columns) && allCols[pk]) {
2131
2387
  columns[pk] = allCols[pk];
@@ -2138,7 +2394,7 @@ var getPrimaryKeyPropNamesFromConfig = (table, getTableConfig4) => {
2138
2394
  return getPrimaryKeyPropNames(table, compositePkColumnNames);
2139
2395
  };
2140
2396
  var primaryKeyOrderExprs = (table, pkNames) => {
2141
- const cols = getColumns(table);
2397
+ const cols = getColumns2(table);
2142
2398
  return pkNames.map((n) => cols[n]).filter(Boolean).map((col) => asc(col));
2143
2399
  };
2144
2400
  var CURSOR_FIELD_NAME = "cursor";
@@ -2155,7 +2411,7 @@ var cursorOrderingEntries = (orderBy, pkNames) => {
2155
2411
  return entries;
2156
2412
  };
2157
2413
  var cursorOrderExprs = (table, entries) => {
2158
- const cols = getColumns(table);
2414
+ const cols = getColumns2(table);
2159
2415
  return entries.flatMap(
2160
2416
  ([column, direction, nulls]) => orderExpressions(cols[column], direction, nulls ?? void 0, cols[column])
2161
2417
  );
@@ -2192,10 +2448,10 @@ var decodeCursor = (after, entries) => {
2192
2448
  try {
2193
2449
  payload = JSON.parse(Buffer.from(after, "base64url").toString("utf8"));
2194
2450
  } catch (_e) {
2195
- throw new GraphQLError3("Invalid cursor: unable to decode it. Pass a cursor returned by a previous page.");
2451
+ throw new GraphQLError4("Invalid cursor: unable to decode it. Pass a cursor returned by a previous page.");
2196
2452
  }
2197
2453
  if (!payload || typeof payload !== "object" || !Array.isArray(payload.o) || !Array.isArray(payload.v) || payload.o.length !== payload.v.length) {
2198
- throw new GraphQLError3("Invalid cursor: malformed payload. Pass a cursor returned by a previous page.");
2454
+ throw new GraphQLError4("Invalid cursor: malformed payload. Pass a cursor returned by a previous page.");
2199
2455
  }
2200
2456
  const matchesOrdering = payload.o.length === entries.length && payload.o.every(
2201
2457
  (entry, i) => Array.isArray(entry) && entry[0] === entries[i][0] && entry[1] === entries[i][1] && // The nulls override changes where NULLs sort, so it is part of the ordering identity.
@@ -2203,20 +2459,20 @@ var decodeCursor = (after, entries) => {
2203
2459
  (entry[2] ?? null) === (entries[i][2] ?? null)
2204
2460
  );
2205
2461
  if (!matchesOrdering) {
2206
- throw new GraphQLError3(
2462
+ throw new GraphQLError4(
2207
2463
  "Invalid cursor: it was issued for a different ordering. Pass the same orderBy the cursor's page used."
2208
2464
  );
2209
2465
  }
2210
2466
  return payload.v.map(decodeCursorValue);
2211
2467
  };
2212
2468
  var buildCursorCondition = (table, entries, values, nullOrdering) => {
2213
- const cols = getColumns(table);
2469
+ const cols = getColumns2(table);
2214
2470
  const disjuncts = [];
2215
2471
  const equalities = [];
2216
2472
  entries.forEach(([column, direction, nulls], i) => {
2217
2473
  const col = cols[column];
2218
2474
  if (!col) {
2219
- throw new GraphQLError3(`Invalid cursor: unknown column '${column}'.`);
2475
+ throw new GraphQLError4(`Invalid cursor: unknown column '${column}'.`);
2220
2476
  }
2221
2477
  const value = values[i];
2222
2478
  const nullsSortLast = nulls != null ? nulls === "last" : direction === "asc" === (nullOrdering === "nulls-largest");
@@ -2233,7 +2489,7 @@ var buildCursorCondition = (table, entries, values, nullOrdering) => {
2233
2489
  equalities.push(value === null || value === void 0 ? isNull(col) : eq(col, value));
2234
2490
  });
2235
2491
  if (!disjuncts.length) {
2236
- return sql`1 = 0`;
2492
+ return sql2`1 = 0`;
2237
2493
  }
2238
2494
  return disjuncts.length > 1 ? or(...disjuncts) : disjuncts[0];
2239
2495
  };
@@ -2241,11 +2497,33 @@ var isCursorFieldSelected = (tree, table) => {
2241
2497
  if (!tree) {
2242
2498
  return false;
2243
2499
  }
2244
- if (getColumns(table)[CURSOR_FIELD_NAME]) {
2500
+ if (getColumns2(table)[CURSOR_FIELD_NAME]) {
2245
2501
  return false;
2246
2502
  }
2247
2503
  return Object.values(tree).some((field) => field.name === CURSOR_FIELD_NAME);
2248
2504
  };
2505
+ var selectsCursorField = (info, table) => {
2506
+ if (getColumns2(table)[CURSOR_FIELD_NAME]) {
2507
+ return false;
2508
+ }
2509
+ const visited = /* @__PURE__ */ new Set();
2510
+ const walk = (selections) => selections.some((selection) => {
2511
+ if (selection.kind === "Field") {
2512
+ return selection.name.value === CURSOR_FIELD_NAME;
2513
+ }
2514
+ if (selection.kind === "InlineFragment") {
2515
+ return walk(selection.selectionSet.selections);
2516
+ }
2517
+ const name = selection.name?.value;
2518
+ if (!name || visited.has(name)) {
2519
+ return false;
2520
+ }
2521
+ visited.add(name);
2522
+ const fragment = info.fragments?.[name];
2523
+ return fragment ? walk(fragment.selectionSet.selections) : false;
2524
+ });
2525
+ return (info.fieldNodes ?? []).some((node) => !!node.selectionSet && walk(node.selectionSet.selections));
2526
+ };
2249
2527
  var attachRowCursors = (rows, entries) => {
2250
2528
  for (const row of rows) {
2251
2529
  row[ROW_CURSOR_PROP] = encodeCursor(entries, row);
@@ -2253,7 +2531,7 @@ var attachRowCursors = (rows, entries) => {
2253
2531
  };
2254
2532
  var rowCursorResolver = (source) => source?.[ROW_CURSOR_PROP] ?? null;
2255
2533
  var getUniqueColumnSets = (table, getTableConfig4) => {
2256
- const cols = getColumns(table);
2534
+ const cols = getColumns2(table);
2257
2535
  const propNameByColumnName = new Map(Object.entries(cols).map(([propName, col]) => [col.name, propName]));
2258
2536
  const toPropNames = (columnNames) => {
2259
2537
  const propNames = [];
@@ -2298,7 +2576,7 @@ var generateColumnEnum = (table, enumName, description, predicate = () => true)
2298
2576
  if (cached) {
2299
2577
  return cached;
2300
2578
  }
2301
- const columnNames = Object.entries(getColumns(table)).filter(([columnName, column]) => predicate(column, columnName)).map(([columnName]) => columnName);
2579
+ const columnNames = Object.entries(getColumns2(table)).filter(([columnName, column]) => predicate(column, columnName)).map(([columnName]) => columnName);
2302
2580
  if (!columnNames.length) {
2303
2581
  return void 0;
2304
2582
  }
@@ -2340,7 +2618,7 @@ var generateOnConflictInput = (params) => {
2340
2618
  description: "Whether a conflicting row is overwritten or left alone. Defaults to UPDATE."
2341
2619
  },
2342
2620
  update: {
2343
- type: new GraphQLList2(new GraphQLNonNull2(updateEnum)),
2621
+ type: new GraphQLList3(new GraphQLNonNull3(updateEnum)),
2344
2622
  description: "Columns to overwrite on conflict. Defaults to every column the request supplied, minus the conflict target. Columns the request did not supply cannot be listed here \u2014 there would be no value to write."
2345
2623
  }
2346
2624
  };
@@ -2356,7 +2634,7 @@ var generateOnConflictInput = (params) => {
2356
2634
  return void 0;
2357
2635
  }
2358
2636
  fields["target"] = {
2359
- type: new GraphQLList2(new GraphQLNonNull2(targetEnum)),
2637
+ type: new GraphQLList3(new GraphQLNonNull3(targetEnum)),
2360
2638
  description: "The unique column set a conflict is detected on. Must match one of the table\u2019s unique constraints exactly. Defaults to the primary key."
2361
2639
  };
2362
2640
  fields["where"] = {
@@ -2364,7 +2642,7 @@ var generateOnConflictInput = (params) => {
2364
2642
  description: "Only overwrite conflicting rows that match this filter. Others are left alone."
2365
2643
  };
2366
2644
  }
2367
- return new GraphQLInputObjectType2({
2645
+ return new GraphQLInputObjectType3({
2368
2646
  name: `${typeName}OnConflict`,
2369
2647
  description: `Conflict handling for an upsert of ${typeName}`,
2370
2648
  fields
@@ -2372,18 +2650,18 @@ var generateOnConflictInput = (params) => {
2372
2650
  };
2373
2651
  var resolveConflictPlan = (params) => {
2374
2652
  const { table, values, onConflict, pkNames, uniqueSets, excludedRef, withTarget, buildWhere } = params;
2375
- const columns = getColumns(table);
2653
+ const columns = getColumns2(table);
2376
2654
  let target;
2377
2655
  if (withTarget) {
2378
2656
  const targetNames2 = onConflict?.target?.length ? onConflict.target : [...pkNames];
2379
2657
  if (!targetNames2.length) {
2380
- throw new GraphQLError3(
2658
+ throw new GraphQLError4(
2381
2659
  "Unable to upsert: no conflict target was given and this table has no primary key. Pass onConflict.target."
2382
2660
  );
2383
2661
  }
2384
2662
  const requested = [...targetNames2].sort().join(",");
2385
2663
  if (!uniqueSets.some((set2) => [...set2].sort().join(",") === requested)) {
2386
- throw new GraphQLError3(
2664
+ throw new GraphQLError4(
2387
2665
  `Unable to upsert: [${targetNames2.join(", ")}] is not a unique constraint on this table. Valid conflict targets: ${uniqueSets.map((set2) => `[${set2.join(", ")}]`).join(", ")}.`
2388
2666
  );
2389
2667
  }
@@ -2398,7 +2676,7 @@ var resolveConflictPlan = (params) => {
2398
2676
  if (onConflict?.update?.length) {
2399
2677
  const unsupplied = onConflict.update.filter((name) => !supplied.has(name));
2400
2678
  if (unsupplied.length) {
2401
- throw new GraphQLError3(
2679
+ throw new GraphQLError4(
2402
2680
  `Unable to upsert: onConflict.update lists ${unsupplied.join(", ")}, which the values do not supply.`
2403
2681
  );
2404
2682
  }
@@ -2413,18 +2691,19 @@ var resolveConflictPlan = (params) => {
2413
2691
  const setWhere = onConflict?.where && buildWhere ? buildWhere(onConflict.where) : void 0;
2414
2692
  return { action: "UPDATE", target, set, setWhere };
2415
2693
  };
2416
- var excludedColumnRef = (columnName) => sql`excluded.${sql.identifier(columnName)}`;
2417
- var mysqlValuesColumnRef = (columnName) => sql`values(${sql.identifier(columnName)})`;
2694
+ var excludedColumnRef = (columnName) => sql2`excluded.${sql2.identifier(columnName)}`;
2695
+ var mysqlValuesColumnRef = (columnName) => sql2`values(${sql2.identifier(columnName)})`;
2418
2696
  var selectDistinctKeys = async (params) => {
2419
- const { db, table, tableName, distinct, pkNames, where, orderBy, limit, offset } = params;
2420
- const cols = getColumns(table);
2697
+ const { db, table, tableName, distinct, pkNames, where, orderBy, limit, offset, partitionBy } = params;
2698
+ const cols = getColumns2(table);
2421
2699
  if (!pkNames.length) {
2422
- throw new GraphQLError3(`Table ${tableName} has no primary key, so 'distinct' cannot be applied to it.`);
2700
+ throw new GraphQLError4(`Table ${tableName} has no primary key, so 'distinct' cannot be applied to it.`);
2423
2701
  }
2424
- const partitionCols = distinct.map((name) => cols[name]).filter(Boolean);
2425
- if (!partitionCols.length) {
2426
- throw new GraphQLError3(`No known columns were given to 'distinct' on ${tableName}.`);
2702
+ const requestedCols = distinct.map((name) => cols[name]).filter(Boolean);
2703
+ if (!requestedCols.length) {
2704
+ throw new GraphQLError4(`No known columns were given to 'distinct' on ${tableName}.`);
2427
2705
  }
2706
+ const partitionCols = [...partitionBy ?? [], ...requestedCols];
2428
2707
  const orderEntries = orderBy ? orderByEntries(orderBy) : [];
2429
2708
  const windowOrder = [
2430
2709
  ...orderEntries.flatMap(
@@ -2432,9 +2711,9 @@ var selectDistinctKeys = async (params) => {
2432
2711
  ),
2433
2712
  ...primaryKeyOrderExprs(table, pkNames)
2434
2713
  ];
2435
- const rowNumber = sql`row_number() over (partition by ${sql.join(partitionCols, sql`, `)} order by ${sql.join(
2714
+ const rowNumber = sql2`row_number() over (partition by ${sql2.join(partitionCols, sql2`, `)} order by ${sql2.join(
2436
2715
  windowOrder,
2437
- sql`, `
2716
+ sql2`, `
2438
2717
  )})`.as(DISTINCT_RN);
2439
2718
  const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
2440
2719
  const outerOrder = [
@@ -2453,7 +2732,7 @@ var selectDistinctKeys = async (params) => {
2453
2732
  return await query;
2454
2733
  };
2455
2734
  var primaryKeyRestriction = (table, pkNames, keys) => {
2456
- const cols = getColumns(table);
2735
+ const cols = getColumns2(table);
2457
2736
  if (pkNames.length === 1) {
2458
2737
  const name = pkNames[0];
2459
2738
  return inArray(
@@ -2476,17 +2755,17 @@ var prepareMutationRelationColumns = (params) => {
2476
2755
  return { columns, hasRelations, withParams };
2477
2756
  };
2478
2757
  var toGraphQLError = (e) => {
2479
- if (e instanceof GraphQLError3) {
2758
+ if (e instanceof GraphQLError4) {
2480
2759
  return e;
2481
2760
  }
2482
- return e instanceof Error ? new GraphQLError3(e.message, { originalError: e }) : e;
2761
+ return e instanceof Error ? new GraphQLError4(e.message, { originalError: e }) : e;
2483
2762
  };
2484
2763
  var defaultErrorMapper = (error) => {
2485
- if (error instanceof GraphQLError3 && !error.originalError) {
2764
+ if (error instanceof GraphQLError4 && !error.originalError) {
2486
2765
  return error;
2487
2766
  }
2488
- return new GraphQLError3("Internal server error", {
2489
- originalError: error instanceof GraphQLError3 ? error.originalError ?? error : error instanceof Error ? error : null,
2767
+ return new GraphQLError4("Internal server error", {
2768
+ originalError: error instanceof GraphQLError4 ? error.originalError ?? error : error instanceof Error ? error : null,
2490
2769
  extensions: { code: "INTERNAL_SERVER_ERROR" }
2491
2770
  });
2492
2771
  };
@@ -2543,6 +2822,9 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2543
2822
  const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
2544
2823
  const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
2545
2824
  const deleteSingleFieldName = `${deleteFieldName}${writeSingleSuffix}`;
2825
+ const pluralNoun = mapped ? capitalize(mapped.plural) : capitalize(tableName);
2826
+ const updateCountFieldName = `${prefixes.update}${pluralNoun}Count`;
2827
+ const deleteCountFieldName = `${prefixes.delete}${pluralNoun}Count`;
2546
2828
  return {
2547
2829
  typeName,
2548
2830
  listFieldName,
@@ -2556,13 +2838,15 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
2556
2838
  updateFieldName,
2557
2839
  updateManyFieldName,
2558
2840
  updateSingleFieldName,
2841
+ updateCountFieldName,
2559
2842
  deleteFieldName,
2560
- deleteSingleFieldName
2843
+ deleteSingleFieldName,
2844
+ deleteCountFieldName
2561
2845
  };
2562
2846
  };
2563
2847
  var generateUpdateManyInput = (params) => {
2564
2848
  const { typeName, updatePrefix, updateInput, tableFilters } = params;
2565
- return new GraphQLInputObjectType2({
2849
+ return new GraphQLInputObjectType3({
2566
2850
  name: `${capitalize(updatePrefix)}${typeName}ManyInput`,
2567
2851
  description: `One entry of a batch update of ${typeName}: the rows \`where\` matches get this entry's \`set\` applied.`,
2568
2852
  fields: {
@@ -2571,7 +2855,7 @@ var generateUpdateManyInput = (params) => {
2571
2855
  description: "Rows this entry updates. An omitted filter updates every row."
2572
2856
  },
2573
2857
  set: {
2574
- type: new GraphQLNonNull2(updateInput)
2858
+ type: new GraphQLNonNull3(updateInput)
2575
2859
  }
2576
2860
  }
2577
2861
  });
@@ -2579,29 +2863,101 @@ var generateUpdateManyInput = (params) => {
2579
2863
  var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
2580
2864
  const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2581
2865
  if (!filters) {
2582
- throw new GraphQLError3(`${fieldName} requires a 'where' argument with at least one filter!`);
2866
+ throw new GraphQLError4(`${fieldName} requires a 'where' argument with at least one filter!`);
2583
2867
  }
2584
2868
  return filters;
2585
2869
  };
2870
+ var rowsAffected = (result, fieldName) => {
2871
+ const asNumber = (value) => typeof value === "number" ? value : typeof value === "bigint" ? Number(value) : void 0;
2872
+ if (result && typeof result === "object") {
2873
+ for (const key of ["rowCount", "affectedRows", "rowsAffected", "changes", "count"]) {
2874
+ const value = asNumber(result[key]);
2875
+ if (value !== void 0) {
2876
+ return value;
2877
+ }
2878
+ }
2879
+ const header = Array.isArray(result) ? result[0] : void 0;
2880
+ const affected = header && typeof header === "object" ? asNumber(header.affectedRows) : void 0;
2881
+ if (affected !== void 0) {
2882
+ return affected;
2883
+ }
2884
+ }
2885
+ throw new GraphQLError4(`${fieldName}: the driver did not report how many rows the write affected.`);
2886
+ };
2586
2887
  var assertSingleMatch = async (executor, table, filters, fieldName) => {
2587
- const matched = await executor.select({ found: sql`1` }).from(table).where(filters).limit(2);
2888
+ const matched = await executor.select({ found: sql2`1` }).from(table).where(filters).limit(2);
2588
2889
  if (matched.length > 1) {
2589
- throw new GraphQLError3(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
2590
- }
2890
+ throw new GraphQLError4(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
2891
+ }
2892
+ };
2893
+ var generateWriteCount = ({
2894
+ db,
2895
+ tableName,
2896
+ table,
2897
+ kind,
2898
+ setArgs,
2899
+ filterArgs,
2900
+ fieldName,
2901
+ requireWhere,
2902
+ filterCtx,
2903
+ txCtx,
2904
+ nested
2905
+ }) => {
2906
+ const queryArgs = {
2907
+ ...setArgs ? { set: { type: new GraphQLNonNull3(setArgs) } } : {},
2908
+ where: {
2909
+ type: requireWhere ? new GraphQLNonNull3(filterArgs) : filterArgs
2910
+ }
2911
+ };
2912
+ return {
2913
+ name: fieldName,
2914
+ resolver: async (_source, args, context, info) => {
2915
+ try {
2916
+ return await runMutation(db, context, info, txCtx, async (executor) => {
2917
+ const { where, set } = args;
2918
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
2919
+ const filters = requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2920
+ let query;
2921
+ if (kind === "delete") {
2922
+ query = executor.delete(table);
2923
+ } else {
2924
+ const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
2925
+ if (entry && nested.hasOps(entry.ops)) {
2926
+ throw new GraphQLError4(
2927
+ `${fieldName} does not support nested writes \u2014 use ${fieldName.slice(0, -"Count".length)} instead.`
2928
+ );
2929
+ }
2930
+ const values = remapUpdateInput(entry ? entry.columns : set, table, tableName);
2931
+ if (!Object.keys(values).length) {
2932
+ throw new GraphQLError4("Unable to update with no values specified!");
2933
+ }
2934
+ query = executor.update(table).set(values);
2935
+ }
2936
+ if (filters) {
2937
+ query = query.where(filters);
2938
+ }
2939
+ return rowsAffected(await query, fieldName);
2940
+ });
2941
+ } catch (e) {
2942
+ throw toGraphQLError(e);
2943
+ }
2944
+ },
2945
+ args: queryArgs
2946
+ };
2591
2947
  };
2592
2948
  var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
2593
- offset: { type: GraphQLInt2 },
2594
- limit: { type: GraphQLInt2 },
2949
+ offset: { type: GraphQLInt3 },
2950
+ limit: { type: GraphQLInt3 },
2595
2951
  orderBy: { type: orderArgs },
2596
2952
  where: { type: filterArgs },
2597
2953
  after: {
2598
2954
  type: GraphQLString2,
2599
2955
  description: "Keyset pagination: only return rows strictly after this cursor (a row's `cursor` field from a previous page, under the same orderBy)."
2600
2956
  },
2601
- ...distinctEnum ? { distinct: { type: new GraphQLList2(new GraphQLNonNull2(distinctEnum)) } } : {}
2957
+ ...distinctEnum ? { distinct: { type: new GraphQLList3(new GraphQLNonNull3(distinctEnum)) } } : {}
2602
2958
  });
2603
2959
  var selectSingleArgs = (orderArgs, filterArgs) => ({
2604
- offset: { type: GraphQLInt2 },
2960
+ offset: { type: GraphQLInt3 },
2605
2961
  orderBy: { type: orderArgs },
2606
2962
  where: { type: filterArgs }
2607
2963
  });
@@ -2628,17 +2984,17 @@ var runRelationalSelect = async (opts) => {
2628
2984
  let cursorEntries;
2629
2985
  if (!single && (after != null || cursorSelected)) {
2630
2986
  if (after != null && distinct) {
2631
- throw new GraphQLError3("'after' cannot be combined with 'distinct'.");
2987
+ throw new GraphQLError4("'after' cannot be combined with 'distinct'.");
2632
2988
  }
2633
2989
  if (orderByHasRelationEntry(orderBy)) {
2634
2990
  if (after != null) {
2635
- throw new GraphQLError3(
2991
+ throw new GraphQLError4(
2636
2992
  "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor."
2637
2993
  );
2638
2994
  }
2639
2995
  } else if (!pkNames?.length) {
2640
2996
  if (after != null) {
2641
- throw new GraphQLError3(`Table ${tableName} has no primary key, so cursor pagination cannot be used on it.`);
2997
+ throw new GraphQLError4(`Table ${tableName} has no primary key, so cursor pagination cannot be used on it.`);
2642
2998
  }
2643
2999
  } else {
2644
3000
  cursorEntries = cursorOrderingEntries(orderBy, pkNames);
@@ -2667,7 +3023,8 @@ var runRelationalSelect = async (opts) => {
2667
3023
  columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table, {
2668
3024
  tableName,
2669
3025
  relationMap,
2670
- tables
3026
+ tables,
3027
+ allRelations: filterCtx?.relationMap
2671
3028
  }),
2672
3029
  offset: distinctKeys ? void 0 : offset,
2673
3030
  // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
@@ -2734,20 +3091,20 @@ var eagerLoadMutationRelations = async (db, tableName, rows, pkNames, withParams
2734
3091
  whereRaw = (aliased) => inArray(aliased[pkName], ids);
2735
3092
  } else {
2736
3093
  whereRaw = (aliased) => {
2737
- const lhs = sql.join(
2738
- pkNames.map((n) => sql`${aliased[n]}`),
2739
- sql`, `
3094
+ const lhs = sql2.join(
3095
+ pkNames.map((n) => sql2`${aliased[n]}`),
3096
+ sql2`, `
2740
3097
  );
2741
- const tuples = sql.join(
3098
+ const tuples = sql2.join(
2742
3099
  keyableRows.map(
2743
- (row) => sql`(${sql.join(
2744
- pkNames.map((n) => sql`${row[n]}`),
2745
- sql`, `
3100
+ (row) => sql2`(${sql2.join(
3101
+ pkNames.map((n) => sql2`${row[n]}`),
3102
+ sql2`, `
2746
3103
  )})`
2747
3104
  ),
2748
- sql`, `
3105
+ sql2`, `
2749
3106
  );
2750
- return sql`(${lhs}) in (${tuples})`;
3107
+ return sql2`(${lhs}) in (${tuples})`;
2751
3108
  };
2752
3109
  }
2753
3110
  let enriched;
@@ -2782,9 +3139,10 @@ import { is as is4, One as One3 } from "drizzle-orm";
2782
3139
  import { getTableConfig, MySqlTable } from "drizzle-orm/mysql-core";
2783
3140
  import {
2784
3141
  GraphQLBoolean as GraphQLBoolean3,
2785
- GraphQLError as GraphQLError5,
2786
- GraphQLList as GraphQLList4,
2787
- GraphQLNonNull as GraphQLNonNull4,
3142
+ GraphQLError as GraphQLError6,
3143
+ GraphQLInt as GraphQLInt5,
3144
+ GraphQLList as GraphQLList5,
3145
+ GraphQLNonNull as GraphQLNonNull5,
2788
3146
  GraphQLObjectType as GraphQLObjectType4
2789
3147
  } from "graphql";
2790
3148
  import { parseResolveInfo as parseResolveInfo2 } from "graphql-parse-resolve-info";
@@ -2797,7 +3155,7 @@ import {
2797
3155
  countDistinct,
2798
3156
  eq as eq2,
2799
3157
  extractExtendedColumnType as extractExtendedColumnType3,
2800
- getColumns as getColumns2,
3158
+ getColumns as getColumns3,
2801
3159
  gt as gt2,
2802
3160
  gte as gte2,
2803
3161
  inArray as inArray2,
@@ -2809,12 +3167,12 @@ import {
2809
3167
  sum
2810
3168
  } from "drizzle-orm";
2811
3169
  import {
2812
- GraphQLError as GraphQLError4,
2813
- GraphQLFloat as GraphQLFloat3,
2814
- GraphQLInputObjectType as GraphQLInputObjectType3,
2815
- GraphQLInt as GraphQLInt3,
2816
- GraphQLList as GraphQLList3,
2817
- GraphQLNonNull as GraphQLNonNull3,
3170
+ GraphQLError as GraphQLError5,
3171
+ GraphQLFloat as GraphQLFloat4,
3172
+ GraphQLInputObjectType as GraphQLInputObjectType4,
3173
+ GraphQLInt as GraphQLInt4,
3174
+ GraphQLList as GraphQLList4,
3175
+ GraphQLNonNull as GraphQLNonNull4,
2818
3176
  GraphQLObjectType as GraphQLObjectType3
2819
3177
  } from "graphql";
2820
3178
  import { parseResolveInfo } from "graphql-parse-resolve-info";
@@ -2833,11 +3191,11 @@ var classifyAggregateColumns = (table, tableName) => {
2833
3191
  const numeric = {};
2834
3192
  const orderable = {};
2835
3193
  const all = {};
2836
- for (const [columnName, column] of Object.entries(getColumns2(table))) {
3194
+ for (const [columnName, column] of Object.entries(getColumns3(table))) {
2837
3195
  all[columnName] = column;
2838
3196
  const converted = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, false);
2839
3197
  const gqlType = converted.type;
2840
- if (gqlType instanceof GraphQLList3 || gqlType instanceof GraphQLObjectType3) {
3198
+ if (gqlType instanceof GraphQLList4 || gqlType instanceof GraphQLObjectType3) {
2841
3199
  continue;
2842
3200
  }
2843
3201
  const { type: dataType, constraint } = extractExtendedColumnType3(column);
@@ -2861,14 +3219,14 @@ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
2861
3219
  }
2862
3220
  const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
2863
3221
  const fields = {
2864
- count: { type: new GraphQLNonNull3(GraphQLInt3) }
3222
+ count: { type: new GraphQLNonNull4(GraphQLInt4) }
2865
3223
  };
2866
3224
  if (Object.keys(numeric).length) {
2867
3225
  for (const op of ["avg", "sum"]) {
2868
3226
  fields[op] = {
2869
3227
  type: new GraphQLObjectType3({
2870
3228
  name: `${typeName}${capitalize(op)}Aggregate`,
2871
- fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat3 }]))
3229
+ fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat4 }]))
2872
3230
  })
2873
3231
  };
2874
3232
  }
@@ -2879,9 +3237,9 @@ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
2879
3237
  type: new GraphQLObjectType3({
2880
3238
  name: `${typeName}${capitalize(op)}Aggregate`,
2881
3239
  fields: Object.fromEntries(
2882
- Object.entries(orderable).map(([columnName, { converted }]) => [
3240
+ Object.entries(orderable).map(([columnName, { column, converted }]) => [
2883
3241
  columnName,
2884
- { type: converted.type, description: converted.description }
3242
+ { type: converted.type, ...columnDocs(cacheCtx?.docs ?? {}, column, tableName, columnName) }
2885
3243
  ])
2886
3244
  )
2887
3245
  })
@@ -2898,7 +3256,7 @@ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
2898
3256
  type: new GraphQLObjectType3({
2899
3257
  name: `${typeName}${capitalize(op)}Aggregate`,
2900
3258
  fields: Object.fromEntries(
2901
- columnNames.map((columnName) => [columnName, { type: new GraphQLNonNull3(GraphQLInt3) }])
3259
+ columnNames.map((columnName) => [columnName, { type: new GraphQLNonNull4(GraphQLInt4) }])
2902
3260
  )
2903
3261
  })
2904
3262
  };
@@ -2926,9 +3284,9 @@ var aggregateTarget = (table, tableName, typeName) => {
2926
3284
  return {
2927
3285
  tableName,
2928
3286
  typeName,
2929
- columns: getColumns2(table),
3287
+ columns: getColumns3(table),
2930
3288
  dateTimeColumns: new Set(
2931
- Object.entries(orderable).filter(([, { converted }]) => converted.description === "DateTime").map(([columnName]) => columnName)
3289
+ Object.entries(orderable).filter(([, { converted }]) => converted.typeLabel === "DateTime").map(([columnName]) => columnName)
2932
3290
  )
2933
3291
  };
2934
3292
  };
@@ -3077,7 +3435,7 @@ var HAVING_OPS = { eq: eq2, ne: ne2, gt: gt2, gte: gte2, lt: lt2, lte: lte2 };
3077
3435
  var groupableColumns = (table, tableName) => {
3078
3436
  const { orderable } = classifyAggregateColumns(table, tableName);
3079
3437
  const groupable = { ...orderable };
3080
- for (const [columnName, column] of Object.entries(getColumns2(table))) {
3438
+ for (const [columnName, column] of Object.entries(getColumns3(table))) {
3081
3439
  if (groupable[columnName]) {
3082
3440
  continue;
3083
3441
  }
@@ -3101,10 +3459,10 @@ var generateGroupByEnum = (table, tableName, typeName) => {
3101
3459
  (_column, columnName) => Boolean(groupable[columnName])
3102
3460
  );
3103
3461
  };
3104
- var aggregateNumberFilter = new GraphQLInputObjectType3({
3462
+ var aggregateNumberFilter = new GraphQLInputObjectType4({
3105
3463
  name: "AggregateNumberFilter",
3106
3464
  description: "Compares an aggregated value. Several operators in one filter are ANDed together.",
3107
- fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: GraphQLFloat3 }]))
3465
+ fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: GraphQLFloat4 }]))
3108
3466
  });
3109
3467
  var generateHavingInput = (table, tableName, typeName) => {
3110
3468
  const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
@@ -3125,13 +3483,13 @@ var generateHavingInput = (table, tableName, typeName) => {
3125
3483
  continue;
3126
3484
  }
3127
3485
  fields[op] = {
3128
- type: new GraphQLInputObjectType3({
3486
+ type: new GraphQLInputObjectType4({
3129
3487
  name: `${typeName}${capitalize(op)}Having`,
3130
3488
  fields: Object.fromEntries(columnNames.map((columnName) => [columnName, { type: aggregateNumberFilter }]))
3131
3489
  })
3132
3490
  };
3133
3491
  }
3134
- return new GraphQLInputObjectType3({
3492
+ return new GraphQLInputObjectType4({
3135
3493
  name: `${typeName}Having`,
3136
3494
  description: `Filters ${typeName} groups by their aggregated values`,
3137
3495
  fields
@@ -3146,9 +3504,9 @@ var generateGroupByType = (table, tableName, typeName, cacheCtx) => {
3146
3504
  name: `${typeName}GroupKeys`,
3147
3505
  description: `The grouped column values of one ${typeName} group. A column the query did not group by is null.`,
3148
3506
  fields: Object.fromEntries(
3149
- Object.entries(groupable).map(([columnName, { converted }]) => [
3507
+ Object.entries(groupable).map(([columnName, { column, converted }]) => [
3150
3508
  columnName,
3151
- { type: converted.type, description: converted.description }
3509
+ { type: converted.type, ...columnDocs(cacheCtx?.docs ?? {}, column, tableName, columnName) }
3152
3510
  ])
3153
3511
  )
3154
3512
  });
@@ -3161,7 +3519,7 @@ var generateGroupByType = (table, tableName, typeName, cacheCtx) => {
3161
3519
  );
3162
3520
  return new GraphQLObjectType3({
3163
3521
  name: `${typeName}GroupBy`,
3164
- fields: { group: { type: new GraphQLNonNull3(keysType) }, ...aggregateFields }
3522
+ fields: { group: { type: new GraphQLNonNull4(keysType) }, ...aggregateFields }
3165
3523
  });
3166
3524
  };
3167
3525
  var havingComparisons = (expression, filter) => Object.entries(filter).filter(([op, value]) => value != null && op in HAVING_OPS).map(([op, value]) => HAVING_OPS[op](expression, value));
@@ -3194,11 +3552,11 @@ var buildHavingCondition = (having, columns) => {
3194
3552
  var generateGroupBy = (db, tableName, table, typeName, fieldName, filterArgs, groupByEnum, havingInput, filterCtx) => {
3195
3553
  const target = aggregateTarget(table, tableName, typeName);
3196
3554
  const groupable = groupableColumns(table, tableName);
3197
- const columns = getColumns2(table);
3555
+ const columns = getColumns3(table);
3198
3556
  const rootTypeName = `${typeName}GroupBy`;
3199
3557
  const queryArgs = {
3200
3558
  groupBy: {
3201
- type: new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(groupByEnum))),
3559
+ type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(groupByEnum))),
3202
3560
  description: "Columns to group by. One result row per distinct combination of their values."
3203
3561
  },
3204
3562
  where: { type: filterArgs, description: "Filters the rows before they are grouped." },
@@ -3210,12 +3568,12 @@ var generateGroupBy = (db, tableName, table, typeName, fieldName, filterArgs, gr
3210
3568
  try {
3211
3569
  const requestedKeys = [...new Set(args.groupBy ?? [])];
3212
3570
  if (!requestedKeys.length) {
3213
- throw new GraphQLError4("At least one column to group by is required!");
3571
+ throw new GraphQLError5("At least one column to group by is required!");
3214
3572
  }
3215
3573
  const keyColumns = requestedKeys.map((columnName) => {
3216
3574
  const groupableColumn = groupable[columnName];
3217
3575
  if (!groupableColumn) {
3218
- throw new GraphQLError4(`Cannot group ${typeName} by ${columnName}!`);
3576
+ throw new GraphQLError5(`Cannot group ${typeName} by ${columnName}!`);
3219
3577
  }
3220
3578
  return [columnName, groupableColumn.column];
3221
3579
  });
@@ -3337,7 +3695,7 @@ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filte
3337
3695
  var generateInsertArray = (db, _tableName, table, baseType, fieldName, txCtx) => {
3338
3696
  const queryArgs = {
3339
3697
  values: {
3340
- type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
3698
+ type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
3341
3699
  }
3342
3700
  };
3343
3701
  return {
@@ -3347,7 +3705,7 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName, txCtx) =>
3347
3705
  return await runMutation(db, context, info, txCtx, async (executor) => {
3348
3706
  const input = remapFromGraphQLArrayInput(args.values, table);
3349
3707
  if (!input.length) {
3350
- throw new GraphQLError5("No values were provided!");
3708
+ throw new GraphQLError6("No values were provided!");
3351
3709
  }
3352
3710
  await executor.insert(table).values(input);
3353
3711
  return { isSuccess: true };
@@ -3362,7 +3720,7 @@ var generateInsertArray = (db, _tableName, table, baseType, fieldName, txCtx) =>
3362
3720
  var generateInsertSingle = (db, _tableName, table, baseType, fieldName, txCtx) => {
3363
3721
  const queryArgs = {
3364
3722
  values: {
3365
- type: new GraphQLNonNull4(baseType)
3723
+ type: new GraphQLNonNull5(baseType)
3366
3724
  }
3367
3725
  };
3368
3726
  return {
@@ -3384,7 +3742,7 @@ var generateInsertSingle = (db, _tableName, table, baseType, fieldName, txCtx) =
3384
3742
  var generateUpsert = (db, table, baseType, onConflictType, fieldName, single, txCtx) => {
3385
3743
  const queryArgs = {
3386
3744
  values: {
3387
- type: single ? new GraphQLNonNull4(baseType) : new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
3745
+ type: single ? new GraphQLNonNull5(baseType) : new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
3388
3746
  },
3389
3747
  onConflict: {
3390
3748
  type: onConflictType,
@@ -3399,7 +3757,7 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single, tx
3399
3757
  return await runMutation(db, context, info, txCtx, async (executor) => {
3400
3758
  const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3401
3759
  if (!input.length) {
3402
- throw new GraphQLError5("No values were provided!");
3760
+ throw new GraphQLError6("No values were provided!");
3403
3761
  }
3404
3762
  const plan = resolveConflictPlan({
3405
3763
  table,
@@ -3427,10 +3785,10 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single, tx
3427
3785
  var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3428
3786
  const queryArgs = {
3429
3787
  set: {
3430
- type: new GraphQLNonNull4(setArgs)
3788
+ type: new GraphQLNonNull5(setArgs)
3431
3789
  },
3432
3790
  where: {
3433
- type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
3791
+ type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
3434
3792
  }
3435
3793
  };
3436
3794
  return {
@@ -3439,9 +3797,9 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3439
3797
  try {
3440
3798
  return await runMutation(db, context, info, txCtx, async (executor) => {
3441
3799
  const { where, set } = args;
3442
- const input = remapFromGraphQLSingleInput(set, table);
3800
+ const input = remapUpdateInput(set, table, tableName);
3443
3801
  if (!Object.keys(input).length) {
3444
- throw new GraphQLError5("Unable to update with no values specified!");
3802
+ throw new GraphQLError6("Unable to update with no values specified!");
3445
3803
  }
3446
3804
  const relationCtx = relationFilterCtx(filterCtx, tableName);
3447
3805
  const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
@@ -3465,7 +3823,7 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, sing
3465
3823
  var generateUpdateMany = (db, tableName, table, updateManyInput, fieldName, filterCtx, txCtx) => {
3466
3824
  const queryArgs = {
3467
3825
  updates: {
3468
- type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(updateManyInput)))
3826
+ type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(updateManyInput)))
3469
3827
  }
3470
3828
  };
3471
3829
  return {
@@ -3475,12 +3833,12 @@ var generateUpdateMany = (db, tableName, table, updateManyInput, fieldName, filt
3475
3833
  return await runMutation(db, context, info, txCtx, async (executor) => {
3476
3834
  const { updates } = args;
3477
3835
  if (!updates.length) {
3478
- throw new GraphQLError5("No updates were provided!");
3836
+ throw new GraphQLError6("No updates were provided!");
3479
3837
  }
3480
3838
  const entries = updates.map(({ where, set }) => {
3481
- const input = remapFromGraphQLSingleInput(set, table);
3839
+ const input = remapUpdateInput(set, table, tableName);
3482
3840
  if (!Object.keys(input).length) {
3483
- throw new GraphQLError5("Unable to update with no values specified!");
3841
+ throw new GraphQLError6("Unable to update with no values specified!");
3484
3842
  }
3485
3843
  return {
3486
3844
  set: input,
@@ -3508,7 +3866,7 @@ var generateUpdateMany = (db, tableName, table, updateManyInput, fieldName, filt
3508
3866
  var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx, txCtx) => {
3509
3867
  const queryArgs = {
3510
3868
  where: {
3511
- type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
3869
+ type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
3512
3870
  }
3513
3871
  };
3514
3872
  return {
@@ -3548,12 +3906,23 @@ var generateSchemaData = (db, schema, relations, options) => {
3548
3906
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
3549
3907
  );
3550
3908
  }
3909
+ if (features.nestedWrites) {
3910
+ throw new Error(
3911
+ "Drizzle-GraphQL Error: features.nestedWrites is not supported on MySQL \u2014 a nested write needs the parent row it just inserted returned to it, and MySQL has no RETURNING clause."
3912
+ );
3913
+ }
3551
3914
  registerScalarOverrides(tables, options);
3915
+ registerEnumConfig(options);
3552
3916
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
3553
3917
  attachTargetPrimaryKeys(namedRelations, tables, mysqlPrimaryKeyPropNames);
3554
3918
  const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
3555
3919
  const filterCtx = { tables, relationMap: namedRelations };
3556
- const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
3920
+ const resolverFactory = createRelationResolverFactory(
3921
+ db,
3922
+ tables,
3923
+ "nulls-smallest",
3924
+ filterCtx
3925
+ );
3557
3926
  const cacheCtx = {
3558
3927
  genericFilterCache: /* @__PURE__ */ new Map(),
3559
3928
  objectTypeCache: /* @__PURE__ */ new Map(),
@@ -3566,7 +3935,9 @@ var generateSchemaData = (db, schema, relations, options) => {
3566
3935
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
3567
3936
  listRelationFilterCache: /* @__PURE__ */ new Map(),
3568
3937
  aggregateTypeCache: /* @__PURE__ */ new Map(),
3569
- complexity
3938
+ complexity,
3939
+ docs: options.docs ?? {},
3940
+ features
3570
3941
  };
3571
3942
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3572
3943
  const queries = {};
@@ -3594,7 +3965,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3594
3965
  name: "MutationReturn",
3595
3966
  fields: {
3596
3967
  isSuccess: {
3597
- type: new GraphQLNonNull4(GraphQLBoolean3)
3968
+ type: new GraphQLNonNull5(GraphQLBoolean3)
3598
3969
  }
3599
3970
  }
3600
3971
  });
@@ -3619,8 +3990,10 @@ var generateSchemaData = (db, schema, relations, options) => {
3619
3990
  updateFieldName,
3620
3991
  updateManyFieldName,
3621
3992
  updateSingleFieldName,
3993
+ updateCountFieldName,
3622
3994
  deleteFieldName,
3623
- deleteSingleFieldName
3995
+ deleteSingleFieldName,
3996
+ deleteCountFieldName
3624
3997
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
3625
3998
  const selectArrGenerated = generateSelectArray(
3626
3999
  db,
@@ -3744,6 +4117,29 @@ var generateSchemaData = (db, schema, relations, options) => {
3744
4117
  filterCtx,
3745
4118
  mutationTxCtx
3746
4119
  ) : void 0;
4120
+ const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
4121
+ db,
4122
+ tableName,
4123
+ table: schema[tableName],
4124
+ kind: "update",
4125
+ setArgs: updateInput,
4126
+ filterArgs: tableFilters,
4127
+ fieldName: updateCountFieldName,
4128
+ requireWhere: features.requireWhere,
4129
+ filterCtx,
4130
+ txCtx: mutationTxCtx
4131
+ }) : void 0;
4132
+ const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
4133
+ db,
4134
+ tableName,
4135
+ table: schema[tableName],
4136
+ kind: "delete",
4137
+ filterArgs: tableFilters,
4138
+ fieldName: deleteCountFieldName,
4139
+ requireWhere: features.requireWhere,
4140
+ filterCtx,
4141
+ txCtx: mutationTxCtx
4142
+ }) : void 0;
3747
4143
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3748
4144
  const aggregateGenerated = features.aggregates ? generateAggregate(
3749
4145
  db,
@@ -3781,7 +4177,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3781
4177
  };
3782
4178
  if (aggregateGenerated && aggregateType) {
3783
4179
  queries[aggregateGenerated.name] = {
3784
- type: new GraphQLNonNull4(aggregateType),
4180
+ type: new GraphQLNonNull5(aggregateType),
3785
4181
  args: aggregateGenerated.args,
3786
4182
  resolve: aggregateGenerated.resolver,
3787
4183
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -3789,7 +4185,7 @@ var generateSchemaData = (db, schema, relations, options) => {
3789
4185
  }
3790
4186
  if (groupByGenerated && groupByType) {
3791
4187
  queries[groupByGenerated.name] = {
3792
- type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(groupByType))),
4188
+ type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(groupByType))),
3793
4189
  args: groupByGenerated.args,
3794
4190
  resolve: groupByGenerated.resolver,
3795
4191
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -3814,6 +4210,22 @@ var generateSchemaData = (db, schema, relations, options) => {
3814
4210
  };
3815
4211
  }
3816
4212
  }
4213
+ if (updateCountGenerated) {
4214
+ mutations[updateCountGenerated.name] = {
4215
+ type: new GraphQLNonNull5(GraphQLInt5),
4216
+ args: updateCountGenerated.args,
4217
+ resolve: updateCountGenerated.resolver,
4218
+ description: "How many rows the update touched. The rows themselves are not read back, which is the point of this mutation."
4219
+ };
4220
+ }
4221
+ if (deleteCountGenerated) {
4222
+ mutations[deleteCountGenerated.name] = {
4223
+ type: new GraphQLNonNull5(GraphQLInt5),
4224
+ args: deleteCountGenerated.args,
4225
+ resolve: deleteCountGenerated.resolver,
4226
+ description: "How many rows the delete removed. The rows themselves are not read back, which is the point of this mutation."
4227
+ };
4228
+ }
3817
4229
  const activeInputs = [
3818
4230
  // The insert input types the upsert mutations too, so either feature keeps it.
3819
4231
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -3858,14 +4270,400 @@ var generateSchemaData = (db, schema, relations, options) => {
3858
4270
  };
3859
4271
 
3860
4272
  // src/util/builders/pg.ts
3861
- import { and as and3, getColumns as getColumns3, is as is5, One as One4 } from "drizzle-orm";
4273
+ import { and as and4, getColumns as getColumns5, is as is6, One as One5 } from "drizzle-orm";
3862
4274
  import { getTableConfig as getTableConfig2, PgTable } from "drizzle-orm/pg-core";
3863
4275
  import {
3864
- GraphQLError as GraphQLError6,
3865
- GraphQLList as GraphQLList5,
3866
- GraphQLNonNull as GraphQLNonNull5
4276
+ GraphQLError as GraphQLError8,
4277
+ GraphQLInt as GraphQLInt6,
4278
+ GraphQLList as GraphQLList7,
4279
+ GraphQLNonNull as GraphQLNonNull7
3867
4280
  } from "graphql";
3868
4281
  import { parseResolveInfo as parseResolveInfo3 } from "graphql-parse-resolve-info";
4282
+
4283
+ // src/util/builders/nested-writes.ts
4284
+ import { and as and3, eq as eq3, getColumns as getColumns4, is as is5, One as One4 } from "drizzle-orm";
4285
+ import {
4286
+ GraphQLBoolean as GraphQLBoolean4,
4287
+ GraphQLError as GraphQLError7,
4288
+ GraphQLInputObjectType as GraphQLInputObjectType5,
4289
+ GraphQLList as GraphQLList6,
4290
+ GraphQLNonNull as GraphQLNonNull6
4291
+ } from "graphql";
4292
+ var isOptionalOnInsert = (column) => !column.notNull || !!column.hasDefault || !!column.defaultFn;
4293
+ var buildNestedWritePlans = (tables, relationMap, resolveUniqueSets, resolvePrimaryKeys, extractJoinColumns) => {
4294
+ const uniqueCache = /* @__PURE__ */ new Map();
4295
+ const singleColumnUniques = (tableName, table) => {
4296
+ let cached = uniqueCache.get(tableName);
4297
+ if (!cached) {
4298
+ cached = new Set(
4299
+ resolveUniqueSets(table).filter((set) => set.length === 1).map((set) => set[0])
4300
+ );
4301
+ uniqueCache.set(tableName, cached);
4302
+ }
4303
+ return cached;
4304
+ };
4305
+ const pkCache = /* @__PURE__ */ new Map();
4306
+ const singleColumnPk = (tableName, table) => {
4307
+ if (!pkCache.has(tableName)) {
4308
+ const pk = resolvePrimaryKeys(table);
4309
+ pkCache.set(tableName, pk.length === 1 ? pk[0] : void 0);
4310
+ }
4311
+ return pkCache.get(tableName);
4312
+ };
4313
+ const plans = {};
4314
+ for (const [tableName, relations] of Object.entries(relationMap)) {
4315
+ const table = tables[tableName];
4316
+ if (!table) {
4317
+ continue;
4318
+ }
4319
+ const tablePlans = {};
4320
+ for (const [relationName, relEntry] of Object.entries(relations)) {
4321
+ const relation = relEntry.relation;
4322
+ if (relation.through) {
4323
+ continue;
4324
+ }
4325
+ const targetTableName = relEntry.targetTableName;
4326
+ const targetTable = tables[targetTableName];
4327
+ if (!targetTable) {
4328
+ continue;
4329
+ }
4330
+ const joinColumns = extractJoinColumns(relEntry, table, targetTable);
4331
+ if (!joinColumns) {
4332
+ continue;
4333
+ }
4334
+ const { localColPropName, foreignCol, foreignColPropName } = joinColumns;
4335
+ const localCol = getColumns4(table)[localColPropName];
4336
+ if (!localCol) {
4337
+ continue;
4338
+ }
4339
+ const isOne = is5(relation, One4);
4340
+ const localIsPk = singleColumnPk(tableName, table) === localColPropName;
4341
+ const foreignIsPk = singleColumnPk(targetTableName, targetTable) === foreignColPropName;
4342
+ const localIsUnique = singleColumnUniques(tableName, table).has(localColPropName);
4343
+ const foreignIsUnique = singleColumnUniques(targetTableName, targetTable).has(foreignColPropName);
4344
+ let fkSide;
4345
+ if (!isOne) {
4346
+ fkSide = "child";
4347
+ } else if (foreignIsPk && !localIsPk) {
4348
+ fkSide = "parent";
4349
+ } else if (localIsPk) {
4350
+ fkSide = "child";
4351
+ } else if (foreignIsUnique) {
4352
+ fkSide = "parent";
4353
+ } else if (localIsUnique) {
4354
+ fkSide = "child";
4355
+ } else {
4356
+ continue;
4357
+ }
4358
+ const fkColumn = fkSide === "child" ? foreignCol : localCol;
4359
+ tablePlans[relationName] = {
4360
+ relationName,
4361
+ targetTableName,
4362
+ targetTable,
4363
+ localColPropName,
4364
+ foreignColPropName,
4365
+ foreignCol,
4366
+ localCol,
4367
+ isOne,
4368
+ fkSide,
4369
+ canDetach: !fkColumn.notNull
4370
+ };
4371
+ }
4372
+ if (Object.keys(tablePlans).length) {
4373
+ plans[tableName] = tablePlans;
4374
+ }
4375
+ }
4376
+ return plans;
4377
+ };
4378
+ var NO_COLUMNS = /* @__PURE__ */ new Set();
4379
+ var createNestedWriteTypes = (params) => {
4380
+ const { plans, cacheCtx, typeNameMapper, insertPrefix } = params;
4381
+ const wrapperCache = /* @__PURE__ */ new Map();
4382
+ const payloadCache = /* @__PURE__ */ new Map();
4383
+ const payloadType = (tableName, typeName, plan) => {
4384
+ const key = `${tableName}.${plan.relationName}`;
4385
+ const cached = payloadCache.get(key);
4386
+ if (cached) {
4387
+ return cached;
4388
+ }
4389
+ const omitted = plan.fkSide === "child" ? plan.foreignColPropName : void 0;
4390
+ const fields = Object.fromEntries(
4391
+ Object.entries(getColumns4(plan.targetTable)).filter(([columnName]) => columnName !== omitted).map(([columnName, column]) => [
4392
+ columnName,
4393
+ drizzleColumnToGraphQLType(column, columnName, plan.targetTableName, false, true, true)
4394
+ ])
4395
+ );
4396
+ const type = new GraphQLInputObjectType5({
4397
+ name: `${capitalize(insertPrefix)}${typeName}${capitalize(plan.relationName)}Input`,
4398
+ description: omitted === void 0 ? `A new ${resolveTypeName(plan.targetTableName, typeNameMapper)} row for ${typeName}.${plan.relationName}` : `A new ${resolveTypeName(plan.targetTableName, typeNameMapper)} row for ${typeName}.${plan.relationName}. \`${omitted}\` is set from the ${typeName} row this is written with.`,
4399
+ fields
4400
+ });
4401
+ payloadCache.set(key, type);
4402
+ return type;
4403
+ };
4404
+ const targetFilters = (plan) => cacheCtx.filterTypeCache.get(plan.targetTable);
4405
+ const listOf = (type) => new GraphQLList6(new GraphQLNonNull6(type));
4406
+ const wrapperType = (tableName, typeName, plan, forUpdate) => {
4407
+ const key = `${tableName}.${plan.relationName}.${forUpdate ? "update" : "create"}`;
4408
+ const cached = wrapperCache.get(key);
4409
+ if (cached) {
4410
+ return cached;
4411
+ }
4412
+ const filters = targetFilters(plan);
4413
+ const payload = payloadType(tableName, typeName, plan);
4414
+ const targetTypeName = resolveTypeName(plan.targetTableName, typeNameMapper);
4415
+ const fields = {};
4416
+ if (plan.isOne) {
4417
+ fields["create"] = { type: payload, description: `Insert a ${targetTypeName} row and attach it` };
4418
+ if (filters) {
4419
+ fields["connect"] = {
4420
+ type: filters,
4421
+ description: `Attach the existing ${targetTypeName} row this matches. Must match exactly one row.`
4422
+ };
4423
+ }
4424
+ if (forUpdate && plan.canDetach) {
4425
+ fields["disconnect"] = {
4426
+ type: GraphQLBoolean4,
4427
+ description: `Detach the currently attached ${targetTypeName} row, leaving it in place`
4428
+ };
4429
+ }
4430
+ } else {
4431
+ fields["create"] = { type: listOf(payload), description: `Insert these ${targetTypeName} rows and attach them` };
4432
+ if (filters) {
4433
+ fields["connect"] = {
4434
+ type: listOf(filters),
4435
+ description: `Attach every existing ${targetTypeName} row these match`
4436
+ };
4437
+ if (forUpdate && plan.canDetach) {
4438
+ fields["disconnect"] = {
4439
+ type: listOf(filters),
4440
+ description: `Detach every attached ${targetTypeName} row these match, leaving the rows in place`
4441
+ };
4442
+ fields["set"] = {
4443
+ type: listOf(filters),
4444
+ description: `Replace the whole set: detach everything attached, then attach every ${targetTypeName} row these match. Applied before \`disconnect\`, \`connect\` and \`create\`.`
4445
+ };
4446
+ }
4447
+ }
4448
+ }
4449
+ const type = new GraphQLInputObjectType5({
4450
+ name: `${typeName}${capitalize(plan.relationName)}Nested${forUpdate ? "Update" : "Create"}Input`,
4451
+ description: `Writes through ${typeName}.${plan.relationName}`,
4452
+ fields
4453
+ });
4454
+ wrapperCache.set(key, type);
4455
+ return type;
4456
+ };
4457
+ const relationFields = (tableName, typeName, forUpdate) => {
4458
+ const tablePlans = plans[tableName];
4459
+ if (!tablePlans) {
4460
+ return {};
4461
+ }
4462
+ return Object.fromEntries(
4463
+ Object.values(tablePlans).flatMap((plan) => {
4464
+ const wrapper = wrapperType(tableName, typeName, plan, forUpdate);
4465
+ return wrapper ? [[plan.relationName, { type: wrapper, description: `Writes through ${typeName}.${plan.relationName}` }]] : [];
4466
+ })
4467
+ );
4468
+ };
4469
+ return {
4470
+ createFields: (tableName, typeName) => relationFields(tableName, typeName, false),
4471
+ updateFields: (tableName, typeName) => relationFields(tableName, typeName, true),
4472
+ relaxedColumns: (tableName) => {
4473
+ const tablePlans = plans[tableName];
4474
+ if (!tablePlans) {
4475
+ return NO_COLUMNS;
4476
+ }
4477
+ const relaxed = /* @__PURE__ */ new Set();
4478
+ for (const plan of Object.values(tablePlans)) {
4479
+ if (plan.fkSide === "parent" && !isOptionalOnInsert(plan.localCol)) {
4480
+ relaxed.add(plan.localColPropName);
4481
+ }
4482
+ }
4483
+ return relaxed.size ? relaxed : NO_COLUMNS;
4484
+ }
4485
+ };
4486
+ };
4487
+ var mergedOps = (entries) => Object.assign({}, ...entries.map((entry) => entry.ops));
4488
+ var asArray = (value) => Array.isArray(value) ? value : value === void 0 ? [] : [value];
4489
+ var createNestedWriteRuntime = (params) => {
4490
+ const { plans, filterCtx } = params;
4491
+ const conditionOf = (plan, filter, operation) => {
4492
+ const condition = extractFilters(
4493
+ plan.targetTable,
4494
+ plan.targetTableName,
4495
+ filter,
4496
+ relationFilterCtx(filterCtx, plan.targetTableName)
4497
+ );
4498
+ if (!condition) {
4499
+ throw new GraphQLError7(
4500
+ `Drizzle-GraphQL Error: '${operation}' on '${plan.relationName}' needs a filter that selects rows \u2014 it was given one that matches everything.`
4501
+ );
4502
+ }
4503
+ return condition;
4504
+ };
4505
+ const assertSingleOperation = (plan, op) => {
4506
+ const supplied = ["create", "connect", "disconnect"].filter((key) => op[key] !== void 0 && op[key] !== null);
4507
+ if (supplied.length > 1) {
4508
+ throw new GraphQLError7(
4509
+ `Drizzle-GraphQL Error: '${plan.relationName}' takes one of ${supplied.join(", ")} at a time \u2014 it holds a single row.`
4510
+ );
4511
+ }
4512
+ };
4513
+ const detachAll = async (executor, plan, key) => executor.update(plan.targetTable).set({ [plan.foreignColPropName]: null }).where(eq3(plan.foreignCol, key));
4514
+ return {
4515
+ enabled: (tableName) => !!plans[tableName],
4516
+ split: (tableName, values) => {
4517
+ const tablePlans = plans[tableName];
4518
+ if (!tablePlans) {
4519
+ return { columns: values, ops: {} };
4520
+ }
4521
+ const columns = {};
4522
+ const ops = {};
4523
+ for (const [key, value] of Object.entries(values)) {
4524
+ if (tablePlans[key] && value !== void 0 && value !== null) {
4525
+ ops[key] = value;
4526
+ } else if (!tablePlans[key]) {
4527
+ columns[key] = value;
4528
+ }
4529
+ }
4530
+ return { columns, ops };
4531
+ },
4532
+ hasOps: (ops) => Object.keys(ops).length > 0,
4533
+ withJoinColumns: (tableName, ops, columns, table) => {
4534
+ const tablePlans = plans[tableName];
4535
+ if (!tablePlans) {
4536
+ return columns;
4537
+ }
4538
+ const allColumns = getColumns4(table);
4539
+ for (const relationName of Object.keys(ops)) {
4540
+ const plan = tablePlans[relationName];
4541
+ if (plan?.fkSide === "child" && !(plan.localColPropName in columns) && allColumns[plan.localColPropName]) {
4542
+ columns[plan.localColPropName] = allColumns[plan.localColPropName];
4543
+ }
4544
+ }
4545
+ return columns;
4546
+ },
4547
+ applyParentSide: async (executor, tableName, ops) => {
4548
+ const tablePlans = plans[tableName];
4549
+ const patch = {};
4550
+ if (!tablePlans) {
4551
+ return patch;
4552
+ }
4553
+ for (const [relationName, op] of Object.entries(ops)) {
4554
+ const plan = tablePlans[relationName];
4555
+ if (!plan || plan.fkSide !== "parent") {
4556
+ continue;
4557
+ }
4558
+ assertSingleOperation(plan, op);
4559
+ if (op["create"] !== void 0) {
4560
+ const values = remapFromGraphQLSingleInput({ ...op["create"] }, plan.targetTable);
4561
+ const inserted = await executor.insert(plan.targetTable).values(values).returning();
4562
+ const created = inserted[0];
4563
+ if (!created) {
4564
+ throw new GraphQLError7(
4565
+ `Drizzle-GraphQL Error: 'create' on '${relationName}' inserted no row, so there is nothing to attach.`
4566
+ );
4567
+ }
4568
+ patch[plan.localColPropName] = created[plan.foreignColPropName];
4569
+ } else if (op["connect"] !== void 0) {
4570
+ const rows = await executor.select().from(plan.targetTable).where(conditionOf(plan, op["connect"], "connect"));
4571
+ if (rows.length !== 1) {
4572
+ throw new GraphQLError7(
4573
+ `Drizzle-GraphQL Error: 'connect' on '${relationName}' matched ${rows.length} rows \u2014 it attaches a single row, so its filter must match exactly one.`
4574
+ );
4575
+ }
4576
+ patch[plan.localColPropName] = rows[0][plan.foreignColPropName];
4577
+ } else if (op["disconnect"] === true) {
4578
+ patch[plan.localColPropName] = null;
4579
+ }
4580
+ }
4581
+ return patch;
4582
+ },
4583
+ applyChildSide: async (executor, tableName, ops, parentRows) => {
4584
+ const tablePlans = plans[tableName];
4585
+ if (!tablePlans) {
4586
+ return;
4587
+ }
4588
+ for (const [relationName, op] of Object.entries(ops)) {
4589
+ const plan = tablePlans[relationName];
4590
+ if (!plan || plan.fkSide !== "child") {
4591
+ continue;
4592
+ }
4593
+ if (plan.isOne) {
4594
+ assertSingleOperation(plan, op);
4595
+ }
4596
+ for (const parentRow of parentRows) {
4597
+ const key = parentRow?.[plan.localColPropName];
4598
+ if (key === void 0 || key === null) {
4599
+ throw new GraphQLError7(
4600
+ `Drizzle-GraphQL Error: cannot write through '${relationName}': the ${tableName} row has no '${plan.localColPropName}' value to attach to.`
4601
+ );
4602
+ }
4603
+ if (op["set"] !== void 0) {
4604
+ await detachAll(executor, plan, key);
4605
+ for (const filter of asArray(op["set"])) {
4606
+ await executor.update(plan.targetTable).set({ [plan.foreignColPropName]: key }).where(conditionOf(plan, filter, "set"));
4607
+ }
4608
+ }
4609
+ if (op["disconnect"] !== void 0) {
4610
+ if (plan.isOne) {
4611
+ if (op["disconnect"] === true) {
4612
+ await detachAll(executor, plan, key);
4613
+ }
4614
+ } else {
4615
+ for (const filter of asArray(op["disconnect"])) {
4616
+ await executor.update(plan.targetTable).set({ [plan.foreignColPropName]: null }).where(and3(eq3(plan.foreignCol, key), conditionOf(plan, filter, "disconnect")));
4617
+ }
4618
+ }
4619
+ }
4620
+ const attaches = op["connect"] !== void 0 || op["create"] !== void 0;
4621
+ if (plan.isOne && attaches && plan.canDetach && op["set"] === void 0) {
4622
+ await detachAll(executor, plan, key);
4623
+ }
4624
+ if (op["connect"] !== void 0) {
4625
+ for (const filter of asArray(op["connect"])) {
4626
+ await executor.update(plan.targetTable).set({ [plan.foreignColPropName]: key }).where(conditionOf(plan, filter, "connect"));
4627
+ }
4628
+ }
4629
+ if (op["create"] !== void 0) {
4630
+ const rows = asArray(op["create"]).map((row) => ({
4631
+ ...remapFromGraphQLSingleInput({ ...row }, plan.targetTable),
4632
+ [plan.foreignColPropName]: key
4633
+ }));
4634
+ if (rows.length) {
4635
+ await executor.insert(plan.targetTable).values(rows);
4636
+ }
4637
+ }
4638
+ }
4639
+ }
4640
+ }
4641
+ };
4642
+ };
4643
+ var writeWithNestedOps = async (params) => {
4644
+ const { executor, runtime, tableName, entries, remapValues, write } = params;
4645
+ return executor.transaction(async (tx) => {
4646
+ const rows = [];
4647
+ for (const entry of entries) {
4648
+ const patch = await runtime.applyParentSide(tx, tableName, entry.ops);
4649
+ const written = await write(tx, { ...remapValues(entry.columns), ...patch });
4650
+ await runtime.applyChildSide(tx, tableName, entry.ops, written);
4651
+ rows.push(...written);
4652
+ }
4653
+ return rows;
4654
+ });
4655
+ };
4656
+ var updateWithNestedOps = async (params) => {
4657
+ const { executor, runtime, tableName, columns, ops, remapValues, write } = params;
4658
+ return executor.transaction(async (tx) => {
4659
+ const patch = await runtime.applyParentSide(tx, tableName, ops);
4660
+ const rows = await write(tx, { ...remapValues(columns), ...patch });
4661
+ await runtime.applyChildSide(tx, tableName, ops, rows);
4662
+ return rows;
4663
+ });
4664
+ };
4665
+
4666
+ // src/util/builders/pg.ts
3869
4667
  var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
3870
4668
  const queryBase = db.query[tableName];
3871
4669
  const table = tables[tableName];
@@ -3910,24 +4708,24 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
3910
4708
  let cursorEntries;
3911
4709
  if (after != null || cursorSelected) {
3912
4710
  if (after != null && distinct?.length) {
3913
- throw new GraphQLError6("'after' cannot be combined with 'distinct'.");
4711
+ throw new GraphQLError8("'after' cannot be combined with 'distinct'.");
3914
4712
  }
3915
4713
  if (orderByHasRelationEntry(orderBy)) {
3916
4714
  if (after != null) {
3917
- throw new GraphQLError6(
4715
+ throw new GraphQLError8(
3918
4716
  "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor."
3919
4717
  );
3920
4718
  }
3921
4719
  } else if (!pkNames.length) {
3922
4720
  if (after != null) {
3923
- throw new GraphQLError6(
4721
+ throw new GraphQLError8(
3924
4722
  `Table ${tableName} has no primary key, so cursor pagination cannot be used on it.`
3925
4723
  );
3926
4724
  }
3927
4725
  } else {
3928
4726
  cursorEntries = cursorOrderingEntries(orderBy, pkNames);
3929
4727
  if (cursorSelected) {
3930
- const allColumns = getColumns3(table);
4728
+ const allColumns = getColumns5(table);
3931
4729
  for (const [column] of cursorEntries) {
3932
4730
  selectedColumnsSql[column] ??= allColumns[column];
3933
4731
  }
@@ -3936,7 +4734,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
3936
4734
  }
3937
4735
  const cursorCondition = after != null && cursorEntries ? buildCursorCondition(table, cursorEntries, decodeCursor(after, cursorEntries), "nulls-largest") : void 0;
3938
4736
  const baseWhereSql = where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0;
3939
- const whereSql = cursorCondition ? and3(baseWhereSql, cursorCondition) : baseWhereSql;
4737
+ const whereSql = cursorCondition ? and4(baseWhereSql, cursorCondition) : baseWhereSql;
3940
4738
  let distinctKeys;
3941
4739
  if (distinct?.length) {
3942
4740
  distinctKeys = await selectDistinctKeys({
@@ -4047,10 +4845,10 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
4047
4845
  };
4048
4846
  };
4049
4847
  var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig2);
4050
- var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4848
+ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx, nested) => {
4051
4849
  const queryArgs = {
4052
4850
  values: {
4053
- type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
4851
+ type: new GraphQLNonNull7(new GraphQLList7(new GraphQLNonNull7(baseType)))
4054
4852
  }
4055
4853
  };
4056
4854
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -4059,10 +4857,12 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
4059
4857
  resolver: async (_source, args, context, info) => {
4060
4858
  try {
4061
4859
  return await runMutation(db, context, info, txCtx, async (executor) => {
4062
- const input = remapFromGraphQLArrayInput(args.values, table);
4063
- if (!input.length) {
4064
- throw new GraphQLError6("No values were provided!");
4860
+ if (!args.values.length) {
4861
+ throw new GraphQLError8("No values were provided!");
4065
4862
  }
4863
+ const entries = nested?.enabled(tableName) ? args.values.map((values) => nested.split(tableName, values)) : void 0;
4864
+ const nestedEntries = entries?.some((entry) => nested.hasOps(entry.ops)) ? entries : void 0;
4865
+ const input = nestedEntries ? [] : remapFromGraphQLArrayInput(entries ? entries.map((entry) => entry.columns) : args.values, table);
4066
4866
  const parsedInfo = parseResolveInfo3(info, {
4067
4867
  deep: true
4068
4868
  });
@@ -4076,11 +4876,22 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
4076
4876
  pkNames,
4077
4877
  parsedInfo
4078
4878
  });
4079
- let query = executor.insert(table).values(input).returning(columns);
4080
- if (conflictDoNothing) {
4081
- query = query.onConflictDoNothing();
4082
- }
4083
- const result = await query;
4879
+ const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
4880
+ const runInsert = async (target, values) => {
4881
+ let query = target.insert(table).values(values).returning(returning);
4882
+ if (conflictDoNothing) {
4883
+ query = query.onConflictDoNothing();
4884
+ }
4885
+ return await query;
4886
+ };
4887
+ const result = nestedEntries ? await writeWithNestedOps({
4888
+ executor,
4889
+ runtime: nested,
4890
+ tableName,
4891
+ entries: nestedEntries,
4892
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
4893
+ write: (tx, values) => runInsert(tx, [values])
4894
+ }) : await runInsert(executor, input);
4084
4895
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4085
4896
  return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4086
4897
  });
@@ -4091,10 +4902,10 @@ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType,
4091
4902
  args: queryArgs
4092
4903
  };
4093
4904
  };
4094
- var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
4905
+ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx, nested) => {
4095
4906
  const queryArgs = {
4096
4907
  values: {
4097
- type: new GraphQLNonNull5(baseType)
4908
+ type: new GraphQLNonNull7(baseType)
4098
4909
  }
4099
4910
  };
4100
4911
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -4103,7 +4914,9 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
4103
4914
  resolver: async (_source, args, context, info) => {
4104
4915
  try {
4105
4916
  return await runMutation(db, context, info, txCtx, async (executor) => {
4106
- const input = remapFromGraphQLSingleInput(args.values, table);
4917
+ const entry = nested?.enabled(tableName) ? nested.split(tableName, args.values) : void 0;
4918
+ const nestedEntry = entry && nested.hasOps(entry.ops) ? entry : void 0;
4919
+ const input = nestedEntry ? {} : remapFromGraphQLSingleInput(entry ? entry.columns : args.values, table);
4107
4920
  const parsedInfo = parseResolveInfo3(info, {
4108
4921
  deep: true
4109
4922
  });
@@ -4117,12 +4930,26 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
4117
4930
  pkNames,
4118
4931
  parsedInfo
4119
4932
  });
4120
- let query = executor.insert(table).values(input).returning(columns);
4121
- if (conflictDoNothing) {
4122
- query = query.onConflictDoNothing();
4123
- }
4124
- const result = await query;
4933
+ const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
4934
+ const runInsert = async (target, values) => {
4935
+ let query = target.insert(table).values(values).returning(returning);
4936
+ if (conflictDoNothing) {
4937
+ query = query.onConflictDoNothing();
4938
+ }
4939
+ return await query;
4940
+ };
4941
+ const result = nestedEntry ? await writeWithNestedOps({
4942
+ executor,
4943
+ runtime: nested,
4944
+ tableName,
4945
+ entries: [nestedEntry],
4946
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
4947
+ write: runInsert
4948
+ }) : await runInsert(executor, input);
4125
4949
  if (!result[0]) {
4950
+ if (!conflictDoNothing) {
4951
+ throw new GraphQLError8(`${fieldName}: the insert returned no row.`);
4952
+ }
4126
4953
  return void 0;
4127
4954
  }
4128
4955
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
@@ -4135,10 +4962,10 @@ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType
4135
4962
  args: queryArgs
4136
4963
  };
4137
4964
  };
4138
- var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
4965
+ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx, nested) => {
4139
4966
  const queryArgs = {
4140
4967
  values: {
4141
- type: single ? new GraphQLNonNull5(baseType) : new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
4968
+ type: single ? new GraphQLNonNull7(baseType) : new GraphQLNonNull7(new GraphQLList7(new GraphQLNonNull7(baseType)))
4142
4969
  },
4143
4970
  onConflict: {
4144
4971
  type: onConflictType,
@@ -4151,10 +4978,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
4151
4978
  resolver: async (_source, args, context, info) => {
4152
4979
  try {
4153
4980
  return await runMutation(db, context, info, txCtx, async (executor) => {
4154
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4155
- if (!input.length) {
4156
- throw new GraphQLError6("No values were provided!");
4981
+ const supplied = single ? [args.values] : args.values;
4982
+ if (!supplied.length) {
4983
+ throw new GraphQLError8("No values were provided!");
4157
4984
  }
4985
+ const entries = nested?.enabled(tableName) ? supplied.map((values) => nested.split(tableName, values)) : void 0;
4986
+ const nestedEntries = entries?.some((entry) => nested.hasOps(entry.ops)) ? entries : void 0;
4987
+ const input = nestedEntries ? [] : remapFromGraphQLArrayInput(entries ? entries.map((entry) => entry.columns) : supplied, table);
4158
4988
  const parsedInfo = parseResolveInfo3(info, { deep: true });
4159
4989
  const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4160
4990
  relationMap,
@@ -4166,19 +4996,30 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
4166
4996
  pkNames,
4167
4997
  parsedInfo
4168
4998
  });
4169
- const plan = resolveConflictPlan({
4170
- table,
4171
- values: input,
4172
- onConflict: args.onConflict,
4173
- pkNames,
4174
- uniqueSets,
4175
- excludedRef: excludedColumnRef,
4176
- withTarget: true,
4177
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4178
- });
4179
- let query = executor.insert(table).values(input).returning(columns);
4180
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
4181
- const result = await query;
4999
+ const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
5000
+ const runUpsert = async (target, values) => {
5001
+ const plan = resolveConflictPlan({
5002
+ table,
5003
+ values,
5004
+ onConflict: args.onConflict,
5005
+ pkNames,
5006
+ uniqueSets,
5007
+ excludedRef: excludedColumnRef,
5008
+ withTarget: true,
5009
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
5010
+ });
5011
+ let query = target.insert(table).values(values).returning(returning);
5012
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
5013
+ return await query;
5014
+ };
5015
+ const result = nestedEntries ? await writeWithNestedOps({
5016
+ executor,
5017
+ runtime: nested,
5018
+ tableName,
5019
+ entries: nestedEntries,
5020
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
5021
+ write: (tx, values) => runUpsert(tx, [values])
5022
+ }) : await runUpsert(executor, input);
4182
5023
  if (single && !result[0]) {
4183
5024
  return void 0;
4184
5025
  }
@@ -4192,13 +5033,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
4192
5033
  args: queryArgs
4193
5034
  };
4194
5035
  };
4195
- var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
5036
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx, nested) => {
4196
5037
  const queryArgs = {
4197
5038
  set: {
4198
- type: new GraphQLNonNull5(setArgs)
5039
+ type: new GraphQLNonNull7(setArgs)
4199
5040
  },
4200
5041
  where: {
4201
- type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
5042
+ type: single || requireWhere ? new GraphQLNonNull7(filterArgs) : filterArgs
4202
5043
  }
4203
5044
  };
4204
5045
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -4221,23 +5062,37 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
4221
5062
  pkNames,
4222
5063
  parsedInfo
4223
5064
  });
4224
- const input = remapFromGraphQLSingleInput(set, table);
4225
- if (!Object.keys(input).length) {
4226
- throw new GraphQLError6("Unable to update with no values specified!");
5065
+ const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
5066
+ const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
5067
+ const input = remapUpdateInput(entry ? entry.columns : set, table, tableName);
5068
+ if (!Object.keys(input).length && !nestedOps) {
5069
+ throw new GraphQLError8("Unable to update with no values specified!");
4227
5070
  }
4228
5071
  const relationCtx = relationFilterCtx(filterCtx, tableName);
4229
5072
  const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
4230
5073
  if (single) {
4231
5074
  await assertSingleMatch(executor, table, filters, fieldName);
4232
5075
  }
4233
- let query = executor.update(table).set(input);
4234
- if (filters) {
4235
- query = query.where(filters);
4236
- }
4237
- query = query.returning(columns);
4238
- const result = await query;
5076
+ const returning = nestedOps ? nested.withJoinColumns(tableName, nestedOps, { ...columns }, table) : columns;
5077
+ const runUpdate = async (target, values) => {
5078
+ const writes = Object.keys(values).length > 0;
5079
+ let query = writes ? target.update(table).set(values) : target.select(returning).from(table);
5080
+ if (filters) {
5081
+ query = query.where(filters);
5082
+ }
5083
+ return await (writes ? query.returning(returning) : query);
5084
+ };
5085
+ const result = nestedOps ? await updateWithNestedOps({
5086
+ executor,
5087
+ runtime: nested,
5088
+ tableName,
5089
+ columns: input,
5090
+ ops: nestedOps,
5091
+ remapValues: (values) => values,
5092
+ write: runUpdate
5093
+ }) : await runUpdate(executor, input);
4239
5094
  if (single && result.length > 1) {
4240
- throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
5095
+ throw new GraphQLError8(`${fieldName}: 'where' matched more than one row!`);
4241
5096
  }
4242
5097
  if (single && !result[0]) {
4243
5098
  return void 0;
@@ -4252,10 +5107,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
4252
5107
  args: queryArgs
4253
5108
  };
4254
5109
  };
4255
- var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
5110
+ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx, nested) => {
4256
5111
  const queryArgs = {
4257
5112
  updates: {
4258
- type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(updateManyInput)))
5113
+ type: new GraphQLNonNull7(new GraphQLList7(new GraphQLNonNull7(updateManyInput)))
4259
5114
  }
4260
5115
  };
4261
5116
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -4266,7 +5121,7 @@ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateMany
4266
5121
  return await runMutation(db, context, info, txCtx, async (executor) => {
4267
5122
  const { updates } = args;
4268
5123
  if (!updates.length) {
4269
- throw new GraphQLError6("No updates were provided!");
5124
+ throw new GraphQLError8("No updates were provided!");
4270
5125
  }
4271
5126
  const parsedInfo = parseResolveInfo3(info, {
4272
5127
  deep: true
@@ -4282,23 +5137,40 @@ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateMany
4282
5137
  parsedInfo
4283
5138
  });
4284
5139
  const entries = updates.map(({ where, set }) => {
4285
- const input = remapFromGraphQLSingleInput(set, table);
4286
- if (!Object.keys(input).length) {
4287
- throw new GraphQLError6("Unable to update with no values specified!");
5140
+ const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
5141
+ const ops = split && nested.hasOps(split.ops) ? split.ops : void 0;
5142
+ const input = remapUpdateInput(split ? split.columns : set, table, tableName);
5143
+ if (!Object.keys(input).length && !ops) {
5144
+ throw new GraphQLError8("Unable to update with no values specified!");
4288
5145
  }
4289
5146
  return {
4290
5147
  set: input,
5148
+ ops,
4291
5149
  filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
4292
5150
  };
4293
5151
  });
5152
+ const returning = entries.some((entry) => entry.ops) ? nested.withJoinColumns(
5153
+ tableName,
5154
+ mergedOps(entries.map((entry) => ({ ops: entry.ops ?? {} }))),
5155
+ {
5156
+ ...columns
5157
+ },
5158
+ table
5159
+ ) : columns;
4294
5160
  const perEntry = await executor.transaction(async (tx) => {
4295
5161
  const results = [];
4296
5162
  for (const entry of entries) {
4297
- let query = tx.update(table).set(entry.set);
5163
+ const values = entry.ops ? { ...entry.set, ...await nested.applyParentSide(tx, tableName, entry.ops) } : entry.set;
5164
+ const writes = Object.keys(values).length > 0;
5165
+ let query = writes ? tx.update(table).set(values) : tx.select(returning).from(table);
4298
5166
  if (entry.filters) {
4299
5167
  query = query.where(entry.filters);
4300
5168
  }
4301
- results.push(await query.returning(columns));
5169
+ const rows = await (writes ? query.returning(returning) : query);
5170
+ if (entry.ops) {
5171
+ await nested.applyChildSide(tx, tableName, entry.ops, rows);
5172
+ }
5173
+ results.push(rows);
4302
5174
  }
4303
5175
  return results;
4304
5176
  });
@@ -4328,7 +5200,7 @@ var generateUpdateMany2 = (db, tableName, table, tables, relationMap, updateMany
4328
5200
  var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
4329
5201
  const queryArgs = {
4330
5202
  where: {
4331
- type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
5203
+ type: single || requireWhere ? new GraphQLNonNull7(filterArgs) : filterArgs
4332
5204
  }
4333
5205
  };
4334
5206
  return {
@@ -4357,7 +5229,7 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, si
4357
5229
  query = query.returning(columns);
4358
5230
  const result = await query;
4359
5231
  if (single && result.length > 1) {
4360
- throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
5232
+ throw new GraphQLError8(`${fieldName}: 'where' matched more than one row!`);
4361
5233
  }
4362
5234
  if (single) {
4363
5235
  return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
@@ -4383,7 +5255,7 @@ function generateSchemaData2(db, schema, relations, options) {
4383
5255
  complexity
4384
5256
  } = options;
4385
5257
  const schemaEntries = Object.entries(schema);
4386
- const tableEntries = schemaEntries.filter(([_key, value]) => is5(value, PgTable));
5258
+ const tableEntries = schemaEntries.filter(([_key, value]) => is6(value, PgTable));
4387
5259
  const tables = Object.fromEntries(tableEntries);
4388
5260
  if (!tableEntries.length) {
4389
5261
  throw new Error(
@@ -4391,11 +5263,17 @@ function generateSchemaData2(db, schema, relations, options) {
4391
5263
  );
4392
5264
  }
4393
5265
  registerScalarOverrides(tables, options);
5266
+ registerEnumConfig(options);
4394
5267
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
4395
5268
  attachTargetPrimaryKeys(namedRelations, tables, pgPrimaryKeyPropNames);
4396
5269
  const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
4397
5270
  const filterCtx = { tables, relationMap: namedRelations };
4398
- const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
5271
+ const resolverFactory = createRelationResolverFactory(
5272
+ db,
5273
+ tables,
5274
+ "nulls-largest",
5275
+ filterCtx
5276
+ );
4399
5277
  const cacheCtx = {
4400
5278
  genericFilterCache: /* @__PURE__ */ new Map(),
4401
5279
  objectTypeCache: /* @__PURE__ */ new Map(),
@@ -4408,8 +5286,19 @@ function generateSchemaData2(db, schema, relations, options) {
4408
5286
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
4409
5287
  listRelationFilterCache: /* @__PURE__ */ new Map(),
4410
5288
  aggregateTypeCache: /* @__PURE__ */ new Map(),
4411
- complexity
5289
+ complexity,
5290
+ docs: options.docs ?? {},
5291
+ features
4412
5292
  };
5293
+ const nestedPlans = features.nestedWrites ? buildNestedWritePlans(
5294
+ tables,
5295
+ namedRelations,
5296
+ (target) => getUniqueColumnSets(target, getTableConfig2),
5297
+ (target) => pgPrimaryKeyPropNames(target),
5298
+ extractRelationJoinColumns
5299
+ ) : void 0;
5300
+ const nestedTypes = nestedPlans ? createNestedWriteTypes({ plans: nestedPlans, cacheCtx, typeNameMapper, insertPrefix: prefixes.insert }) : void 0;
5301
+ const nestedRuntime = nestedPlans ? createNestedWriteRuntime({ plans: nestedPlans, filterCtx }) : void 0;
4413
5302
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
4414
5303
  const queries = {};
4415
5304
  const mutations = {};
@@ -4428,7 +5317,8 @@ function generateSchemaData2(db, schema, relations, options) {
4428
5317
  prefixes.insert,
4429
5318
  prefixes.update,
4430
5319
  resolverFactory,
4431
- relationAggregateFactory
5320
+ relationAggregateFactory,
5321
+ nestedTypes
4432
5322
  )
4433
5323
  ])
4434
5324
  );
@@ -4450,8 +5340,10 @@ function generateSchemaData2(db, schema, relations, options) {
4450
5340
  updateFieldName,
4451
5341
  updateManyFieldName,
4452
5342
  updateSingleFieldName,
5343
+ updateCountFieldName,
4453
5344
  deleteFieldName,
4454
- deleteSingleFieldName
5345
+ deleteSingleFieldName,
5346
+ deleteCountFieldName
4455
5347
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
4456
5348
  const selectArrGenerated = generateSelectArray2(
4457
5349
  db,
@@ -4489,7 +5381,8 @@ function generateSchemaData2(db, schema, relations, options) {
4489
5381
  typeName,
4490
5382
  typeNameMapper,
4491
5383
  conflictDoNothing,
4492
- mutationTxCtx
5384
+ mutationTxCtx,
5385
+ nestedRuntime
4493
5386
  ) : void 0;
4494
5387
  const insertSingleGenerated = features.insert ? generateInsertSingle2(
4495
5388
  db,
@@ -4502,7 +5395,8 @@ function generateSchemaData2(db, schema, relations, options) {
4502
5395
  typeName,
4503
5396
  typeNameMapper,
4504
5397
  conflictDoNothing,
4505
- mutationTxCtx
5398
+ mutationTxCtx,
5399
+ nestedRuntime
4506
5400
  ) : void 0;
4507
5401
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig2) : [];
4508
5402
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -4526,7 +5420,8 @@ function generateSchemaData2(db, schema, relations, options) {
4526
5420
  false,
4527
5421
  typeNameMapper,
4528
5422
  filterCtx,
4529
- mutationTxCtx
5423
+ mutationTxCtx,
5424
+ nestedRuntime
4530
5425
  ) : void 0;
4531
5426
  const upsertSingleGenerated = onConflictInput ? generateUpsert2(
4532
5427
  db,
@@ -4542,7 +5437,8 @@ function generateSchemaData2(db, schema, relations, options) {
4542
5437
  true,
4543
5438
  typeNameMapper,
4544
5439
  filterCtx,
4545
- mutationTxCtx
5440
+ mutationTxCtx,
5441
+ nestedRuntime
4546
5442
  ) : void 0;
4547
5443
  const updateGenerated = features.update ? generateUpdate2(
4548
5444
  db,
@@ -4558,7 +5454,8 @@ function generateSchemaData2(db, schema, relations, options) {
4558
5454
  features.requireWhere,
4559
5455
  typeNameMapper,
4560
5456
  filterCtx,
4561
- mutationTxCtx
5457
+ mutationTxCtx,
5458
+ nestedRuntime
4562
5459
  ) : void 0;
4563
5460
  const updateSingleGenerated = features.update ? generateUpdate2(
4564
5461
  db,
@@ -4574,7 +5471,8 @@ function generateSchemaData2(db, schema, relations, options) {
4574
5471
  features.requireWhere,
4575
5472
  typeNameMapper,
4576
5473
  filterCtx,
4577
- mutationTxCtx
5474
+ mutationTxCtx,
5475
+ nestedRuntime
4578
5476
  ) : void 0;
4579
5477
  const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
4580
5478
  const updateManyGenerated = updateManyInput ? generateUpdateMany2(
@@ -4588,7 +5486,8 @@ function generateSchemaData2(db, schema, relations, options) {
4588
5486
  typeName,
4589
5487
  typeNameMapper,
4590
5488
  filterCtx,
4591
- mutationTxCtx
5489
+ mutationTxCtx,
5490
+ nestedRuntime
4592
5491
  ) : void 0;
4593
5492
  const deleteGenerated = features.delete ? generateDelete2(
4594
5493
  db,
@@ -4616,6 +5515,30 @@ function generateSchemaData2(db, schema, relations, options) {
4616
5515
  { tableName, relationMap: namedRelations, tables },
4617
5516
  mutationTxCtx
4618
5517
  ) : void 0;
5518
+ const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
5519
+ db,
5520
+ tableName,
5521
+ table: schema[tableName],
5522
+ kind: "update",
5523
+ setArgs: updateInput,
5524
+ filterArgs: tableFilters,
5525
+ fieldName: updateCountFieldName,
5526
+ requireWhere: features.requireWhere,
5527
+ filterCtx,
5528
+ txCtx: mutationTxCtx,
5529
+ nested: nestedRuntime
5530
+ }) : void 0;
5531
+ const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
5532
+ db,
5533
+ tableName,
5534
+ table: schema[tableName],
5535
+ kind: "delete",
5536
+ filterArgs: tableFilters,
5537
+ fieldName: deleteCountFieldName,
5538
+ requireWhere: features.requireWhere,
5539
+ filterCtx,
5540
+ txCtx: mutationTxCtx
5541
+ }) : void 0;
4619
5542
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4620
5543
  const aggregateGenerated = features.aggregates ? generateAggregate(
4621
5544
  db,
@@ -4653,7 +5576,7 @@ function generateSchemaData2(db, schema, relations, options) {
4653
5576
  };
4654
5577
  if (aggregateGenerated && aggregateType) {
4655
5578
  queries[aggregateGenerated.name] = {
4656
- type: new GraphQLNonNull5(aggregateType),
5579
+ type: new GraphQLNonNull7(aggregateType),
4657
5580
  args: aggregateGenerated.args,
4658
5581
  resolve: aggregateGenerated.resolver,
4659
5582
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -4661,7 +5584,7 @@ function generateSchemaData2(db, schema, relations, options) {
4661
5584
  }
4662
5585
  if (groupByGenerated && groupByType) {
4663
5586
  queries[groupByGenerated.name] = {
4664
- type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(groupByType))),
5587
+ type: new GraphQLNonNull7(new GraphQLList7(new GraphQLNonNull7(groupByType))),
4665
5588
  args: groupByGenerated.args,
4666
5589
  resolve: groupByGenerated.resolver,
4667
5590
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -4676,7 +5599,9 @@ function generateSchemaData2(db, schema, relations, options) {
4676
5599
  }
4677
5600
  if (insertSingleGenerated) {
4678
5601
  mutations[insertSingleGenerated.name] = {
4679
- type: singleTableItemOutput,
5602
+ // An insert either returns the row it inserted or throws — the one path to `null` is
5603
+ // `conflictDoNothing` swallowing the insert, so the field is nullable only there.
5604
+ type: conflictDoNothing ? singleTableItemOutput : new GraphQLNonNull7(singleTableItemOutput),
4680
5605
  args: insertSingleGenerated.args,
4681
5606
  resolve: insertSingleGenerated.resolver
4682
5607
  };
@@ -4704,10 +5629,13 @@ function generateSchemaData2(db, schema, relations, options) {
4704
5629
  }
4705
5630
  if (updateManyGenerated) {
4706
5631
  mutations[updateManyGenerated.name] = {
4707
- // Nullable items: a no-match entry yields `null` in its slot.
4708
- type: new GraphQLNonNull5(new GraphQLList5(singleTableItemOutput)),
5632
+ type: new GraphQLNonNull7(new GraphQLList7(singleTableItemOutput)),
4709
5633
  args: updateManyGenerated.args,
4710
- resolve: updateManyGenerated.resolver
5634
+ resolve: updateManyGenerated.resolver,
5635
+ // The nullable element is deliberate, and the reason this mutation's return type
5636
+ // differs from every sibling's: the result is aligned with the input, one slot per
5637
+ // entry, so an entry that matched nothing has to be able to say so.
5638
+ description: "Each entry's updated rows, in entry order. An entry whose `where` matched no rows contributes `null` in its slot; an entry that matched several contributes each of its rows."
4711
5639
  };
4712
5640
  }
4713
5641
  if (updateSingleGenerated) {
@@ -4731,6 +5659,22 @@ function generateSchemaData2(db, schema, relations, options) {
4731
5659
  resolve: deleteSingleGenerated.resolver
4732
5660
  };
4733
5661
  }
5662
+ if (updateCountGenerated) {
5663
+ mutations[updateCountGenerated.name] = {
5664
+ type: new GraphQLNonNull7(GraphQLInt6),
5665
+ args: updateCountGenerated.args,
5666
+ resolve: updateCountGenerated.resolver,
5667
+ description: "How many rows the update touched. The rows themselves are not read back, which is the point of this mutation."
5668
+ };
5669
+ }
5670
+ if (deleteCountGenerated) {
5671
+ mutations[deleteCountGenerated.name] = {
5672
+ type: new GraphQLNonNull7(GraphQLInt6),
5673
+ args: deleteCountGenerated.args,
5674
+ resolve: deleteCountGenerated.resolver,
5675
+ description: "How many rows the delete removed. The rows themselves are not read back, which is the point of this mutation."
5676
+ };
5677
+ }
4734
5678
  const activeInputs = [
4735
5679
  // The insert input types the upsert mutations too, so either feature keeps it.
4736
5680
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -4762,7 +5706,7 @@ function generateSchemaData2(db, schema, relations, options) {
4762
5706
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
4763
5707
  const relResolvers = {};
4764
5708
  for (const [relName, relEntry] of Object.entries(tableRelations)) {
4765
- const isOne = is5(relEntry.relation ?? relEntry, One4);
5709
+ const isOne = is6(relEntry.relation ?? relEntry, One5);
4766
5710
  const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
4767
5711
  if (resolver) {
4768
5712
  relResolvers[relName] = resolver;
@@ -4776,12 +5720,13 @@ function generateSchemaData2(db, schema, relations, options) {
4776
5720
  }
4777
5721
 
4778
5722
  // src/util/builders/sqlite.ts
4779
- import { is as is6, One as One5 } from "drizzle-orm";
5723
+ import { is as is7, One as One6 } from "drizzle-orm";
4780
5724
  import { getTableConfig as getTableConfig3, SQLiteTable } from "drizzle-orm/sqlite-core";
4781
5725
  import {
4782
- GraphQLError as GraphQLError7,
4783
- GraphQLList as GraphQLList6,
4784
- GraphQLNonNull as GraphQLNonNull6
5726
+ GraphQLError as GraphQLError9,
5727
+ GraphQLInt as GraphQLInt7,
5728
+ GraphQLList as GraphQLList8,
5729
+ GraphQLNonNull as GraphQLNonNull8
4785
5730
  } from "graphql";
4786
5731
  import { parseResolveInfo as parseResolveInfo4 } from "graphql-parse-resolve-info";
4787
5732
  var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
@@ -4867,10 +5812,10 @@ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filt
4867
5812
  };
4868
5813
  };
4869
5814
  var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig3);
4870
- var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
5815
+ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx, nested) => {
4871
5816
  const queryArgs = {
4872
5817
  values: {
4873
- type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
5818
+ type: new GraphQLNonNull8(new GraphQLList8(new GraphQLNonNull8(baseType)))
4874
5819
  }
4875
5820
  };
4876
5821
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -4879,10 +5824,12 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4879
5824
  resolver: async (_source, args, context, info) => {
4880
5825
  try {
4881
5826
  return await runMutation(db, context, info, txCtx, async (executor) => {
4882
- const input = remapFromGraphQLArrayInput(args.values, table);
4883
- if (!input.length) {
4884
- throw new GraphQLError7("No values were provided!");
5827
+ if (!args.values.length) {
5828
+ throw new GraphQLError9("No values were provided!");
4885
5829
  }
5830
+ const entries = nested?.enabled(tableName) ? args.values.map((values) => nested.split(tableName, values)) : void 0;
5831
+ const nestedEntries = entries?.some((entry) => nested.hasOps(entry.ops)) ? entries : void 0;
5832
+ const input = nestedEntries ? [] : remapFromGraphQLArrayInput(entries ? entries.map((entry) => entry.columns) : args.values, table);
4886
5833
  const parsedInfo = parseResolveInfo4(info, {
4887
5834
  deep: true
4888
5835
  });
@@ -4896,11 +5843,22 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4896
5843
  pkNames,
4897
5844
  parsedInfo
4898
5845
  });
4899
- let query = executor.insert(table).values(input).returning(columns);
4900
- if (conflictDoNothing) {
4901
- query = query.onConflictDoNothing();
4902
- }
4903
- const result = await query;
5846
+ const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
5847
+ const runInsert = async (target, values) => {
5848
+ let query = target.insert(table).values(values).returning(returning);
5849
+ if (conflictDoNothing) {
5850
+ query = query.onConflictDoNothing();
5851
+ }
5852
+ return await query;
5853
+ };
5854
+ const result = nestedEntries ? await writeWithNestedOps({
5855
+ executor,
5856
+ runtime: nested,
5857
+ tableName,
5858
+ entries: nestedEntries,
5859
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
5860
+ write: (tx, values) => runInsert(tx, [values])
5861
+ }) : await runInsert(executor, input);
4904
5862
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
4905
5863
  return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4906
5864
  });
@@ -4911,10 +5869,10 @@ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType,
4911
5869
  args: queryArgs
4912
5870
  };
4913
5871
  };
4914
- var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx) => {
5872
+ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false, txCtx, nested) => {
4915
5873
  const queryArgs = {
4916
5874
  values: {
4917
- type: new GraphQLNonNull6(baseType)
5875
+ type: new GraphQLNonNull8(baseType)
4918
5876
  }
4919
5877
  };
4920
5878
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -4923,7 +5881,9 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4923
5881
  resolver: async (_source, args, context, info) => {
4924
5882
  try {
4925
5883
  return await runMutation(db, context, info, txCtx, async (executor) => {
4926
- const input = remapFromGraphQLSingleInput(args.values, table);
5884
+ const entry = nested?.enabled(tableName) ? nested.split(tableName, args.values) : void 0;
5885
+ const nestedEntry = entry && nested.hasOps(entry.ops) ? entry : void 0;
5886
+ const input = nestedEntry ? {} : remapFromGraphQLSingleInput(entry ? entry.columns : args.values, table);
4927
5887
  const parsedInfo = parseResolveInfo4(info, {
4928
5888
  deep: true
4929
5889
  });
@@ -4937,12 +5897,26 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4937
5897
  pkNames,
4938
5898
  parsedInfo
4939
5899
  });
4940
- let query = executor.insert(table).values(input).returning(columns);
4941
- if (conflictDoNothing) {
4942
- query = query.onConflictDoNothing();
4943
- }
4944
- const result = await query;
5900
+ const returning = nestedEntry ? nested.withJoinColumns(tableName, nestedEntry.ops, { ...columns }, table) : columns;
5901
+ const runInsert = async (target, values) => {
5902
+ let query = target.insert(table).values(values).returning(returning);
5903
+ if (conflictDoNothing) {
5904
+ query = query.onConflictDoNothing();
5905
+ }
5906
+ return await query;
5907
+ };
5908
+ const result = nestedEntry ? await writeWithNestedOps({
5909
+ executor,
5910
+ runtime: nested,
5911
+ tableName,
5912
+ entries: [nestedEntry],
5913
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
5914
+ write: runInsert
5915
+ }) : await runInsert(executor, input);
4945
5916
  if (!result[0]) {
5917
+ if (!conflictDoNothing) {
5918
+ throw new GraphQLError9(`${fieldName}: the insert returned no row.`);
5919
+ }
4946
5920
  return void 0;
4947
5921
  }
4948
5922
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
@@ -4955,10 +5929,10 @@ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType
4955
5929
  args: queryArgs
4956
5930
  };
4957
5931
  };
4958
- var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx) => {
5932
+ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx, txCtx, nested) => {
4959
5933
  const queryArgs = {
4960
5934
  values: {
4961
- type: single ? new GraphQLNonNull6(baseType) : new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(baseType)))
5935
+ type: single ? new GraphQLNonNull8(baseType) : new GraphQLNonNull8(new GraphQLList8(new GraphQLNonNull8(baseType)))
4962
5936
  },
4963
5937
  onConflict: {
4964
5938
  type: onConflictType,
@@ -4971,10 +5945,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4971
5945
  resolver: async (_source, args, context, info) => {
4972
5946
  try {
4973
5947
  return await runMutation(db, context, info, txCtx, async (executor) => {
4974
- const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
4975
- if (!input.length) {
4976
- throw new GraphQLError7("No values were provided!");
5948
+ const supplied = single ? [args.values] : args.values;
5949
+ if (!supplied.length) {
5950
+ throw new GraphQLError9("No values were provided!");
4977
5951
  }
5952
+ const entries = nested?.enabled(tableName) ? supplied.map((values) => nested.split(tableName, values)) : void 0;
5953
+ const nestedEntries = entries?.some((entry) => nested.hasOps(entry.ops)) ? entries : void 0;
5954
+ const input = nestedEntries ? [] : remapFromGraphQLArrayInput(entries ? entries.map((entry) => entry.columns) : supplied, table);
4978
5955
  const parsedInfo = parseResolveInfo4(info, { deep: true });
4979
5956
  const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
4980
5957
  relationMap,
@@ -4986,19 +5963,30 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
4986
5963
  pkNames,
4987
5964
  parsedInfo
4988
5965
  });
4989
- const plan = resolveConflictPlan({
4990
- table,
4991
- values: input,
4992
- onConflict: args.onConflict,
4993
- pkNames,
4994
- uniqueSets,
4995
- excludedRef: excludedColumnRef,
4996
- withTarget: true,
4997
- buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
4998
- });
4999
- let query = executor.insert(table).values(input).returning(columns);
5000
- query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
5001
- const result = await query;
5966
+ const returning = nestedEntries ? nested.withJoinColumns(tableName, mergedOps(nestedEntries), { ...columns }, table) : columns;
5967
+ const runUpsert = async (target, values) => {
5968
+ const plan = resolveConflictPlan({
5969
+ table,
5970
+ values,
5971
+ onConflict: args.onConflict,
5972
+ pkNames,
5973
+ uniqueSets,
5974
+ excludedRef: excludedColumnRef,
5975
+ withTarget: true,
5976
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
5977
+ });
5978
+ let query = target.insert(table).values(values).returning(returning);
5979
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
5980
+ return await query;
5981
+ };
5982
+ const result = nestedEntries ? await writeWithNestedOps({
5983
+ executor,
5984
+ runtime: nested,
5985
+ tableName,
5986
+ entries: nestedEntries,
5987
+ remapValues: (values) => remapFromGraphQLSingleInput(values, table),
5988
+ write: (tx, values) => runUpsert(tx, [values])
5989
+ }) : await runUpsert(executor, input);
5002
5990
  if (single && !result[0]) {
5003
5991
  return void 0;
5004
5992
  }
@@ -5012,13 +6000,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
5012
6000
  args: queryArgs
5013
6001
  };
5014
6002
  };
5015
- var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx) => {
6003
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx, txCtx, nested) => {
5016
6004
  const queryArgs = {
5017
6005
  set: {
5018
- type: new GraphQLNonNull6(setArgs)
6006
+ type: new GraphQLNonNull8(setArgs)
5019
6007
  },
5020
6008
  where: {
5021
- type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
6009
+ type: single || requireWhere ? new GraphQLNonNull8(filterArgs) : filterArgs
5022
6010
  }
5023
6011
  };
5024
6012
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -5041,23 +6029,37 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
5041
6029
  pkNames,
5042
6030
  parsedInfo
5043
6031
  });
5044
- const input = remapFromGraphQLSingleInput(set, table);
5045
- if (!Object.keys(input).length) {
5046
- throw new GraphQLError7("Unable to update with no values specified!");
6032
+ const entry = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
6033
+ const nestedOps = entry && nested.hasOps(entry.ops) ? entry.ops : void 0;
6034
+ const input = remapUpdateInput(entry ? entry.columns : set, table, tableName);
6035
+ if (!Object.keys(input).length && !nestedOps) {
6036
+ throw new GraphQLError9("Unable to update with no values specified!");
5047
6037
  }
5048
6038
  const relationCtx = relationFilterCtx(filterCtx, tableName);
5049
6039
  const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
5050
6040
  if (single) {
5051
6041
  await assertSingleMatch(executor, table, filters, fieldName);
5052
6042
  }
5053
- let query = executor.update(table).set(input);
5054
- if (filters) {
5055
- query = query.where(filters);
5056
- }
5057
- query = query.returning(columns);
5058
- const result = await query;
6043
+ const returning = nestedOps ? nested.withJoinColumns(tableName, nestedOps, { ...columns }, table) : columns;
6044
+ const runUpdate = async (target, values) => {
6045
+ const writes = Object.keys(values).length > 0;
6046
+ let query = writes ? target.update(table).set(values) : target.select(returning).from(table);
6047
+ if (filters) {
6048
+ query = query.where(filters);
6049
+ }
6050
+ return await (writes ? query.returning(returning) : query);
6051
+ };
6052
+ const result = nestedOps ? await updateWithNestedOps({
6053
+ executor,
6054
+ runtime: nested,
6055
+ tableName,
6056
+ columns: input,
6057
+ ops: nestedOps,
6058
+ remapValues: (values) => values,
6059
+ write: runUpdate
6060
+ }) : await runUpdate(executor, input);
5059
6061
  if (single && result.length > 1) {
5060
- throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
6062
+ throw new GraphQLError9(`${fieldName}: 'where' matched more than one row!`);
5061
6063
  }
5062
6064
  if (single && !result[0]) {
5063
6065
  return void 0;
@@ -5072,10 +6074,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
5072
6074
  args: queryArgs
5073
6075
  };
5074
6076
  };
5075
- var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx) => {
6077
+ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateManyInput, fieldName, typeName, typeNameMapper, filterCtx, txCtx, nested) => {
5076
6078
  const queryArgs = {
5077
6079
  updates: {
5078
- type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(updateManyInput)))
6080
+ type: new GraphQLNonNull8(new GraphQLList8(new GraphQLNonNull8(updateManyInput)))
5079
6081
  }
5080
6082
  };
5081
6083
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -5086,7 +6088,7 @@ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateMany
5086
6088
  return await runMutation(db, context, info, txCtx, async (executor) => {
5087
6089
  const { updates } = args;
5088
6090
  if (!updates.length) {
5089
- throw new GraphQLError7("No updates were provided!");
6091
+ throw new GraphQLError9("No updates were provided!");
5090
6092
  }
5091
6093
  const parsedInfo = parseResolveInfo4(info, {
5092
6094
  deep: true
@@ -5102,23 +6104,55 @@ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateMany
5102
6104
  parsedInfo
5103
6105
  });
5104
6106
  const entries = updates.map(({ where, set }) => {
5105
- const input = remapFromGraphQLSingleInput(set, table);
5106
- if (!Object.keys(input).length) {
5107
- throw new GraphQLError7("Unable to update with no values specified!");
6107
+ const split = nested?.enabled(tableName) ? nested.split(tableName, set) : void 0;
6108
+ const ops = split && nested.hasOps(split.ops) ? split.ops : void 0;
6109
+ const input = remapUpdateInput(split ? split.columns : set, table, tableName);
6110
+ if (!Object.keys(input).length && !ops) {
6111
+ throw new GraphQLError9("Unable to update with no values specified!");
5108
6112
  }
5109
6113
  return {
5110
6114
  set: input,
6115
+ ops,
5111
6116
  filters: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0
5112
6117
  };
5113
6118
  });
6119
+ const anyNested = entries.some((entry) => entry.ops);
6120
+ const returning = anyNested ? nested.withJoinColumns(
6121
+ tableName,
6122
+ mergedOps(entries.map((entry) => ({ ops: entry.ops ?? {} }))),
6123
+ { ...columns },
6124
+ table
6125
+ ) : columns;
5114
6126
  const runEntry = (tx, entry) => {
5115
6127
  let query = tx.update(table).set(entry.set);
5116
6128
  if (entry.filters) {
5117
6129
  query = query.where(entry.filters);
5118
6130
  }
5119
- return query.returning(columns).all();
6131
+ return query.returning(returning).all();
6132
+ };
6133
+ const runNestedEntry = async (tx, entry) => {
6134
+ const values = entry.ops ? { ...entry.set, ...await nested.applyParentSide(tx, tableName, entry.ops) } : entry.set;
6135
+ const writes = Object.keys(values).length > 0;
6136
+ let query = writes ? tx.update(table).set(values) : tx.select(returning).from(table);
6137
+ if (entry.filters) {
6138
+ query = query.where(entry.filters);
6139
+ }
6140
+ const rows = await (writes ? query.returning(returning) : query);
6141
+ if (entry.ops) {
6142
+ await nested.applyChildSide(tx, tableName, entry.ops, rows);
6143
+ }
6144
+ return rows;
5120
6145
  };
5121
6146
  const perEntry = await executor.transaction((tx) => {
6147
+ if (anyNested) {
6148
+ return (async () => {
6149
+ const results2 = [];
6150
+ for (const entry of entries) {
6151
+ results2.push(await runNestedEntry(tx, entry));
6152
+ }
6153
+ return results2;
6154
+ })();
6155
+ }
5122
6156
  const first = runEntry(tx, entries[0]);
5123
6157
  if (typeof first?.then === "function") {
5124
6158
  return (async () => {
@@ -5161,7 +6195,7 @@ var generateUpdateMany3 = (db, tableName, table, tables, relationMap, updateMany
5161
6195
  var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx, txCtx) => {
5162
6196
  const queryArgs = {
5163
6197
  where: {
5164
- type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
6198
+ type: single || requireWhere ? new GraphQLNonNull8(filterArgs) : filterArgs
5165
6199
  }
5166
6200
  };
5167
6201
  return {
@@ -5190,7 +6224,7 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, si
5190
6224
  query = query.returning(columns);
5191
6225
  const result = await query;
5192
6226
  if (single && result.length > 1) {
5193
- throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
6227
+ throw new GraphQLError9(`${fieldName}: 'where' matched more than one row!`);
5194
6228
  }
5195
6229
  if (single) {
5196
6230
  return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
@@ -5217,7 +6251,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5217
6251
  } = options;
5218
6252
  const rawSchema = schema;
5219
6253
  const schemaEntries = Object.entries(rawSchema);
5220
- const tableEntries = schemaEntries.filter(([_key, value]) => is6(value, SQLiteTable));
6254
+ const tableEntries = schemaEntries.filter(([_key, value]) => is7(value, SQLiteTable));
5221
6255
  const tables = Object.fromEntries(tableEntries);
5222
6256
  if (!tableEntries.length) {
5223
6257
  throw new Error(
@@ -5225,11 +6259,17 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5225
6259
  );
5226
6260
  }
5227
6261
  registerScalarOverrides(tables, options);
6262
+ registerEnumConfig(options);
5228
6263
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
5229
6264
  attachTargetPrimaryKeys(namedRelations, tables, sqlitePrimaryKeyPropNames);
5230
6265
  const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
5231
6266
  const filterCtx = { tables, relationMap: namedRelations };
5232
- const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
6267
+ const resolverFactory = createRelationResolverFactory(
6268
+ db,
6269
+ tables,
6270
+ "nulls-smallest",
6271
+ filterCtx
6272
+ );
5233
6273
  const cacheCtx = {
5234
6274
  genericFilterCache: /* @__PURE__ */ new Map(),
5235
6275
  objectTypeCache: /* @__PURE__ */ new Map(),
@@ -5242,8 +6282,24 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5242
6282
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
5243
6283
  listRelationFilterCache: /* @__PURE__ */ new Map(),
5244
6284
  aggregateTypeCache: /* @__PURE__ */ new Map(),
5245
- complexity
6285
+ complexity,
6286
+ docs: options.docs ?? {},
6287
+ features
5246
6288
  };
6289
+ if (features.nestedWrites && db.resultKind === "sync") {
6290
+ throw new Error(
6291
+ "Drizzle-GraphQL Error: features.nestedWrites requires an asynchronous SQLite driver (e.g. libsql). Synchronous drivers cannot run the multi-statement transaction a nested write needs."
6292
+ );
6293
+ }
6294
+ const nestedPlans = features.nestedWrites ? buildNestedWritePlans(
6295
+ tables,
6296
+ namedRelations,
6297
+ (target) => getUniqueColumnSets(target, getTableConfig3),
6298
+ (target) => sqlitePrimaryKeyPropNames(target),
6299
+ extractRelationJoinColumns
6300
+ ) : void 0;
6301
+ const nestedTypes = nestedPlans ? createNestedWriteTypes({ plans: nestedPlans, cacheCtx, typeNameMapper, insertPrefix: prefixes.insert }) : void 0;
6302
+ const nestedRuntime = nestedPlans ? createNestedWriteRuntime({ plans: nestedPlans, filterCtx }) : void 0;
5247
6303
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
5248
6304
  const queries = {};
5249
6305
  const mutations = {};
@@ -5267,7 +6323,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5267
6323
  prefixes.insert,
5268
6324
  prefixes.update,
5269
6325
  resolverFactory,
5270
- relationAggregateFactory
6326
+ relationAggregateFactory,
6327
+ nestedTypes
5271
6328
  )
5272
6329
  ])
5273
6330
  );
@@ -5289,8 +6346,10 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5289
6346
  updateFieldName,
5290
6347
  updateManyFieldName,
5291
6348
  updateSingleFieldName,
6349
+ updateCountFieldName,
5292
6350
  deleteFieldName,
5293
- deleteSingleFieldName
6351
+ deleteSingleFieldName,
6352
+ deleteCountFieldName
5294
6353
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
5295
6354
  const selectArrGenerated = generateSelectArray3(
5296
6355
  db,
@@ -5328,7 +6387,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5328
6387
  typeName,
5329
6388
  typeNameMapper,
5330
6389
  conflictDoNothing,
5331
- mutationTxCtx
6390
+ mutationTxCtx,
6391
+ nestedRuntime
5332
6392
  ) : void 0;
5333
6393
  const insertSingleGenerated = features.insert ? generateInsertSingle3(
5334
6394
  db,
@@ -5341,7 +6401,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5341
6401
  typeName,
5342
6402
  typeNameMapper,
5343
6403
  conflictDoNothing,
5344
- mutationTxCtx
6404
+ mutationTxCtx,
6405
+ nestedRuntime
5345
6406
  ) : void 0;
5346
6407
  const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], getTableConfig3) : [];
5347
6408
  const onConflictInput = features.upsert ? generateOnConflictInput({
@@ -5365,7 +6426,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5365
6426
  false,
5366
6427
  typeNameMapper,
5367
6428
  filterCtx,
5368
- mutationTxCtx
6429
+ mutationTxCtx,
6430
+ nestedRuntime
5369
6431
  ) : void 0;
5370
6432
  const upsertSingleGenerated = onConflictInput ? generateUpsert3(
5371
6433
  db,
@@ -5381,7 +6443,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5381
6443
  true,
5382
6444
  typeNameMapper,
5383
6445
  filterCtx,
5384
- mutationTxCtx
6446
+ mutationTxCtx,
6447
+ nestedRuntime
5385
6448
  ) : void 0;
5386
6449
  const updateGenerated = features.update ? generateUpdate3(
5387
6450
  db,
@@ -5397,7 +6460,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5397
6460
  features.requireWhere,
5398
6461
  typeNameMapper,
5399
6462
  filterCtx,
5400
- mutationTxCtx
6463
+ mutationTxCtx,
6464
+ nestedRuntime
5401
6465
  ) : void 0;
5402
6466
  const updateSingleGenerated = features.update ? generateUpdate3(
5403
6467
  db,
@@ -5413,7 +6477,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5413
6477
  features.requireWhere,
5414
6478
  typeNameMapper,
5415
6479
  filterCtx,
5416
- mutationTxCtx
6480
+ mutationTxCtx,
6481
+ nestedRuntime
5417
6482
  ) : void 0;
5418
6483
  const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
5419
6484
  const updateManyGenerated = updateManyInput ? generateUpdateMany3(
@@ -5427,7 +6492,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5427
6492
  typeName,
5428
6493
  typeNameMapper,
5429
6494
  filterCtx,
5430
- mutationTxCtx
6495
+ mutationTxCtx,
6496
+ nestedRuntime
5431
6497
  ) : void 0;
5432
6498
  const deleteGenerated = features.delete ? generateDelete3(
5433
6499
  db,
@@ -5455,6 +6521,30 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5455
6521
  { tableName, relationMap: namedRelations, tables },
5456
6522
  mutationTxCtx
5457
6523
  ) : void 0;
6524
+ const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
6525
+ db,
6526
+ tableName,
6527
+ table: schema[tableName],
6528
+ kind: "update",
6529
+ setArgs: updateInput,
6530
+ filterArgs: tableFilters,
6531
+ fieldName: updateCountFieldName,
6532
+ requireWhere: features.requireWhere,
6533
+ filterCtx,
6534
+ txCtx: mutationTxCtx,
6535
+ nested: nestedRuntime
6536
+ }) : void 0;
6537
+ const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
6538
+ db,
6539
+ tableName,
6540
+ table: schema[tableName],
6541
+ kind: "delete",
6542
+ filterArgs: tableFilters,
6543
+ fieldName: deleteCountFieldName,
6544
+ requireWhere: features.requireWhere,
6545
+ filterCtx,
6546
+ txCtx: mutationTxCtx
6547
+ }) : void 0;
5458
6548
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
5459
6549
  const aggregateGenerated = features.aggregates ? generateAggregate(
5460
6550
  db,
@@ -5492,7 +6582,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5492
6582
  };
5493
6583
  if (aggregateGenerated && aggregateType) {
5494
6584
  queries[aggregateGenerated.name] = {
5495
- type: new GraphQLNonNull6(aggregateType),
6585
+ type: new GraphQLNonNull8(aggregateType),
5496
6586
  args: aggregateGenerated.args,
5497
6587
  resolve: aggregateGenerated.resolver,
5498
6588
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -5500,7 +6590,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5500
6590
  }
5501
6591
  if (groupByGenerated && groupByType) {
5502
6592
  queries[groupByGenerated.name] = {
5503
- type: new GraphQLNonNull6(new GraphQLList6(new GraphQLNonNull6(groupByType))),
6593
+ type: new GraphQLNonNull8(new GraphQLList8(new GraphQLNonNull8(groupByType))),
5504
6594
  args: groupByGenerated.args,
5505
6595
  resolve: groupByGenerated.resolver,
5506
6596
  ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
@@ -5515,7 +6605,9 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5515
6605
  }
5516
6606
  if (insertSingleGenerated) {
5517
6607
  mutations[insertSingleGenerated.name] = {
5518
- type: singleTableItemOutput,
6608
+ // An insert either returns the row it inserted or throws — the one path to `null` is
6609
+ // `conflictDoNothing` swallowing the insert, so the field is nullable only there.
6610
+ type: conflictDoNothing ? singleTableItemOutput : new GraphQLNonNull8(singleTableItemOutput),
5519
6611
  args: insertSingleGenerated.args,
5520
6612
  resolve: insertSingleGenerated.resolver
5521
6613
  };
@@ -5543,10 +6635,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5543
6635
  }
5544
6636
  if (updateManyGenerated) {
5545
6637
  mutations[updateManyGenerated.name] = {
5546
- // Nullable items: a no-match entry yields `null` in its slot.
5547
- type: new GraphQLNonNull6(new GraphQLList6(singleTableItemOutput)),
6638
+ type: new GraphQLNonNull8(new GraphQLList8(singleTableItemOutput)),
5548
6639
  args: updateManyGenerated.args,
5549
- resolve: updateManyGenerated.resolver
6640
+ resolve: updateManyGenerated.resolver,
6641
+ // The nullable element is deliberate, and the reason this mutation's return type
6642
+ // differs from every sibling's: the result is aligned with the input, one slot per
6643
+ // entry, so an entry that matched nothing has to be able to say so.
6644
+ description: "Each entry's updated rows, in entry order. An entry whose `where` matched no rows contributes `null` in its slot; an entry that matched several contributes each of its rows."
5550
6645
  };
5551
6646
  }
5552
6647
  if (updateSingleGenerated) {
@@ -5570,6 +6665,22 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5570
6665
  resolve: deleteSingleGenerated.resolver
5571
6666
  };
5572
6667
  }
6668
+ if (updateCountGenerated) {
6669
+ mutations[updateCountGenerated.name] = {
6670
+ type: new GraphQLNonNull8(GraphQLInt7),
6671
+ args: updateCountGenerated.args,
6672
+ resolve: updateCountGenerated.resolver,
6673
+ description: "How many rows the update touched. The rows themselves are not read back, which is the point of this mutation."
6674
+ };
6675
+ }
6676
+ if (deleteCountGenerated) {
6677
+ mutations[deleteCountGenerated.name] = {
6678
+ type: new GraphQLNonNull8(GraphQLInt7),
6679
+ args: deleteCountGenerated.args,
6680
+ resolve: deleteCountGenerated.resolver,
6681
+ description: "How many rows the delete removed. The rows themselves are not read back, which is the point of this mutation."
6682
+ };
6683
+ }
5573
6684
  const activeInputs = [
5574
6685
  // The insert input types the upsert mutations too, so either feature keeps it.
5575
6686
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -5601,7 +6712,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
5601
6712
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
5602
6713
  const relResolvers = {};
5603
6714
  for (const [relName, relEntry] of Object.entries(tableRelations)) {
5604
- const isOne = is6(relEntry.relation ?? relEntry, One5);
6715
+ const isOne = is7(relEntry.relation ?? relEntry, One6);
5605
6716
  const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
5606
6717
  if (resolver) {
5607
6718
  relResolvers[relName] = resolver;
@@ -5646,6 +6757,9 @@ var buildSchema = (db, config) => {
5646
6757
  updateMany: config?.features?.updateMany ?? true,
5647
6758
  delete: config?.features?.delete ?? true,
5648
6759
  upsert: config?.features?.upsert ?? false,
6760
+ nestedWrites: config?.features?.nestedWrites ?? false,
6761
+ fieldUpdateOperations: config?.features?.fieldUpdateOperations ?? false,
6762
+ countMutations: config?.features?.countMutations ?? false,
5649
6763
  requireWhere: config?.features?.requireWhere ?? false
5650
6764
  };
5651
6765
  const complexityConfig = config?.complexity ?? true;
@@ -5685,14 +6799,21 @@ var buildSchema = (db, config) => {
5685
6799
  complexity,
5686
6800
  scalars: config?.scalars,
5687
6801
  mapColumnType: config?.mapColumnType,
5688
- transactions
6802
+ enumNameMapper: config?.enumNameMapper,
6803
+ transactions,
6804
+ docs: {
6805
+ describeColumn: config?.describeColumn,
6806
+ describeTable: config?.describeTable,
6807
+ describeRelation: config?.describeRelation,
6808
+ deprecateColumn: config?.deprecateColumn
6809
+ }
5689
6810
  };
5690
6811
  let generatorOutput;
5691
- if (is7(db, MySqlDatabase)) {
6812
+ if (is8(db, MySqlDatabase)) {
5692
6813
  generatorOutput = generateSchemaData(db, schema, relations, generatorOptions);
5693
- } else if (is7(db, PgAsyncDatabase)) {
6814
+ } else if (is8(db, PgAsyncDatabase)) {
5694
6815
  generatorOutput = generateSchemaData2(db, schema, relations, generatorOptions);
5695
- } else if (is7(db, BaseSQLiteDatabase)) {
6816
+ } else if (is8(db, BaseSQLiteDatabase)) {
5696
6817
  generatorOutput = generateSchemaData3(db, schema, relations, generatorOptions);
5697
6818
  } else {
5698
6819
  throw new Error("Drizzle-GraphQL Error: Unknown database instance type");