@vantreeseba/drizzle-graphql 4.2.0 → 5.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.cjs CHANGED
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  GraphQLBigIntString: () => GraphQLBigIntString,
34
34
  GraphQLDate: () => import_graphql_scalars.GraphQLDate,
35
35
  GraphQLDateTime: () => import_graphql_scalars.GraphQLDateTime,
36
+ GraphQLDecimalString: () => GraphQLDecimalString,
36
37
  GraphQLJSON: () => import_graphql_scalars.GraphQLJSON,
37
38
  GraphQLUUID: () => import_graphql_scalars.GraphQLUUID,
38
39
  buildSchema: () => buildSchema,
@@ -298,13 +299,6 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
298
299
  return queryInput;
299
300
  };
300
301
 
301
- // src/util/type-converter/index.ts
302
- var import_drizzle_orm2 = require("drizzle-orm");
303
- var import_mysql_core = require("drizzle-orm/mysql-core");
304
- var import_pg_core = require("drizzle-orm/pg-core");
305
- var import_sqlite_core = require("drizzle-orm/sqlite-core");
306
- var import_graphql3 = require("graphql");
307
-
308
302
  // src/util/scalars/index.ts
309
303
  var import_graphql2 = require("graphql");
310
304
  var import_graphql_scalars = require("graphql-scalars");
@@ -343,8 +337,44 @@ var GraphQLBigIntString = new import_graphql2.GraphQLScalarType({
343
337
  return asDecimalString(ast.value);
344
338
  }
345
339
  });
340
+ var numericStringPattern = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
341
+ var asNumericString = (value) => {
342
+ if (typeof value === "bigint") {
343
+ return value.toString();
344
+ }
345
+ if (typeof value === "number") {
346
+ if (!Number.isFinite(value)) {
347
+ throw new import_graphql2.GraphQLError(`Decimal cannot represent non-finite value: ${value}`);
348
+ }
349
+ return String(value);
350
+ }
351
+ if (typeof value === "string") {
352
+ if (!numericStringPattern.test(value)) {
353
+ throw new import_graphql2.GraphQLError(`Decimal cannot represent non-numeric value: "${value}"`);
354
+ }
355
+ return value;
356
+ }
357
+ throw new import_graphql2.GraphQLError(`Decimal cannot represent value: ${JSON.stringify(value)}`);
358
+ };
359
+ var GraphQLDecimalString = new import_graphql2.GraphQLScalarType({
360
+ name: "Decimal",
361
+ description: "An arbitrary-precision decimal, transported as a numeric string so that values beyond JavaScript's double-precision range survive the round-trip intact.",
362
+ serialize: asNumericString,
363
+ parseValue: asNumericString,
364
+ parseLiteral: (ast) => {
365
+ if (ast.kind !== import_graphql2.Kind.STRING && ast.kind !== import_graphql2.Kind.INT && ast.kind !== import_graphql2.Kind.FLOAT) {
366
+ throw new import_graphql2.GraphQLError(`Decimal cannot represent a ${ast.kind}`, { nodes: ast });
367
+ }
368
+ return asNumericString(ast.value);
369
+ }
370
+ });
346
371
 
347
372
  // src/util/type-converter/index.ts
373
+ var import_drizzle_orm2 = require("drizzle-orm");
374
+ var import_mysql_core = require("drizzle-orm/mysql-core");
375
+ var import_pg_core = require("drizzle-orm/pg-core");
376
+ var import_sqlite_core = require("drizzle-orm/sqlite-core");
377
+ var import_graphql3 = require("graphql");
348
378
  var allowedNameChars = /^[a-zA-Z0-9_]+$/;
349
379
  var enumMap = /* @__PURE__ */ new WeakMap();
350
380
  var generateEnumCached = (column, columnName, tableName) => {
@@ -381,7 +411,7 @@ var geoXyInputType = new import_graphql3.GraphQLInputObjectType({
381
411
  }
382
412
  });
383
413
  var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
384
- const { type: baseType } = (0, import_drizzle_orm2.extractExtendedColumnType)(column);
414
+ const { type: baseType, constraint } = (0, import_drizzle_orm2.extractExtendedColumnType)(column);
385
415
  switch (baseType) {
386
416
  case "boolean":
387
417
  return { type: import_graphql3.GraphQLBoolean, description: "Boolean" };
@@ -400,6 +430,9 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
400
430
  if (column.enumValues?.length) {
401
431
  return { type: generateEnumCached(column, columnName, tableName) };
402
432
  }
433
+ if (constraint === "numeric" && !column.dimensions) {
434
+ return { type: GraphQLDecimalString, description: "Decimal" };
435
+ }
403
436
  if (column instanceof import_pg_core.PgTimestamp || column instanceof import_pg_core.PgTimestampString) {
404
437
  return { type: import_graphql_scalars.GraphQLDateTime, description: "DateTime" };
405
438
  }
@@ -409,6 +442,15 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
409
442
  if (column instanceof import_pg_core.PgDateString) {
410
443
  return isInput ? { type: import_graphql3.GraphQLString, description: "Date" } : { type: import_graphql_scalars.GraphQLDate, description: "Date" };
411
444
  }
445
+ {
446
+ const dims = column.dimensions;
447
+ if (dims !== void 0 && dims > 0) {
448
+ return {
449
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLString)),
450
+ description: "Array<String>"
451
+ };
452
+ }
453
+ }
412
454
  return { type: import_graphql3.GraphQLString, description: "String" };
413
455
  case "bigint":
414
456
  return { type: GraphQLBigIntString, description: "BigInt" };
@@ -559,10 +601,10 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
559
601
  queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
560
602
  };
561
603
  };
562
- var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
604
+ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
563
605
  const cols = (0, import_drizzle_orm3.getColumns)(targetTable);
564
606
  const orderExprs = [
565
- ...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
607
+ ...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
566
608
  ...primaryKeyOrderExprs(targetTable, pkNames)
567
609
  ];
568
610
  const orderClause = orderExprs.length ? import_drizzle_orm3.sql` order by ${import_drizzle_orm3.sql.join(orderExprs, import_drizzle_orm3.sql`, `)}` : import_drizzle_orm3.sql``;
@@ -626,12 +668,13 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
626
668
  orderByArg,
627
669
  limit ?? null,
628
670
  offset ?? null,
629
- targetPkNames
671
+ targetPkNames,
672
+ relationFilterCtx(filterCtx, targetTableName)
630
673
  );
631
674
  } else {
632
675
  let q = executor.select().from(targetTable).where(whereCondition);
633
676
  if (orderByArg) {
634
- q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
677
+ q = q.orderBy(...extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)));
635
678
  }
636
679
  rows = await q;
637
680
  }
@@ -720,6 +763,20 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
720
763
  }
721
764
  return Object.fromEntries(selectedColumns);
722
765
  };
