@vantreeseba/drizzle-graphql 7.2.0 → 7.4.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
@@ -42,7 +42,8 @@ __export(index_exports, {
42
42
  drizzleExecutorKey: () => drizzleExecutorKey,
43
43
  extractFilters: () => extractFilters,
44
44
  extractOrderBy: () => extractOrderBy,
45
- extractRelationJoinColumns: () => extractRelationJoinColumns
45
+ extractRelationJoinColumns: () => extractRelationJoinColumns,
46
+ singularizeMapper: () => singularizeMapper
46
47
  });
47
48
  module.exports = __toCommonJS(index_exports);
48
49
  var import_drizzle_orm10 = require("drizzle-orm");
@@ -105,6 +106,10 @@ var getOrCreateLoader = (context, key, batchFn) => {
105
106
  var import_pluralize = __toESM(require("pluralize"), 1);
106
107
  var uncapitalize = (input) => input?.length ? `${input[0].toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
107
108
  var capitalize = (input) => input?.length ? `${input[0].toLocaleUpperCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
109
+ var singularizeMapper = (tableName) => ({
110
+ singular: uncapitalize(import_pluralize.default.singular(tableName)),
111
+ plural: uncapitalize(import_pluralize.default.plural(tableName))
112
+ });
108
113
 
109
114
  // src/util/data-mappers/index.ts
110
115
  var import_drizzle_orm2 = require("drizzle-orm");
@@ -996,10 +1001,10 @@ var runMutation = async (db, context, info, txCtx, body) => {
996
1001
  }
997
1002
  return runOnSharedTx(state, body);
998
1003
  };
999
- var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx) => {
1004
+ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames, orderCtx, whereArgs) => {
1000
1005
  const cols = (0, import_drizzle_orm4.getColumns)(targetTable);
1001
1006
  const orderExprs = [
1002
- ...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx) : [],
1007
+ ...orderByArg ? extractOrderBy(targetTable, orderByArg, orderCtx, whereArgs) : [],
1003
1008
  ...primaryKeyOrderExprs(targetTable, pkNames)
1004
1009
  ];
1005
1010
  const orderClause = orderExprs.length ? import_drizzle_orm4.sql` order by ${import_drizzle_orm4.sql.join(orderExprs, import_drizzle_orm4.sql`, `)}` : import_drizzle_orm4.sql``;
@@ -1110,11 +1115,12 @@ var createRelationResolverFactory = (db, tables, nullOrdering, filterCtx, limits
1110
1115
  limit ?? null,
1111
1116
  offset ?? null,
1112
1117
  targetPkNames,
1113
- relationFilterCtx(filterCtx, targetTableName)
1118
+ relationFilterCtx(filterCtx, targetTableName),
1119
+ whereArg
1114
1120
  );
1115
1121
  } else {
1116
1122
  let q = executor.select().from(targetTable).where(whereCondition);
1117
- const orderExprs = cursorEntries ? cursorOrderExprs(targetTable, cursorEntries) : orderByArg ? extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName)) : [];
1123
+ const orderExprs = cursorEntries ? cursorOrderExprs(targetTable, cursorEntries) : orderByArg ? extractOrderBy(targetTable, orderByArg, relationFilterCtx(filterCtx, targetTableName), whereArg) : [];
1118
1124
  if (orderExprs.length) {
1119
1125
  q = q.orderBy(...orderExprs);
1120
1126
  }
@@ -1325,6 +1331,10 @@ var innerOrder = new import_graphql5.GraphQLInputObjectType({
1325
1331
  nulls: {
1326
1332
  type: orderNulls,
1327
1333
  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)"
1334
+ },
1335
+ matchFilterOrder: {
1336
+ type: import_graphql5.GraphQLBoolean,
1337
+ description: "Sort by this column's position in the `inArray` list the same request's `where` gives it, rather than by the column's own value \u2014 `direction: asc` keeps the list's order, `desc` reverses it. Requires an `inArray` filter on the same column at the top level of `where`, and cannot be combined with `after` or `distinct`."
1328
1338
  }
1329
1339
  }
1330
1340
  });
@@ -1390,10 +1400,59 @@ var jsonFilterFields = (column, colType) => {
1390
1400
  description: "Value structurally contains this JSON (Postgres `@>` / MySQL JSON_CONTAINS)"
1391
1401
  }
1392
1402
  } : {},
1403
+ path: {
1404
+ type: new import_graphql5.GraphQLList(new import_graphql5.GraphQLNonNull(jsonPathFilter)),
1405
+ description: "Compares the value at one path inside the document. Several entries are ANDed; a single object may be passed without the list brackets."
1406
+ },
1393
1407
  isNull: { type: import_graphql5.GraphQLBoolean },
1394
1408
  isNotNull: { type: import_graphql5.GraphQLBoolean }
1395
1409
  };
1396
1410
  };
1411
+ var jsonPathCast = new import_graphql5.GraphQLEnumType({
1412
+ name: "JSONPathCast",
1413
+ description: "How to read the value at a JSON path before comparing it",
1414
+ values: {
1415
+ TEXT: { value: "text", description: "Compare as text (lexicographic ordering)" },
1416
+ NUMBER: { value: "number", description: "Compare as a number; a non-numeric value never matches" },
1417
+ BOOLEAN: { value: "boolean", description: "Compare as a boolean" }
1418
+ }
1419
+ });
1420
+ var jsonPathFilter = new import_graphql5.GraphQLInputObjectType({
1421
+ name: "JSONPathFilter",
1422
+ fields: {
1423
+ path: {
1424
+ type: new import_graphql5.GraphQLNonNull(new import_graphql5.GraphQLList(new import_graphql5.GraphQLNonNull(import_graphql5.GraphQLString))),
1425
+ description: 'Keys to walk from the document root, e.g. `["profile", "level"]`. An all-digits key indexes an array.'
1426
+ },
1427
+ as: { type: jsonPathCast, description: "Overrides how the value is read before comparing" },
1428
+ eq: { type: import_graphql_scalars.GraphQLJSON, description: "Equal to" },
1429
+ ne: { type: import_graphql_scalars.GraphQLJSON, description: "Not equal to" },
1430
+ lt: { type: import_graphql_scalars.GraphQLJSON, description: "Less than" },
1431
+ lte: { type: import_graphql_scalars.GraphQLJSON, description: "Less than or equal to" },
1432
+ gt: { type: import_graphql_scalars.GraphQLJSON, description: "Greater than" },
1433
+ gte: { type: import_graphql_scalars.GraphQLJSON, description: "Greater than or equal to" },
1434
+ startsWith: {
1435
+ type: import_graphql5.GraphQLString,
1436
+ description: "Extracted value starts with this string. `%`, `_` and `\\` are matched literally."
1437
+ },
1438
+ endsWith: {
1439
+ type: import_graphql5.GraphQLString,
1440
+ description: "Extracted value ends with this string. `%`, `_` and `\\` are matched literally."
1441
+ },
1442
+ contains: {
1443
+ type: import_graphql5.GraphQLString,
1444
+ description: "Extracted value contains this string. `%`, `_` and `\\` are matched literally."
1445
+ },
1446
+ iStartsWith: { type: import_graphql5.GraphQLString, description: "Case-insensitive `startsWith`." },
1447
+ iEndsWith: { type: import_graphql5.GraphQLString, description: "Case-insensitive `endsWith`." },
1448
+ iContains: { type: import_graphql5.GraphQLString, description: "Case-insensitive `contains`." },
1449
+ isNull: {
1450
+ type: import_graphql5.GraphQLBoolean,
1451
+ description: "When true, matches rows where the path is missing or holds JSON null"
1452
+ },
1453
+ isNotNull: { type: import_graphql5.GraphQLBoolean, description: "When true, matches rows where the path holds a value" }
1454
+ }
1455
+ });
1397
1456
  var IN_ARRAY_DESCRIPTION = "Matches any one of these values (SQL `IN`)";
1398
1457
  var NOT_IN_ARRAY_DESCRIPTION = "Matches none of these values (SQL `NOT IN`)";
1399
1458
  var arrayFilterFields = (colType, colArr) => {
@@ -1828,7 +1887,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1828
1887
  ]);
1829
1888
  continue;
1830
1889
  }
