@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.js CHANGED
@@ -41,6 +41,7 @@ import {
41
41
  GraphQLBoolean as GraphQLBoolean2,
42
42
  GraphQLEnumType as GraphQLEnumType2,
43
43
  GraphQLError as GraphQLError3,
44
+ GraphQLFloat as GraphQLFloat2,
44
45
  GraphQLInputObjectType as GraphQLInputObjectType2,
45
46
  GraphQLInt as GraphQLInt2,
46
47
  GraphQLList as GraphQLList2,
@@ -293,23 +294,6 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
293
294
  return queryInput;
294
295
  };
295
296
 
296
- // src/util/type-converter/index.ts
297
- import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
298
- import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
299
- import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString, PgUUID } from "drizzle-orm/pg-core";
300
- import { SQLiteInteger } from "drizzle-orm/sqlite-core";
301
- import {
302
- GraphQLBoolean,
303
- GraphQLEnumType,
304
- GraphQLFloat,
305
- GraphQLInputObjectType,
306
- GraphQLInt,
307
- GraphQLList,
308
- GraphQLNonNull,
309
- GraphQLObjectType,
310
- GraphQLString
311
- } from "graphql";
312
-
313
297
  // src/util/scalars/index.ts
314
298
  import { GraphQLError as GraphQLError2, GraphQLScalarType, Kind } from "graphql";
315
299
  import { GraphQLDate, GraphQLDateTime, GraphQLJSON, GraphQLUUID } from "graphql-scalars";
@@ -348,8 +332,54 @@ var GraphQLBigIntString = new GraphQLScalarType({
348
332
  return asDecimalString(ast.value);
349
333
  }
350
334
  });
335
+ var numericStringPattern = /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;
336
+ var asNumericString = (value) => {
337
+ if (typeof value === "bigint") {
338
+ return value.toString();
339
+ }
340
+ if (typeof value === "number") {
341
+ if (!Number.isFinite(value)) {
342
+ throw new GraphQLError2(`Decimal cannot represent non-finite value: ${value}`);
343
+ }
344
+ return String(value);
345
+ }
346
+ if (typeof value === "string") {
347
+ if (!numericStringPattern.test(value)) {
348
+ throw new GraphQLError2(`Decimal cannot represent non-numeric value: "${value}"`);
349
+ }
350
+ return value;
351
+ }
352
+ throw new GraphQLError2(`Decimal cannot represent value: ${JSON.stringify(value)}`);
353
+ };
354
+ var GraphQLDecimalString = new GraphQLScalarType({
355
+ name: "Decimal",
356
+ description: "An arbitrary-precision decimal, transported as a numeric string so that values beyond JavaScript's double-precision range survive the round-trip intact.",
357
+ serialize: asNumericString,
358
+ parseValue: asNumericString,
359
+ parseLiteral: (ast) => {
360
+ if (ast.kind !== Kind.STRING && ast.kind !== Kind.INT && ast.kind !== Kind.FLOAT) {
361
+ throw new GraphQLError2(`Decimal cannot represent a ${ast.kind}`, { nodes: ast });
362
+ }
363
+ return asNumericString(ast.value);
364
+ }
365
+ });
351
366
 
352
367
  // src/util/type-converter/index.ts
368
+ import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
369
+ import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
370
+ import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString, PgUUID } from "drizzle-orm/pg-core";
371
+ import { SQLiteInteger } from "drizzle-orm/sqlite-core";
372
+ import {
373
+ GraphQLBoolean,
374
+ GraphQLEnumType,
375
+ GraphQLFloat,
376
+ GraphQLInputObjectType,
377
+ GraphQLInt,
378
+ GraphQLList,
379
+ GraphQLNonNull,
380
+ GraphQLObjectType,
381
+ GraphQLString
382
+ } from "graphql";
353
383
  var allowedNameChars = /^[a-zA-Z0-9_]+$/;
354
384
  var enumMap = /* @__PURE__ */ new WeakMap();
355
385
  var generateEnumCached = (column, columnName, tableName) => {
@@ -386,7 +416,7 @@ var geoXyInputType = new GraphQLInputObjectType({
386
416
  }
387
417
  });
388
418
  var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
389
- const { type: baseType } = extractExtendedColumnType(column);
419
+ const { type: baseType, constraint } = extractExtendedColumnType(column);
390
420
  switch (baseType) {
391
421
  case "boolean":
392
422
  return { type: GraphQLBoolean, description: "Boolean" };
@@ -405,6 +435,9 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
405
435
  if (column.enumValues?.length) {
406
436
  return { type: generateEnumCached(column, columnName, tableName) };
407
437
  }
438
+ if (constraint === "numeric" && !column.dimensions) {
439
+ return { type: GraphQLDecimalString, description: "Decimal" };
440
+ }
408
441
  if (column instanceof PgTimestamp || column instanceof PgTimestampString) {
409
442
  return { type: GraphQLDateTime, description: "DateTime" };
410
443
  }
@@ -414,6 +447,15 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
414
447
  if (column instanceof PgDateString) {
415
448
  return isInput ? { type: GraphQLString, description: "Date" } : { type: GraphQLDate, description: "Date" };
416
449
  }
450
+ {
451
+ const dims = column.dimensions;
452
+ if (dims !== void 0 && dims > 0) {
453
+ return {
454
+ type: new GraphQLList(new GraphQLNonNull(GraphQLString)),
455
+ description: "Array<String>"
456
+ };
457
+ }
458
+ }
417
459
  return { type: GraphQLString, description: "String" };
418
460
  case "bigint":
419
461
  return { type: GraphQLBigIntString, description: "BigInt" };
@@ -564,10 +606,10 @@ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
564
606
  queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
565
607
  };
566
608
  };
567
- var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
609
+ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
568
610
  const cols = getColumns(targetTable);
569
611
  const orderExprs = [
570
- ...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
612
+ ...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
571
613
  ...primaryKeyOrderExprs(targetTable, pkNames)
572
614
  ];
573
615
  const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
@@ -631,12 +673,13 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
631
673
  orderByArg,
632
674
  limit ?? null,
633
675
  offset ?? null,
634
- targetPkNames
676
+ targetPkNames,
677
+ relationFilterCtx(filterCtx, targetTableName)
635
678
  );
636
679
  } else {
637
680
  let q = executor.select().from(targetTable).where(whereCondition);
638
681
  if (orderByArg) {
639
- q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
682
+ q = q.orderBy(...extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)));
640
683
  }
641
684
  rows = await q;
642
685
  }
@@ -725,6 +768,20 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
725
768
  }
726
769
  return Object.fromEntries(selectedColumns);
727
770
  };