766
+ var orderNulls = new import_graphql4.GraphQLEnumType({
767
+ name: "OrderNulls",
768
+ description: "Where NULL values sort relative to non-NULL values",
769
+ values: {
770
+ first: {
771
+ value: "first",
772
+ description: "NULL values sort before all non-NULL values"
773
+ },
774
+ last: {
775
+ value: "last",
776
+ description: "NULL values sort after all non-NULL values"
777
+ }
778
+ }
779
+ });
723
780
  var innerOrder = new import_graphql4.GraphQLInputObjectType({
724
781
  name: "InnerOrder",
725
782
  fields: {
@@ -744,6 +801,10 @@ var innerOrder = new import_graphql4.GraphQLInputObjectType({
744
801
  priority: {
745
802
  type: new import_graphql4.GraphQLNonNull(import_graphql4.GraphQLInt),
746
803
  description: "Priority of current field"
804
+ },
805
+ nulls: {
806
+ type: orderNulls,
807
+ description: "Where NULL values sort. Defaults to the database's own rule (PostgreSQL: last on asc, first on desc; MySQL/SQLite: first on asc, last on desc)"
747
808
  }
748
809
  }
749
810
  });
@@ -757,9 +818,25 @@ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
757
818
  if (columnGraphQLType.type instanceof import_graphql4.GraphQLEnumType) {
758
819
  return columnGraphQLType.type.name;
759
820
  }
821
+ if (columnGraphQLType.type === GraphQLBigIntString) {
822
+ return "BigInt";
823
+ }
824
+ if (columnGraphQLType.type === GraphQLDecimalString) {
825
+ return "Decimal";
826
+ }
760
827
  if (columnGraphQLType.type instanceof import_graphql4.GraphQLList) {
761
828
  const desc2 = columnGraphQLType.description ?? "";
762
- return desc2.includes("Integer") ? "IntArray" : "FloatArray";
829
+ let inner = columnGraphQLType.type.ofType;
830
+ if (inner instanceof import_graphql4.GraphQLNonNull) {
831
+ inner = inner.ofType;
832
+ }
833
+ if (desc2.includes("Integer") || inner === import_graphql4.GraphQLInt) {
834
+ return "IntArray";
835
+ }
836
+ if (desc2.includes("Float") || inner === import_graphql4.GraphQLFloat) {
837
+ return "FloatArray";
838
+ }
839
+ return "StringArray";
763
840
  }
764
841
  const ct = column.columnType ?? "";
765
842
  if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
@@ -772,12 +849,12 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
772
849
  const genericName = resolveGenericFilterName(column, columnName, columnGraphQLType);
773
850
  const cached = cacheCtx.genericFilterCache.get(genericName);
774
851
  if (cached) {
775
- return cached.main;
852
+ return cached;
776
853
  }
777
854
  const colType = columnGraphQLType.type;
778
855
  const colDesc = columnGraphQLType.description;
779
856
  const colArr = new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(colType));
780
- const isId = genericName === "Id";
857
+ const omitStringOps = genericName === "Id" || genericName === "BigInt" || genericName === "Decimal";
781
858
  const baseFields = {
782
859
  eq: { type: colType, description: colDesc },
783
860
  ne: { type: colType, description: colDesc },
@@ -785,31 +862,60 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
785
862
  lte: { type: colType, description: colDesc },
786
863
  gt: { type: colType, description: colDesc },
787
864
  gte: { type: colType, description: colDesc },
788
- ...isId ? {} : {
865
+ ...omitStringOps ? {} : {
789
866
  like: { type: import_graphql4.GraphQLString },
790
867
  notLike: { type: import_graphql4.GraphQLString },
791
868
  ilike: { type: import_graphql4.GraphQLString },
792
- notIlike: { type: import_graphql4.GraphQLString }
869
+ notIlike: { type: import_graphql4.GraphQLString },
870
+ startsWith: {
871
+ type: import_graphql4.GraphQLString,
872
+ description: "Matches values starting with the given string. `%`, `_` and `\\` are matched literally."
873
+ },
874
+ endsWith: {
875
+ type: import_graphql4.GraphQLString,
876
+ description: "Matches values ending with the given string. `%`, `_` and `\\` are matched literally."
877
+ },
878
+ contains: {
879
+ type: import_graphql4.GraphQLString,
880
+ description: "Matches values containing the given string. `%`, `_` and `\\` are matched literally."
881
+ },
882
+ iStartsWith: {
883
+ type: import_graphql4.GraphQLString,
884
+ description: "Case-insensitive `startsWith`."
885
+ },
886
+ iEndsWith: {
887
+ type: import_graphql4.GraphQLString,
888
+ description: "Case-insensitive `endsWith`."
889
+ },
890
+ iContains: {
891
+ type: import_graphql4.GraphQLString,
892
+ description: "Case-insensitive `contains`."
893
+ }
793
894
  },
794
895
  inArray: { type: colArr, description: `Array<${colDesc}>` },
795
896
  notInArray: { type: colArr, description: `Array<${colDesc}>` },
796
897
  isNull: { type: import_graphql4.GraphQLBoolean },
797
898
  isNotNull: { type: import_graphql4.GraphQLBoolean }
798
899
  };
799
- const orType = new import_graphql4.GraphQLInputObjectType({
800
- name: `${genericName}FilterOr`,
801
- fields: { ...baseFields }
802
- });
803
900
  const mainType = new import_graphql4.GraphQLInputObjectType({
804
901
  name: `${genericName}Filter`,
805
- fields: {
902
+ fields: () => ({
806
903
  ...baseFields,
807
904
  OR: {
808
- type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(orType))
905
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(mainType)),
906
+ description: "At least one branch matches; ANDed with any sibling operators"
907
+ },
908
+ AND: {
909
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(mainType)),
910
+ description: "Every branch matches"
911
+ },
912
+ NOT: {
913
+ type: mainType,
914
+ description: "Negates the nested operators"
809
915
  }
810
- }
916
+ })
811
917
  });
812
- cacheCtx.genericFilterCache.set(genericName, { main: mainType, or: orType });
918
+ cacheCtx.genericFilterCache.set(genericName, mainType);
813
919
  return mainType;
814
920
  };
815
921
  var orderMap = /* @__PURE__ */ new WeakMap();
@@ -863,19 +969,53 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
863
969
  fieldMap.set(table, remapped);
864
970
  return remapped;
865
971
  };
866
- var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx) => {
972
+ var isFilterableRelation = (relation) => !relation.through;
973
+ var generateRelationOrderFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
974
+ const relations = relationMap?.[tableName];
975
+ if (!relations || !tables) {
976
+ return {};
977
+ }
978
+ const fields = {};
979
+ for (const [relationName, relEntry] of Object.entries(relations)) {
980
+ if (relationName in columnFields) {
981
+ continue;
982
+ }
983
+ const targetTable = tables[relEntry.targetTableName];
984
+ const relation = relEntry.relation ?? relEntry;
985
+ if (!targetTable || !(0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) || !isFilterableRelation(relation)) {
986
+ continue;
987
+ }
988
+ fields[relationName] = {
989
+ type: generateTableOrderTypeCached(
990
+ targetTable,
991
+ relEntry.targetTableName,
992
+ typeNameMapper,
993
+ cacheCtx,
994
+ relationMap,
995
+ tables
996
+ ),
997
+ description: `Order by columns of the related ${relationName} row`
998
+ };
999
+ }
1000
+ return fields;
1001
+ };
1002
+ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx, relationMap, tables) => {
867
1003
  if (cacheCtx.orderTypeCache.has(table)) {
868
1004
  return cacheCtx.orderTypeCache.get(table);
869
1005
  }
870
- const orderColumns = generateTableOrderCached(table);
871
1006
  const order = new import_graphql4.GraphQLInputObjectType({
872
1007
  name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
873
- fields: orderColumns
1008
+ fields: () => {
1009
+ const orderColumns = generateTableOrderCached(table);
1010
+ return {
1011
+ ...orderColumns,
1012
+ ...generateRelationOrderFields(tableName, cacheCtx, typeNameMapper, orderColumns, relationMap, tables)
1013
+ };
1014
+ }
874
1015
  });
875
1016
  cacheCtx.orderTypeCache.set(table, order);
876
1017
  return order;
877
1018
  };