1831
- const targetDistinctEnum = cacheCtx.features.distinct ? generateDistinctEnum(tables[targetTableName], resolveTypeName(targetTableName, typeNameMapper)) : void 0;
1890
+ const targetDistinctEnum = cacheCtx.featureOf(targetTableName).distinct ? generateDistinctEnum(tables[targetTableName], resolveTypeName(targetTableName, typeNameMapper)) : void 0;
1832
1891
  rawRelationFields.push([
1833
1892
  relationName,
1834
1893
  {
@@ -1938,7 +1997,7 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
1938
1997
  const updateFields = Object.fromEntries(
1939
1998
  columnEntries.map(([columnName, column]) => {
1940
1999
  const converted = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, true);
1941
- const operations = cacheCtx.features.fieldUpdateOperations ? fieldUpdateInputType(column, columnName, tableName) : void 0;
2000
+ const operations = cacheCtx.featureOf(tableName).fieldUpdateOperations ? fieldUpdateInputType(column, columnName, tableName) : void 0;
1942
2001
  const field = operations ? { ...converted, type: operations } : converted;
1943
2002
  return [columnName, { ...field, ...inputFieldDocs(cacheCtx.docs, column, tableName, columnName, field.type) }];
1944
2003
  })
@@ -1987,6 +2046,9 @@ var orderByEntries = (orderArgs) => Object.entries(orderArgs).sort((a, b) => (b[
1987
2046
  if (typeof config === "object" && config.direction === void 0) {
1988
2047
  throw new import_graphql5.GraphQLError(`ORDER BY ${column}: ordering through a relation is not supported in this query`);
1989
2048
  }
2049
+ if (config.matchFilterOrder) {
2050
+ throw new import_graphql5.GraphQLError(`ORDER BY ${column}: 'matchFilterOrder' is not supported in this query`);
2051
+ }
1990
2052
  return [column, config.direction, config.nulls ?? void 0];
1991
2053
  });
1992
2054
  var orderExpressions = (expr, direction, nulls, dialectColumn) => {
@@ -2021,7 +2083,22 @@ var extendRelationOrderChain = (parentTable, relationName, relEntry, ctx, chain)
2021
2083
  table: aliasedTarget
2022
2084
  };
2023
2085
  };
2024
- var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
2086
+ var filterOrderExpression = (column, columnName, whereArgs) => {
2087
+ const values = whereArgs?.[columnName]?.inArray;
2088
+ if (!Array.isArray(values)) {
2089
+ throw new import_graphql5.GraphQLError(
2090
+ `ORDER BY ${columnName}: 'matchFilterOrder' needs an 'inArray' filter on the same column in this query's 'where'`
2091
+ );
2092
+ }
2093
+ if (!values.length) {
2094
+ return import_drizzle_orm4.sql`0`;
2095
+ }
2096
+ const branches = values.map(
2097
+ (value, index) => import_drizzle_orm4.sql`when ${column} = ${remapFromGraphQLCore(value, column, columnName)} then ${import_drizzle_orm4.sql.raw(String(index))}`
2098
+ );
2099
+ return import_drizzle_orm4.sql`case ${import_drizzle_orm4.sql.join(branches, import_drizzle_orm4.sql` `)} else ${import_drizzle_orm4.sql.raw(String(values.length))} end`;
2100
+ };
2101
+ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out, whereArgs) => {
2025
2102
  const columns = (0, import_drizzle_orm4.getColumns)(table);
2026
2103
  const relations = ctx?.relationMap[tableKey];
2027
2104
  for (const [key, config] of Object.entries(orderArgs)) {
@@ -2030,8 +2107,11 @@ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
2030
2107
  }
2031
2108
  const column = columns[key];
2032
2109
  if (column) {
2110
+ if (config.matchFilterOrder && chain) {
2111
+ throw new import_graphql5.GraphQLError(`ORDER BY ${key}: 'matchFilterOrder' is not supported through a relation`);
2112
+ }
2033
2113
  out.push({
2034
- expression: chain ? import_drizzle_orm4.sql`(select ${column} from ${import_drizzle_orm4.sql.join(chain.fromParts, import_drizzle_orm4.sql`, `)} where ${(0, import_drizzle_orm4.and)(...chain.conditions)})` : column,
2114
+ expression: config.matchFilterOrder ? filterOrderExpression(column, key, whereArgs) : chain ? import_drizzle_orm4.sql`(select ${column} from ${import_drizzle_orm4.sql.join(chain.fromParts, import_drizzle_orm4.sql`, `)} where ${(0, import_drizzle_orm4.and)(...chain.conditions)})` : column,
2035
2115
  column,
2036
2116
  direction: config.direction,
2037
2117
  nulls: config.nulls ?? void 0,
@@ -2044,12 +2124,12 @@ var collectOrderEntries = (table, tableKey, orderArgs, ctx, chain, out) => {
2044
2124
  throw new import_graphql5.GraphQLError(`ORDER BY ${key}: Unknown column or relation`);
2045
2125
  }
2046
2126
  const nextChain = extendRelationOrderChain(chain?.table ?? table, key, relEntry, ctx, chain);
2047
- collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out);
2127
+ collectOrderEntries(nextChain.table, relEntry.targetTableName, config, ctx, nextChain, out, void 0);
2048
2128
  }
2049
2129
  };
2050
- var extractOrderBy = (table, orderArgs, ctx) => {
2130
+ var extractOrderBy = (table, orderArgs, ctx, whereArgs) => {
2051
2131
  const entries = [];
2052
- collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries);
2132
+ collectOrderEntries(table, ctx?.tableKey ?? "", orderArgs, ctx, void 0, entries, whereArgs);
2053
2133
  return entries.sort((a, b) => b.priority - a.priority).flatMap((entry) => orderExpressions(entry.expression, entry.direction, entry.nulls, entry.column));
2054
2134
  };
2055
2135
  var LIKE_ESCAPE_CHAR = "\\";
@@ -2081,6 +2161,105 @@ var jsonContains = (column, columnName, value) => {
2081
2161
  throw new import_graphql5.GraphQLError(`WHERE ${columnName}: Operator 'contains' is not supported for this dialect!`);
2082
2162
  }
2083
2163
  };
2164
+ var sqlFalse = () => import_drizzle_orm4.sql`1 = 0`;
2165
+ var sqlTrue = () => import_drizzle_orm4.sql`1 = 1`;
2166
+ var jsonPathString = (path) => `$${path.map((part) => /^\d+$/.test(part) ? `[${part}]` : `."${part.replace(/(["\\])/g, "\\$1")}"`).join("")}`;
2167
+ var NUMERIC_TEXT_PATTERN = "^\\s*-?(\\d+\\.?\\d*|\\.\\d+)([eE][-+]?\\d+)?\\s*$";
2168
+ var jsonPathExprs = (column, path) => {
2169
+ switch (columnDialect(column)) {
2170
+ case "pg": {
2171
+ const pathArray = import_drizzle_orm4.sql`array[${import_drizzle_orm4.sql.join(
2172
+ path.map((part) => import_drizzle_orm4.sql`${part}`),
2173
+ import_drizzle_orm4.sql`, `
2174
+ )}]::text[]`;
2175
+ const text = import_drizzle_orm4.sql`(${column} #>> ${pathArray})`;
2176
+ return {
2177
+ text,
2178
+ number: import_drizzle_orm4.sql`(case when ${text} ~ ${NUMERIC_TEXT_PATTERN} then ${text}::numeric end)`,
2179
+ boolean: text,
2180
+ encodeBoolean: (value) => String(value)
2181
+ };
2182
+ }
2183
+ case "mysql": {
2184
+ const extracted = import_drizzle_orm4.sql`json_extract(${column}, ${jsonPathString(path)})`;
2185
+ const text = import_drizzle_orm4.sql`(case when json_type(${extracted}) = 'NULL' then null else json_unquote(${extracted}) end)`;
2186
+ return {
2187
+ text,
2188
+ number: import_drizzle_orm4.sql`(case when ${text} regexp ${NUMERIC_TEXT_PATTERN} then cast(${text} as decimal(65, 30)) end)`,
2189
+ boolean: text,
2190
+ encodeBoolean: (value) => String(value)
2191
+ };
2192
+ }
2193
+ default: {
2194
+ const extracted = import_drizzle_orm4.sql`json_extract(${column}, ${jsonPathString(path)})`;
2195
+ return {
2196
+ text: import_drizzle_orm4.sql`cast(${extracted} as text)`,
2197
+ number: import_drizzle_orm4.sql`(case when typeof(${extracted}) in ('integer', 'real') then ${extracted} end)`,
2198
+ // SQLite has no boolean type: a JSON `true` comes back as the integer 1.
2199
+ boolean: extracted,
2200
+ encodeBoolean: (value) => value ? 1 : 0
2201
+ };
2202
+ }
2203
+ }
2204
+ };
2205
+ var JSON_PATH_COMPARISONS = {
2206
+ eq: "=",
2207
+ ne: "<>",
2208
+ lt: "<",
2209
+ lte: "<=",
2210
+ gt: ">",
2211
+ gte: ">="
2212
+ };
2213
+ var inferJsonPathCast = (value) => typeof value === "number" ? "number" : typeof value === "boolean" ? "boolean" : "text";
2214
+ var jsonPathCondition = (column, columnName, filter) => {
2215
+ const { path, as: castOverride, ...operators } = filter;
2216
+ const locator = `${columnName}.path`;
2217
+ if (!Array.isArray(path) || !path.length) {
2218
+ throw new import_graphql5.GraphQLError(`WHERE ${locator}: 'path' must name at least one key`);
2219
+ }
2220
+ const exprs = jsonPathExprs(column, path);
2221
+ const variants = [];
2222
+ for (const [operatorName, operatorValue] of Object.entries(operators)) {
2223
+ if (operatorValue === null || operatorValue === void 0) {
2224
+ continue;
2225
+ }
2226
+ if (operatorName === "isNull" || operatorName === "isNotNull") {
2227
+ if (operatorValue === false) {
2228
+ continue;
2229
+ }
2230
+ variants.push(operatorName === "isNull" ? import_drizzle_orm4.sql`${exprs.text} is null` : import_drizzle_orm4.sql`${exprs.text} is not null`);
2231
+ continue;
2232
+ }
2233
+ if (operatorName in safeLikeOps) {
2234
+ const { buildPattern, insensitive } = safeLikeOps[operatorName];
2235
+ if (typeof operatorValue !== "string") {
2236
+ throw new import_graphql5.GraphQLError(`WHERE ${locator}: operator '${operatorName}' takes a string`);
2237
+ }
2238
+ variants.push(safeLikeCondition(exprs.text, buildPattern(operatorValue), insensitive));
2239
+ continue;
2240
+ }
2241
+ const comparison = JSON_PATH_COMPARISONS[operatorName];
2242
+ if (!comparison) {
2243
+ throw new import_graphql5.GraphQLError(`WHERE ${locator}: Unknown operator: ${operatorName}`);
2244
+ }
2245
+ const cast = castOverride ?? inferJsonPathCast(operatorValue);
2246
+ if (cast === "number") {
2247
+ const numeric = Number(operatorValue);
2248
+ if (Number.isNaN(numeric)) {
2249
+ throw new import_graphql5.GraphQLError(
2250
+ `WHERE ${locator}: operator '${operatorName}' compares as a number, so its value must be one`
2251
+ );
2252
+ }
2253
+ variants.push(import_drizzle_orm4.sql`${exprs.number} ${import_drizzle_orm4.sql.raw(comparison)} ${numeric}`);
2254
+ } else if (cast === "boolean") {
2255
+ const truthy = operatorValue === true || operatorValue === "true";
2256
+ variants.push(import_drizzle_orm4.sql`${exprs.boolean} ${import_drizzle_orm4.sql.raw(comparison)} ${exprs.encodeBoolean(truthy)}`);
2257
+ } else {
2258
+ variants.push(import_drizzle_orm4.sql`${exprs.text} ${import_drizzle_orm4.sql.raw(comparison)} ${String(operatorValue)}`);
2259
+ }
2260
+ }
2261
+ return variants.length ? variants.length > 1 ? (0, import_drizzle_orm4.and)(...variants) : variants[0] : void 0;
2262
+ };
2084
2263
  var extractFiltersColumn = (column, columnName, operators) => {
2085
2264
  const { OR, AND, NOT, ...restOperators } = operators;
2086
2265
  const entries = Object.entries(restOperators);
@@ -2102,6 +2281,13 @@ var extractFiltersColumn = (column, columnName, operators) => {
2102
2281
  variants.push(singleValueOps[operatorName](column, singleValue));
2103
2282
  } else if (operatorName in stringValueOps) {
2104
2283
  variants.push(stringValueOps[operatorName](column, operatorValue));
2284
+ } else if (operatorName === "path" && isJsonColumn2(column)) {
2285
+ for (const pathFilter of operatorValue) {
2286
+ const extracted = jsonPathCondition(column, columnName, pathFilter);
2287
+ if (extracted) {
2288
+ variants.push(extracted);
2289
+ }
2290
+ }
2105
2291
  } else if (operatorName === "contains" && isJsonColumn2(column)) {
2106
2292
  variants.push(jsonContains(column, columnName, operatorValue));
2107
2293
  } else if (operatorName in safeLikeOps) {
@@ -2109,7 +2295,8 @@ var extractFiltersColumn = (column, columnName, operators) => {
2109
2295
  variants.push(safeLikeCondition(column, buildPattern(operatorValue), insensitive));
2110
2296
  } else if (operatorName in arrayValueOps) {
2111
2297
  if (!operatorValue.length) {
2112
- throw new import_graphql5.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
2298
+ variants.push(operatorName === "inArray" ? sqlFalse() : sqlTrue());
2299
+ continue;
2113
2300
  }
2114
2301
  const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
2115
2302
  variants.push(arrayValueOps[operatorName](column, arrayValue));
@@ -2117,7 +2304,8 @@ var extractFiltersColumn = (column, columnName, operators) => {
2117
2304
  variants.push((0, import_drizzle_orm4.arrayContains)(column, [operatorValue]));
2118
2305
  } else if (operatorName in arrayMembershipOps) {
2119
2306
  if (!operatorValue.length) {
2120
- throw new import_graphql5.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
2307
+ variants.push(operatorName === "hasSome" ? sqlFalse() : sqlTrue());
2308
+ continue;
2121
2309
  }
2122
2310
  variants.push(arrayMembershipOps[operatorName](column, operatorValue));
2123
2311
  } else if (operatorName === "isEmpty") {
@@ -2380,7 +2568,7 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
2380
2568
  } : void 0;
2381
2569
  const hasPagination = offset != null || limit != null;
2382
2570
  const pkNames = targetPkNames ?? [];
2383
- thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName)) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
2571
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy, relationFilterCtx(filterCtx, targetTableName), relWhere) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
2384
2572
  thisRecord.offset = offset;