771
+ var orderNulls = new GraphQLEnumType2({
772
+ name: "OrderNulls",
773
+ description: "Where NULL values sort relative to non-NULL values",
774
+ values: {
775
+ first: {
776
+ value: "first",
777
+ description: "NULL values sort before all non-NULL values"
778
+ },
779
+ last: {
780
+ value: "last",
781
+ description: "NULL values sort after all non-NULL values"
782
+ }
783
+ }
784
+ });
728
785
  var innerOrder = new GraphQLInputObjectType2({
729
786
  name: "InnerOrder",
730
787
  fields: {
@@ -749,6 +806,10 @@ var innerOrder = new GraphQLInputObjectType2({
749
806
  priority: {
750
807
  type: new GraphQLNonNull2(GraphQLInt2),
751
808
  description: "Priority of current field"
809
+ },
810
+ nulls: {
811
+ type: orderNulls,
812
+ 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)"
752
813
  }
753
814
  }
754
815
  });
@@ -762,9 +823,25 @@ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
762
823
  if (columnGraphQLType.type instanceof GraphQLEnumType2) {
763
824
  return columnGraphQLType.type.name;
764
825
  }
826
+ if (columnGraphQLType.type === GraphQLBigIntString) {
827
+ return "BigInt";
828
+ }
829
+ if (columnGraphQLType.type === GraphQLDecimalString) {
830
+ return "Decimal";
831
+ }
765
832
  if (columnGraphQLType.type instanceof GraphQLList2) {
766
833
  const desc2 = columnGraphQLType.description ?? "";
767
- return desc2.includes("Integer") ? "IntArray" : "FloatArray";
834
+ let inner = columnGraphQLType.type.ofType;
835
+ if (inner instanceof GraphQLNonNull2) {
836
+ inner = inner.ofType;
837
+ }
838
+ if (desc2.includes("Integer") || inner === GraphQLInt2) {
839
+ return "IntArray";
840
+ }
841
+ if (desc2.includes("Float") || inner === GraphQLFloat2) {
842
+ return "FloatArray";
843
+ }
844
+ return "StringArray";
768
845
  }
769
846
  const ct = column.columnType ?? "";
770
847
  if (ct === "PgTimestamp" || ct === "PgTimestampString" || ct === "PgDate") {
@@ -777,12 +854,12 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
777
854
  const genericName = resolveGenericFilterName(column, columnName, columnGraphQLType);
778
855
  const cached = cacheCtx.genericFilterCache.get(genericName);
779
856
  if (cached) {
780
- return cached.main;
857
+ return cached;
781
858
  }
782
859
  const colType = columnGraphQLType.type;
783
860
  const colDesc = columnGraphQLType.description;
784
861
  const colArr = new GraphQLList2(new GraphQLNonNull2(colType));
785
- const isId = genericName === "Id";
862
+ const omitStringOps = genericName === "Id" || genericName === "BigInt" || genericName === "Decimal";
786
863
  const baseFields = {
787
864
  eq: { type: colType, description: colDesc },
788
865
  ne: { type: colType, description: colDesc },
@@ -790,31 +867,60 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
790
867
  lte: { type: colType, description: colDesc },
791
868
  gt: { type: colType, description: colDesc },
792
869
  gte: { type: colType, description: colDesc },
793
- ...isId ? {} : {
870
+ ...omitStringOps ? {} : {
794
871
  like: { type: GraphQLString2 },
795
872
  notLike: { type: GraphQLString2 },
796
873
  ilike: { type: GraphQLString2 },
797
- notIlike: { type: GraphQLString2 }
874
+ notIlike: { type: GraphQLString2 },
875
+ startsWith: {
876
+ type: GraphQLString2,
877
+ description: "Matches values starting with the given string. `%`, `_` and `\\` are matched literally."
878
+ },
879
+ endsWith: {
880
+ type: GraphQLString2,
881
+ description: "Matches values ending with the given string. `%`, `_` and `\\` are matched literally."
882
+ },
883
+ contains: {
884
+ type: GraphQLString2,
885
+ description: "Matches values containing the given string. `%`, `_` and `\\` are matched literally."
886
+ },
887
+ iStartsWith: {
888
+ type: GraphQLString2,
889
+ description: "Case-insensitive `startsWith`."
890
+ },
891
+ iEndsWith: {
892
+ type: GraphQLString2,
893
+ description: "Case-insensitive `endsWith`."
894
+ },
895
+ iContains: {
896
+ type: GraphQLString2,
897
+ description: "Case-insensitive `contains`."
898
+ }
798
899
  },
799
900
  inArray: { type: colArr, description: `Array<${colDesc}>` },
800
901
  notInArray: { type: colArr, description: `Array<${colDesc}>` },
801
902
  isNull: { type: GraphQLBoolean2 },
802
903
  isNotNull: { type: GraphQLBoolean2 }
803
904
  };
804
- const orType = new GraphQLInputObjectType2({
805
- name: `${genericName}FilterOr`,
806
- fields: { ...baseFields }
807
- });
808
905
  const mainType = new GraphQLInputObjectType2({
809
906
  name: `${genericName}Filter`,
810
- fields: {
907
+ fields: () => ({
811
908
  ...baseFields,
812
909
  OR: {
813
- type: new GraphQLList2(new GraphQLNonNull2(orType))
910
+ type: new GraphQLList2(new GraphQLNonNull2(mainType)),
911
+ description: "At least one branch matches; ANDed with any sibling operators"
912
+ },
913
+ AND: {
914
+ type: new GraphQLList2(new GraphQLNonNull2(mainType)),
915
+ description: "Every branch matches"
916
+ },
917
+ NOT: {
918
+ type: mainType,
919
+ description: "Negates the nested operators"
814
920
  }
815
- }
921
+ })
816
922
  });
817
- cacheCtx.genericFilterCache.set(genericName, { main: mainType, or: orType });
923
+ cacheCtx.genericFilterCache.set(genericName, mainType);
818
924
  return mainType;
819
925
  };
820
926
  var orderMap = /* @__PURE__ */ new WeakMap();
@@ -868,19 +974,53 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
868
974
  fieldMap.set(table, remapped);
869
975
  return remapped;
870
976
  };
871
- var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx) => {
977
+ var isFilterableRelation = (relation) => !relation.through;
978
+ var generateRelationOrderFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
979
+ const relations = relationMap?.[tableName];
980
+ if (!relations || !tables) {
981
+ return {};
982
+ }
983
+ const fields = {};
984
+ for (const [relationName, relEntry] of Object.entries(relations)) {
985
+ if (relationName in columnFields) {
986
+ continue;
987
+ }
988
+ const targetTable = tables[relEntry.targetTableName];
989
+ const relation = relEntry.relation ?? relEntry;
990
+ if (!targetTable || !is3(relation, One2) || !isFilterableRelation(relation)) {
991
+ continue;
992
+ }
993
+ fields[relationName] = {
994
+ type: generateTableOrderTypeCached(
995
+ targetTable,
996
+ relEntry.targetTableName,
997
+ typeNameMapper,
998
+ cacheCtx,
999
+ relationMap,
1000
+ tables
1001
+ ),
1002
+ description: `Order by columns of the related ${relationName} row`
1003
+ };
1004
+ }
1005
+ return fields;
1006
+ };
1007
+ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx, relationMap, tables) => {
872
1008
  if (cacheCtx.orderTypeCache.has(table)) {
873
1009
  return cacheCtx.orderTypeCache.get(table);
874
1010
  }
875
- const orderColumns = generateTableOrderCached(table);
876
1011
  const order = new GraphQLInputObjectType2({
877
1012
  name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
878
- fields: orderColumns
1013
+ fields: () => {
1014
+ const orderColumns = generateTableOrderCached(table);
1015
+ return {
1016
+ ...orderColumns,
1017
+ ...generateRelationOrderFields(tableName, cacheCtx, typeNameMapper, orderColumns, relationMap, tables)
1018
+ };
1019
+ }
879
1020
  });
880
1021
  cacheCtx.orderTypeCache.set(table, order);
881
1022
  return order;
882
1023
  };
883
- var isFilterableRelation = (relation) => !relation.through;
884
1024
  var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