878
- var isFilterableRelation = (relation) => !relation.through;
879
1019
  var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
880
1020
  const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
881
1021
  if (cached) {
@@ -914,7 +1054,7 @@ var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnF
914
1054
  }
915
1055
  const targetTable = tables[relEntry.targetTableName];
916
1056
  const relation = relEntry.relation ?? relEntry;
917
- if (!targetTable || !isFilterableRelation(relation)) {
1057
+ if (!targetTable) {
918
1058
  continue;
919
1059
  }
920
1060
  fields[relationName] = (0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) ? {
@@ -951,16 +1091,21 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
951
1091
  ...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
952
1092
  };
953
1093
  };
954
- const orFilters = new import_graphql4.GraphQLInputObjectType({
955
- name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
956
- fields: buildFields
957
- });
958
1094
  const filters = new import_graphql4.GraphQLInputObjectType({
959
1095
  name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
960
1096
  fields: () => ({
961
1097
  ...buildFields(),
962
1098
  OR: {
963
- type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(orFilters))
1099
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(filters)),
1100
+ description: "At least one branch matches; ANDed with any sibling fields"
1101
+ },
1102
+ AND: {
1103
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(filters)),
1104
+ description: "Every branch matches"
1105
+ },
1106
+ NOT: {
1107
+ type: filters,
1108
+ description: "Negates the nested filters"
964
1109
  }
965
1110
  })
966
1111
  });
@@ -969,7 +1114,7 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
969
1114
  };
970
1115
  var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
971
1116
  const table = tables[tableName];
972
- const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
1117
+ const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx, relationMap, tables) : void 0;
973
1118
  const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
974
1119
  const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
975
1120
  const relationsForTable = relationMap[tableName];
@@ -1055,10 +1200,11 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1055
1200
  }
1056
1201
  const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