2385
2573
  thisRecord.limit = limit;
2386
2574
  const relWith = relationField ? extractRelationsParamsInner(
@@ -2460,6 +2648,15 @@ var primaryKeyOrderExprs = (table, pkNames) => {
2460
2648
  var CURSOR_FIELD_NAME = "cursor";
2461
2649
  var ROW_CURSOR_PROP = "__drizzle_graphql_cursor";
2462
2650
  var orderByHasRelationEntry = (orderBy) => !!orderBy && Object.values(orderBy).some((config) => config && typeof config === "object" && config.direction === void 0);
2651
+ var orderByCursorObstacle = (orderBy) => {
2652
+ if (orderByHasRelationEntry(orderBy)) {
2653
+ return "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor.";
2654
+ }
2655
+ if (orderBy && Object.values(orderBy).some((config) => config && typeof config === "object" && config.matchFilterOrder)) {
2656
+ return "'after' cannot be combined with 'matchFilterOrder' \u2014 a row's position in the request's own filter list is not a value of the row, so it cannot be encoded into a cursor.";
2657
+ }
2658
+ return void 0;
2659
+ };
2463
2660
  var cursorOrderingEntries = (orderBy, pkNames) => {
2464
2661
  const entries = orderBy ? orderByEntries(orderBy) : [];
2465
2662
  const seen = new Set(entries.map(([column]) => column));
@@ -3056,11 +3253,10 @@ var runRelationalSelect = async (opts) => {
3056
3253
  if (after != null && distinct) {
3057
3254
  throw new import_graphql5.GraphQLError("'after' cannot be combined with 'distinct'.");
3058
3255
  }
3059
- if (orderByHasRelationEntry(orderBy)) {
3256
+ const cursorObstacle = orderByCursorObstacle(orderBy);
3257
+ if (cursorObstacle) {
3060
3258
  if (after != null) {
3061
- throw new import_graphql5.GraphQLError(
3062
- "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor."
3063
- );
3259
+ throw new import_graphql5.GraphQLError(cursorObstacle);
3064
3260
  }
3065
3261
  } else if (!pkNames?.length) {
3066
3262
  if (after != null) {
@@ -3100,13 +3296,13 @@ var runRelationalSelect = async (opts) => {
3100
3296
  // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
3101
3297
  // directly so column refs match the CTE alias.
3102
3298
  orderBy: distinctKeys ? (aliasedTable2) => [
3103
- ...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : [],
3299
+ ...orderBy ? extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName), where) : [],
3104
3300
  ...primaryKeyOrderExprs(aliasedTable2, pkNames)
3105
3301
  ] : cursorEntries ? (
3106
3302
  // Cursor pagination needs a total order: the request's orderBy plus the PK tiebreak,
3107
3303
  // exactly the ordering the cursor encodes and the keyset predicate compares against.
3108
3304
  (aliasedTable2) => cursorOrderExprs(aliasedTable2, cursorEntries)
3109
- ) : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName)) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
3305
+ ) : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy, relationFilterCtx(filterCtx, tableName), where) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
3110
3306
  where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where || cursorValues ? {
3111
3307
  RAW: (aliasedTable2) => (0, import_drizzle_orm4.and)(
3112
3308
  where ? extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0,
@@ -3219,6 +3415,38 @@ var import_mysql_core2 = require("drizzle-orm/mysql-core");
3219
3415
  var import_graphql7 = require("graphql");
3220
3416
  var import_graphql_parse_resolve_info2 = require("graphql-parse-resolve-info");
3221
3417
 
3418
+ // src/util/features.ts
3419
+ var featureDefaults = {
3420
+ aggregates: true,
3421
+ groupBy: true,
3422
+ relationAggregates: true,
3423
+ distinct: true,
3424
+ insert: true,
3425
+ update: true,
3426
+ updateMany: true,
3427
+ delete: true,
3428
+ upsert: false,
3429
+ fieldUpdateOperations: false,
3430
+ countMutations: false,
3431
+ requireWhere: false
3432
+ };
3433
+ var resolveTableFeatures = (features) => {
3434
+ const cache = /* @__PURE__ */ new Map();
3435
+ const names = Object.keys(featureDefaults);
3436
+ return (tableName) => {
3437
+ let resolved = cache.get(tableName);
3438
+ if (!resolved) {
3439
+ resolved = {};
3440
+ for (const name of names) {
3441
+ const configured = features?.[name];
3442
+ resolved[name] = configured === void 0 ? featureDefaults[name] : typeof configured === "function" ? !!configured(tableName) : !!configured;
3443
+ }
3444
+ cache.set(tableName, resolved);
3445
+ }
3446
+ return resolved;
3447
+ };
3448
+ };
3449
+
3222
3450
  // src/util/builders/aggregates.ts
3223
3451
  var import_drizzle_orm5 = require("drizzle-orm");
3224
3452
  var import_graphql6 = require("graphql");
@@ -3953,6 +4181,8 @@ var generateSchemaData = (db, schema, relations, options) => {
3953
4181
  const excludedTables = new Set(options.exclude?.tables ?? []);
3954
4182
  const tableEntries = schemaEntries.filter(([key, value]) => (0, import_drizzle_orm6.is)(value, import_mysql_core2.MySqlTable) && !excludedTables.has(key));
3955
4183
  const tables = Object.fromEntries(tableEntries);
4184
+ const featureOf = resolveTableFeatures(features);
4185
+ const anyTable = (feature) => tableEntries.some(([name]) => featureOf(name)[feature]);
3956
4186
  if (!tableEntries.length) {
3957
4187
  throw new Error(
3958
4188
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
@@ -3995,9 +4225,9 @@ var generateSchemaData = (db, schema, relations, options) => {
3995
4225
  complexity,
3996
4226
  limits,
3997
4227
  docs: options.docs ?? {},
3998
- features
4228
+ featureOf
3999
4229
  };
4000
- const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
4230
+ const relationAggregateFactory = anyTable("relationAggregates") ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
4001
4231
  const queries = {};
4002
4232
  const mutations = {};
4003
4233
  const mutationTxCtx = createMutationTxCtx(options.transactions);
@@ -4015,7 +4245,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4015
4245
  prefixes.insert,
4016
4246
  prefixes.update,
4017
4247
  resolverFactory,
4018
- relationAggregateFactory
4248
+ featureOf(tableName).relationAggregates ? relationAggregateFactory : void 0
4019
4249
  )
4020
4250
  ])
4021
4251
  );
@@ -4029,10 +4259,11 @@ var generateSchemaData = (db, schema, relations, options) => {
4029
4259
  });
4030
4260
  const inputs = {};
4031
4261
  const outputs = {};
4032
- if (features.insert || features.upsert || features.update || features.delete) {
4262
+ if (["insert", "upsert", "update", "delete"].some((feature) => anyTable(feature))) {
4033
4263
  outputs.MutationReturn = mutationReturnType;
4034
4264
  }
4035
4265
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
4266
+ const tableFeatures = featureOf(tableName);
4036
4267
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
4037
4268
  const { selectSingleOutput, selectArrOutput } = tableTypes.outputs;
4038
4269
  const {
@@ -4064,7 +4295,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4064
4295
  typeName,
4065
4296
  typeNameMapper,
4066
4297
  filterCtx,
4067
- features.distinct,
4298
+ tableFeatures.distinct,
4068
4299
  limits
4069
4300
  );
4070
4301
  const selectSingleGenerated = generateSelectSingle(
@@ -4080,7 +4311,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4080
4311
  filterCtx,
4081
4312
  limits
4082
4313
  );
4083
- const insertArrGenerated = features.insert ? generateInsertArray(
4314
+ const insertArrGenerated = tableFeatures.insert ? generateInsertArray(
4084
4315
  db,
4085
4316
  tableName,
4086
4317
  schema[tableName],
@@ -4088,7 +4319,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4088
4319
  createArrayFieldName,
4089
4320
  mutationTxCtx
4090
4321
  ) : void 0;
4091
- const insertSingleGenerated = features.insert ? generateInsertSingle(
4322
+ const insertSingleGenerated = tableFeatures.insert ? generateInsertSingle(
4092
4323
  db,
4093
4324
  tableName,
4094
4325
  schema[tableName],
@@ -4096,7 +4327,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4096
4327
  createSingleFieldName,
4097
4328
  mutationTxCtx
4098
4329
  ) : void 0;
4099
- const onConflictInput = features.upsert ? generateOnConflictInput({
4330
+ const onConflictInput = tableFeatures.upsert ? generateOnConflictInput({
4100
4331
  table: schema[tableName],
4101
4332
  typeName,
4102
4333
  uniqueSets: [],
@@ -4121,7 +4352,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4121
4352
  true,
4122
4353
  mutationTxCtx
4123
4354
  ) : void 0;
4124
- const updateGenerated = features.update ? generateUpdate(
4355
+ const updateGenerated = tableFeatures.update ? generateUpdate(
4125
4356
  db,
4126
4357
  tableName,
4127
4358
  schema[tableName],
@@ -4129,11 +4360,11 @@ var generateSchemaData = (db, schema, relations, options) => {
4129
4360
  tableFilters,
4130
4361
  updateFieldName,
4131
4362
  false,
4132
- features.requireWhere,
4363
+ tableFeatures.requireWhere,
4133
4364
  filterCtx,
4134
4365
  mutationTxCtx
4135
4366
  ) : void 0;
4136
- const updateSingleGenerated = features.update ? generateUpdate(
4367
+ const updateSingleGenerated = tableFeatures.update ? generateUpdate(
4137
4368
  db,
4138
4369
  tableName,
4139
4370
  schema[tableName],
@@ -4141,11 +4372,11 @@ var generateSchemaData = (db, schema, relations, options) => {
4141
4372
  tableFilters,
4142
4373
  updateSingleFieldName,
4143
4374
  true,
4144
- features.requireWhere,
4375
+ tableFeatures.requireWhere,
4145
4376
  filterCtx,
4146
4377
  mutationTxCtx
4147
4378
  ) : void 0;
4148
- const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
4379
+ const updateManyInput = tableFeatures.update && tableFeatures.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
4149
4380
  const updateManyGenerated = updateManyInput ? generateUpdateMany(
4150
4381
  db,
4151
4382
  tableName,
@@ -4155,29 +4386,29 @@ var generateSchemaData = (db, schema, relations, options) => {
4155
4386
  filterCtx,
4156
4387
  mutationTxCtx
4157
4388
  ) : void 0;
4158
- const deleteGenerated = features.delete ? generateDelete(
4389
+ const deleteGenerated = tableFeatures.delete ? generateDelete(
4159
4390
  db,
4160
4391
  tableName,
4161
4392
  schema[tableName],
4162
4393
  tableFilters,
4163
4394
  deleteFieldName,
4164
4395
  false,
4165
- features.requireWhere,
4396
+ tableFeatures.requireWhere,
4166
4397
  filterCtx,
4167
4398
  mutationTxCtx
4168
4399
  ) : void 0;
4169
- const deleteSingleGenerated = features.delete ? generateDelete(
4400
+ const deleteSingleGenerated = tableFeatures.delete ? generateDelete(
4170
4401
  db,
4171
4402
  tableName,
4172
4403
  schema[tableName],
4173
4404
  tableFilters,
4174
4405
  deleteSingleFieldName,
4175
4406
  true,
4176
- features.requireWhere,
4407
+ tableFeatures.requireWhere,
4177
4408
  filterCtx,
4178
4409
  mutationTxCtx
4179
4410
  ) : void 0;
4180
- const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
4411
+ const updateCountGenerated = tableFeatures.update && tableFeatures.countMutations ? generateWriteCount({
4181
4412
  db,
4182
4413
  tableName,
4183
4414
  table: schema[tableName],
@@ -4185,23 +4416,23 @@ var generateSchemaData = (db, schema, relations, options) => {
4185
4416
  setArgs: updateInput,
4186
4417
  filterArgs: tableFilters,
4187
4418
  fieldName: updateCountFieldName,
4188
- requireWhere: features.requireWhere,
4419
+ requireWhere: tableFeatures.requireWhere,
4189
4420
  filterCtx,
4190
4421
  txCtx: mutationTxCtx
4191
4422
  }) : void 0;
4192
- const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
4423
+ const deleteCountGenerated = tableFeatures.delete && tableFeatures.countMutations ? generateWriteCount({
4193
4424
  db,
4194
4425
  tableName,
4195
4426
  table: schema[tableName],
4196
4427
  kind: "delete",
4197
4428
  filterArgs: tableFilters,
4198
4429
  fieldName: deleteCountFieldName,
4199
- requireWhere: features.requireWhere,
4430
+ requireWhere: tableFeatures.requireWhere,
4200
4431
  filterCtx,
4201
4432
  txCtx: mutationTxCtx
4202
4433
  }) : void 0;
4203
- const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4204
- const aggregateGenerated = features.aggregates ? generateAggregate(
4434
+ const aggregateType = tableFeatures.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4435
+ const aggregateGenerated = tableFeatures.aggregates ? generateAggregate(
4205
4436
  db,
4206
4437
  tableName,
4207
4438
  schema[tableName],
@@ -4210,7 +4441,7 @@ var generateSchemaData = (db, schema, relations, options) => {
4210
4441
  tableFilters,
4211
4442
  filterCtx
4212
4443
  ) : void 0;
4213
- const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4444
+ const groupByType = tableFeatures.aggregates && tableFeatures.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
4214
4445
  const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
4215
4446
  const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
4216
4447
  const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
@@ -4288,9 +4519,9 @@ var generateSchemaData = (db, schema, relations, options) => {
4288
4519
  }
4289
4520
  const activeInputs = [
4290
4521
  // The insert input types the upsert mutations too, so either feature keeps it.
4291
- ...features.insert || onConflictInput ? [insertInput] : [],
4522
+ ...tableFeatures.insert || onConflictInput ? [insertInput] : [],
4292
4523
  ...onConflictInput ? [onConflictInput] : [],
4293
- ...features.update ? [updateInput] : [],
4524
+ ...tableFeatures.update ? [updateInput] : [],
4294
4525
  ...updateManyInput ? [updateManyInput] : [],
4295
4526
  tableFilters,
4296
4527
  tableOrder
@@ -4763,11 +4994,10 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
4763
4994
  if (after != null && distinct?.length) {
4764
4995
  throw new import_graphql9.GraphQLError("'after' cannot be combined with 'distinct'.");
4765
4996
  }
4766
- if (orderByHasRelationEntry(orderBy)) {
4997
+ const cursorObstacle = orderByCursorObstacle(orderBy);
4998
+ if (cursorObstacle) {
4767
4999
  if (after != null) {
4768
- throw new import_graphql9.GraphQLError(
4769
- "'after' cannot be combined with an orderBy that orders through a relation \u2014 a related row's value cannot be encoded into a cursor."
4770
- );
5000
+ throw new import_graphql9.GraphQLError(cursorObstacle);
4771
5001
  }
4772
5002
  } else if (!pkNames.length) {
4773
5003
  if (after != null) {
@@ -4815,7 +5045,7 @@ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filte
4815
5045
  q = q.orderBy(...cursorOrderExprs(table, cursorEntries));
4816
5046
  } else if (orderBy) {
4817
5047
  q = q.orderBy(
4818
- ...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)),
5048
+ ...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName), where),
4819
5049
  ...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
4820
5050
  );
4821
5051
  } else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
@@ -4881,7 +5111,7 @@ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filt
4881
5111
  q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
4882
5112
  }
4883
5113
  if (orderBy) {
4884
- q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName)));
5114
+ q = q.orderBy(...extractOrderBy(table, orderBy, relationFilterCtx(filterCtx, tableName), where));
4885
5115
  } else if (pkNames.length) {
4886
5116
  q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
4887
5117
  }
@@ -5318,6 +5548,8 @@ function generateSchemaData2(db, schema, relations, options) {
5318
5548
  const excludedTables = new Set(options.exclude?.tables ?? []);
5319
5549
  const tableEntries = schemaEntries.filter(([key, value]) => (0, import_drizzle_orm8.is)(value, import_pg_core2.PgTable) && !excludedTables.has(key));
5320
5550
  const tables = Object.fromEntries(tableEntries);
5551
+ const featureOf = resolveTableFeatures(features);
5552
+ const anyTable = (feature) => tableEntries.some(([name]) => featureOf(name)[feature]);
5321
5553
  if (!tableEntries.length) {
5322
5554
  throw new Error(
5323
5555
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
@@ -5355,7 +5587,7 @@ function generateSchemaData2(db, schema, relations, options) {
5355
5587
  complexity,
5356
5588
  limits,
5357
5589
  docs: options.docs ?? {},
5358
- features
5590
+ featureOf
5359
5591
  };
5360
5592
  const nestedPlans = features.nestedWrites ? buildNestedWritePlans(
5361
5593
  tables,
@@ -5366,7 +5598,7 @@ function generateSchemaData2(db, schema, relations, options) {
5366
5598
  ) : void 0;
5367
5599
  const nestedTypes = nestedPlans ? createNestedWriteTypes({ plans: nestedPlans, cacheCtx, typeNameMapper, insertPrefix: prefixes.insert }) : void 0;
5368
5600
  const nestedRuntime = nestedPlans ? createNestedWriteRuntime({ plans: nestedPlans, filterCtx }) : void 0;
5369
- const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
5601
+ const relationAggregateFactory = anyTable("relationAggregates") ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
5370
5602
  const queries = {};
5371
5603
  const mutations = {};
5372
5604
  const mutationTxCtx = createMutationTxCtx(options.transactions);
@@ -5384,7 +5616,7 @@ function generateSchemaData2(db, schema, relations, options) {
5384
5616
  prefixes.insert,
5385
5617
  prefixes.update,
5386
5618
  resolverFactory,
5387
- relationAggregateFactory,
5619
+ featureOf(tableName).relationAggregates ? relationAggregateFactory : void 0,
5388
5620
  nestedTypes
5389
5621
  )
5390
5622
  ])
@@ -5392,6 +5624,7 @@ function generateSchemaData2(db, schema, relations, options) {
5392
5624
  const inputs = {};
5393
5625
  const outputs = {};
5394
5626
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
5627
+ const tableFeatures = featureOf(tableName);
5395
5628
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
5396
5629
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
5397
5630
  const {
@@ -5423,7 +5656,7 @@ function generateSchemaData2(db, schema, relations, options) {
5423
5656
  typeName,
5424
5657
  typeNameMapper,
5425
5658
  filterCtx,
5426
- features.distinct,
5659
+ tableFeatures.distinct,
5427
5660
  limits
5428
5661
  );
5429
5662
  const selectSingleGenerated = generateSelectSingle2(
@@ -5439,7 +5672,7 @@ function generateSchemaData2(db, schema, relations, options) {
5439
5672
  filterCtx,
5440
5673
  limits
5441
5674
  );
5442
- const insertArrGenerated = features.insert ? generateInsertArray2(
5675
+ const insertArrGenerated = tableFeatures.insert ? generateInsertArray2(
5443
5676
  db,
5444
5677
  tableName,
5445
5678
  schema[tableName],
@@ -5454,7 +5687,7 @@ function generateSchemaData2(db, schema, relations, options) {
5454
5687
  nestedRuntime,
5455
5688
  limits
5456
5689
  ) : void 0;
5457
- const insertSingleGenerated = features.insert ? generateInsertSingle2(
5690
+ const insertSingleGenerated = tableFeatures.insert ? generateInsertSingle2(
5458
5691
  db,
5459
5692
  tableName,
5460
5693
  schema[tableName],
@@ -5469,8 +5702,8 @@ function generateSchemaData2(db, schema, relations, options) {
5469
5702
  nestedRuntime,
5470
5703
  limits
5471
5704
  ) : void 0;
5472
- const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_pg_core2.getTableConfig) : [];
5473
- const onConflictInput = features.upsert ? generateOnConflictInput({
5705
+ const uniqueSets = tableFeatures.upsert ? getUniqueColumnSets(schema[tableName], import_pg_core2.getTableConfig) : [];
5706
+ const onConflictInput = tableFeatures.upsert ? generateOnConflictInput({
5474
5707
  table: schema[tableName],
5475
5708
  typeName,
5476
5709
  uniqueSets,
@@ -5513,7 +5746,7 @@ function generateSchemaData2(db, schema, relations, options) {
5513
5746
  nestedRuntime,
5514
5747
  limits
5515
5748
  ) : void 0;
5516
- const updateGenerated = features.update ? generateUpdate2(
5749
+ const updateGenerated = tableFeatures.update ? generateUpdate2(
5517
5750
  db,
5518
5751
  tableName,
5519
5752
  schema[tableName],
@@ -5524,14 +5757,14 @@ function generateSchemaData2(db, schema, relations, options) {
5524
5757
  updateFieldName,
5525
5758
  typeName,
5526
5759
  false,
5527
- features.requireWhere,
5760
+ tableFeatures.requireWhere,
5528
5761
  typeNameMapper,
5529
5762
  filterCtx,
5530
5763
  mutationTxCtx,
5531
5764
  nestedRuntime,
5532
5765
  limits
5533
5766
  ) : void 0;
5534
- const updateSingleGenerated = features.update ? generateUpdate2(
5767
+ const updateSingleGenerated = tableFeatures.update ? generateUpdate2(
5535
5768
  db,
5536
5769
  tableName,
5537
5770
  schema[tableName],
@@ -5542,14 +5775,14 @@ function generateSchemaData2(db, schema, relations, options) {
5542
5775
  updateSingleFieldName,
5543
5776
  typeName,
5544
5777
  true,
5545
- features.requireWhere,
5778
+ tableFeatures.requireWhere,
5546
5779
  typeNameMapper,
5547
5780
  filterCtx,
5548
5781
  mutationTxCtx,
5549
5782
  nestedRuntime,
5550
5783
  limits
5551
5784
  ) : void 0;
5552
- const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
5785
+ const updateManyInput = tableFeatures.update && tableFeatures.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
5553
5786
  const updateManyGenerated = updateManyInput ? generateUpdateMany2(
5554
5787
  db,
5555
5788
  tableName,
@@ -5565,7 +5798,7 @@ function generateSchemaData2(db, schema, relations, options) {
5565
5798
  nestedRuntime,
5566
5799
  limits
5567
5800
  ) : void 0;
5568
- const deleteGenerated = features.delete ? generateDelete2(
5801
+ const deleteGenerated = tableFeatures.delete ? generateDelete2(
5569
5802
  db,
5570
5803
  tableName,
5571
5804
  schema[tableName],
@@ -5573,12 +5806,12 @@ function generateSchemaData2(db, schema, relations, options) {
5573
5806
  deleteFieldName,
5574
5807
  typeName,
5575
5808
  false,
5576
- features.requireWhere,
5809
+ tableFeatures.requireWhere,
5577
5810
  filterCtx,
5578
5811
  { tableName, relationMap: namedRelations, tables },
5579
5812
  mutationTxCtx
5580
5813
  ) : void 0;
5581
- const deleteSingleGenerated = features.delete ? generateDelete2(
5814
+ const deleteSingleGenerated = tableFeatures.delete ? generateDelete2(
5582
5815
  db,
5583
5816
  tableName,
5584
5817
  schema[tableName],
@@ -5586,12 +5819,12 @@ function generateSchemaData2(db, schema, relations, options) {
5586
5819
  deleteSingleFieldName,
5587
5820
  typeName,
5588
5821
  true,
5589
- features.requireWhere,
5822
+ tableFeatures.requireWhere,
5590
5823
  filterCtx,
5591
5824
  { tableName, relationMap: namedRelations, tables },
5592
5825
  mutationTxCtx
5593
5826
  ) : void 0;
5594
- const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
5827
+ const updateCountGenerated = tableFeatures.update && tableFeatures.countMutations ? generateWriteCount({
5595
5828
  db,
5596
5829
  tableName,
5597
5830
  table: schema[tableName],
@@ -5599,24 +5832,24 @@ function generateSchemaData2(db, schema, relations, options) {
5599
5832
  setArgs: updateInput,
5600
5833
  filterArgs: tableFilters,
5601
5834
  fieldName: updateCountFieldName,
5602
- requireWhere: features.requireWhere,
5835
+ requireWhere: tableFeatures.requireWhere,
5603
5836
  filterCtx,
5604
5837
  txCtx: mutationTxCtx,
5605
5838
  nested: nestedRuntime
5606
5839
  }) : void 0;
5607
- const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
5840
+ const deleteCountGenerated = tableFeatures.delete && tableFeatures.countMutations ? generateWriteCount({
5608
5841
  db,
5609
5842
  tableName,
5610
5843
  table: schema[tableName],
5611
5844
  kind: "delete",
5612
5845
  filterArgs: tableFilters,
5613
5846
  fieldName: deleteCountFieldName,
5614
- requireWhere: features.requireWhere,
5847
+ requireWhere: tableFeatures.requireWhere,
5615
5848
  filterCtx,
5616
5849
  txCtx: mutationTxCtx
5617
5850
  }) : void 0;
5618
- const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
5619
- const aggregateGenerated = features.aggregates ? generateAggregate(
5851
+ const aggregateType = tableFeatures.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
5852
+ const aggregateGenerated = tableFeatures.aggregates ? generateAggregate(
5620
5853
  db,
5621
5854
  tableName,
5622
5855
  schema[tableName],
@@ -5625,7 +5858,7 @@ function generateSchemaData2(db, schema, relations, options) {
5625
5858
  tableFilters,
5626
5859
  filterCtx
5627
5860
  ) : void 0;
5628
- const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
5861
+ const groupByType = tableFeatures.aggregates && tableFeatures.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
5629
5862
  const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
5630
5863
  const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
5631
5864
  const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
@@ -5753,9 +5986,9 @@ function generateSchemaData2(db, schema, relations, options) {
5753
5986
  }
5754
5987
  const activeInputs = [
5755
5988
  // The insert input types the upsert mutations too, so either feature keeps it.
5756
- ...features.insert || onConflictInput ? [insertInput] : [],
5989
+ ...tableFeatures.insert || onConflictInput ? [insertInput] : [],
5757
5990
  ...onConflictInput ? [onConflictInput] : [],
5758
- ...features.update ? [updateInput] : [],
5991
+ ...tableFeatures.update ? [updateInput] : [],
5759
5992
  ...updateManyInput ? [updateManyInput] : [],
5760
5993
  tableFilters,
5761
5994
  tableOrder
@@ -6335,6 +6568,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6335
6568
  const excludedTables = new Set(options.exclude?.tables ?? []);
6336
6569
  const tableEntries = schemaEntries.filter(([key, value]) => (0, import_drizzle_orm9.is)(value, import_sqlite_core2.SQLiteTable) && !excludedTables.has(key));
6337
6570
  const tables = Object.fromEntries(tableEntries);
6571
+ const featureOf = resolveTableFeatures(features);
6572
+ const anyTable = (feature) => tableEntries.some(([name]) => featureOf(name)[feature]);
6338
6573
  if (!tableEntries.length) {
6339
6574
  throw new Error(
6340
6575
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
@@ -6372,7 +6607,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6372
6607
  complexity,
6373
6608
  limits,
6374
6609
  docs: options.docs ?? {},
6375
- features
6610
+ featureOf
6376
6611
  };
6377
6612
  if (features.nestedWrites && db.resultKind === "sync") {
6378
6613
  throw new Error(
@@ -6388,7 +6623,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6388
6623
  ) : void 0;
6389
6624
  const nestedTypes = nestedPlans ? createNestedWriteTypes({ plans: nestedPlans, cacheCtx, typeNameMapper, insertPrefix: prefixes.insert }) : void 0;
6390
6625
  const nestedRuntime = nestedPlans ? createNestedWriteRuntime({ plans: nestedPlans, filterCtx }) : void 0;
6391
- const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
6626
+ const relationAggregateFactory = anyTable("relationAggregates") ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
6392
6627
  const queries = {};
6393
6628
  const mutations = {};
6394
6629
  if (options.transactions && db.resultKind === "sync") {
@@ -6411,7 +6646,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6411
6646
  prefixes.insert,
6412
6647
  prefixes.update,
6413
6648
  resolverFactory,
6414
- relationAggregateFactory,
6649
+ featureOf(tableName).relationAggregates ? relationAggregateFactory : void 0,
6415
6650
  nestedTypes
6416
6651
  )
6417
6652
  ])
@@ -6419,6 +6654,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6419
6654
  const inputs = {};
6420
6655
  const outputs = {};
6421
6656
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
6657
+ const tableFeatures = featureOf(tableName);
6422
6658
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
6423
6659
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
6424
6660
  const {
@@ -6450,7 +6686,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6450
6686
  typeName,
6451
6687
  typeNameMapper,
6452
6688
  filterCtx,
6453
- features.distinct,
6689
+ tableFeatures.distinct,
6454
6690
  limits
6455
6691
  );
6456
6692
  const selectSingleGenerated = generateSelectSingle3(
@@ -6466,7 +6702,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6466
6702
  filterCtx,
6467
6703
  limits
6468
6704
  );
6469
- const insertArrGenerated = features.insert ? generateInsertArray3(
6705
+ const insertArrGenerated = tableFeatures.insert ? generateInsertArray3(
6470
6706
  db,
6471
6707
  tableName,
6472
6708
  schema[tableName],
@@ -6481,7 +6717,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6481
6717
  nestedRuntime,
6482
6718
  limits
6483
6719
  ) : void 0;
6484
- const insertSingleGenerated = features.insert ? generateInsertSingle3(
6720
+ const insertSingleGenerated = tableFeatures.insert ? generateInsertSingle3(
6485
6721
  db,
6486
6722
  tableName,
6487
6723
  schema[tableName],
@@ -6496,8 +6732,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6496
6732
  nestedRuntime,
6497
6733
  limits
6498
6734
  ) : void 0;
6499
- const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_sqlite_core2.getTableConfig) : [];
6500
- const onConflictInput = features.upsert ? generateOnConflictInput({
6735
+ const uniqueSets = tableFeatures.upsert ? getUniqueColumnSets(schema[tableName], import_sqlite_core2.getTableConfig) : [];
6736
+ const onConflictInput = tableFeatures.upsert ? generateOnConflictInput({
6501
6737
  table: schema[tableName],
6502
6738
  typeName,
6503
6739
  uniqueSets,
@@ -6540,7 +6776,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6540
6776
  nestedRuntime,
6541
6777
  limits
6542
6778
  ) : void 0;
6543
- const updateGenerated = features.update ? generateUpdate3(
6779
+ const updateGenerated = tableFeatures.update ? generateUpdate3(
6544
6780
  db,
6545
6781
  tableName,
6546
6782
  schema[tableName],
@@ -6551,14 +6787,14 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6551
6787
  updateFieldName,
6552
6788
  typeName,
6553
6789
  false,
6554
- features.requireWhere,
6790
+ tableFeatures.requireWhere,
6555
6791
  typeNameMapper,
6556
6792
  filterCtx,
6557
6793
  mutationTxCtx,
6558
6794
  nestedRuntime,
6559
6795
  limits
6560
6796
  ) : void 0;
6561
- const updateSingleGenerated = features.update ? generateUpdate3(
6797
+ const updateSingleGenerated = tableFeatures.update ? generateUpdate3(
6562
6798
  db,
6563
6799
  tableName,
6564
6800
  schema[tableName],
@@ -6569,14 +6805,14 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6569
6805
  updateSingleFieldName,
6570
6806
  typeName,
6571
6807
  true,
6572
- features.requireWhere,
6808
+ tableFeatures.requireWhere,
6573
6809
  typeNameMapper,
6574
6810
  filterCtx,
6575
6811
  mutationTxCtx,
6576
6812
  nestedRuntime,
6577
6813
  limits
6578
6814
  ) : void 0;
6579
- const updateManyInput = features.update && features.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
6815
+ const updateManyInput = tableFeatures.update && tableFeatures.updateMany ? generateUpdateManyInput({ typeName, updatePrefix: prefixes.update, updateInput, tableFilters }) : void 0;
6580
6816
  const updateManyGenerated = updateManyInput ? generateUpdateMany3(
6581
6817
  db,
6582
6818
  tableName,
@@ -6592,7 +6828,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6592
6828
  nestedRuntime,
6593
6829
  limits
6594
6830
  ) : void 0;
6595
- const deleteGenerated = features.delete ? generateDelete3(
6831
+ const deleteGenerated = tableFeatures.delete ? generateDelete3(
6596
6832
  db,
6597
6833
  tableName,
6598
6834
  schema[tableName],
@@ -6600,12 +6836,12 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6600
6836
  deleteFieldName,
6601
6837
  typeName,
6602
6838
  false,
6603
- features.requireWhere,
6839
+ tableFeatures.requireWhere,
6604
6840
  filterCtx,
6605
6841
  { tableName, relationMap: namedRelations, tables },
6606
6842
  mutationTxCtx
6607
6843
  ) : void 0;
6608
- const deleteSingleGenerated = features.delete ? generateDelete3(
6844
+ const deleteSingleGenerated = tableFeatures.delete ? generateDelete3(
6609
6845
  db,
6610
6846
  tableName,
6611
6847
  schema[tableName],
@@ -6613,12 +6849,12 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6613
6849
  deleteSingleFieldName,
6614
6850
  typeName,
6615
6851
  true,
6616
- features.requireWhere,
6852
+ tableFeatures.requireWhere,
6617
6853
  filterCtx,
6618
6854
  { tableName, relationMap: namedRelations, tables },
6619
6855
  mutationTxCtx
6620
6856
  ) : void 0;
6621
- const updateCountGenerated = features.update && features.countMutations ? generateWriteCount({
6857
+ const updateCountGenerated = tableFeatures.update && tableFeatures.countMutations ? generateWriteCount({
6622
6858
  db,
6623
6859
  tableName,
6624
6860
  table: schema[tableName],
@@ -6626,24 +6862,24 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6626
6862
  setArgs: updateInput,
6627
6863
  filterArgs: tableFilters,
6628
6864
  fieldName: updateCountFieldName,
6629
- requireWhere: features.requireWhere,
6865
+ requireWhere: tableFeatures.requireWhere,
6630
6866
  filterCtx,
6631
6867
  txCtx: mutationTxCtx,
6632
6868
  nested: nestedRuntime
6633
6869
  }) : void 0;
6634
- const deleteCountGenerated = features.delete && features.countMutations ? generateWriteCount({
6870
+ const deleteCountGenerated = tableFeatures.delete && tableFeatures.countMutations ? generateWriteCount({
6635
6871
  db,
6636
6872
  tableName,
6637
6873
  table: schema[tableName],
6638
6874
  kind: "delete",
6639
6875
  filterArgs: tableFilters,
6640
6876
  fieldName: deleteCountFieldName,
6641
- requireWhere: features.requireWhere,
6877
+ requireWhere: tableFeatures.requireWhere,
6642
6878
  filterCtx,
6643
6879
  txCtx: mutationTxCtx
6644
6880
  }) : void 0;
6645
- const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
6646
- const aggregateGenerated = features.aggregates ? generateAggregate(
6881
+ const aggregateType = tableFeatures.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
6882
+ const aggregateGenerated = tableFeatures.aggregates ? generateAggregate(
6647
6883
  db,
6648
6884
  tableName,
6649
6885
  schema[tableName],
@@ -6652,7 +6888,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6652
6888
  tableFilters,
6653
6889
  filterCtx
6654
6890
  ) : void 0;
6655
- const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
6891
+ const groupByType = tableFeatures.aggregates && tableFeatures.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
6656
6892
  const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
6657
6893
  const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
6658
6894
  const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
@@ -6780,9 +7016,9 @@ var generateSchemaData3 = (db, schema, relations, options) => {
6780
7016
  }
6781
7017
  const activeInputs = [
6782
7018
  // The insert input types the upsert mutations too, so either feature keeps it.
6783
- ...features.insert || onConflictInput ? [insertInput] : [],
7019
+ ...tableFeatures.insert || onConflictInput ? [insertInput] : [],
6784
7020
  ...onConflictInput ? [onConflictInput] : [],
6785
- ...features.update ? [updateInput] : [],
7021
+ ...tableFeatures.update ? [updateInput] : [],
6786
7022
  ...updateManyInput ? [updateManyInput] : [],
6787
7023
  tableFilters,
6788
7024
  tableOrder
@@ -6843,22 +7079,11 @@ var buildSchema = (db, config) => {
6843
7079
  list: config?.suffixes?.list ?? "",
6844
7080
  single: config?.suffixes?.single ?? "Single"
6845
7081
  };
6846
- const typeNameMapper = config?.typeNameMapper;
6847
- const features = {
6848
- aggregates: config?.features?.aggregates ?? true,
6849
- groupBy: config?.features?.groupBy ?? true,
6850
- relationAggregates: config?.features?.relationAggregates ?? true,
6851
- distinct: config?.features?.distinct ?? true,
6852
- insert: config?.features?.insert ?? true,
6853
- update: config?.features?.update ?? true,
6854
- updateMany: config?.features?.updateMany ?? true,
6855
- delete: config?.features?.delete ?? true,
6856
- upsert: config?.features?.upsert ?? false,
6857
- nestedWrites: config?.features?.nestedWrites ?? false,
6858
- fieldUpdateOperations: config?.features?.fieldUpdateOperations ?? false,
6859
- countMutations: config?.features?.countMutations ?? false,
6860
- requireWhere: config?.features?.requireWhere ?? false
6861
- };
7082
+ const typeNameMapper = config?.typeNameMapper === "singularize" ? singularizeMapper : config?.typeNameMapper;
7083
+ const tableKeys = Object.entries(schema).filter(([, value]) => (0, import_drizzle_orm10.is)(value, import_drizzle_orm10.Table)).map(([key]) => key);
7084
+ const excludedTableNames = new Set(config?.exclude?.tables ?? []);
7085
+ const featureTables = tableKeys.filter((key) => !excludedTableNames.has(key));
7086
+ const forTable = resolveTableFeatures(config?.features);
6862
7087
  const complexityConfig = config?.complexity ?? true;
6863
7088
  const complexity = complexityConfig === false ? void 0 : {
6864
7089
  defaultListSize: (complexityConfig === true ? void 0 : complexityConfig.defaultListSize) ?? 10,
@@ -6895,10 +7120,8 @@ var buildSchema = (db, config) => {
6895
7120
  } : void 0;
6896
7121
  const exclude = config?.exclude;
6897
7122
  if (exclude) {
6898
- const tableNames = new Set(
6899
- Object.entries(schema).filter(([, value]) => (0, import_drizzle_orm10.is)(value, import_drizzle_orm10.Table)).map(([key]) => key)
6900
- );
6901
- const excludedTables = new Set(exclude.tables ?? []);
7123
+ const tableNames = new Set(tableKeys);
7124
+ const excludedTables = excludedTableNames;
6902
7125
  for (const tableName of excludedTables) {
6903
7126
  if (!tableNames.has(tableName)) {
6904
7127
  throw new Error(
@@ -6936,6 +7159,49 @@ var buildSchema = (db, config) => {
6936
7159
  }
6937
7160
  }
6938
7161
  }
7162
+ const featureConflicts = /* @__PURE__ */ new Map();
7163
+ const noteConflict = (message, tableName) => {
7164
+ const tables = featureConflicts.get(message);
7165
+ if (tables) {
7166
+ tables.push(tableName);
7167
+ } else {
7168
+ featureConflicts.set(message, [tableName]);
7169
+ }
7170
+ };
7171
+ for (const tableName of featureTables) {
7172
+ const tableFeatures = forTable(tableName);
7173
+ if (tableFeatures.upsert) {
7174
+ const missing = [!tableFeatures.insert ? "insert" : void 0, !tableFeatures.update ? "update" : void 0].filter(Boolean).join(" and ");
7175
+ if (missing) {
7176
+ noteConflict(
7177
+ `upsert is on while ${missing} is off, so the upsert mutations are a second write path past the operation you turned off`,
7178
+ tableName
7179
+ );
7180
+ }
7181
+ }
7182
+ if (config?.features?.nestedWrites && (!tableFeatures.insert || !tableFeatures.update)) {
7183
+ noteConflict(
7184
+ "nestedWrites is on while this table's own insert or update is off, so a nested `create` or `connect` under another table's mutation can still write it",
7185
+ tableName
7186
+ );
7187
+ }
7188
+ if (config?.features?.updateMany !== void 0 && tableFeatures.updateMany && !tableFeatures.update) {
7189
+ noteConflict("updateMany is on while update is off, so no batch update is generated", tableName);
7190
+ }
7191
+ if (config?.features?.groupBy !== void 0 && tableFeatures.groupBy && !tableFeatures.aggregates) {
7192
+ noteConflict("groupBy is on while aggregates is off, so no grouped query is generated", tableName);
7193
+ }
7194
+ if (tableFeatures.countMutations && !tableFeatures.update && !tableFeatures.delete) {
7195
+ noteConflict(
7196
+ "countMutations is on while update and delete are both off, so no count mutation is generated",
7197
+ tableName
7198
+ );
7199
+ }
7200
+ }
7201
+ for (const [message, tables] of featureConflicts) {
7202
+ const listed = tables.length > 5 ? `${tables.slice(0, 5).join(", ")} and ${tables.length - 5} more` : tables.join(", ");
7203
+ console.warn(`Drizzle-GraphQL Warning: config.features \u2014 ${message} (${listed}).`);
7204
+ }
6939
7205
  const eagerOpt = config?.eagerLoadRelations;
6940
7206
  const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
6941
7207
  if (!typeNameMapper && suffixes.list === suffixes.single) {
@@ -6962,7 +7228,7 @@ var buildSchema = (db, config) => {
6962
7228
  conflictDoNothing: config?.conflictDoNothing ?? false,
6963
7229
  typeNameMapper,
6964
7230
  shouldEagerLoad,
6965
- features,
7231
+ features: config?.features ?? {},
6966
7232
  complexity,
6967
7233
  scalars: config?.scalars,
6968
7234
  mapColumnType: config?.mapColumnType,
@@ -7024,6 +7290,7 @@ var buildSchema = (db, config) => {
7024
7290
  drizzleExecutorKey,
7025
7291
  extractFilters,
7026
7292
  extractOrderBy,
7027
- extractRelationJoinColumns
7293
+ extractRelationJoinColumns,
7294
+ singularizeMapper
7028
7295
  });
7029
7296
  //# sourceMappingURL=index.cjs.map