885
1025
  const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
886
1026
  if (cached) {
@@ -919,7 +1059,7 @@ var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnF
919
1059
  }
920
1060
  const targetTable = tables[relEntry.targetTableName];
921
1061
  const relation = relEntry.relation ?? relEntry;
922
- if (!targetTable || !isFilterableRelation(relation)) {
1062
+ if (!targetTable) {
923
1063
  continue;
924
1064
  }
925
1065
  fields[relationName] = is3(relation, One2) ? {
@@ -956,16 +1096,21 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
956
1096
  ...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
957
1097
  };
958
1098
  };
959
- const orFilters = new GraphQLInputObjectType2({
960
- name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
961
- fields: buildFields
962
- });
963
1099
  const filters = new GraphQLInputObjectType2({
964
1100
  name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
965
1101
  fields: () => ({
966
1102
  ...buildFields(),
967
1103
  OR: {
968
- type: new GraphQLList2(new GraphQLNonNull2(orFilters))
1104
+ type: new GraphQLList2(new GraphQLNonNull2(filters)),
1105
+ description: "At least one branch matches; ANDed with any sibling fields"
1106
+ },
1107
+ AND: {
1108
+ type: new GraphQLList2(new GraphQLNonNull2(filters)),
1109
+ description: "Every branch matches"
1110
+ },
1111
+ NOT: {
1112
+ type: filters,
1113
+ description: "Negates the nested filters"
969
1114
  }
970
1115
  })
971
1116
  });
@@ -974,7 +1119,7 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper,
974
1119
  };
975
1120
  var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
976
1121
  const table = tables[tableName];
977
- const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
1122
+ const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx, relationMap, tables) : void 0;
978
1123
  const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
979
1124
  const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
980
1125
  const relationsForTable = relationMap[tableName];
@@ -1060,10 +1205,11 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1060
1205
  }
1061
1206
  const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