1057
1202
  if (isOne) {
1203
+ const isRequired = relation.optional === false;
1058
1204
  rawRelationFields.push([
1059
1205
  relationName,
1060
1206
  {
1061
- type: relType,
1207
+ type: isRequired ? new import_graphql4.GraphQLNonNull(relType) : relType,
1062
1208
  args: {
1063
1209
  where: { type: relSelectData.filters }
1064
1210
  },
@@ -1196,28 +1342,95 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
1196
1342
  outputs
1197
1343
  };
1198
1344
  };
1199
- var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => [column, config.direction]);
1200
- var extractOrderBy = (table, orderArgs) => orderByEntries(orderArgs).map(
1201
- ([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)((0, import_drizzle_orm3.getColumns)(table)[column]) : (0, import_drizzle_orm3.desc)((0, import_drizzle_orm3.getColumns)(table)[column])
1202
- );
1203
- var extractFiltersColumn = (column, columnName, operators) => {
1204
- if (!operators.OR?.length) {
1205
- delete operators.OR;
1345
+ var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => {
1346
+ if (typeof config === "object" && config.direction === void 0) {
1347
+ throw new import_graphql4.GraphQLError(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
1348
+ }
1349
+ return [column, config.direction, config.nulls ?? void 0];
1350
+ });
1351
+ var orderExpressions = (expr, direction, nulls, dialectColumn) => {
1352
+ const directed = direction === "asc" ? (0, import_drizzle_orm3.asc)(expr) : (0, import_drizzle_orm3.desc)(expr);
1353
+ if (!nulls) {
1354
+ return [directed];
1206
1355
  }
1207
- const entries = Object.entries(operators);
1208
- if (operators.OR) {
1209
- if (entries.length > 1) {
1210
- throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
1356
+ const isMySql = (dialectColumn.columnType ?? "").startsWith("MySql");
1357
+ if (isMySql) {
1358
+ const nullsKey = nulls === "first" ? (0, import_drizzle_orm3.desc)(import_drizzle_orm3.sql`(${expr} is null)`) : (0, import_drizzle_orm3.asc)(import_drizzle_orm3.sql`(${expr} is null)`);
1359
+ return [nullsKey, directed];
1360
+ }
1361
+ return [nulls === "first" ? import_drizzle_orm3.sql`${directed} nulls first` : import_drizzle_orm3.sql`${directed} nulls last`];
1362
+ };
1363
+ var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain) => {
1364
+ const targetTable = ctx.tables[relEntry.targetTableName];
1365
+ const relation = relEntry.relation ?? relEntry;
1366
+ if (!targetTable || !(0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) || !isFilterableRelation(relation)) {
1367
+ throw new import_graphql4.GraphQLError(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
1368
+ }
1369
+ ctx.aliases ??= { n: 0 };
1370
+ const aliasedTarget = (0, import_drizzle_orm3.aliasedTable)(targetTable, `dgql_ord_${ctx.aliases.n++}`);
1371
+ const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1372
+ const relationWhere = relation.where ? (0, import_drizzle_orm3.relationsFilterToSQL)(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
1373
+ return {
1374
+ fromParts: [...chain?.fromParts ?? [], (0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)],
1375
+ conditions: [
1376
+ ...chain?.conditions ?? [],
1377
+ ...joinCondition ? [joinCondition] : [],
1378
+ ...relationWhere ? [relationWhere] : []
1379
+ ],
1380
+ table: aliasedTarget
1381
+ };
1382
+ };
1383
+ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
1384
+ const columns = (0, import_drizzle_orm3.getColumns)(table);
1385
+ const relations = ctx?.relationMap[tableKey];
1386
+ for (const [key, config] of Object.entries(orderArgs)) {
1387
+ if (config === null || config === void 0) {
1388
+ continue;
1211
1389
  }
1212
- const variants2 = [];
1213
- for (const variant of operators.OR) {
1214
- const extracted = extractFiltersColumn(column, columnName, variant);
1215
- if (extracted) {
1216
- variants2.push(extracted);
1217
- }
1390
+ const column = columns[key];
1391
+ if (column) {
1392
+ out.push({
1393
+ expression: chain ? import_drizzle_orm3.sql`(select ${column} from ${import_drizzle_orm3.sql.join(chain.fromParts, import_drizzle_orm3.sql`, `)} where ${(0, import_drizzle_orm3.and)(...chain.conditions)})` : column,
1394
+ column,
1395
+ direction: config.direction,
1396
+ nulls: config.nulls ?? void 0,
1397
+ priority: config.priority ?? 0
1398
+ });
1399
+ continue;
1400
+ }
1401
+ const relEntry = relations?.[key];
1402
+ if (!relEntry || !ctx) {
1403
+ throw new import_graphql4.GraphQLError(`ORDER BY ${key}: Unknown column or relation`);
1218
1404
  }
1219
- return variants2.length ? variants2.length > 1 ? (0, import_drizzle_orm3.or)(...variants2) : variants2[0] : void 0;
1405
+ const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
1406
+ collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
1220
1407
  }
1408
+ };
1409
+ var extractOrderBy = (table, orderArgs, ctx) => {
1410
+ const entries = [];
1411
+ collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries);
1412
+ return entries.sort((a, b) => b.priority - a.priority).flatMap((entry) => orderExpressions(entry.expression, entry.direction, entry.nulls, entry.column));
1413
+ };
1414
+ var LIKE_ESCAPE_CHAR = "\\";
1415
+ var escapeLikeValue = (value) => value.replace(/[\\%_]/g, (char) => `\\${char}`);
1416
+ var safeLikeOps = {
1417
+ startsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: false },
1418
+ endsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: false },
1419
+ contains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: false },
1420
+ iStartsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: true },
1421
+ iEndsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: true },
1422
+ iContains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: true }
1423
+ };
1424
+ var safeLikeCondition = (column, pattern, insensitive) => {
1425
+ if (!insensitive) {
1426
+ return import_drizzle_orm3.sql`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
1427
+ }
1428
+ const isPg = (column.columnType ?? "").startsWith("Pg");
1429
+ return isPg ? import_drizzle_orm3.sql`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : import_drizzle_orm3.sql`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
1430
+ };
1431
+ var extractFiltersColumn = (column, columnName, operators) => {
1432
+ const { OR, AND, NOT, ...restOperators } = operators;
1433
+ const entries = Object.entries(restOperators);
1221
1434
  const singleValueOps = { eq: import_drizzle_orm3.eq, ne: import_drizzle_orm3.ne, gt: import_drizzle_orm3.gt, gte: import_drizzle_orm3.gte, lt: import_drizzle_orm3.lt, lte: import_drizzle_orm3.lte };
1222
1435
  const stringValueOps = { like: import_drizzle_orm3.like, notLike: import_drizzle_orm3.notLike, ilike: import_drizzle_orm3.ilike, notIlike: import_drizzle_orm3.notIlike };
1223
1436
  const arrayValueOps = { inArray: import_drizzle_orm3.inArray, notInArray: import_drizzle_orm3.notInArray };
@@ -1232,6 +1445,9 @@ var extractFiltersColumn = (column, columnName, operators) => {
1232
1445
  variants.push(singleValueOps[operatorName](column, singleValue));
1233
1446
  } else if (operatorName in stringValueOps) {
1234
1447
  variants.push(stringValueOps[operatorName](column, operatorValue));
1448
+ } else if (operatorName in safeLikeOps) {
1449
+ const { buildPattern, insensitive } = safeLikeOps[operatorName];
1450
+ variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
1235
1451
  } else if (operatorName in arrayValueOps) {
1236
1452
  if (!operatorValue.length) {
1237
1453
  throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
@@ -1240,6 +1456,34 @@ var extractFiltersColumn = (column, columnName, operators) => {
1240
1456
  variants.push(arrayValueOps[operatorName](column, arrayValue));
1241
1457
  } else if (operatorName in nullableOps) {
1242
1458
  variants.push(nullableOps[operatorName](column));
1459
+ } else {
1460
+ throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
1461
+ }
1462
+ }
1463
+ if (AND?.length) {
1464
+ for (const variant of AND) {
1465
+ const extracted = extractFiltersColumn(column, columnName, variant);
1466
+ if (extracted) {
1467
+ variants.push(extracted);
1468
+ }
1469
+ }
1470
+ }
1471
+ if (NOT) {
1472
+ const extracted = extractFiltersColumn(column, columnName, NOT);
1473
+ if (extracted) {
1474
+ variants.push((0, import_drizzle_orm3.not)(extracted));
1475
+ }
1476
+ }
1477
+ if (OR?.length) {
1478
+ const orVariants = [];
1479
+ for (const variant of OR) {
1480
+ const extracted = extractFiltersColumn(column, columnName, variant);
1481
+ if (extracted) {
1482
+ orVariants.push(extracted);
1483
+ }
1484
+ }
1485
+ if (orVariants.length) {
1486
+ variants.push(orVariants.length > 1 ? (0, import_drizzle_orm3.or)(...orVariants) : orVariants[0]);
1243
1487
  }
1244
1488
  }
1245
1489
  return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
@@ -1264,39 +1508,105 @@ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relation
1264
1508
  }
1265
1509
  return conditions.length > 1 ? (0, import_drizzle_orm3.and)(...conditions) : conditions[0];
1266
1510
  };
1511
+ var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
1512
+ const throughColumns = (0, import_drizzle_orm3.getColumns)(aliasedThrough);
1513
+ const key = junctionRef?._?.key;
1514
+ const byKey = key ? throughColumns[key] : void 0;
1515
+ if (byKey) {
1516
+ return byKey;
1517
+ }
1518
+ const columnName = junctionRef?._?.column?.name;
1519
+ const byName = columnName ? Object.values(throughColumns).find((c) => c.name === columnName) : void 0;
1520
+ if (!byName) {
1521
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1522
+ }
1523
+ return byName;
1524
+ };
1525
+ var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliasedTarget, relationName) => {
1526
+ const sourceColumns = relation.sourceColumns;
1527
+ const targetColumns = relation.targetColumns;
1528
+ const through = relation.through;
1529
+ if (!sourceColumns?.length || !targetColumns?.length || through?.source.length !== sourceColumns.length || through.target.length !== targetColumns.length) {
1530
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1531
+ }
1532
+ const parentColumns = Object.values((0, import_drizzle_orm3.getColumns)(parentTable));
1533
+ const targetTableColumns = Object.values((0, import_drizzle_orm3.getColumns)(aliasedTarget));
1534
+ const correlationConditions = [];
1535
+ for (let i = 0; i < sourceColumns.length; i++) {
1536
+ const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
1537
+ if (!localColumn) {
1538
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1539
+ }
1540
+ correlationConditions.push((0, import_drizzle_orm3.eq)(localColumn, resolveJunctionColumn(aliasedThrough, through.source[i], relationName)));
1541
+ }
1542
+ const junctionJoinConditions = [];
1543
+ for (let i = 0; i < targetColumns.length; i++) {
1544
+ const foreignColumn = targetTableColumns.find((c) => c.name === targetColumns[i].name);
1545
+ if (!foreignColumn) {
1546
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1547
+ }
1548
+ junctionJoinConditions.push(
1549
+ (0, import_drizzle_orm3.eq)(resolveJunctionColumn(aliasedThrough, through.target[i], relationName), foreignColumn)
1550
+ );
1551
+ }
1552
+ return {
1553
+ correlation: correlationConditions.length > 1 ? (0, import_drizzle_orm3.and)(...correlationConditions) : correlationConditions[0],
1554
+ junctionJoin: junctionJoinConditions.length > 1 ? (0, import_drizzle_orm3.and)(...junctionJoinConditions) : junctionJoinConditions[0]
1555
+ };
1556
+ };
1267
1557
  var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
1268
1558
  const { targetTableName } = relEntry;
1269
1559
  const targetTable = ctx.tables[targetTableName];
1270
1560
  const relation = relEntry.relation ?? relEntry;
1271
- if (!targetTable || !isFilterableRelation(relation)) {
1561
+ if (!targetTable) {
1272
1562
  throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1273
1563
  }
1274
1564
  ctx.aliases ??= { n: 0 };
1275
1565
  const aliases = ctx.aliases;
1276
1566
  const aliasedTarget = (0, import_drizzle_orm3.aliasedTable)(targetTable, `dgql_rel_${aliases.n++}`);
1277
- const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1567
+ const throughTable = relation.throughTable;
1568
+ let fromClause;
1569
+ let joinCondition;
1570
+ if (throughTable) {
1571
+ const aliasedThrough = (0, import_drizzle_orm3.aliasedTable)(throughTable, `dgql_rel_${aliases.n++}`);
1572
+ const { correlation, junctionJoin } = buildThroughJoinConditions(
1573
+ parentTable,
1574
+ relation,
1575
+ aliasedThrough,
1576
+ aliasedTarget,
1577
+ relationName
1578
+ );
1579
+ fromClause = import_drizzle_orm3.sql`${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} inner join ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedThrough)} on ${junctionJoin}`;
1580
+ joinCondition = correlation;
1581
+ } else {
1582
+ fromClause = (0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget);
1583
+ joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1584
+ }
1278
1585
  const relationWhere = relation.where ? (0, import_drizzle_orm3.relationsFilterToSQL)(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
1279
1586
  const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
1280
1587
  if (mode === "every") {
1281
1588
  if (!inner) {
1282
1589
  return void 0;
1283
1590
  }
1284
- return import_drizzle_orm3.sql`not exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${(0, import_drizzle_orm3.and)(joinCondition, relationWhere, (0, import_drizzle_orm3.not)(inner))})`;
1591
+ return import_drizzle_orm3.sql`not exists (select 1 from ${fromClause} where ${(0, import_drizzle_orm3.and)(joinCondition, relationWhere, (0, import_drizzle_orm3.not)(inner))})`;
1285
1592
  }
1286
1593
  const condition = (0, import_drizzle_orm3.and)(joinCondition, relationWhere, inner);
1287
- return mode === "none" ? import_drizzle_orm3.sql`not exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${condition})` : import_drizzle_orm3.sql`exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${condition})`;
1594
+ return mode === "none" ? import_drizzle_orm3.sql`not exists (select 1 from ${fromClause} where ${condition})` : import_drizzle_orm3.sql`exists (select 1 from ${fromClause} where ${condition})`;
1288
1595
  };
1289
1596
  var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
1290
1597
  const relation = relEntry.relation ?? relEntry;
1291
1598
  if ((0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One)) {
1292
1599
  return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
1293
1600
  }
1601
+ const relationMatchModes = ["some", "none", "every"];
1294
1602
  const variants = [];
1295
- for (const mode of ["some", "none", "every"]) {
1296
- const inner = value[mode];
1603
+ for (const [mode, inner] of Object.entries(value)) {
1297
1604
  if (inner === void 0 || inner === null) {
1298
1605
  continue;
1299
1606
  }
1607
+ if (!relationMatchModes.includes(mode)) {
1608
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
1609
+ }
1300
1610
  const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
1301
1611
  if (extracted) {
1302
1612
  variants.push(extracted);
@@ -1305,26 +1615,8 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
1305
1615
  return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
1306
1616
  };
1307
1617
  var extractFilters = (table, tableName, filters, relationCtx) => {
1308
- if (!filters.OR?.length) {
1309
- delete filters.OR;
1310
- }
1311
- const entries = Object.entries(filters);
1312
- if (!entries.length) {
1313
- return;
1314
- }
1315
- if (filters.OR) {
1316
- if (entries.length > 1) {
1317
- throw new import_graphql4.GraphQLError(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
1318
- }
1319
- const variants2 = [];
1320
- for (const variant of filters.OR) {
1321
- const extracted = extractFilters(table, tableName, variant, relationCtx);
1322
- if (extracted) {
1323
- variants2.push(extracted);
1324
- }
1325
- }
1326
- return variants2.length ? variants2.length > 1 ? (0, import_drizzle_orm3.or)(...variants2) : variants2[0] : void 0;
1327
- }
1618
+ const { OR, AND, NOT, ...fieldFilters } = filters;
1619
+ const entries = Object.entries(fieldFilters);
1328
1620
  const columns = (0, import_drizzle_orm3.getColumns)(table);
1329
1621
  const relations = relationCtx?.relationMap[relationCtx.tableKey];
1330
1622
  const variants = [];
@@ -1333,11 +1625,40 @@ var extractFilters = (table, tableName, filters, relationCtx) => {
1333
1625
  continue;
1334
1626
  }
1335
1627
  const column = columns[fieldName];
1336
- const extracted = column ? extractFiltersColumn(column, fieldName, operators) : relations?.[fieldName] && relationCtx ? extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx) : void 0;
1628
+ if (!column && !(relations?.[fieldName] && relationCtx)) {
1629
+ throw new import_graphql4.GraphQLError(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
1630
+ }
1631
+ const extracted = column ? extractFiltersColumn(column, fieldName, operators) : extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx);
1337
1632
  if (extracted) {
1338
1633
  variants.push(extracted);
1339
1634
  }
1340
1635
  }
1636
+ if (AND?.length) {
1637
+ for (const variant of AND) {
1638
+ const extracted = extractFilters(table, tableName, variant, relationCtx);
1639
+ if (extracted) {
1640
+ variants.push(extracted);
1641
+ }
1642
+ }
1643
+ }
1644
+ if (NOT) {
1645
+ const extracted = extractFilters(table, tableName, NOT, relationCtx);
1646
+ if (extracted) {
1647
+ variants.push((0, import_drizzle_orm3.not)(extracted));
1648
+ }
1649
+ }
1650
+ if (OR?.length) {
1651
+ const orVariants = [];
1652
+ for (const variant of OR) {
1653
+ const extracted = extractFilters(table, tableName, variant, relationCtx);
1654
+ if (extracted) {
1655
+ orVariants.push(extracted);
1656
+ }
1657
+ }
1658
+ if (orVariants.length) {
1659
+ variants.push(orVariants.length > 1 ? (0, import_drizzle_orm3.or)(...orVariants) : orVariants[0]);
1660
+ }
1661
+ }
1341
1662
  return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
1342
1663
  };
1343
1664
  var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
@@ -1379,7 +1700,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
1379
1700
  } : void 0;
1380
1701
  const hasPagination = offset != null || limit != null;
1381
1702
  const pkNames = targetPkNames ?? [];
1382
- thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
1703
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName)) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
1383
1704
  thisRecord.offset = offset;
1384
1705
  thisRecord.limit = limit;
1385
1706
  const relWith = relationField ? extractRelationsParamsInner(
@@ -1620,7 +1941,9 @@ var selectDistinctKeys = async (params) => {
1620
1941
  }
1621
1942
  const orderEntries = orderBy ? orderByEntries(orderBy) : [];
1622
1943
  const windowOrder = [
1623
- ...orderEntries.map(([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)(cols[column]) : (0, import_drizzle_orm3.desc)(cols[column])),
1944
+ ...orderEntries.flatMap(
1945
+ ([column, direction, nulls]) => orderExpressions(cols[column], direction, nulls, cols[column])
1946
+ ),
1624
1947
  ...primaryKeyOrderExprs(table, pkNames)
1625
1948
  ];
1626
1949
  const rowNumber = import_drizzle_orm3.sql`row_number() over (partition by ${import_drizzle_orm3.sql.join(partitionCols, import_drizzle_orm3.sql`, `)} order by ${import_drizzle_orm3.sql.join(
@@ -1629,7 +1952,9 @@ var selectDistinctKeys = async (params) => {
1629
1952
  )})`.as(DISTINCT_RN);
1630
1953
  const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
1631
1954
  const outerOrder = [
1632
- ...orderEntries.map(([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)(sub[column]) : (0, import_drizzle_orm3.desc)(sub[column])),
1955
+ ...orderEntries.flatMap(
1956
+ ([column, direction, nulls]) => orderExpressions(sub[column], direction, nulls, cols[column])
1957
+ ),
1633
1958
  ...pkNames.filter((name) => sub[name]).map((name) => (0, import_drizzle_orm3.asc)(sub[name]))
1634
1959
  ];
1635
1960
  let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where((0, import_drizzle_orm3.eq)(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
@@ -1728,6 +2053,9 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1728
2053
  const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
1729
2054
  const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1730
2055
  const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2056
+ const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
2057
+ const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
2058
+ const deleteSingleFieldName = `${deleteFieldName}${writeSingleSuffix}`;
1731
2059
  return {
1732
2060
  typeName,
1733
2061
  listFieldName,
@@ -1739,9 +2067,24 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1739
2067
  upsertArrayFieldName,
1740
2068
  upsertSingleFieldName,
1741
2069
  updateFieldName,
1742
- deleteFieldName
2070
+ updateSingleFieldName,
2071
+ deleteFieldName,
2072
+ deleteSingleFieldName
1743
2073
  };
1744
2074
  };
2075
+ var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
2076
+ const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2077
+ if (!filters) {
2078
+ throw new import_graphql4.GraphQLError(`${fieldName} requires a 'where' argument with at least one filter!`);
2079
+ }
2080
+ return filters;
2081
+ };
2082
+ var assertSingleMatch = async (executor, table, filters, fieldName) => {
2083
+ const matched = await executor.select({ found: import_drizzle_orm3.sql`1` }).from(table).where(filters).limit(2);
2084
+ if (matched.length > 1) {
2085
+ throw new import_graphql4.GraphQLError(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
2086
+ }
2087
+ };
1745
2088
  var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
1746
2089
  offset: { type: import_graphql4.GraphQLInt },
1747
2090
  limit: { type: import_graphql4.GraphQLInt },
@@ -1800,9 +2143,9 @@ var runRelationalSelect = async (opts) => {
1800
2143
  // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
1801
2144
  // directly so column refs match the CTE alias.
1802
2145
  orderBy: distinctKeys ? (aliasedTable2) => [
1803
- ...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
2146
+ ...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : [],
1804
2147
  ...primaryKeyOrderExprs(aliasedTable2, pkNames)
1805
- ] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
2148
+ ] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
1806
2149
  where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
1807
2150
  RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
1808
2151
  } : void 0,
@@ -2493,13 +2836,13 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
2493
2836
  args: queryArgs
2494
2837
  };
2495
2838
  };
2496
- var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
2839
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
2497
2840
  const queryArgs = {
2498
2841
  set: {
2499
2842
  type: new import_graphql6.GraphQLNonNull(setArgs)
2500
2843
  },
2501
2844
  where: {
2502
- type: filterArgs
2845
+ type: single || requireWhere ? new import_graphql6.GraphQLNonNull(filterArgs) : filterArgs
2503
2846
  }
2504
2847
  };
2505
2848
  return {
@@ -2511,10 +2854,14 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
2511
2854
  if (!Object.keys(input).length) {
2512
2855
  throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
2513
2856
  }
2857
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
2858
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2514
2859
  const executor = resolveExecutor(db, context);
2860
+ if (single) {
2861
+ await assertSingleMatch(executor, table, filters, fieldName);
2862
+ }
2515
2863
  let query = executor.update(table).set(input);
2516
- if (where) {
2517
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2864
+ if (filters) {
2518
2865
  query = query.where(filters);
2519
2866
  }
2520
2867
  await query;
@@ -2526,10 +2873,10 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
2526
2873
  args: queryArgs
2527
2874
  };
2528
2875
  };
2529
- var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
2876
+ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
2530
2877
  const queryArgs = {
2531
2878
  where: {
2532
- type: filterArgs
2879
+ type: single || requireWhere ? new import_graphql6.GraphQLNonNull(filterArgs) : filterArgs
2533
2880
  }
2534
2881
  };
2535
2882
  return {
@@ -2537,10 +2884,14 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) =>
2537
2884
  resolver: async (_source, args, context, _info) => {
2538
2885
  try {
2539
2886
  const { where } = args;
2887
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
2888
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2540
2889
  const executor = resolveExecutor(db, context);
2890
+ if (single) {
2891
+ await assertSingleMatch(executor, table, filters, fieldName);
2892
+ }
2541
2893
  let query = executor.delete(table);
2542
- if (where) {
2543
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2894
+ if (filters) {
2544
2895
  query = query.where(filters);
2545
2896
  }
2546
2897
  await query;
@@ -2629,7 +2980,9 @@ var generateSchemaData = (db, schema, relations, options) => {
2629
2980
  upsertArrayFieldName,
2630
2981
  upsertSingleFieldName,
2631
2982
  updateFieldName,
2632
- deleteFieldName
2983
+ updateSingleFieldName,
2984
+ deleteFieldName,
2985
+ deleteSingleFieldName
2633
2986
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
2634
2987
  const selectArrGenerated = generateSelectArray(
2635
2988
  db,
@@ -2674,9 +3027,41 @@ var generateSchemaData = (db, schema, relations, options) => {
2674
3027
  updateInput,
2675
3028
  tableFilters,
2676
3029
  updateFieldName,
3030
+ false,
3031
+ features.requireWhere,
3032
+ filterCtx
3033
+ ) : void 0;
3034
+ const updateSingleGenerated = features.update ? generateUpdate(
3035
+ db,
3036
+ tableName,
3037
+ schema[tableName],
3038
+ updateInput,
3039
+ tableFilters,
3040
+ updateSingleFieldName,
3041
+ true,
3042
+ features.requireWhere,
3043
+ filterCtx
3044
+ ) : void 0;
3045
+ const deleteGenerated = features.delete ? generateDelete(
3046
+ db,
3047
+ tableName,
3048
+ schema[tableName],
3049
+ tableFilters,
3050
+ deleteFieldName,
3051
+ false,
3052
+ features.requireWhere,
3053
+ filterCtx
3054
+ ) : void 0;
3055
+ const deleteSingleGenerated = features.delete ? generateDelete(
3056
+ db,
3057
+ tableName,
3058
+ schema[tableName],
3059
+ tableFilters,
3060
+ deleteSingleFieldName,
3061
+ true,
3062
+ features.requireWhere,
2677
3063
  filterCtx
2678
3064
  ) : void 0;
2679
- const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
2680
3065
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
2681
3066
  const aggregateGenerated = features.aggregates ? generateAggregate(
2682
3067
  db,
@@ -2734,7 +3119,9 @@ var generateSchemaData = (db, schema, relations, options) => {
2734
3119
  upsertArrGenerated,
2735
3120
  upsertSingleGenerated,
2736
3121
  updateGenerated,
2737
- deleteGenerated
3122
+ updateSingleGenerated,
3123
+ deleteGenerated,
3124
+ deleteSingleGenerated
2738
3125
  ]) {
2739
3126
  if (generated) {
2740
3127
  mutations[generated.name] = {
@@ -2850,7 +3237,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
2850
3237
  }
2851
3238
  if (orderBy) {
2852
3239
  q = q.orderBy(
2853
- ...extractOrderBy(table, orderBy),
3240
+ ...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)),
2854
3241
  ...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
2855
3242
  );
2856
3243
  } else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
@@ -2911,7 +3298,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
2911
3298
  q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
2912
3299
  }
2913
3300
  if (orderBy) {
2914
- q = q.orderBy(...extractOrderBy(table, orderBy));
3301
+ q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)));
2915
3302
  } else if (pkNames.length) {
2916
3303
  q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
2917
3304
  }
@@ -3071,13 +3458,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3071
3458
  args: queryArgs
3072
3459
  };
3073
3460
  };
3074
- var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
3461
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
3075
3462
  const queryArgs = {
3076
3463
  set: {
3077
3464
  type: new import_graphql7.GraphQLNonNull(setArgs)
3078
3465
  },
3079
3466
  where: {
3080
- type: filterArgs
3467
+ type: single || requireWhere ? new import_graphql7.GraphQLNonNull(filterArgs) : filterArgs
3081
3468
  }
3082
3469
  };
3083
3470
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -3103,16 +3490,26 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3103
3490
  if (!Object.keys(input).length) {
3104
3491
  throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
3105
3492
  }
3493
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3494
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3106
3495
  const executor = resolveExecutor(db, context);
3496
+ if (single) {
3497
+ await assertSingleMatch(executor, table, filters, fieldName);
3498
+ }
3107
3499
  let query = executor.update(table).set(input);
3108
- if (where) {
3109
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
3500
+ if (filters) {
3110
3501
  query = query.where(filters);
3111
3502
  }
3112
3503
  query = query.returning(columns);
3113
3504
  const result = await query;
3505
+ if (single && result.length > 1) {
3506
+ throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
3507
+ }
3508
+ if (single && !result[0]) {
3509
+ return void 0;
3510
+ }
3114
3511
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3115
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3512
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3116
3513
  } catch (e) {
3117
3514
  throw toGraphQLError(e);
3118
3515
  }
@@ -3120,10 +3517,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3120
3517
  args: queryArgs
3121
3518
  };
3122
3519
  };
3123
- var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
3520
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
3124
3521
  const queryArgs = {
3125
3522
  where: {
3126
- type: filterArgs
3523
+ type: single || requireWhere ? new import_graphql7.GraphQLNonNull(filterArgs) : filterArgs
3127
3524
  }
3128
3525
  };
3129
3526
  return {
@@ -3139,14 +3536,24 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, fi
3139
3536
  table,
3140
3537
  selectionCtx
3141
3538
  );
3539
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3540
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3142
3541
  const executor = resolveExecutor(db, context);
3542
+ if (single) {
3543
+ await assertSingleMatch(executor, table, filters, fieldName);
3544
+ }
3143
3545
  let query = executor.delete(table);
3144
- if (where) {
3145
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
3546
+ if (filters) {
3146
3547
  query = query.where(filters);
3147
3548
  }
3148
3549
  query = query.returning(columns);
3149
3550
  const result = await query;
3551
+ if (single && result.length > 1) {
3552
+ throw new import_graphql7.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
3553
+ }
3554
+ if (single) {
3555
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
3556
+ }
3150
3557
  return remapToGraphQLArrayOutput(result, tableName, table);
3151
3558
  } catch (e) {
3152
3559
  throw toGraphQLError(e);
@@ -3228,7 +3635,9 @@ function generateSchemaData2(db, schema, relations, options) {
3228
3635
  upsertArrayFieldName,
3229
3636
  upsertSingleFieldName,
3230
3637
  updateFieldName,
3231
- deleteFieldName
3638
+ updateSingleFieldName,
3639
+ deleteFieldName,
3640
+ deleteSingleFieldName
3232
3641
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
3233
3642
  const selectArrGenerated = generateSelectArray2(
3234
3643
  db,
@@ -3327,6 +3736,23 @@ function generateSchemaData2(db, schema, relations, options) {
3327
3736
  tableFilters,
3328
3737
  updateFieldName,
3329
3738
  typeName,
3739
+ false,
3740
+ features.requireWhere,
3741
+ typeNameMapper,
3742
+ filterCtx
3743
+ ) : void 0;
3744
+ const updateSingleGenerated = features.update ? generateUpdate2(
3745
+ db,
3746
+ tableName,
3747
+ schema[tableName],
3748
+ tables,
3749
+ eagerRelations,
3750
+ updateInput,
3751
+ tableFilters,
3752
+ updateSingleFieldName,
3753
+ typeName,
3754
+ true,
3755
+ features.requireWhere,
3330
3756
  typeNameMapper,
3331
3757
  filterCtx
3332
3758
  ) : void 0;
@@ -3337,6 +3763,20 @@ function generateSchemaData2(db, schema, relations, options) {
3337
3763
  tableFilters,
3338
3764
  deleteFieldName,
3339
3765
  typeName,
3766
+ false,
3767
+ features.requireWhere,
3768
+ filterCtx,
3769
+ { tableName, relationMap: namedRelations, tables }
3770
+ ) : void 0;
3771
+ const deleteSingleGenerated = features.delete ? generateDelete2(
3772
+ db,
3773
+ tableName,
3774
+ schema[tableName],
3775
+ tableFilters,
3776
+ deleteSingleFieldName,
3777
+ typeName,
3778
+ true,
3779
+ features.requireWhere,
3340
3780
  filterCtx,
3341
3781
  { tableName, relationMap: namedRelations, tables }
3342
3782
  ) : void 0;
@@ -3426,6 +3866,13 @@ function generateSchemaData2(db, schema, relations, options) {
3426
3866
  resolve: updateGenerated.resolver
3427
3867
  };
3428
3868
  }
3869
+ if (updateSingleGenerated) {
3870
+ mutations[updateSingleGenerated.name] = {
3871
+ type: singleTableItemOutput,
3872
+ args: updateSingleGenerated.args,
3873
+ resolve: updateSingleGenerated.resolver
3874
+ };
3875
+ }
3429
3876
  if (deleteGenerated) {
3430
3877
  mutations[deleteGenerated.name] = {
3431
3878
  type: arrTableItemOutput,
@@ -3433,6 +3880,13 @@ function generateSchemaData2(db, schema, relations, options) {
3433
3880
  resolve: deleteGenerated.resolver
3434
3881
  };
3435
3882
  }
3883
+ if (deleteSingleGenerated) {
3884
+ mutations[deleteSingleGenerated.name] = {
3885
+ type: singleTableItemOutput,
3886
+ args: deleteSingleGenerated.args,
3887
+ resolve: deleteSingleGenerated.resolver
3888
+ };
3889
+ }
3436
3890
  const activeInputs = [
3437
3891
  // The insert input types the upsert mutations too, so either feature keeps it.
3438
3892
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -3699,13 +4153,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
3699
4153
  args: queryArgs
3700
4154
  };
3701
4155
  };
3702
- var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
4156
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
3703
4157
  const queryArgs = {
3704
4158
  set: {
3705
4159
  type: new import_graphql8.GraphQLNonNull(setArgs)
3706
4160
  },
3707
4161
  where: {
3708
- type: filterArgs
4162
+ type: single || requireWhere ? new import_graphql8.GraphQLNonNull(filterArgs) : filterArgs
3709
4163
  }
3710
4164
  };
3711
4165
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -3731,16 +4185,26 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
3731
4185
  if (!Object.keys(input).length) {
3732
4186
  throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
3733
4187
  }
4188
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4189
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3734
4190
  const executor = resolveExecutor(db, context);
4191
+ if (single) {
4192
+ await assertSingleMatch(executor, table, filters, fieldName);
4193
+ }
3735
4194
  let query = executor.update(table).set(input);
3736
- if (where) {
3737
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
4195
+ if (filters) {
3738
4196
  query = query.where(filters);
3739
4197
  }
3740
4198
  query = query.returning(columns);
3741
4199
  const result = await query;
4200
+ if (single && result.length > 1) {
4201
+ throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4202
+ }
4203
+ if (single && !result[0]) {
4204
+ return void 0;
4205
+ }
3742
4206
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3743
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4207
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3744
4208
  } catch (e) {
3745
4209
  throw toGraphQLError(e);
3746
4210
  }
@@ -3748,10 +4212,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
3748
4212
  args: queryArgs
3749
4213
  };
3750
4214
  };
3751
- var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
4215
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
3752
4216
  const queryArgs = {
3753
4217
  where: {
3754
- type: filterArgs
4218
+ type: single || requireWhere ? new import_graphql8.GraphQLNonNull(filterArgs) : filterArgs
3755
4219
  }
3756
4220
  };
3757
4221
  return {
@@ -3767,14 +4231,24 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, fi
3767
4231
  table,
3768
4232
  selectionCtx
3769
4233
  );
4234
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4235
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3770
4236
  const executor = resolveExecutor(db, context);
4237
+ if (single) {
4238
+ await assertSingleMatch(executor, table, filters, fieldName);
4239
+ }
3771
4240
  let query = executor.delete(table);
3772
- if (where) {
3773
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
4241
+ if (filters) {
3774
4242
  query = query.where(filters);
3775
4243
  }
3776
4244
  query = query.returning(columns);
3777
4245
  const result = await query;
4246
+ if (single && result.length > 1) {
4247
+ throw new import_graphql8.GraphQLError(`${fieldName}: 'where' matched more than one row!`);
4248
+ }
4249
+ if (single) {
4250
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4251
+ }
3778
4252
  return remapToGraphQLArrayOutput(result, tableName, table);
3779
4253
  } catch (e) {
3780
4254
  throw toGraphQLError(e);
@@ -3857,7 +4331,9 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3857
4331
  upsertArrayFieldName,
3858
4332
  upsertSingleFieldName,
3859
4333
  updateFieldName,
3860
- deleteFieldName
4334
+ updateSingleFieldName,
4335
+ deleteFieldName,
4336
+ deleteSingleFieldName
3861
4337
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
3862
4338
  const selectArrGenerated = generateSelectArray3(
3863
4339
  db,
@@ -3956,6 +4432,23 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3956
4432
  tableFilters,
3957
4433
  updateFieldName,
3958
4434
  typeName,
4435
+ false,
4436
+ features.requireWhere,
4437
+ typeNameMapper,
4438
+ filterCtx
4439
+ ) : void 0;
4440
+ const updateSingleGenerated = features.update ? generateUpdate3(
4441
+ db,
4442
+ tableName,
4443
+ schema[tableName],
4444
+ tables,
4445
+ eagerRelations,
4446
+ updateInput,
4447
+ tableFilters,
4448
+ updateSingleFieldName,
4449
+ typeName,
4450
+ true,
4451
+ features.requireWhere,
3959
4452
  typeNameMapper,
3960
4453
  filterCtx
3961
4454
  ) : void 0;
@@ -3966,6 +4459,20 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3966
4459
  tableFilters,
3967
4460
  deleteFieldName,
3968
4461
  typeName,
4462
+ false,
4463
+ features.requireWhere,
4464
+ filterCtx,
4465
+ { tableName, relationMap: namedRelations, tables }
4466
+ ) : void 0;
4467
+ const deleteSingleGenerated = features.delete ? generateDelete3(
4468
+ db,
4469
+ tableName,
4470
+ schema[tableName],
4471
+ tableFilters,
4472
+ deleteSingleFieldName,
4473
+ typeName,
4474
+ true,
4475
+ features.requireWhere,
3969
4476
  filterCtx,
3970
4477
  { tableName, relationMap: namedRelations, tables }
3971
4478
  ) : void 0;
@@ -4055,6 +4562,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4055
4562
  resolve: updateGenerated.resolver
4056
4563
  };
4057
4564
  }
4565
+ if (updateSingleGenerated) {
4566
+ mutations[updateSingleGenerated.name] = {
4567
+ type: singleTableItemOutput,
4568
+ args: updateSingleGenerated.args,
4569
+ resolve: updateSingleGenerated.resolver
4570
+ };
4571
+ }
4058
4572
  if (deleteGenerated) {
4059
4573
  mutations[deleteGenerated.name] = {
4060
4574
  type: arrTableItemOutput,
@@ -4062,6 +4576,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4062
4576
  resolve: deleteGenerated.resolver
4063
4577
  };
4064
4578
  }
4579
+ if (deleteSingleGenerated) {
4580
+ mutations[deleteSingleGenerated.name] = {
4581
+ type: singleTableItemOutput,
4582
+ args: deleteSingleGenerated.args,
4583
+ resolve: deleteSingleGenerated.resolver
4584
+ };
4585
+ }
4065
4586
  const activeInputs = [
4066
4587
  // The insert input types the upsert mutations too, so either feature keeps it.
4067
4588
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -4130,7 +4651,8 @@ var buildSchema = (db, config) => {
4130
4651
  insert: config?.features?.insert ?? true,
4131
4652
  update: config?.features?.update ?? true,
4132
4653
  delete: config?.features?.delete ?? true,
4133
- upsert: config?.features?.upsert ?? false
4654
+ upsert: config?.features?.upsert ?? false,
4655
+ requireWhere: config?.features?.requireWhere ?? false
4134
4656
  };
4135
4657
  const complexityConfig = config?.complexity ?? true;
4136
4658
  const complexity = complexityConfig === false ? void 0 : {
@@ -4204,6 +4726,7 @@ var buildSchema = (db, config) => {
4204
4726
  GraphQLBigIntString,
4205
4727
  GraphQLDate,
4206
4728
  GraphQLDateTime,
4729
+ GraphQLDecimalString,
4207
4730
  GraphQLJSON,
4208
4731
  GraphQLUUID,
4209
4732
  buildSchema,