1062
1207
  if (isOne) {
1208
+ const isRequired = relation.optional === false;
1063
1209
  rawRelationFields.push([
1064
1210
  relationName,
1065
1211
  {
1066
- type: relType,
1212
+ type: isRequired ? new GraphQLNonNull2(relType) : relType,
1067
1213
  args: {
1068
1214
  where: { type: relSelectData.filters }
1069
1215
  },
@@ -1201,28 +1347,95 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
1201
1347
  outputs
1202
1348
  };
1203
1349
  };
1204
- 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]);
1205
- var extractOrderBy = (table, orderArgs) => orderByEntries(orderArgs).map(
1206
- ([column, direction]) => direction === "asc" ? asc(getColumns(table)[column]) : desc(getColumns(table)[column])
1207
- );
1208
- var extractFiltersColumn = (column, columnName, operators) => {
1209
- if (!operators.OR?.length) {
1210
- delete operators.OR;
1350
+ var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)).filter(([, config]) => config).map(([column, config]) => {
1351
+ if (typeof config === "object" && config.direction === void 0) {
1352
+ throw new GraphQLError3(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
1353
+ }
1354
+ return [column, config.direction, config.nulls ?? void 0];
1355
+ });
1356
+ var orderExpressions = (expr, direction, nulls, dialectColumn) => {
1357
+ const directed = direction === "asc" ? asc(expr) : desc(expr);
1358
+ if (!nulls) {
1359
+ return [directed];
1211
1360
  }
1212
- const entries = Object.entries(operators);
1213
- if (operators.OR) {
1214
- if (entries.length > 1) {
1215
- throw new GraphQLError3(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
1361
+ const isMySql = (dialectColumn.columnType ?? "").startsWith("MySql");
1362
+ if (isMySql) {
1363
+ const nullsKey = nulls === "first" ? desc(sql`(${expr} is null)`) : asc(sql`(${expr} is null)`);
1364
+ return [nullsKey, directed];
1365
+ }
1366
+ return [nulls === "first" ? sql`${directed} nulls first` : sql`${directed} nulls last`];
1367
+ };
1368
+ var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain) => {
1369
+ const targetTable = ctx.tables[relEntry.targetTableName];
1370
+ const relation = relEntry.relation ?? relEntry;
1371
+ if (!targetTable || !is3(relation, One2) || !isFilterableRelation(relation)) {
1372
+ throw new GraphQLError3(`ORDER BY ${relationName}: Relation cannot be used for ordering`);
1373
+ }
1374
+ ctx.aliases ??= { n: 0 };
1375
+ const aliasedTarget = aliasedTable(targetTable, `dgql_ord_${ctx.aliases.n++}`);
1376
+ const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1377
+ const relationWhere = relation.where ? relationsFilterToSQL(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
1378
+ return {
1379
+ fromParts: [...chain?.fromParts ?? [], getTableAsAliasSQL(aliasedTarget)],
1380
+ conditions: [
1381
+ ...chain?.conditions ?? [],
1382
+ ...joinCondition ? [joinCondition] : [],
1383
+ ...relationWhere ? [relationWhere] : []
1384
+ ],
1385
+ table: aliasedTarget
1386
+ };
1387
+ };
1388
+ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
1389
+ const columns = getColumns(table);
1390
+ const relations = ctx?.relationMap[tableKey];
1391
+ for (const [key, config] of Object.entries(orderArgs)) {
1392
+ if (config === null || config === void 0) {
1393
+ continue;
1216
1394
  }
1217
- const variants2 = [];
1218
- for (const variant of operators.OR) {
1219
- const extracted = extractFiltersColumn(column, columnName, variant);
1220
- if (extracted) {
1221
- variants2.push(extracted);
1222
- }
1395
+ const column = columns[key];
1396
+ if (column) {
1397
+ out.push({
1398
+ expression: chain ? sql`(select ${column} from ${sql.join(chain.fromParts, sql`, `)} where ${and(...chain.conditions)})` : column,
1399
+ column,
1400
+ direction: config.direction,
1401
+ nulls: config.nulls ?? void 0,
1402
+ priority: config.priority ?? 0
1403
+ });
1404
+ continue;
1223
1405
  }
1224
- return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
1406
+ const relEntry = relations?.[key];
1407
+ if (!relEntry || !ctx) {
1408
+ throw new GraphQLError3(`ORDER BY ${key}: Unknown column or relation`);
1409
+ }
1410
+ const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
1411
+ collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
1412
+ }
1413
+ };
1414
+ var extractOrderBy = (table, orderArgs, ctx) => {
1415
+ const entries = [];
1416
+ collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries);
1417
+ return entries.sort((a, b) => b.priority - a.priority).flatMap((entry) => orderExpressions(entry.expression, entry.direction, entry.nulls, entry.column));
1418
+ };
1419
+ var LIKE_ESCAPE_CHAR = "\\";
1420
+ var escapeLikeValue = (value) => value.replace(/[\\%_]/g, (char) => `\\${char}`);
1421
+ var safeLikeOps = {
1422
+ startsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: false },
1423
+ endsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: false },
1424
+ contains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: false },
1425
+ iStartsWith: { buildPattern: (value) => `${escapeLikeValue(value)}%`, insensitive: true },
1426
+ iEndsWith: { buildPattern: (value) => `%${escapeLikeValue(value)}`, insensitive: true },
1427
+ iContains: { buildPattern: (value) => `%${escapeLikeValue(value)}%`, insensitive: true }
1428
+ };
1429
+ var safeLikeCondition = (column, pattern, insensitive) => {
1430
+ if (!insensitive) {
1431
+ return sql`${column} like ${pattern} escape ${LIKE_ESCAPE_CHAR}`;
1225
1432
  }
1433
+ const isPg = (column.columnType ?? "").startsWith("Pg");
1434
+ return isPg ? sql`${column} ilike ${pattern} escape ${LIKE_ESCAPE_CHAR}` : sql`lower(${column}) like ${pattern.toLowerCase()} escape ${LIKE_ESCAPE_CHAR}`;
1435
+ };
1436
+ var extractFiltersColumn = (column, columnName, operators) => {
1437
+ const { OR, AND, NOT, ...restOperators } = operators;
1438
+ const entries = Object.entries(restOperators);
1226
1439
  const singleValueOps = { eq, ne, gt, gte, lt, lte };
1227
1440
  const stringValueOps = { like, notLike, ilike, notIlike };
1228
1441
  const arrayValueOps = { inArray, notInArray };
@@ -1237,6 +1450,9 @@ var extractFiltersColumn = (column, columnName, operators) => {
1237
1450
  variants.push(singleValueOps[operatorName](column, singleValue));
1238
1451
  } else if (operatorName in stringValueOps) {
1239
1452
  variants.push(stringValueOps[operatorName](column, operatorValue));
1453
+ } else if (operatorName in safeLikeOps) {
1454
+ const { buildPattern, insensitive } = safeLikeOps[operatorName];
1455
+ variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
1240
1456
  } else if (operatorName in arrayValueOps) {
1241
1457
  if (!operatorValue.length) {
1242
1458
  throw new GraphQLError3(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
@@ -1245,6 +1461,34 @@ var extractFiltersColumn = (column, columnName, operators) => {
1245
1461
  variants.push(arrayValueOps[operatorName](column, arrayValue));
1246
1462
  } else if (operatorName in nullableOps) {
1247
1463
  variants.push(nullableOps[operatorName](column));
1464
+ } else {
1465
+ throw new GraphQLError3(`WHERE ${columnName}: Unknown operator: ${operatorName}`);
1466
+ }
1467
+ }
1468
+ if (AND?.length) {
1469
+ for (const variant of AND) {
1470
+ const extracted = extractFiltersColumn(column, columnName, variant);
1471
+ if (extracted) {
1472
+ variants.push(extracted);
1473
+ }
1474
+ }
1475
+ }
1476
+ if (NOT) {
1477
+ const extracted = extractFiltersColumn(column, columnName, NOT);
1478
+ if (extracted) {
1479
+ variants.push(not(extracted));
1480
+ }
1481
+ }
1482
+ if (OR?.length) {
1483
+ const orVariants = [];
1484
+ for (const variant of OR) {
1485
+ const extracted = extractFiltersColumn(column, columnName, variant);
1486
+ if (extracted) {
1487
+ orVariants.push(extracted);
1488
+ }
1489
+ }
1490
+ if (orVariants.length) {
1491
+ variants.push(orVariants.length > 1 ? or(...orVariants) : orVariants[0]);
1248
1492
  }
1249
1493
  }
1250
1494
  return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
@@ -1269,39 +1513,105 @@ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relation
1269
1513
  }
1270
1514
  return conditions.length > 1 ? and(...conditions) : conditions[0];
1271
1515
  };
1516
+ var resolveJunctionColumn = (aliasedThrough, junctionRef, relationName) => {
1517
+ const throughColumns = getColumns(aliasedThrough);
1518
+ const key = junctionRef?._?.key;
1519
+ const byKey = key ? throughColumns[key] : void 0;
1520
+ if (byKey) {
1521
+ return byKey;
1522
+ }
1523
+ const columnName = junctionRef?._?.column?.name;
1524
+ const byName = columnName ? Object.values(throughColumns).find((c) => c.name === columnName) : void 0;
1525
+ if (!byName) {
1526
+ throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
1527
+ }
1528
+ return byName;
1529
+ };
1530
+ var buildThroughJoinConditions = (parentTable, relation, aliasedThrough, aliasedTarget, relationName) => {
1531
+ const sourceColumns = relation.sourceColumns;
1532
+ const targetColumns = relation.targetColumns;
1533
+ const through = relation.through;
1534
+ if (!sourceColumns?.length || !targetColumns?.length || through?.source.length !== sourceColumns.length || through.target.length !== targetColumns.length) {
1535
+ throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
1536
+ }
1537
+ const parentColumns = Object.values(getColumns(parentTable));
1538
+ const targetTableColumns = Object.values(getColumns(aliasedTarget));
1539
+ const correlationConditions = [];
1540
+ for (let i = 0; i < sourceColumns.length; i++) {
1541
+ const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
1542
+ if (!localColumn) {
1543
+ throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
1544
+ }
1545
+ correlationConditions.push(eq(localColumn, resolveJunctionColumn(aliasedThrough, through.source[i], relationName)));
1546
+ }
1547
+ const junctionJoinConditions = [];
1548
+ for (let i = 0; i < targetColumns.length; i++) {
1549
+ const foreignColumn = targetTableColumns.find((c) => c.name === targetColumns[i].name);
1550
+ if (!foreignColumn) {
1551
+ throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
1552
+ }
1553
+ junctionJoinConditions.push(
1554
+ eq(resolveJunctionColumn(aliasedThrough, through.target[i], relationName), foreignColumn)
1555
+ );
1556
+ }
1557
+ return {
1558
+ correlation: correlationConditions.length > 1 ? and(...correlationConditions) : correlationConditions[0],
1559
+ junctionJoin: junctionJoinConditions.length > 1 ? and(...junctionJoinConditions) : junctionJoinConditions[0]
1560
+ };
1561
+ };
1272
1562
  var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
1273
1563
  const { targetTableName } = relEntry;
1274
1564
  const targetTable = ctx.tables[targetTableName];
1275
1565
  const relation = relEntry.relation ?? relEntry;
1276
- if (!targetTable || !isFilterableRelation(relation)) {
1566
+ if (!targetTable) {
1277
1567
  throw new GraphQLError3(`WHERE ${relationName}: Relation cannot be used as a filter`);
1278
1568
  }
1279
1569
  ctx.aliases ??= { n: 0 };
1280
1570
  const aliases = ctx.aliases;
1281
1571
  const aliasedTarget = aliasedTable(targetTable, `dgql_rel_${aliases.n++}`);
1282
- const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1572
+ const throughTable = relation.throughTable;
1573
+ let fromClause;
1574
+ let joinCondition;
1575
+ if (throughTable) {
1576
+ const aliasedThrough = aliasedTable(throughTable, `dgql_rel_${aliases.n++}`);
1577
+ const { correlation, junctionJoin } = buildThroughJoinConditions(
1578
+ parentTable,
1579
+ relation,
1580
+ aliasedThrough,
1581
+ aliasedTarget,
1582
+ relationName
1583
+ );
1584
+ fromClause = sql`${getTableAsAliasSQL(aliasedTarget)} inner join ${getTableAsAliasSQL(aliasedThrough)} on ${junctionJoin}`;
1585
+ joinCondition = correlation;
1586
+ } else {
1587
+ fromClause = getTableAsAliasSQL(aliasedTarget);
1588
+ joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1589
+ }
1283
1590
  const relationWhere = relation.where ? relationsFilterToSQL(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
1284
1591
  const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
1285
1592
  if (mode === "every") {
1286
1593
  if (!inner) {
1287
1594
  return void 0;
1288
1595
  }
1289
- return sql`not exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${and(joinCondition, relationWhere, not(inner))})`;
1596
+ return sql`not exists (select 1 from ${fromClause} where ${and(joinCondition, relationWhere, not(inner))})`;
1290
1597
  }
1291
1598
  const condition = and(joinCondition, relationWhere, inner);
1292
- return mode === "none" ? sql`not exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${condition})` : sql`exists (select 1 from ${getTableAsAliasSQL(aliasedTarget)} where ${condition})`;
1599
+ return mode === "none" ? sql`not exists (select 1 from ${fromClause} where ${condition})` : sql`exists (select 1 from ${fromClause} where ${condition})`;
1293
1600
  };
1294
1601
  var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
1295
1602
  const relation = relEntry.relation ?? relEntry;
1296
1603
  if (is3(relation, One2)) {
1297
1604
  return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
1298
1605
  }
1606
+ const relationMatchModes = ["some", "none", "every"];
1299
1607
  const variants = [];
1300
- for (const mode of ["some", "none", "every"]) {
1301
- const inner = value[mode];
1608
+ for (const [mode, inner] of Object.entries(value)) {
1302
1609
  if (inner === void 0 || inner === null) {
1303
1610
  continue;
1304
1611
  }
1612
+ if (!relationMatchModes.includes(mode)) {
1613
+ throw new GraphQLError3(`WHERE ${relationName}: Unknown relation filter key: ${mode}`);
1614
+ }
1305
1615
  const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
1306
1616
  if (extracted) {
1307
1617
  variants.push(extracted);
@@ -1310,26 +1620,8 @@ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) =>
1310
1620
  return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
1311
1621
  };
1312
1622
  var extractFilters = (table, tableName, filters, relationCtx) => {
1313
- if (!filters.OR?.length) {
1314
- delete filters.OR;
1315
- }
1316
- const entries = Object.entries(filters);
1317
- if (!entries.length) {
1318
- return;
1319
- }
1320
- if (filters.OR) {
1321
- if (entries.length > 1) {
1322
- throw new GraphQLError3(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
1323
- }
1324
- const variants2 = [];
1325
- for (const variant of filters.OR) {
1326
- const extracted = extractFilters(table, tableName, variant, relationCtx);
1327
- if (extracted) {
1328
- variants2.push(extracted);
1329
- }
1330
- }
1331
- return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
1332
- }
1623
+ const { OR, AND, NOT, ...fieldFilters } = filters;
1624
+ const entries = Object.entries(fieldFilters);
1333
1625
  const columns = getColumns(table);
1334
1626
  const relations = relationCtx?.relationMap[relationCtx.tableKey];
1335
1627
  const variants = [];
@@ -1338,11 +1630,40 @@ var extractFilters = (table, tableName, filters, relationCtx) => {
1338
1630
  continue;
1339
1631
  }
1340
1632
  const column = columns[fieldName];
1341
- const extracted = column ? extractFiltersColumn(column, fieldName, operators) : relations?.[fieldName] && relationCtx ? extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx) : void 0;
1633
+ if (!column && !(relations?.[fieldName] && relationCtx)) {
1634
+ throw new GraphQLError3(`WHERE ${tableName}: Unknown filter key: ${fieldName}`);
1635
+ }
1636
+ const extracted = column ? extractFiltersColumn(column, fieldName, operators) : extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx);
1342
1637
  if (extracted) {
1343
1638
  variants.push(extracted);
1344
1639
  }
1345
1640
  }
1641
+ if (AND?.length) {
1642
+ for (const variant of AND) {
1643
+ const extracted = extractFilters(table, tableName, variant, relationCtx);
1644
+ if (extracted) {
1645
+ variants.push(extracted);
1646
+ }
1647
+ }
1648
+ }
1649
+ if (NOT) {
1650
+ const extracted = extractFilters(table, tableName, NOT, relationCtx);
1651
+ if (extracted) {
1652
+ variants.push(not(extracted));
1653
+ }
1654
+ }
1655
+ if (OR?.length) {
1656
+ const orVariants = [];
1657
+ for (const variant of OR) {
1658
+ const extracted = extractFilters(table, tableName, variant, relationCtx);
1659
+ if (extracted) {
1660
+ orVariants.push(extracted);
1661
+ }
1662
+ }
1663
+ if (orVariants.length) {
1664
+ variants.push(orVariants.length > 1 ? or(...orVariants) : orVariants[0]);
1665
+ }
1666
+ }
1346
1667
  return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
1347
1668
  };
1348
1669
  var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
@@ -1384,7 +1705,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
1384
1705
  } : void 0;
1385
1706
  const hasPagination = offset != null || limit != null;
1386
1707
  const pkNames = targetPkNames ?? [];
1387
- thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
1708
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName)) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
1388
1709
  thisRecord.offset = offset;
1389
1710
  thisRecord.limit = limit;
1390
1711
  const relWith = relationField ? extractRelationsParamsInner(
@@ -1625,7 +1946,9 @@ var selectDistinctKeys = async (params) => {
1625
1946
  }
1626
1947
  const orderEntries = orderBy ? orderByEntries(orderBy) : [];
1627
1948
  const windowOrder = [
1628
- ...orderEntries.map(([column, direction]) => direction === "asc" ? asc(cols[column]) : desc(cols[column])),
1949
+ ...orderEntries.flatMap(
1950
+ ([column, direction, nulls]) => orderExpressions(cols[column], direction, nulls, cols[column])
1951
+ ),
1629
1952
  ...primaryKeyOrderExprs(table, pkNames)
1630
1953
  ];
1631
1954
  const rowNumber = sql`row_number() over (partition by ${sql.join(partitionCols, sql`, `)} order by ${sql.join(
@@ -1634,7 +1957,9 @@ var selectDistinctKeys = async (params) => {
1634
1957
  )})`.as(DISTINCT_RN);
1635
1958
  const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
1636
1959
  const outerOrder = [
1637
- ...orderEntries.map(([column, direction]) => direction === "asc" ? asc(sub[column]) : desc(sub[column])),
1960
+ ...orderEntries.flatMap(
1961
+ ([column, direction, nulls]) => orderExpressions(sub[column], direction, nulls, cols[column])
1962
+ ),
1638
1963
  ...pkNames.filter((name) => sub[name]).map((name) => asc(sub[name]))
1639
1964
  ];
1640
1965
  let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where(eq(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
@@ -1733,6 +2058,9 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1733
2058
  const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
1734
2059
  const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1735
2060
  const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
2061
+ const writeSingleSuffix = suffixes.single === "" ? "Single" : suffixes.single;
2062
+ const updateSingleFieldName = `${updateFieldName}${writeSingleSuffix}`;
2063
+ const deleteSingleFieldName = `${deleteFieldName}${writeSingleSuffix}`;
1736
2064
  return {
1737
2065
  typeName,
1738
2066
  listFieldName,
@@ -1744,9 +2072,24 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1744
2072
  upsertArrayFieldName,
1745
2073
  upsertSingleFieldName,
1746
2074
  updateFieldName,
1747
- deleteFieldName
2075
+ updateSingleFieldName,
2076
+ deleteFieldName,
2077
+ deleteSingleFieldName
1748
2078
  };
1749
2079
  };
2080
+ var extractRequiredFilters = (table, tableName, where, fieldName, relationCtx) => {
2081
+ const filters = where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2082
+ if (!filters) {
2083
+ throw new GraphQLError3(`${fieldName} requires a 'where' argument with at least one filter!`);
2084
+ }
2085
+ return filters;
2086
+ };
2087
+ var assertSingleMatch = async (executor, table, filters, fieldName) => {
2088
+ const matched = await executor.select({ found: sql`1` }).from(table).where(filters).limit(2);
2089
+ if (matched.length > 1) {
2090
+ throw new GraphQLError3(`${fieldName}: 'where' matched more than one row \u2014 nothing was written!`);
2091
+ }
2092
+ };
1750
2093
  var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
1751
2094
  offset: { type: GraphQLInt2 },
1752
2095
  limit: { type: GraphQLInt2 },
@@ -1805,9 +2148,9 @@ var runRelationalSelect = async (opts) => {
1805
2148
  // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
1806
2149
  // directly so column refs match the CTE alias.
1807
2150
  orderBy: distinctKeys ? (aliasedTable2) => [
1808
- ...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
2151
+ ...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : [],
1809
2152
  ...primaryKeyOrderExprs(aliasedTable2, pkNames)
1810
- ] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
2153
+ ] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
1811
2154
  where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
1812
2155
  RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
1813
2156
  } : void 0,
@@ -1922,7 +2265,7 @@ import {
1922
2265
  } from "drizzle-orm";
1923
2266
  import {
1924
2267
  GraphQLError as GraphQLError4,
1925
- GraphQLFloat as GraphQLFloat2,
2268
+ GraphQLFloat as GraphQLFloat3,
1926
2269
  GraphQLInputObjectType as GraphQLInputObjectType3,
1927
2270
  GraphQLInt as GraphQLInt3,
1928
2271
  GraphQLList as GraphQLList3,
@@ -1980,7 +2323,7 @@ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
1980
2323
  fields[op] = {
1981
2324
  type: new GraphQLObjectType3({
1982
2325
  name: `${typeName}${capitalize(op)}Aggregate`,
1983
- fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat2 }]))
2326
+ fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: GraphQLFloat3 }]))
1984
2327
  })
1985
2328
  };
1986
2329
  }
@@ -2216,7 +2559,7 @@ var generateGroupByEnum = (table, tableName, typeName) => {
2216
2559
  var aggregateNumberFilter = new GraphQLInputObjectType3({
2217
2560
  name: "AggregateNumberFilter",
2218
2561
  description: "Compares an aggregated value. Several operators in one filter are ANDed together.",
2219
- fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: GraphQLFloat2 }]))
2562
+ fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: GraphQLFloat3 }]))
2220
2563
  });
2221
2564
  var generateHavingInput = (table, tableName, typeName) => {
2222
2565
  const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
@@ -2529,13 +2872,13 @@ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) =>
2529
2872
  args: queryArgs
2530
2873
  };
2531
2874
  };
2532
- var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
2875
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, single, requireWhere, filterCtx) => {
2533
2876
  const queryArgs = {
2534
2877
  set: {
2535
2878
  type: new GraphQLNonNull4(setArgs)
2536
2879
  },
2537
2880
  where: {
2538
- type: filterArgs
2881
+ type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
2539
2882
  }
2540
2883
  };
2541
2884
  return {
@@ -2547,10 +2890,14 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
2547
2890
  if (!Object.keys(input).length) {
2548
2891
  throw new GraphQLError5("Unable to update with no values specified!");
2549
2892
  }
2893
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
2894
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2550
2895
  const executor = resolveExecutor(db, context);
2896
+ if (single) {
2897
+ await assertSingleMatch(executor, table, filters, fieldName);
2898
+ }
2551
2899
  let query = executor.update(table).set(input);
2552
- if (where) {
2553
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2900
+ if (filters) {
2554
2901
  query = query.where(filters);
2555
2902
  }
2556
2903
  await query;
@@ -2562,10 +2909,10 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filt
2562
2909
  args: queryArgs
2563
2910
  };
2564
2911
  };
2565
- var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
2912
+ var generateDelete = (db, tableName, table, filterArgs, fieldName, single, requireWhere, filterCtx) => {
2566
2913
  const queryArgs = {
2567
2914
  where: {
2568
- type: filterArgs
2915
+ type: single || requireWhere ? new GraphQLNonNull4(filterArgs) : filterArgs
2569
2916
  }
2570
2917
  };
2571
2918
  return {
@@ -2573,10 +2920,14 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) =>
2573
2920
  resolver: async (_source, args, context, _info) => {
2574
2921
  try {
2575
2922
  const { where } = args;
2923
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
2924
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
2576
2925
  const executor = resolveExecutor(db, context);
2926
+ if (single) {
2927
+ await assertSingleMatch(executor, table, filters, fieldName);
2928
+ }
2577
2929
  let query = executor.delete(table);
2578
- if (where) {
2579
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2930
+ if (filters) {
2580
2931
  query = query.where(filters);
2581
2932
  }
2582
2933
  await query;
@@ -2665,7 +3016,9 @@ var generateSchemaData = (db, schema, relations, options) => {
2665
3016
  upsertArrayFieldName,
2666
3017
  upsertSingleFieldName,
2667
3018
  updateFieldName,
2668
- deleteFieldName
3019
+ updateSingleFieldName,
3020
+ deleteFieldName,
3021
+ deleteSingleFieldName
2669
3022
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
2670
3023
  const selectArrGenerated = generateSelectArray(
2671
3024
  db,
@@ -2710,9 +3063,41 @@ var generateSchemaData = (db, schema, relations, options) => {
2710
3063
  updateInput,
2711
3064
  tableFilters,
2712
3065
  updateFieldName,
3066
+ false,
3067
+ features.requireWhere,
3068
+ filterCtx
3069
+ ) : void 0;
3070
+ const updateSingleGenerated = features.update ? generateUpdate(
3071
+ db,
3072
+ tableName,
3073
+ schema[tableName],
3074
+ updateInput,
3075
+ tableFilters,
3076
+ updateSingleFieldName,
3077
+ true,
3078
+ features.requireWhere,
3079
+ filterCtx
3080
+ ) : void 0;
3081
+ const deleteGenerated = features.delete ? generateDelete(
3082
+ db,
3083
+ tableName,
3084
+ schema[tableName],
3085
+ tableFilters,
3086
+ deleteFieldName,
3087
+ false,
3088
+ features.requireWhere,
3089
+ filterCtx
3090
+ ) : void 0;
3091
+ const deleteSingleGenerated = features.delete ? generateDelete(
3092
+ db,
3093
+ tableName,
3094
+ schema[tableName],
3095
+ tableFilters,
3096
+ deleteSingleFieldName,
3097
+ true,
3098
+ features.requireWhere,
2713
3099
  filterCtx
2714
3100
  ) : void 0;
2715
- const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
2716
3101
  const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
2717
3102
  const aggregateGenerated = features.aggregates ? generateAggregate(
2718
3103
  db,
@@ -2770,7 +3155,9 @@ var generateSchemaData = (db, schema, relations, options) => {
2770
3155
  upsertArrGenerated,
2771
3156
  upsertSingleGenerated,
2772
3157
  updateGenerated,
2773
- deleteGenerated
3158
+ updateSingleGenerated,
3159
+ deleteGenerated,
3160
+ deleteSingleGenerated
2774
3161
  ]) {
2775
3162
  if (generated) {
2776
3163
  mutations[generated.name] = {
@@ -2890,7 +3277,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
2890
3277
  }
2891
3278
  if (orderBy) {
2892
3279
  q = q.orderBy(
2893
- ...extractOrderBy(table, orderBy),
3280
+ ...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)),
2894
3281
  ...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
2895
3282
  );
2896
3283
  } else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
@@ -2951,7 +3338,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
2951
3338
  q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
2952
3339
  }
2953
3340
  if (orderBy) {
2954
- q = q.orderBy(...extractOrderBy(table, orderBy));
3341
+ q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)));
2955
3342
  } else if (pkNames.length) {
2956
3343
  q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
2957
3344
  }
@@ -3111,13 +3498,13 @@ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onCo
3111
3498
  args: queryArgs
3112
3499
  };
3113
3500
  };
3114
- var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
3501
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
3115
3502
  const queryArgs = {
3116
3503
  set: {
3117
3504
  type: new GraphQLNonNull5(setArgs)
3118
3505
  },
3119
3506
  where: {
3120
- type: filterArgs
3507
+ type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
3121
3508
  }
3122
3509
  };
3123
3510
  const pkNames = pgPrimaryKeyPropNames(table);
@@ -3143,16 +3530,26 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3143
3530
  if (!Object.keys(input).length) {
3144
3531
  throw new GraphQLError6("Unable to update with no values specified!");
3145
3532
  }
3533
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3534
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3146
3535
  const executor = resolveExecutor(db, context);
3536
+ if (single) {
3537
+ await assertSingleMatch(executor, table, filters, fieldName);
3538
+ }
3147
3539
  let query = executor.update(table).set(input);
3148
- if (where) {
3149
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
3540
+ if (filters) {
3150
3541
  query = query.where(filters);
3151
3542
  }
3152
3543
  query = query.returning(columns);
3153
3544
  const result = await query;
3545
+ if (single && result.length > 1) {
3546
+ throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
3547
+ }
3548
+ if (single && !result[0]) {
3549
+ return void 0;
3550
+ }
3154
3551
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3155
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3552
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3156
3553
  } catch (e) {
3157
3554
  throw toGraphQLError(e);
3158
3555
  }
@@ -3160,10 +3557,10 @@ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filte
3160
3557
  args: queryArgs
3161
3558
  };
3162
3559
  };
3163
- var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
3560
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
3164
3561
  const queryArgs = {
3165
3562
  where: {
3166
- type: filterArgs
3563
+ type: single || requireWhere ? new GraphQLNonNull5(filterArgs) : filterArgs
3167
3564
  }
3168
3565
  };
3169
3566
  return {
@@ -3179,14 +3576,24 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, fi
3179
3576
  table,
3180
3577
  selectionCtx
3181
3578
  );
3579
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
3580
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3182
3581
  const executor = resolveExecutor(db, context);
3582
+ if (single) {
3583
+ await assertSingleMatch(executor, table, filters, fieldName);
3584
+ }
3183
3585
  let query = executor.delete(table);
3184
- if (where) {
3185
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
3586
+ if (filters) {
3186
3587
  query = query.where(filters);
3187
3588
  }
3188
3589
  query = query.returning(columns);
3189
3590
  const result = await query;
3591
+ if (single && result.length > 1) {
3592
+ throw new GraphQLError6(`${fieldName}: 'where' matched more than one row!`);
3593
+ }
3594
+ if (single) {
3595
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
3596
+ }
3190
3597
  return remapToGraphQLArrayOutput(result, tableName, table);
3191
3598
  } catch (e) {
3192
3599
  throw toGraphQLError(e);
@@ -3268,7 +3675,9 @@ function generateSchemaData2(db, schema, relations, options) {
3268
3675
  upsertArrayFieldName,
3269
3676
  upsertSingleFieldName,
3270
3677
  updateFieldName,
3271
- deleteFieldName
3678
+ updateSingleFieldName,
3679
+ deleteFieldName,
3680
+ deleteSingleFieldName
3272
3681
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
3273
3682
  const selectArrGenerated = generateSelectArray2(
3274
3683
  db,
@@ -3367,6 +3776,23 @@ function generateSchemaData2(db, schema, relations, options) {
3367
3776
  tableFilters,
3368
3777
  updateFieldName,
3369
3778
  typeName,
3779
+ false,
3780
+ features.requireWhere,
3781
+ typeNameMapper,
3782
+ filterCtx
3783
+ ) : void 0;
3784
+ const updateSingleGenerated = features.update ? generateUpdate2(
3785
+ db,
3786
+ tableName,
3787
+ schema[tableName],
3788
+ tables,
3789
+ eagerRelations,
3790
+ updateInput,
3791
+ tableFilters,
3792
+ updateSingleFieldName,
3793
+ typeName,
3794
+ true,
3795
+ features.requireWhere,
3370
3796
  typeNameMapper,
3371
3797
  filterCtx
3372
3798
  ) : void 0;
@@ -3377,6 +3803,20 @@ function generateSchemaData2(db, schema, relations, options) {
3377
3803
  tableFilters,
3378
3804
  deleteFieldName,
3379
3805
  typeName,
3806
+ false,
3807
+ features.requireWhere,
3808
+ filterCtx,
3809
+ { tableName, relationMap: namedRelations, tables }
3810
+ ) : void 0;
3811
+ const deleteSingleGenerated = features.delete ? generateDelete2(
3812
+ db,
3813
+ tableName,
3814
+ schema[tableName],
3815
+ tableFilters,
3816
+ deleteSingleFieldName,
3817
+ typeName,
3818
+ true,
3819
+ features.requireWhere,
3380
3820
  filterCtx,
3381
3821
  { tableName, relationMap: namedRelations, tables }
3382
3822
  ) : void 0;
@@ -3466,6 +3906,13 @@ function generateSchemaData2(db, schema, relations, options) {
3466
3906
  resolve: updateGenerated.resolver
3467
3907
  };
3468
3908
  }
3909
+ if (updateSingleGenerated) {
3910
+ mutations[updateSingleGenerated.name] = {
3911
+ type: singleTableItemOutput,
3912
+ args: updateSingleGenerated.args,
3913
+ resolve: updateSingleGenerated.resolver
3914
+ };
3915
+ }
3469
3916
  if (deleteGenerated) {
3470
3917
  mutations[deleteGenerated.name] = {
3471
3918
  type: arrTableItemOutput,
@@ -3473,6 +3920,13 @@ function generateSchemaData2(db, schema, relations, options) {
3473
3920
  resolve: deleteGenerated.resolver
3474
3921
  };
3475
3922
  }
3923
+ if (deleteSingleGenerated) {
3924
+ mutations[deleteSingleGenerated.name] = {
3925
+ type: singleTableItemOutput,
3926
+ args: deleteSingleGenerated.args,
3927
+ resolve: deleteSingleGenerated.resolver
3928
+ };
3929
+ }
3476
3930
  const activeInputs = [
3477
3931
  // The insert input types the upsert mutations too, so either feature keeps it.
3478
3932
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -3743,13 +4197,13 @@ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onCo
3743
4197
  args: queryArgs
3744
4198
  };
3745
4199
  };
3746
- var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
4200
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, single, requireWhere, typeNameMapper, filterCtx) => {
3747
4201
  const queryArgs = {
3748
4202
  set: {
3749
4203
  type: new GraphQLNonNull6(setArgs)
3750
4204
  },
3751
4205
  where: {
3752
- type: filterArgs
4206
+ type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
3753
4207
  }
3754
4208
  };
3755
4209
  const pkNames = sqlitePrimaryKeyPropNames(table);
@@ -3775,16 +4229,26 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
3775
4229
  if (!Object.keys(input).length) {
3776
4230
  throw new GraphQLError7("Unable to update with no values specified!");
3777
4231
  }
4232
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4233
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3778
4234
  const executor = resolveExecutor(db, context);
4235
+ if (single) {
4236
+ await assertSingleMatch(executor, table, filters, fieldName);
4237
+ }
3779
4238
  let query = executor.update(table).set(input);
3780
- if (where) {
3781
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
4239
+ if (filters) {
3782
4240
  query = query.where(filters);
3783
4241
  }
3784
4242
  query = query.returning(columns);
3785
4243
  const result = await query;
4244
+ if (single && result.length > 1) {
4245
+ throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
4246
+ }
4247
+ if (single && !result[0]) {
4248
+ return void 0;
4249
+ }
3786
4250
  const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3787
- return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
4251
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3788
4252
  } catch (e) {
3789
4253
  throw toGraphQLError(e);
3790
4254
  }
@@ -3792,10 +4256,10 @@ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filte
3792
4256
  args: queryArgs
3793
4257
  };
3794
4258
  };
3795
- var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
4259
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, single, requireWhere, filterCtx, selectionCtx) => {
3796
4260
  const queryArgs = {
3797
4261
  where: {
3798
- type: filterArgs
4262
+ type: single || requireWhere ? new GraphQLNonNull6(filterArgs) : filterArgs
3799
4263
  }
3800
4264
  };
3801
4265
  return {
@@ -3811,14 +4275,24 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, fi
3811
4275
  table,
3812
4276
  selectionCtx
3813
4277
  );
4278
+ const relationCtx = relationFilterCtx(filterCtx, tableName);
4279
+ const filters = single || requireWhere ? extractRequiredFilters(table, tableName, where, fieldName, relationCtx) : where ? extractFilters(table, tableName, where, relationCtx) : void 0;
3814
4280
  const executor = resolveExecutor(db, context);
4281
+ if (single) {
4282
+ await assertSingleMatch(executor, table, filters, fieldName);
4283
+ }
3815
4284
  let query = executor.delete(table);
3816
- if (where) {
3817
- const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
4285
+ if (filters) {
3818
4286
  query = query.where(filters);
3819
4287
  }
3820
4288
  query = query.returning(columns);
3821
4289
  const result = await query;
4290
+ if (single && result.length > 1) {
4291
+ throw new GraphQLError7(`${fieldName}: 'where' matched more than one row!`);
4292
+ }
4293
+ if (single) {
4294
+ return result[0] ? remapToGraphQLSingleOutput(result[0], tableName, table) : void 0;
4295
+ }
3822
4296
  return remapToGraphQLArrayOutput(result, tableName, table);
3823
4297
  } catch (e) {
3824
4298
  throw toGraphQLError(e);
@@ -3901,7 +4375,9 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3901
4375
  upsertArrayFieldName,
3902
4376
  upsertSingleFieldName,
3903
4377
  updateFieldName,
3904
- deleteFieldName
4378
+ updateSingleFieldName,
4379
+ deleteFieldName,
4380
+ deleteSingleFieldName
3905
4381
  } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
3906
4382
  const selectArrGenerated = generateSelectArray3(
3907
4383
  db,
@@ -4000,6 +4476,23 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4000
4476
  tableFilters,
4001
4477
  updateFieldName,
4002
4478
  typeName,
4479
+ false,
4480
+ features.requireWhere,
4481
+ typeNameMapper,
4482
+ filterCtx
4483
+ ) : void 0;
4484
+ const updateSingleGenerated = features.update ? generateUpdate3(
4485
+ db,
4486
+ tableName,
4487
+ schema[tableName],
4488
+ tables,
4489
+ eagerRelations,
4490
+ updateInput,
4491
+ tableFilters,
4492
+ updateSingleFieldName,
4493
+ typeName,
4494
+ true,
4495
+ features.requireWhere,
4003
4496
  typeNameMapper,
4004
4497
  filterCtx
4005
4498
  ) : void 0;
@@ -4010,6 +4503,20 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4010
4503
  tableFilters,
4011
4504
  deleteFieldName,
4012
4505
  typeName,
4506
+ false,
4507
+ features.requireWhere,
4508
+ filterCtx,
4509
+ { tableName, relationMap: namedRelations, tables }
4510
+ ) : void 0;
4511
+ const deleteSingleGenerated = features.delete ? generateDelete3(
4512
+ db,
4513
+ tableName,
4514
+ schema[tableName],
4515
+ tableFilters,
4516
+ deleteSingleFieldName,
4517
+ typeName,
4518
+ true,
4519
+ features.requireWhere,
4013
4520
  filterCtx,
4014
4521
  { tableName, relationMap: namedRelations, tables }
4015
4522
  ) : void 0;
@@ -4099,6 +4606,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4099
4606
  resolve: updateGenerated.resolver
4100
4607
  };
4101
4608
  }
4609
+ if (updateSingleGenerated) {
4610
+ mutations[updateSingleGenerated.name] = {
4611
+ type: singleTableItemOutput,
4612
+ args: updateSingleGenerated.args,
4613
+ resolve: updateSingleGenerated.resolver
4614
+ };
4615
+ }
4102
4616
  if (deleteGenerated) {
4103
4617
  mutations[deleteGenerated.name] = {
4104
4618
  type: arrTableItemOutput,
@@ -4106,6 +4620,13 @@ var generateSchemaData3 = (db, schema, relations, options) => {
4106
4620
  resolve: deleteGenerated.resolver
4107
4621
  };
4108
4622
  }
4623
+ if (deleteSingleGenerated) {
4624
+ mutations[deleteSingleGenerated.name] = {
4625
+ type: singleTableItemOutput,
4626
+ args: deleteSingleGenerated.args,
4627
+ resolve: deleteSingleGenerated.resolver
4628
+ };
4629
+ }
4109
4630
  const activeInputs = [
4110
4631
  // The insert input types the upsert mutations too, so either feature keeps it.
4111
4632
  ...features.insert || onConflictInput ? [insertInput] : [],
@@ -4174,7 +4695,8 @@ var buildSchema = (db, config) => {
4174
4695
  insert: config?.features?.insert ?? true,
4175
4696
  update: config?.features?.update ?? true,
4176
4697
  delete: config?.features?.delete ?? true,
4177
- upsert: config?.features?.upsert ?? false
4698
+ upsert: config?.features?.upsert ?? false,
4699
+ requireWhere: config?.features?.requireWhere ?? false
4178
4700
  };
4179
4701
  const complexityConfig = config?.complexity ?? true;
4180
4702
  const complexity = complexityConfig === false ? void 0 : {
@@ -4247,6 +4769,7 @@ export {
4247
4769
  GraphQLBigIntString,
4248
4770
  GraphQLDate,
4249
4771
  GraphQLDateTime,
4772
+ GraphQLDecimalString,
4250
4773
  GraphQLJSON,
4251
4774
  GraphQLUUID,
4252
4775
  buildSchema,