@vantreeseba/drizzle-graphql 1.0.3 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -30,36 +30,85 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ GraphQLBigIntString: () => GraphQLBigIntString,
34
+ GraphQLDate: () => import_graphql_scalars.GraphQLDate,
35
+ GraphQLDateTime: () => import_graphql_scalars.GraphQLDateTime,
36
+ GraphQLJSON: () => import_graphql_scalars.GraphQLJSON,
37
+ GraphQLUUID: () => import_graphql_scalars.GraphQLUUID,
33
38
  buildSchema: () => buildSchema,
39
+ createRelationResolverFactory: () => createRelationResolverFactory,
40
+ defaultErrorMapper: () => defaultErrorMapper,
41
+ drizzleExecutorKey: () => drizzleExecutorKey,
34
42
  extractFilters: () => extractFilters,
35
- extractOrderBy: () => extractOrderBy
43
+ extractOrderBy: () => extractOrderBy,
44
+ extractRelationJoinColumns: () => extractRelationJoinColumns
36
45
  });
37
46
  module.exports = __toCommonJS(index_exports);
38
- var import_drizzle_orm7 = require("drizzle-orm");
47
+ var import_drizzle_orm8 = require("drizzle-orm");
39
48
  var import_mysql_core3 = require("drizzle-orm/mysql-core");
40
49
  var import_pg_core3 = require("drizzle-orm/pg-core");
41
50
  var import_sqlite_core3 = require("drizzle-orm/sqlite-core");
42
- var import_graphql7 = require("graphql");
43
-
44
- // src/util/builders/mysql.ts
45
- var import_drizzle_orm4 = require("drizzle-orm");
46
- var import_mysql_core2 = require("drizzle-orm/mysql-core");
47
- var import_graphql4 = require("graphql");
48
- var import_graphql_parse_resolve_info = require("graphql-parse-resolve-info");
51
+ var import_graphql9 = require("graphql");
49
52
 
50
53
  // src/util/builders/common.ts
51
54
  var import_drizzle_orm3 = require("drizzle-orm");
52
- var import_graphql3 = require("graphql");
55
+ var import_graphql4 = require("graphql");
56
+
57
+ // src/util/batch-loader/index.ts
58
+ var DRIZZLE_LOADERS_KEY = /* @__PURE__ */ Symbol("drizzle-graphql-loaders");
59
+ var BatchLoader = class {
60
+ constructor(batchFn) {
61
+ this.batchFn = batchFn;
62
+ }
63
+ batch = [];
64
+ scheduled = false;
65
+ load(key) {
66
+ return new Promise((resolve, reject) => {
67
+ this.batch.push({ key, resolve, reject });
68
+ if (!this.scheduled) {
69
+ this.scheduled = true;
70
+ Promise.resolve().then(() => this.dispatch());
71
+ }
72
+ });
73
+ }
74
+ async dispatch() {
75
+ const current = this.batch.splice(0);
76
+ this.scheduled = false;
77
+ try {
78
+ const results = await this.batchFn(current.map(({ key }) => key));
79
+ for (let i = 0; i < current.length; i++) {
80
+ current[i].resolve(results[i]);
81
+ }
82
+ } catch (err) {
83
+ for (const { reject } of current) {
84
+ reject(err);
85
+ }
86
+ }
87
+ }
88
+ };
89
+ var getOrCreateLoader = (context, key, batchFn) => {
90
+ if (!context || typeof context !== "object") {
91
+ return new BatchLoader(batchFn);
92
+ }
93
+ if (!context[DRIZZLE_LOADERS_KEY]) {
94
+ context[DRIZZLE_LOADERS_KEY] = /* @__PURE__ */ new Map();
95
+ }
96
+ const loaders = context[DRIZZLE_LOADERS_KEY];
97
+ if (!loaders.has(key)) {
98
+ loaders.set(key, new BatchLoader(batchFn));
99
+ }
100
+ return loaders.get(key);
101
+ };
53
102
 
54
103
  // src/util/case-ops/index.ts
55
104
  var import_pluralize = __toESM(require("pluralize"), 1);
56
105
  var uncapitalize = (input) => input?.length ? `${input[0].toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
57
106
  var capitalize = (input) => input?.length ? `${input[0].toLocaleUpperCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
58
- var singularize = (input) => import_pluralize.default.singular(input);
59
107
 
60
108
  // src/util/data-mappers/index.ts
61
109
  var import_drizzle_orm = require("drizzle-orm");
62
110
  var import_graphql = require("graphql");
111
+ var isJsonColumn = (column) => (column.dataType ?? "").includes("json") && column.columnType !== "PgGeometryObject";
63
112
  var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
64
113
  if (Array.isArray(value)) {
65
114
  const relations = relationMap?.[tableName];
@@ -89,6 +138,9 @@ var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
89
138
  if (!column) {
90
139
  return value;
91
140
  }
141
+ if (isJsonColumn(column)) {
142
+ return value;
143
+ }
92
144
  if (value instanceof Date) {
93
145
  return value.toISOString();
94
146
  }
@@ -115,6 +167,11 @@ var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
115
167
  var remapToGraphQLSingleOutput = (queryOutput, tableName, table, relationMap) => {
116
168
  for (const [key, value] of Object.entries(queryOutput)) {
117
169
  if (value === void 0 || value === null) {
170
+ const relEntry = value === null ? relationMap?.[tableName]?.[key] : void 0;
171
+ if (relEntry && (0, import_drizzle_orm.is)(relEntry.relation, import_drizzle_orm.One)) {
172
+ queryOutput[key] = null;
173
+ continue;
174
+ }
118
175
  delete queryOutput[key];
119
176
  continue;
120
177
  }
@@ -161,17 +218,7 @@ var remapFromGraphQLCore = (value, column, columnName) => {
161
218
  }
162
219
  }
163
220
  if (dataType.includes("json") && column.columnType !== "PgGeometryObject") {
164
- if (typeof value !== "string") {
165
- return value;
166
- }
167
- try {
168
- return JSON.parse(value);
169
- } catch (e) {
170
- throw new import_graphql.GraphQLError(
171
- `Invalid JSON in field '${columnName}':
172
- ${e instanceof Error ? e.message : "Unknown error"}`
173
- );
174
- }
221
+ return value;
175
222
  }
176
223
  switch (dataType) {
177
224
  case "date": {
@@ -256,15 +303,55 @@ var import_drizzle_orm2 = require("drizzle-orm");
256
303
  var import_mysql_core = require("drizzle-orm/mysql-core");
257
304
  var import_pg_core = require("drizzle-orm/pg-core");
258
305
  var import_sqlite_core = require("drizzle-orm/sqlite-core");
306
+ var import_graphql3 = require("graphql");
307
+
308
+ // src/util/scalars/index.ts
259
309
  var import_graphql2 = require("graphql");
260
310
  var import_graphql_scalars = require("graphql-scalars");
311
+ var asDecimalString = (value) => {
312
+ if (typeof value === "bigint") {
313
+ return value.toString();
314
+ }
315
+ if (typeof value === "number") {
316
+ if (!Number.isInteger(value)) {
317
+ throw new import_graphql2.GraphQLError(`BigInt cannot represent non-integer value: ${value}`);
318
+ }
319
+ if (!Number.isSafeInteger(value)) {
320
+ throw new import_graphql2.GraphQLError(
321
+ `BigInt cannot represent the number ${value} without precision loss \u2014 pass it as a string instead`
322
+ );
323
+ }
324
+ return String(value);
325
+ }
326
+ if (typeof value === "string") {
327
+ if (!/^-?\d+$/.test(value)) {
328
+ throw new import_graphql2.GraphQLError(`BigInt cannot represent non-integer value: "${value}"`);
329
+ }
330
+ return value;
331
+ }
332
+ throw new import_graphql2.GraphQLError(`BigInt cannot represent value: ${JSON.stringify(value)}`);
333
+ };
334
+ var GraphQLBigIntString = new import_graphql2.GraphQLScalarType({
335
+ name: "BigInt",
336
+ description: "A 64-bit integer, transported as a decimal string so that values beyond JavaScript's safe integer range survive the round-trip intact.",
337
+ serialize: asDecimalString,
338
+ parseValue: asDecimalString,
339
+ parseLiteral: (ast) => {
340
+ if (ast.kind !== import_graphql2.Kind.STRING && ast.kind !== import_graphql2.Kind.INT) {
341
+ throw new import_graphql2.GraphQLError(`BigInt cannot represent a ${ast.kind}`, { nodes: ast });
342
+ }
343
+ return asDecimalString(ast.value);
344
+ }
345
+ });
346
+
347
+ // src/util/type-converter/index.ts
261
348
  var allowedNameChars = /^[a-zA-Z0-9_]+$/;
262
349
  var enumMap = /* @__PURE__ */ new WeakMap();
263
350
  var generateEnumCached = (column, columnName, tableName) => {
264
351
  if (enumMap.has(column)) {
265
352
  return enumMap.get(column);
266
353
  }
267
- const gqlEnum = new import_graphql2.GraphQLEnumType({
354
+ const gqlEnum = new import_graphql3.GraphQLEnumType({
268
355
  name: `${capitalize(tableName)}${capitalize(columnName)}Enum`,
269
356
  values: Object.fromEntries(
270
357
  column.enumValues.map((e, index) => [
@@ -279,25 +366,25 @@ var generateEnumCached = (column, columnName, tableName) => {
279
366
  enumMap.set(column, gqlEnum);
280
367
  return gqlEnum;
281
368
  };
282
- var geoXyType = new import_graphql2.GraphQLObjectType({
369
+ var geoXyType = new import_graphql3.GraphQLObjectType({
283
370
  name: "PgGeometryObject",
284
371
  fields: {
285
- x: { type: import_graphql2.GraphQLFloat },
286
- y: { type: import_graphql2.GraphQLFloat }
372
+ x: { type: import_graphql3.GraphQLFloat },
373
+ y: { type: import_graphql3.GraphQLFloat }
287
374
  }
288
375
  });
289
- var geoXyInputType = new import_graphql2.GraphQLInputObjectType({
376
+ var geoXyInputType = new import_graphql3.GraphQLInputObjectType({
290
377
  name: "PgGeometryObjectInput",
291
378
  fields: {
292
- x: { type: import_graphql2.GraphQLFloat },
293
- y: { type: import_graphql2.GraphQLFloat }
379
+ x: { type: import_graphql3.GraphQLFloat },
380
+ y: { type: import_graphql3.GraphQLFloat }
294
381
  }
295
382
  });
296
383
  var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
297
384
  const { type: baseType } = (0, import_drizzle_orm2.extractExtendedColumnType)(column);
298
385
  switch (baseType) {
299
386
  case "boolean":
300
- return { type: import_graphql2.GraphQLBoolean, description: "Boolean" };
387
+ return { type: import_graphql3.GraphQLBoolean, description: "Boolean" };
301
388
  case "object":
302
389
  if (column instanceof import_pg_core.PgTimestamp || column instanceof import_pg_core.PgDate) {
303
390
  return { type: import_graphql_scalars.GraphQLDateTime, description: "DateTime" };
@@ -306,9 +393,9 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
306
393
  type: isInput ? geoXyInputType : geoXyType,
307
394
  description: "Geometry points XY"
308
395
  } : column.columnType === "PgBytea" ? {
309
- type: new import_graphql2.GraphQLList(new import_graphql2.GraphQLNonNull(import_graphql2.GraphQLInt)),
396
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLInt)),
310
397
  description: "Buffer"
311
- } : { type: import_graphql2.GraphQLString, description: "JSON" };
398
+ } : { type: import_graphql_scalars.GraphQLJSON, description: "JSON" };
312
399
  case "string":
313
400
  if (column.enumValues?.length) {
314
401
  return { type: generateEnumCached(column, columnName, tableName) };
@@ -316,34 +403,37 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
316
403
  if (column instanceof import_pg_core.PgTimestamp || column instanceof import_pg_core.PgTimestampString) {
317
404
  return { type: import_graphql_scalars.GraphQLDateTime, description: "DateTime" };
318
405
  }
406
+ if (column instanceof import_pg_core.PgUUID) {
407
+ return { type: import_graphql_scalars.GraphQLUUID, description: "UUID" };
408
+ }
319
409
  if (column instanceof import_pg_core.PgDateString) {
320
- return isInput ? { type: import_graphql2.GraphQLString, description: "Date" } : { type: import_graphql_scalars.GraphQLDate, description: "Date" };
410
+ return isInput ? { type: import_graphql3.GraphQLString, description: "Date" } : { type: import_graphql_scalars.GraphQLDate, description: "Date" };
321
411
  }
322
- return { type: import_graphql2.GraphQLString, description: "String" };
412
+ return { type: import_graphql3.GraphQLString, description: "String" };
323
413
  case "bigint":
324
- return { type: import_graphql2.GraphQLString, description: "BigInt" };
414
+ return { type: GraphQLBigIntString, description: "BigInt" };
325
415
  case "number": {
326
416
  const dims = column.dimensions;
327
417
  if (dims !== void 0 && dims > 0) {
328
418
  const baseDesc = (0, import_drizzle_orm2.is)(column, import_pg_core.PgInteger) || (0, import_drizzle_orm2.is)(column, import_pg_core.PgSerial) ? "Integer" : "Float";
329
- const baseType2 = baseDesc === "Integer" ? import_graphql2.GraphQLInt : import_graphql2.GraphQLFloat;
419
+ const baseType2 = baseDesc === "Integer" ? import_graphql3.GraphQLInt : import_graphql3.GraphQLFloat;
330
420
  return {
331
- type: new import_graphql2.GraphQLList(new import_graphql2.GraphQLNonNull(baseType2)),
421
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(baseType2)),
332
422
  description: `Array<${baseDesc}>`
333
423
  };
334
424
  }
335
- return (0, import_drizzle_orm2.is)(column, import_pg_core.PgInteger) || (0, import_drizzle_orm2.is)(column, import_pg_core.PgSerial) || (0, import_drizzle_orm2.is)(column, import_mysql_core.MySqlInt) || (0, import_drizzle_orm2.is)(column, import_mysql_core.MySqlSerial) || (0, import_drizzle_orm2.is)(column, import_sqlite_core.SQLiteInteger) ? { type: import_graphql2.GraphQLInt, description: "Integer" } : { type: import_graphql2.GraphQLFloat, description: "Float" };
425
+ return (0, import_drizzle_orm2.is)(column, import_pg_core.PgInteger) || (0, import_drizzle_orm2.is)(column, import_pg_core.PgSerial) || (0, import_drizzle_orm2.is)(column, import_mysql_core.MySqlInt) || (0, import_drizzle_orm2.is)(column, import_mysql_core.MySqlSerial) || (0, import_drizzle_orm2.is)(column, import_sqlite_core.SQLiteInteger) ? { type: import_graphql3.GraphQLInt, description: "Integer" } : { type: import_graphql3.GraphQLFloat, description: "Float" };
336
426
  }
337
427
  case "array": {
338
428
  if (column.columnType === "PgVector") {
339
429
  return {
340
- type: new import_graphql2.GraphQLList(new import_graphql2.GraphQLNonNull(import_graphql2.GraphQLFloat)),
430
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLFloat)),
341
431
  description: "Array<Float>"
342
432
  };
343
433
  }
344
434
  if (column.columnType === "PgGeometry") {
345
435
  return {
346
- type: new import_graphql2.GraphQLList(new import_graphql2.GraphQLNonNull(import_graphql2.GraphQLFloat)),
436
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLFloat)),
347
437
  description: "Tuple<[Float, Float]>"
348
438
  };
349
439
  }
@@ -354,7 +444,7 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
354
444
  isInput
355
445
  );
356
446
  return {
357
- type: new import_graphql2.GraphQLList(new import_graphql2.GraphQLNonNull(innerType.type)),
447
+ type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(innerType.type)),
358
448
  description: `Array<${innerType.description}>`
359
449
  };
360
450
  }
@@ -362,26 +452,6 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
362
452
  throw new Error(`Drizzle-GraphQL Error: Type ${column.dataType} is not implemented!`);
363
453
  }
364
454
  };
365
- var drizzleRelationToGraphQLInsertType = (tables, relationMap) => {
366
- if (!relationMap) {
367
- return null;
368
- }
369
- for (const [tableName, _val] of Object.entries(relationMap)) {
370
- const table = tables[tableName];
371
- if (!table) {
372
- continue;
373
- }
374
- const columns = (0, import_drizzle_orm2.getColumns)(table);
375
- const columnEntries = Object.entries(columns).filter(([_key, value]) => value.primary);
376
- const _connectFields = Object.fromEntries(
377
- columnEntries.map(([columnName, columnDescription]) => [
378
- columnName,
379
- drizzleColumnToGraphQLType(columnDescription, columnName, tableName, false, true, true)
380
- ])
381
- );
382
- }
383
- return null;
384
- };
385
455
  var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable = false, defaultIsNullable = false, isInput = false) => {
386
456
  const typeDesc = columnToGraphQLCore(column, columnName, tableName, isInput);
387
457
  const noDesc = ["string", "boolean", "number"];
@@ -394,7 +464,7 @@ var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable =
394
464
  }
395
465
  if (column.notNull && !(defaultIsNullable && (column.hasDefault || column.defaultFn))) {
396
466
  return {
397
- type: new import_graphql2.GraphQLNonNull(typeDesc.type),
467
+ type: new import_graphql3.GraphQLNonNull(typeDesc.type),
398
468
  description: typeDesc.description
399
469
  };
400
470
  }
@@ -403,7 +473,10 @@ var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable =
403
473
 
404
474
  // src/util/builders/common.ts
405
475
  var rqbCrashTypes = ["SQLiteBigInt", "SQLiteBlobJson", "SQLiteBlobBuffer"];
406
- var toTypeName = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
476
+ var resolveTypeName = (name, typeNameMapper) => {
477
+ const mapped = typeNameMapper?.(name);
478
+ return mapped ? capitalize(mapped.singular) : capitalize(name);
479
+ };
407
480
  var buildNamedRelations = (relations, tableEntries) => {
408
481
  const namedRelations = {};
409
482
  for (const [relTableName, relConfig] of Object.entries(relations)) {
@@ -436,7 +509,172 @@ var buildNamedRelations = (relations, tableEntries) => {
436
509
  }
437
510
  return namedRelations;
438
511
  };
439
- var extractSelectedColumnsFromTree = (tree, table) => {
512
+ var attachTargetPrimaryKeys = (namedRelations, tables, resolvePkNames) => {
513
+ const cache = /* @__PURE__ */ new Map();
514
+ for (const rels of Object.values(namedRelations)) {
515
+ for (const relEntry of Object.values(rels)) {
516
+ const { targetTableName } = relEntry;
517
+ let pk = cache.get(targetTableName);
518
+ if (!pk) {
519
+ const targetTable = tables[targetTableName];
520
+ pk = targetTable ? resolvePkNames(targetTable) : [];
521
+ cache.set(targetTableName, pk);
522
+ }
523
+ relEntry.targetPkNames = pk;
524
+ }
525
+ }
526
+ };
527
+ var extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
528
+ const rel = relEntry.relation ?? relEntry;
529
+ const sourceColumns = rel.sourceColumns;
530
+ const targetColumns = rel.targetColumns;
531
+ if (!sourceColumns?.length || !targetColumns?.length) {
532
+ return void 0;
533
+ }
534
+ const sourceCol = sourceColumns[0];
535
+ const targetCol = targetColumns[0];
536
+ const parentCols = (0, import_drizzle_orm3.getColumns)(parentTable);
537
+ const localColPropName = Object.entries(parentCols).find(([, c]) => c === sourceCol)?.[0];
538
+ const targetCols = (0, import_drizzle_orm3.getColumns)(targetTable);
539
+ const foreignColPropName = Object.entries(targetCols).find(([, c]) => c === targetCol)?.[0];
540
+ if (!localColPropName || !foreignColPropName) {
541
+ return void 0;
542
+ }
543
+ return { localColPropName, foreignCol: targetCol, foreignColPropName };
544
+ };
545
+ var drizzleExecutorKey = /* @__PURE__ */ Symbol.for("drizzle-graphql:executor");
546
+ var resolveExecutor = (db, context) => {
547
+ if (context && typeof context === "object") {
548
+ const executor = context[drizzleExecutorKey];
549
+ if (executor) {
550
+ return executor;
551
+ }
552
+ }
553
+ return db;
554
+ };
555
+ var resolveQueryExecutor = (db, context, tableName, buildTimeQueryBase) => {
556
+ const executor = resolveExecutor(db, context);
557
+ return {
558
+ executor,
559
+ queryBase: buildTimeQueryBase ? executor?.query?.[tableName] ?? buildTimeQueryBase : buildTimeQueryBase
560
+ };
561
+ };
562
+ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
563
+ const cols = (0, import_drizzle_orm3.getColumns)(targetTable);
564
+ const orderExprs = [
565
+ ...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
566
+ ...primaryKeyOrderExprs(targetTable, pkNames)
567
+ ];
568
+ const orderClause = orderExprs.length ? import_drizzle_orm3.sql` order by ${import_drizzle_orm3.sql.join(orderExprs, import_drizzle_orm3.sql`, `)}` : import_drizzle_orm3.sql``;
569
+ const RN = "__drizzle_graphql_rn";
570
+ const rowNumber = import_drizzle_orm3.sql`row_number() over (partition by ${foreignCol}${orderClause})`.as(RN);
571
+ const sub = db.select({ ...cols, [RN]: rowNumber }).from(targetTable).where(whereCondition).as("__paginated");
572
+ const lower = offset ?? 0;
573
+ const windowConds = [(0, import_drizzle_orm3.gt)(sub[RN], lower)];
574
+ if (limit != null) {
575
+ windowConds.push((0, import_drizzle_orm3.lte)(sub[RN], lower + limit));
576
+ }
577
+ const rows = await db.select().from(sub).where((0, import_drizzle_orm3.and)(...windowConds)).orderBy(sub[RN]);
578
+ for (const row of rows) {
579
+ delete row[RN];
580
+ }
581
+ return rows;
582
+ };
583
+ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, relationName, relEntry, isOne }) => {
584
+ const parentTable = tables[tableName];
585
+ const targetTableName = relEntry.targetTableName;
586
+ const targetTable = tables[targetTableName];
587
+ if (!parentTable || !targetTable) {
588
+ return void 0;
589
+ }
590
+ const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
591
+ if (!joinCols) {
592
+ return void 0;
593
+ }
594
+ const { localColPropName, foreignCol, foreignColPropName } = joinCols;
595
+ const targetPkNames = relEntry.targetPkNames ?? [];
596
+ return async (parent, args, context) => {
597
+ if (parent[relationName] !== void 0) {
598
+ return parent[relationName];
599
+ }
600
+ const localValue = parent[localColPropName];
601
+ if (localValue == null) {
602
+ return isOne ? null : [];
603
+ }
604
+ const { where: whereArg, orderBy: orderByArg, limit, offset } = args ?? {};
605
+ const argsKey = JSON.stringify({
606
+ where: whereArg ?? null,
607
+ orderBy: orderByArg ?? null,
608
+ limit: limit ?? null,
609
+ offset: offset ?? null
610
+ });
611
+ const loaderKey = `${tableName}::${relationName}::${argsKey}`;
612
+ const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
613
+ const executor = resolveExecutor(db, context);
614
+ const uniqueIds = [...new Set(parentIds)];
615
+ const whereCondition = (0, import_drizzle_orm3.and)(
616
+ (0, import_drizzle_orm3.inArray)(foreignCol, uniqueIds),
617
+ whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0
618
+ );
619
+ let rows;
620
+ if (limit != null || offset != null) {
621
+ rows = await batchedPaginatedRelationQuery(
622
+ executor,
623
+ targetTable,
624
+ foreignCol,
625
+ whereCondition,
626
+ orderByArg,
627
+ limit ?? null,
628
+ offset ?? null,
629
+ targetPkNames
630
+ );
631
+ } else {
632
+ let q = executor.select().from(targetTable).where(whereCondition);
633
+ if (orderByArg) {
634
+ q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
635
+ }
636
+ rows = await q;
637
+ }
638
+ if (isOne) {
639
+ const byKey = new Map(rows.map((row) => [String(row[foreignColPropName]), row]));
640
+ remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
641
+ return parentIds.map((id) => byKey.get(String(id)) ?? null);
642
+ }
643
+ const grouped = new Map(uniqueIds.map((id) => [String(id), []]));
644
+ for (const row of rows) {
645
+ grouped.get(String(row[foreignColPropName]))?.push(row);
646
+ }
647
+ remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
648
+ return parentIds.map((id) => grouped.get(String(id)) ?? []);
649
+ });
650
+ return loader.load(localValue);
651
+ };
652
+ };
653
+ var AGGREGATE_FIELD_SUFFIX = "Aggregate";
654
+ var relationAggregateJoinColumns = (tree, table, selectionCtx) => {
655
+ const relations = selectionCtx?.relationMap[selectionCtx.tableName];
656
+ if (!relations || !selectionCtx) {
657
+ return [];
658
+ }
659
+ const tableColumns = (0, import_drizzle_orm3.getColumns)(table);
660
+ const needed = [];
661
+ for (const fieldData of Object.values(tree)) {
662
+ if (tableColumns[fieldData.name] || !fieldData.name.endsWith(AGGREGATE_FIELD_SUFFIX)) {
663
+ continue;
664
+ }
665
+ const relEntry = relations[fieldData.name.slice(0, -AGGREGATE_FIELD_SUFFIX.length)];
666
+ const targetTable = relEntry ? selectionCtx.tables[relEntry.targetTableName] : void 0;
667
+ if (!relEntry || !targetTable) {
668
+ continue;
669
+ }
670
+ const joinCols = extractRelationJoinColumns(relEntry, table, targetTable);
671
+ if (joinCols) {
672
+ needed.push(joinCols.localColPropName);
673
+ }
674
+ }
675
+ return needed;
676
+ };
677
+ var extractSelectedColumnsFromTree = (tree, table, selectionCtx) => {
440
678
  const tableColumns = (0, import_drizzle_orm3.getColumns)(table);
441
679
  const treeEntries = Object.entries(tree);
442
680
  const selectedColumns = [];
@@ -446,6 +684,9 @@ var extractSelectedColumnsFromTree = (tree, table) => {
446
684
  }
447
685
  selectedColumns.push([fieldData.name, true]);
448
686
  }
687
+ for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
688
+ selectedColumns.push([columnName, true]);
689
+ }
449
690
  if (!selectedColumns.length) {
450
691
  const columnKeys = Object.entries(tableColumns);
451
692
  const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
@@ -453,7 +694,7 @@ var extractSelectedColumnsFromTree = (tree, table) => {
453
694
  }
454
695
  return Object.fromEntries(selectedColumns);
455
696
  };
456
- var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
697
+ var extractSelectedColumnsFromTreeSQLFormat = (tree, table, selectionCtx) => {
457
698
  const tableColumns = (0, import_drizzle_orm3.getColumns)(table);
458
699
  const treeEntries = Object.entries(tree);
459
700
  const selectedColumns = [];
@@ -463,6 +704,9 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
463
704
  }
464
705
  selectedColumns.push([fieldData.name, tableColumns[fieldData.name]]);
465
706
  }
707
+ for (const columnName of relationAggregateJoinColumns(tree, table, selectionCtx)) {
708
+ selectedColumns.push([columnName, tableColumns[columnName]]);
709
+ }
466
710
  if (!selectedColumns.length) {
467
711
  const columnKeys = Object.entries(tableColumns);
468
712
  const columnName = columnKeys.find((e) => rqbCrashTypes.find((haram) => e[1].columnType !== haram))?.[0] ?? columnKeys[0][0];
@@ -470,12 +714,12 @@ var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
470
714
  }
471
715
  return Object.fromEntries(selectedColumns);
472
716
  };
473
- var innerOrder = new import_graphql3.GraphQLInputObjectType({
717
+ var innerOrder = new import_graphql4.GraphQLInputObjectType({
474
718
  name: "InnerOrder",
475
719
  fields: {
476
720
  direction: {
477
- type: new import_graphql3.GraphQLNonNull(
478
- new import_graphql3.GraphQLEnumType({
721
+ type: new import_graphql4.GraphQLNonNull(
722
+ new import_graphql4.GraphQLEnumType({
479
723
  name: "OrderDirection",
480
724
  description: "Order by direction",
481
725
  values: {
@@ -492,7 +736,7 @@ var innerOrder = new import_graphql3.GraphQLInputObjectType({
492
736
  )
493
737
  },
494
738
  priority: {
495
- type: new import_graphql3.GraphQLNonNull(import_graphql3.GraphQLInt),
739
+ type: new import_graphql4.GraphQLNonNull(import_graphql4.GraphQLInt),
496
740
  description: "Priority of current field"
497
741
  }
498
742
  }
@@ -501,13 +745,13 @@ var resolveGenericFilterName = (column, columnName, columnGraphQLType) => {
501
745
  if (columnName === "id" || columnName.endsWith("Id")) {
502
746
  return "Id";
503
747
  }
504
- if (columnGraphQLType.type === import_graphql3.GraphQLBoolean) {
748
+ if (columnGraphQLType.type === import_graphql4.GraphQLBoolean) {
505
749
  return "Boolean";
506
750
  }
507
- if (columnGraphQLType.type instanceof import_graphql3.GraphQLEnumType) {
751
+ if (columnGraphQLType.type instanceof import_graphql4.GraphQLEnumType) {
508
752
  return columnGraphQLType.type.name;
509
753
  }
510
- if (columnGraphQLType.type instanceof import_graphql3.GraphQLList) {
754
+ if (columnGraphQLType.type instanceof import_graphql4.GraphQLList) {
511
755
  const desc2 = columnGraphQLType.description ?? "";
512
756
  return desc2.includes("Integer") ? "IntArray" : "FloatArray";
513
757
  }
@@ -526,7 +770,7 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
526
770
  }
527
771
  const colType = columnGraphQLType.type;
528
772
  const colDesc = columnGraphQLType.description;
529
- const colArr = new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(colType));
773
+ const colArr = new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(colType));
530
774
  const isId = genericName === "Id";
531
775
  const baseFields = {
532
776
  eq: { type: colType, description: colDesc },
@@ -536,26 +780,26 @@ var generateColumnFilterValues = (column, tableName, columnName, cacheCtx) => {
536
780
  gt: { type: colType, description: colDesc },
537
781
  gte: { type: colType, description: colDesc },
538
782
  ...isId ? {} : {
539
- like: { type: import_graphql3.GraphQLString },
540
- notLike: { type: import_graphql3.GraphQLString },
541
- ilike: { type: import_graphql3.GraphQLString },
542
- notIlike: { type: import_graphql3.GraphQLString }
783
+ like: { type: import_graphql4.GraphQLString },
784
+ notLike: { type: import_graphql4.GraphQLString },
785
+ ilike: { type: import_graphql4.GraphQLString },
786
+ notIlike: { type: import_graphql4.GraphQLString }
543
787
  },
544
788
  inArray: { type: colArr, description: `Array<${colDesc}>` },
545
789
  notInArray: { type: colArr, description: `Array<${colDesc}>` },
546
- isNull: { type: import_graphql3.GraphQLBoolean },
547
- isNotNull: { type: import_graphql3.GraphQLBoolean }
790
+ isNull: { type: import_graphql4.GraphQLBoolean },
791
+ isNotNull: { type: import_graphql4.GraphQLBoolean }
548
792
  };
549
- const orType = new import_graphql3.GraphQLInputObjectType({
793
+ const orType = new import_graphql4.GraphQLInputObjectType({
550
794
  name: `${genericName}FilterOr`,
551
795
  fields: { ...baseFields }
552
796
  });
553
- const mainType = new import_graphql3.GraphQLInputObjectType({
797
+ const mainType = new import_graphql4.GraphQLInputObjectType({
554
798
  name: `${genericName}Filter`,
555
799
  fields: {
556
800
  ...baseFields,
557
801
  OR: {
558
- type: new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(orType))
802
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(orType))
559
803
  }
560
804
  }
561
805
  });
@@ -613,51 +857,125 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
613
857
  fieldMap.set(table, remapped);
614
858
  return remapped;
615
859
  };
616
- var orderTypeMap = /* @__PURE__ */ new WeakMap();
617
- var generateTableOrderTypeCached = (table, tableName, singularTypes) => {
618
- if (orderTypeMap.has(table)) {
619
- return orderTypeMap.get(table);
860
+ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx) => {
861
+ if (cacheCtx.orderTypeCache.has(table)) {
862
+ return cacheCtx.orderTypeCache.get(table);
620
863
  }
621
864
  const orderColumns = generateTableOrderCached(table);
622
- const order = new import_graphql3.GraphQLInputObjectType({
623
- name: `${toTypeName(tableName, singularTypes)}OrderBy`,
865
+ const order = new import_graphql4.GraphQLInputObjectType({
866
+ name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
624
867
  fields: orderColumns
625
868
  });
626
- orderTypeMap.set(table, order);
869
+ cacheCtx.orderTypeCache.set(table, order);
627
870
  return order;
628
871
  };
629
- var filterTypeMap = /* @__PURE__ */ new WeakMap();
630
- var generateTableFilterTypeCached = (table, tableName, cacheCtx, singularTypes) => {
631
- if (filterTypeMap.has(table)) {
632
- return filterTypeMap.get(table);
872
+ var isFilterableRelation = (relation) => !relation.through;
873
+ var generateListRelationFilterCached = (targetTable, targetTableName, cacheCtx, typeNameMapper, relationMap, tables) => {
874
+ const cached = cacheCtx.listRelationFilterCache.get(targetTableName);
875
+ if (cached) {
876
+ return cached;
633
877
  }
634
- const filterColumns = generateTableFilterValuesCached(table, tableName, cacheCtx);
635
- const filters = new import_graphql3.GraphQLInputObjectType({
636
- name: `${toTypeName(tableName, singularTypes)}Filters`,
637
- fields: {
878
+ const listFilter = new import_graphql4.GraphQLInputObjectType({
879
+ name: `${resolveTypeName(targetTableName, typeNameMapper)}ListRelationFilter`,
880
+ fields: () => {
881
+ const targetFilters = generateTableFilterTypeCached(
882
+ targetTable,
883
+ targetTableName,
884
+ cacheCtx,
885
+ typeNameMapper,
886
+ relationMap,
887
+ tables
888
+ );
889
+ return {
890
+ some: { type: targetFilters, description: "At least one related row matches" },
891
+ none: { type: targetFilters, description: "No related row matches" },
892
+ every: { type: targetFilters, description: "Every related row matches" }
893
+ };
894
+ }
895
+ });
896
+ cacheCtx.listRelationFilterCache.set(targetTableName, listFilter);
897
+ return listFilter;
898
+ };
899
+ var generateRelationFilterFields = (tableName, cacheCtx, typeNameMapper, columnFields, relationMap, tables) => {
900
+ const relations = relationMap?.[tableName];
901
+ if (!relations || !tables) {
902
+ return {};
903
+ }
904
+ const fields = {};
905
+ for (const [relationName, relEntry] of Object.entries(relations)) {
906
+ if (relationName in columnFields) {
907
+ continue;
908
+ }
909
+ const targetTable = tables[relEntry.targetTableName];
910
+ const relation = relEntry.relation ?? relEntry;
911
+ if (!targetTable || !isFilterableRelation(relation)) {
912
+ continue;
913
+ }
914
+ fields[relationName] = (0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One) ? {
915
+ type: generateTableFilterTypeCached(
916
+ targetTable,
917
+ relEntry.targetTableName,
918
+ cacheCtx,
919
+ typeNameMapper,
920
+ relationMap,
921
+ tables
922
+ ),
923
+ description: `Matches rows whose ${relationName} matches these filters`
924
+ } : {
925
+ type: generateListRelationFilterCached(
926
+ targetTable,
927
+ relEntry.targetTableName,
928
+ cacheCtx,
929
+ typeNameMapper,
930
+ relationMap,
931
+ tables
932
+ )
933
+ };
934
+ }
935
+ return fields;
936
+ };
937
+ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper, relationMap, tables) => {
938
+ if (cacheCtx.filterTypeCache.has(table)) {
939
+ return cacheCtx.filterTypeCache.get(table);
940
+ }
941
+ const buildFields = () => {
942
+ const filterColumns = generateTableFilterValuesCached(table, tableName, cacheCtx);
943
+ return {
638
944
  ...filterColumns,
945
+ ...generateRelationFilterFields(tableName, cacheCtx, typeNameMapper, filterColumns, relationMap, tables)
946
+ };
947
+ };
948
+ const orFilters = new import_graphql4.GraphQLInputObjectType({
949
+ name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
950
+ fields: buildFields
951
+ });
952
+ const filters = new import_graphql4.GraphQLInputObjectType({
953
+ name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
954
+ fields: () => ({
955
+ ...buildFields(),
639
956
  OR: {
640
- type: new import_graphql3.GraphQLList(
641
- new import_graphql3.GraphQLNonNull(
642
- new import_graphql3.GraphQLInputObjectType({
643
- name: `${toTypeName(tableName, singularTypes)}FiltersOr`,
644
- fields: filterColumns
645
- })
646
- )
647
- )
957
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(orFilters))
648
958
  }
649
- }
959
+ })
650
960
  });
651
- filterTypeMap.set(table, filters);
961
+ cacheCtx.filterTypeCache.set(table, filters);
652
962
  return filters;
653
963
  };
654
- var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, _relationsDepthLimit, cacheCtx, singularTypes, usedTables = /* @__PURE__ */ new Set()) => {
964
+ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0, relationAggregateFactory) => {
655
965
  const table = tables[tableName];
656
- const order = withOrder ? generateTableOrderTypeCached(table, tableName, singularTypes) : void 0;
657
- const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, singularTypes);
966
+ const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
967
+ const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper, relationMap, tables);
658
968
  const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
659
969
  const relationsForTable = relationMap[tableName];
660
970
  const relationEntries = relationsForTable ? Object.entries(relationsForTable) : [];
971
+ if (relationsDepthLimit !== void 0 && currentDepth >= relationsDepthLimit) {
972
+ return {
973
+ order,
974
+ filters,
975
+ tableFields,
976
+ relationFields: {}
977
+ };
978
+ }
661
979
  if (usedTables.has(tableName)) {
662
980
  return {
663
981
  order,
@@ -681,8 +999,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
681
999
  cacheCtx.relationFieldContainers.set(tableName, container);
682
1000
  }
683
1001
  if (isRootCall && !cacheCtx.objectTypeCache.has(tableName)) {
684
- const typeName = toTypeName(tableName, singularTypes);
685
- const shell = new import_graphql3.GraphQLObjectType({
1002
+ const typeName = resolveTypeName(tableName, typeNameMapper);
1003
+ const shell = new import_graphql4.GraphQLObjectType({
686
1004
  name: typeName,
687
1005
  fields: () => ({ ...tableFields, ...container.fields })
688
1006
  });
@@ -705,10 +1023,13 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
705
1023
  relationName,
706
1024
  // fromRelationName for the relation type
707
1025
  !isOne,
708
- void 0,
1026
+ relationsDepthLimit,
709
1027
  cacheCtx,
710
- singularTypes,
711
- nextUsedTables
1028
+ typeNameMapper,
1029
+ nextUsedTables,
1030
+ resolverFactory,
1031
+ currentDepth + 1,
1032
+ relationAggregateFactory
712
1033
  );
713
1034
  let relType = cacheCtx.objectTypeCache.get(targetTableName);
714
1035
  if (!relType) {
@@ -720,12 +1041,13 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
720
1041
  cacheCtx.relationFieldContainers.set(targetTableName, targetContainer);
721
1042
  }
722
1043
  const capturedTargetContainer = targetContainer;
723
- relType = new import_graphql3.GraphQLObjectType({
724
- name: toTypeName(targetTableName, singularTypes),
1044
+ relType = new import_graphql4.GraphQLObjectType({
1045
+ name: resolveTypeName(targetTableName, typeNameMapper),
725
1046
  fields: () => ({ ...targetTableFields, ...capturedTargetContainer.fields })
726
1047
  });
727
1048
  cacheCtx.objectTypeCache.set(targetTableName, relType);
728
1049
  }
1050
+ const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
729
1051
  if (isOne) {
730
1052
  rawRelationFields.push([
731
1053
  relationName,
@@ -733,7 +1055,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
733
1055
  type: relType,
734
1056
  args: {
735
1057
  where: { type: relSelectData.filters }
736
- }
1058
+ },
1059
+ resolve
737
1060
  }
738
1061
  ]);
739
1062
  continue;
@@ -741,15 +1064,36 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
741
1064
  rawRelationFields.push([
742
1065
  relationName,
743
1066
  {
744
- type: new import_graphql3.GraphQLNonNull(new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(relType))),
1067
+ type: new import_graphql4.GraphQLNonNull(new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(relType))),
745
1068
  args: {
746
1069
  where: { type: relSelectData.filters },
747
1070
  orderBy: { type: relSelectData.order },
748
- offset: { type: import_graphql3.GraphQLInt },
749
- limit: { type: import_graphql3.GraphQLInt }
750
- }
1071
+ offset: { type: import_graphql4.GraphQLInt },
1072
+ limit: { type: import_graphql4.GraphQLInt }
1073
+ },
1074
+ resolve
751
1075
  }
752
1076
  ]);
1077
+ const aggregateFieldName = `${relationName}Aggregate`;
1078
+ if (!tableFields[aggregateFieldName] && !relationsForTable?.[aggregateFieldName]) {
1079
+ const relationAggregate = relationAggregateFactory?.({
1080
+ tableName,
1081
+ relationName,
1082
+ relEntry
1083
+ });
1084
+ if (relationAggregate) {
1085
+ rawRelationFields.push([
1086
+ aggregateFieldName,
1087
+ {
1088
+ type: new import_graphql4.GraphQLNonNull(relationAggregate.type),
1089
+ args: {
1090
+ where: { type: relSelectData.filters }
1091
+ },
1092
+ resolve: relationAggregate.resolve
1093
+ }
1094
+ ]);
1095
+ }
1096
+ }
753
1097
  }
754
1098
  const builtRelationFields = Object.fromEntries(rawRelationFields);
755
1099
  if (isRootCall) {
@@ -773,7 +1117,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
773
1117
  relationFields: {}
774
1118
  };
775
1119
  };
776
- var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, singularTypes = false, insertPrefix = "insertInto", updatePrefix = "update") => {
1120
+ var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory, relationAggregateFactory) => {
777
1121
  const { tableFields, relationFields, filters, order } = generateSelectFields(
778
1122
  tables,
779
1123
  tableName,
@@ -785,12 +1129,15 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
785
1129
  true,
786
1130
  relationsDepthLimit,
787
1131
  cacheCtx,
788
- singularTypes
1132
+ typeNameMapper,
1133
+ /* @__PURE__ */ new Set(),
1134
+ resolverFactory,
1135
+ 0,
1136
+ relationAggregateFactory
789
1137
  );
790
1138
  const table = tables[tableName];
791
1139
  const columns = (0, import_drizzle_orm3.getColumns)(table);
792
1140
  const columnEntries = Object.entries(columns);
793
- const _insertNested = drizzleRelationToGraphQLInsertType(tables, relationMap[tableName] ?? {});
794
1141
  const insertFields = Object.fromEntries(
795
1142
  columnEntries.map(([columnName, columnDescription]) => [
796
1143
  columnName,
@@ -803,22 +1150,22 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
803
1150
  drizzleColumnToGraphQLType(columnDescription, columnName, tableName, true, false, true)
804
1151
  ])
805
1152
  );
806
- const insertInput = new import_graphql3.GraphQLInputObjectType({
807
- name: `${capitalize(insertPrefix)}${toTypeName(tableName, singularTypes)}Input`,
1153
+ const insertInput = new import_graphql4.GraphQLInputObjectType({
1154
+ name: `${capitalize(insertPrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
808
1155
  fields: insertFields
809
1156
  });
810
- const updateInput = new import_graphql3.GraphQLInputObjectType({
811
- name: `${capitalize(updatePrefix)}${toTypeName(tableName, singularTypes)}Input`,
1157
+ const updateInput = new import_graphql4.GraphQLInputObjectType({
1158
+ name: `${capitalize(updatePrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
812
1159
  fields: updateFields
813
1160
  });
814
- const selectSingleOutput = cacheCtx.objectTypeCache.get(tableName) ?? new import_graphql3.GraphQLObjectType({
815
- name: toTypeName(tableName, singularTypes),
1161
+ const selectSingleOutput = cacheCtx.objectTypeCache.get(tableName) ?? new import_graphql4.GraphQLObjectType({
1162
+ name: resolveTypeName(tableName, typeNameMapper),
816
1163
  fields: { ...tableFields, ...relationFields }
817
1164
  });
818
- const selectArrOutput = new import_graphql3.GraphQLNonNull(new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(selectSingleOutput)));
1165
+ const selectArrOutput = new import_graphql4.GraphQLNonNull(new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(selectSingleOutput)));
819
1166
  const arrTableItemOutput = withReturning ? (
820
1167
  // ? new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(singleTableItemOutput!)))
821
- new import_graphql3.GraphQLNonNull(new import_graphql3.GraphQLList(new import_graphql3.GraphQLNonNull(selectSingleOutput)))
1168
+ new import_graphql4.GraphQLNonNull(new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(selectSingleOutput)))
822
1169
  ) : void 0;
823
1170
  const inputs = {
824
1171
  insertInput,
@@ -841,19 +1188,10 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
841
1188
  outputs
842
1189
  };
843
1190
  };
844
- var extractOrderBy = (table, orderArgs) => {
845
- const res = [];
846
- for (const [column, config] of Object.entries(orderArgs).sort(
847
- (a, b) => (b[1]?.priority ?? 0) - (a[1]?.priority ?? 0)
848
- )) {
849
- if (!config) {
850
- continue;
851
- }
852
- const { direction } = config;
853
- res.push(direction === "asc" ? (0, import_drizzle_orm3.asc)((0, import_drizzle_orm3.getColumns)(table)[column]) : (0, import_drizzle_orm3.desc)((0, import_drizzle_orm3.getColumns)(table)[column]));
854
- }
855
- return res;
856
- };
1191
+ 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]);
1192
+ var extractOrderBy = (table, orderArgs) => orderByEntries(orderArgs).map(
1193
+ ([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)((0, import_drizzle_orm3.getColumns)(table)[column]) : (0, import_drizzle_orm3.desc)((0, import_drizzle_orm3.getColumns)(table)[column])
1194
+ );
857
1195
  var extractFiltersColumn = (column, columnName, operators) => {
858
1196
  if (!operators.OR?.length) {
859
1197
  delete operators.OR;
@@ -861,7 +1199,7 @@ var extractFiltersColumn = (column, columnName, operators) => {
861
1199
  const entries = Object.entries(operators);
862
1200
  if (operators.OR) {
863
1201
  if (entries.length > 1) {
864
- throw new import_graphql3.GraphQLError(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
1202
+ throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Cannot specify both fields and 'OR' in column operators!`);
865
1203
  }
866
1204
  const variants2 = [];
867
1205
  for (const variant of operators.OR) {
@@ -872,60 +1210,93 @@ var extractFiltersColumn = (column, columnName, operators) => {
872
1210
  }
873
1211
  return variants2.length ? variants2.length > 1 ? (0, import_drizzle_orm3.or)(...variants2) : variants2[0] : void 0;
874
1212
  }
1213
+ const singleValueOps = { eq: import_drizzle_orm3.eq, ne: import_drizzle_orm3.ne, gt: import_drizzle_orm3.gt, gte: import_drizzle_orm3.gte, lt: import_drizzle_orm3.lt, lte: import_drizzle_orm3.lte };
1214
+ const stringValueOps = { like: import_drizzle_orm3.like, notLike: import_drizzle_orm3.notLike, ilike: import_drizzle_orm3.ilike, notIlike: import_drizzle_orm3.notIlike };
1215
+ const arrayValueOps = { inArray: import_drizzle_orm3.inArray, notInArray: import_drizzle_orm3.notInArray };
1216
+ const nullableOps = { isNull: import_drizzle_orm3.isNull, isNotNull: import_drizzle_orm3.isNotNull };
875
1217
  const variants = [];
876
1218
  for (const [operatorName, operatorValue] of entries) {
877
1219
  if (operatorValue === null || operatorValue === false) {
878
1220
  continue;
879
1221
  }
880
- let operator;
881
- switch (operatorName) {
882
- case "eq":
883
- operator = operator ?? import_drizzle_orm3.eq;
884
- case "ne":
885
- operator = operator ?? import_drizzle_orm3.ne;
886
- case "gt":
887
- operator = operator ?? import_drizzle_orm3.gt;
888
- case "gte":
889
- operator = operator ?? import_drizzle_orm3.gte;
890
- case "lt":
891
- operator = operator ?? import_drizzle_orm3.lt;
892
- case "lte": {
893
- operator = operator ?? import_drizzle_orm3.lte;
894
- const singleValue = remapFromGraphQLCore(operatorValue, column, columnName);
895
- variants.push(operator(column, singleValue));
896
- break;
897
- }
898
- case "like":
899
- operator = operator ?? import_drizzle_orm3.like;
900
- case "notLike":
901
- operator = operator ?? import_drizzle_orm3.notLike;
902
- case "ilike":
903
- operator = operator ?? import_drizzle_orm3.ilike;
904
- case "notIlike":
905
- operator = operator ?? import_drizzle_orm3.notIlike;
906
- variants.push(operator(column, operatorValue));
907
- break;
908
- case "inArray":
909
- operator = operator ?? import_drizzle_orm3.inArray;
910
- case "notInArray": {
911
- operator = operator ?? import_drizzle_orm3.notInArray;
912
- if (!operatorValue.length) {
913
- throw new import_graphql3.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
914
- }
915
- const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
916
- variants.push(operator(column, arrayValue));
917
- break;
1222
+ if (operatorName in singleValueOps) {
1223
+ const singleValue = remapFromGraphQLCore(operatorValue, column, columnName);
1224
+ variants.push(singleValueOps[operatorName](column, singleValue));
1225
+ } else if (operatorName in stringValueOps) {
1226
+ variants.push(stringValueOps[operatorName](column, operatorValue));
1227
+ } else if (operatorName in arrayValueOps) {
1228
+ if (!operatorValue.length) {
1229
+ throw new import_graphql4.GraphQLError(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
918
1230
  }
919
- case "isNull":
920
- operator = operator ?? import_drizzle_orm3.isNull;
921
- case "isNotNull":
922
- operator = operator ?? import_drizzle_orm3.isNotNull;
923
- variants.push(operator(column));
1231
+ const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
1232
+ variants.push(arrayValueOps[operatorName](column, arrayValue));
1233
+ } else if (operatorName in nullableOps) {
1234
+ variants.push(nullableOps[operatorName](column));
1235
+ }
1236
+ }
1237
+ return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
1238
+ };
1239
+ var relationFilterCtx = (base, tableKey) => base ? { ...base, tableKey } : void 0;
1240
+ var buildRelationJoinCondition = (parentTable, relation, aliasedTarget, relationName) => {
1241
+ const sourceColumns = relation.sourceColumns;
1242
+ const targetColumns = relation.targetColumns;
1243
+ if (!sourceColumns?.length || sourceColumns.length !== targetColumns?.length) {
1244
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1245
+ }
1246
+ const parentColumns = Object.values((0, import_drizzle_orm3.getColumns)(parentTable));
1247
+ const targetColumnsByName = Object.values((0, import_drizzle_orm3.getColumns)(aliasedTarget));
1248
+ const conditions = [];
1249
+ for (let i = 0; i < sourceColumns.length; i++) {
1250
+ const localColumn = parentColumns.find((c) => c.name === sourceColumns[i].name);
1251
+ const foreignColumn = targetColumnsByName.find((c) => c.name === targetColumns[i].name);
1252
+ if (!localColumn || !foreignColumn) {
1253
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1254
+ }
1255
+ conditions.push((0, import_drizzle_orm3.eq)(localColumn, foreignColumn));
1256
+ }
1257
+ return conditions.length > 1 ? (0, import_drizzle_orm3.and)(...conditions) : conditions[0];
1258
+ };
1259
+ var buildRelationExists = (parentTable, relationName, relEntry, innerFilters, mode, ctx) => {
1260
+ const { targetTableName } = relEntry;
1261
+ const targetTable = ctx.tables[targetTableName];
1262
+ const relation = relEntry.relation ?? relEntry;
1263
+ if (!targetTable || !isFilterableRelation(relation)) {
1264
+ throw new import_graphql4.GraphQLError(`WHERE ${relationName}: Relation cannot be used as a filter`);
1265
+ }
1266
+ ctx.aliases ??= { n: 0 };
1267
+ const aliases = ctx.aliases;
1268
+ const aliasedTarget = (0, import_drizzle_orm3.aliasedTable)(targetTable, `dgql_rel_${aliases.n++}`);
1269
+ const joinCondition = buildRelationJoinCondition(parentTable, relation, aliasedTarget, relationName);
1270
+ const relationWhere = relation.where ? (0, import_drizzle_orm3.relationsFilterToSQL)(relation.isReversed ? parentTable : aliasedTarget, relation.where) : void 0;
1271
+ const inner = innerFilters ? extractFilters(aliasedTarget, targetTableName, innerFilters, { ...ctx, tableKey: targetTableName, aliases }) : void 0;
1272
+ if (mode === "every") {
1273
+ if (!inner) {
1274
+ return void 0;
1275
+ }
1276
+ return import_drizzle_orm3.sql`not exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${(0, import_drizzle_orm3.and)(joinCondition, relationWhere, (0, import_drizzle_orm3.not)(inner))})`;
1277
+ }
1278
+ const condition = (0, import_drizzle_orm3.and)(joinCondition, relationWhere, inner);
1279
+ return mode === "none" ? import_drizzle_orm3.sql`not exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${condition})` : import_drizzle_orm3.sql`exists (select 1 from ${(0, import_drizzle_orm3.getTableAsAliasSQL)(aliasedTarget)} where ${condition})`;
1280
+ };
1281
+ var extractRelationFilter = (parentTable, relationName, relEntry, value, ctx) => {
1282
+ const relation = relEntry.relation ?? relEntry;
1283
+ if ((0, import_drizzle_orm3.is)(relation, import_drizzle_orm3.One)) {
1284
+ return buildRelationExists(parentTable, relationName, relEntry, value, "some", ctx);
1285
+ }
1286
+ const variants = [];
1287
+ for (const mode of ["some", "none", "every"]) {
1288
+ const inner = value[mode];
1289
+ if (inner === void 0 || inner === null) {
1290
+ continue;
1291
+ }
1292
+ const extracted = buildRelationExists(parentTable, relationName, relEntry, inner, mode, ctx);
1293
+ if (extracted) {
1294
+ variants.push(extracted);
924
1295
  }
925
1296
  }
926
1297
  return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
927
1298
  };
928
- var extractFilters = (table, tableName, filters) => {
1299
+ var extractFilters = (table, tableName, filters, relationCtx) => {
929
1300
  if (!filters.OR?.length) {
930
1301
  delete filters.OR;
931
1302
  }
@@ -935,28 +1306,33 @@ var extractFilters = (table, tableName, filters) => {
935
1306
  }
936
1307
  if (filters.OR) {
937
1308
  if (entries.length > 1) {
938
- throw new import_graphql3.GraphQLError(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
1309
+ throw new import_graphql4.GraphQLError(`WHERE ${tableName}: Cannot specify both fields and 'OR' in table filters!`);
939
1310
  }
940
1311
  const variants2 = [];
941
1312
  for (const variant of filters.OR) {
942
- const extracted = extractFilters(table, tableName, variant);
1313
+ const extracted = extractFilters(table, tableName, variant, relationCtx);
943
1314
  if (extracted) {
944
1315
  variants2.push(extracted);
945
1316
  }
946
1317
  }
947
1318
  return variants2.length ? variants2.length > 1 ? (0, import_drizzle_orm3.or)(...variants2) : variants2[0] : void 0;
948
1319
  }
1320
+ const columns = (0, import_drizzle_orm3.getColumns)(table);
1321
+ const relations = relationCtx?.relationMap[relationCtx.tableKey];
949
1322
  const variants = [];
950
- for (const [columnName, operators] of entries) {
951
- if (operators === null) {
1323
+ for (const [fieldName, operators] of entries) {
1324
+ if (operators === null || operators === void 0) {
952
1325
  continue;
953
1326
  }
954
- const column = (0, import_drizzle_orm3.getColumns)(table)[columnName];
955
- variants.push(extractFiltersColumn(column, columnName, operators));
1327
+ const column = columns[fieldName];
1328
+ const extracted = column ? extractFiltersColumn(column, fieldName, operators) : relations?.[fieldName] && relationCtx ? extractRelationFilter(table, fieldName, relations[fieldName], operators, relationCtx) : void 0;
1329
+ if (extracted) {
1330
+ variants.push(extracted);
1331
+ }
956
1332
  }
957
1333
  return variants.length ? variants.length > 1 ? (0, import_drizzle_orm3.and)(...variants) : variants[0] : void 0;
958
1334
  };
959
- var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, singularTypes = false, _isInitial = false) => {
1335
+ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false, filterCtx) => {
960
1336
  const relationsForTable = relationMap[tableName];
961
1337
  if (!relationsForTable) {
962
1338
  return void 0;
@@ -966,8 +1342,9 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
966
1342
  return void 0;
967
1343
  }
968
1344
  const args = {};
969
- for (const [relName, { targetTableName }] of Object.entries(relationsForTable)) {
970
- const relTypeName = toTypeName(targetTableName, singularTypes);
1345
+ for (const [relName, relEntry] of Object.entries(relationsForTable)) {
1346
+ const { targetTableName, targetPkNames } = relEntry;
1347
+ const relTypeName = resolveTypeName(targetTableName, typeNameMapper);
971
1348
  const field = baseField[relName] ?? Object.values(baseField).find((f) => f.name === relName);
972
1349
  if (!field) {
973
1350
  continue;
@@ -977,7 +1354,11 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
977
1354
  if (!relFieldSelection) {
978
1355
  continue;
979
1356
  }
980
- const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName]);
1357
+ const columns = extractSelectedColumnsFromTree(relFieldSelection, tables[targetTableName], {
1358
+ tableName: targetTableName,
1359
+ relationMap,
1360
+ tables
1361
+ });
981
1362
  const thisRecord = {};
982
1363
  thisRecord.columns = columns;
983
1364
  const relationField = Object.values(baseField).find((e) => e.name === relName);
@@ -985,298 +1366,1033 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
985
1366
  const offset = relationArgs?.offset ?? void 0;
986
1367
  const limit = relationArgs?.limit ?? void 0;
987
1368
  const relWhere = relationArgs?.where;
988
- thisRecord.where = relWhere ? { RAW: (aliasedTable) => extractFilters(aliasedTable, relName, relWhere) } : void 0;
989
- thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy) : void 0;
1369
+ thisRecord.where = relWhere ? {
1370
+ RAW: (aliasedTable2) => extractFilters(aliasedTable2, relName, relWhere, relationFilterCtx(filterCtx, targetTableName))
1371
+ } : void 0;
1372
+ const hasPagination = offset != null || limit != null;
1373
+ const pkNames = targetPkNames ?? [];
1374
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0;
990
1375
  thisRecord.offset = offset;
991
1376
  thisRecord.limit = limit;
992
- const relWith = relationField ? extractRelationsParamsInner(relationMap, tables, targetTableName, relTypeName, relationField, singularTypes) : void 0;
1377
+ const relWith = relationField ? extractRelationsParamsInner(
1378
+ relationMap,
1379
+ tables,
1380
+ targetTableName,
1381
+ relTypeName,
1382
+ relationField,
1383
+ typeNameMapper,
1384
+ false,
1385
+ filterCtx
1386
+ ) : void 0;
993
1387
  thisRecord.with = relWith;
994
1388
  args[relName] = thisRecord;
995
1389
  }
996
1390
  return args;
997
1391
  };
998
- var extractRelationsParams = (relationMap, tables, tableName, info, typeName, singularTypes = false) => {
1392
+ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper, filterCtx) => {
999
1393
  if (!info) {
1000
1394
  return void 0;
1001
1395
  }
1002
- return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, singularTypes, true);
1396
+ return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, typeNameMapper, true, filterCtx);
1003
1397
  };
1004
-
1005
- // src/util/builders/mysql.ts
1006
- var toTypeName2 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1007
- var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1008
- const queryName = `${uncapitalize(tableName)}${listSuffix}`;
1009
- const queryBase = db.query[tableName];
1010
- if (!queryBase) {
1011
- throw new Error(
1012
- `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1398
+ var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
1399
+ const out = {};
1400
+ for (const [tableName, rels] of Object.entries(relationMap)) {
1401
+ out[tableName] = Object.fromEntries(
1402
+ Object.entries(rels).filter(([relationName]) => shouldEagerLoad(tableName, relationName))
1013
1403
  );
1014
1404
  }
1015
- const queryArgs = {
1016
- offset: {
1017
- type: import_graphql4.GraphQLInt
1018
- },
1019
- limit: {
1020
- type: import_graphql4.GraphQLInt
1021
- },
1022
- orderBy: {
1023
- type: orderArgs
1024
- },
1025
- where: {
1026
- type: filterArgs
1405
+ return out;
1406
+ };
1407
+ var getPrimaryKeyPropNames = (table, compositePkColumnNames) => {
1408
+ const cols = (0, import_drizzle_orm3.getColumns)(table);
1409
+ const entries = Object.entries(cols);
1410
+ const inlinePks = entries.filter(([, c]) => c.primary).map(([k]) => k);
1411
+ if (inlinePks.length) {
1412
+ return inlinePks;
1413
+ }
1414
+ if (compositePkColumnNames?.length) {
1415
+ const wanted = new Set(compositePkColumnNames);
1416
+ const fromComposite = entries.filter(([, c]) => wanted.has(c.name)).map(([k]) => k);
1417
+ if (fromComposite.length) {
1418
+ return fromComposite;
1027
1419
  }
1028
- };
1029
- const typeName = toTypeName2(tableName, singularTypes);
1030
- const table = tables[tableName];
1031
- return {
1032
- name: queryName,
1033
- resolver: async (_source, args, _context, info) => {
1034
- try {
1035
- const { offset, limit, orderBy, where } = args;
1036
- const parsedInfo = (0, import_graphql_parse_resolve_info.parseResolveInfo)(info, {
1037
- deep: true
1038
- });
1039
- const query = queryBase.findMany({
1040
- columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1041
- offset,
1042
- limit,
1043
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1044
- // use it directly so column refs match the CTE alias.
1045
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1046
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1047
- with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1048
- });
1049
- const result = await query;
1050
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1051
- } catch (e) {
1052
- if (e instanceof Error) {
1053
- throw new import_graphql4.GraphQLError(e.message);
1054
- }
1055
- throw e;
1420
+ }
1421
+ return [];
1422
+ };
1423
+ var withPrimaryKeyColumns = (columns, table, pkNames) => {
1424
+ const allCols = (0, import_drizzle_orm3.getColumns)(table);
1425
+ for (const pk of pkNames) {
1426
+ if (!(pk in columns) && allCols[pk]) {
1427
+ columns[pk] = allCols[pk];
1428
+ }
1429
+ }
1430
+ return columns;
1431
+ };
1432
+ var getPrimaryKeyPropNamesFromConfig = (table, getTableConfig4) => {
1433
+ const compositePkColumnNames = getTableConfig4(table).primaryKeys.flatMap((pk) => pk.columns.map((c) => c.name));
1434
+ return getPrimaryKeyPropNames(table, compositePkColumnNames);
1435
+ };
1436
+ var primaryKeyOrderExprs = (table, pkNames) => {
1437
+ const cols = (0, import_drizzle_orm3.getColumns)(table);
1438
+ return pkNames.map((n) => cols[n]).filter(Boolean).map((col) => (0, import_drizzle_orm3.asc)(col));
1439
+ };
1440
+ var getUniqueColumnSets = (table, getTableConfig4) => {
1441
+ const cols = (0, import_drizzle_orm3.getColumns)(table);
1442
+ const propNameByColumnName = new Map(Object.entries(cols).map(([propName, col]) => [col.name, propName]));
1443
+ const toPropNames = (columnNames) => {
1444
+ const propNames = [];
1445
+ for (const columnName of columnNames) {
1446
+ const propName = columnName === void 0 ? void 0 : propNameByColumnName.get(columnName);
1447
+ if (!propName) {
1448
+ return void 0;
1056
1449
  }
1057
- },
1058
- args: queryArgs
1450
+ propNames.push(propName);
1451
+ }
1452
+ return propNames.length ? propNames : void 0;
1059
1453
  };
1454
+ const config = getTableConfig4(table);
1455
+ const candidates = [
1456
+ // Inline `.primaryKey()` columns, then table-level `primaryKey({ columns })`.
1457
+ Object.entries(cols).filter(([, col]) => col.primary).map(([propName]) => propName),
1458
+ ...config.primaryKeys.map((pk) => toPropNames(pk.columns.map((c) => c.name))),
1459
+ ...(config.uniqueConstraints ?? []).map((uc) => toPropNames(uc.columns.map((c) => c.name))),
1460
+ ...(config.indexes ?? []).filter((index) => index.config.unique).map((index) => toPropNames(index.config.columns.map((c) => c?.name))),
1461
+ ...Object.entries(cols).filter(([, col]) => col.isUnique).map(([propName]) => [propName])
1462
+ ];
1463
+ const seen = /* @__PURE__ */ new Set();
1464
+ const sets = [];
1465
+ for (const set of candidates) {
1466
+ if (!set?.length) {
1467
+ continue;
1468
+ }
1469
+ const key = [...set].sort().join(",");
1470
+ if (seen.has(key)) {
1471
+ continue;
1472
+ }
1473
+ seen.add(key);
1474
+ sets.push(set);
1475
+ }
1476
+ return sets;
1060
1477
  };
1061
- var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1062
- const queryName = `${uncapitalize(tableName)}${singleSuffix}`;
1063
- const queryBase = db.query[tableName];
1064
- if (!queryBase) {
1065
- throw new Error(
1066
- `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1067
- );
1478
+ var DISTINCT_RN = "__drizzle_graphql_distinct_rn";
1479
+ var columnEnumCache = /* @__PURE__ */ new WeakMap();
1480
+ var generateColumnEnum = (table, enumName, description, predicate = () => true) => {
1481
+ let tableCache = columnEnumCache.get(table);
1482
+ const cached = tableCache?.get(enumName);
1483
+ if (cached) {
1484
+ return cached;
1068
1485
  }
1069
- const queryArgs = {
1070
- offset: {
1071
- type: import_graphql4.GraphQLInt
1072
- },
1073
- orderBy: {
1074
- type: orderArgs
1486
+ const columnNames = Object.entries((0, import_drizzle_orm3.getColumns)(table)).filter(([columnName, column]) => predicate(column, columnName)).map(([columnName]) => columnName);
1487
+ if (!columnNames.length) {
1488
+ return void 0;
1489
+ }
1490
+ const enumType = new import_graphql4.GraphQLEnumType({
1491
+ name: enumName,
1492
+ description,
1493
+ values: Object.fromEntries(columnNames.map((columnName) => [columnName, { value: columnName }]))
1494
+ });
1495
+ if (!tableCache) {
1496
+ tableCache = /* @__PURE__ */ new Map();
1497
+ columnEnumCache.set(table, tableCache);
1498
+ }
1499
+ tableCache.set(enumName, enumType);
1500
+ return enumType;
1501
+ };
1502
+ var generateDistinctEnum = (table, typeName) => generateColumnEnum(table, `${typeName}DistinctColumn`, `Columns of ${typeName} that a query can be made distinct on`);
1503
+ var conflictActionEnum = new import_graphql4.GraphQLEnumType({
1504
+ name: "ConflictAction",
1505
+ description: "What an upsert does when a row with the same unique key already exists",
1506
+ values: {
1507
+ UPDATE: { value: "UPDATE", description: "Overwrite the conflicting row with the supplied values" },
1508
+ NOTHING: { value: "NOTHING", description: "Keep the existing row and insert nothing" }
1509
+ }
1510
+ });
1511
+ var generateOnConflictInput = (params) => {
1512
+ const { table, typeName, uniqueSets, tableFilters, withTarget } = params;
1513
+ const updateEnum = generateColumnEnum(
1514
+ table,
1515
+ `${typeName}UpdateColumn`,
1516
+ `Columns of ${typeName} that an upsert can overwrite`
1517
+ );
1518
+ if (!updateEnum) {
1519
+ return void 0;
1520
+ }
1521
+ const fields = {
1522
+ action: {
1523
+ type: conflictActionEnum,
1524
+ defaultValue: "UPDATE",
1525
+ description: "Whether a conflicting row is overwritten or left alone. Defaults to UPDATE."
1075
1526
  },
1076
- where: {
1077
- type: filterArgs
1527
+ update: {
1528
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(updateEnum)),
1529
+ description: "Columns to overwrite on conflict. Defaults to every column the request supplied, minus the conflict target. Columns the request did not supply cannot be listed here \u2014 there would be no value to write."
1078
1530
  }
1079
1531
  };
1080
- const typeName = toTypeName2(tableName, singularTypes);
1081
- const table = tables[tableName];
1082
- return {
1083
- name: queryName,
1084
- resolver: async (_source, args, _context, info) => {
1085
- try {
1086
- const { offset, orderBy, where } = args;
1087
- const parsedInfo = (0, import_graphql_parse_resolve_info.parseResolveInfo)(info, {
1088
- deep: true
1089
- });
1090
- const query = queryBase.findFirst({
1091
- columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1092
- offset,
1093
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1094
- // use it directly so column refs match the CTE alias.
1095
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1096
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1097
- with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1098
- });
1099
- const result = await query;
1100
- if (!result) {
1101
- return void 0;
1102
- }
1103
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1104
- } catch (e) {
1105
- if (e instanceof Error) {
1106
- throw new import_graphql4.GraphQLError(e.message);
1107
- }
1108
- throw e;
1109
- }
1110
- },
1111
- args: queryArgs
1112
- };
1113
- };
1114
- var generateInsertArray = (db, tableName, table, baseType) => {
1115
- const queryName = `insertInto${capitalize(tableName)}`;
1116
- const queryArgs = {
1117
- values: {
1118
- type: new import_graphql4.GraphQLNonNull(new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(baseType)))
1532
+ if (withTarget) {
1533
+ const uniqueColumns = new Set(uniqueSets.flat());
1534
+ const targetEnum = generateColumnEnum(
1535
+ table,
1536
+ `${typeName}ConflictTarget`,
1537
+ `Columns of ${typeName} that carry a unique constraint, and so can be conflicted on`,
1538
+ (_column, columnName) => uniqueColumns.has(columnName)
1539
+ );
1540
+ if (!targetEnum) {
1541
+ return void 0;
1119
1542
  }
1543
+ fields["target"] = {
1544
+ type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(targetEnum)),
1545
+ description: "The unique column set a conflict is detected on. Must match one of the table\u2019s unique constraints exactly. Defaults to the primary key."
1546
+ };
1547
+ fields["where"] = {
1548
+ type: tableFilters,
1549
+ description: "Only overwrite conflicting rows that match this filter. Others are left alone."
1550
+ };
1551
+ }
1552
+ return new import_graphql4.GraphQLInputObjectType({
1553
+ name: `${typeName}OnConflict`,
1554
+ description: `Conflict handling for an upsert of ${typeName}`,
1555
+ fields
1556
+ });
1557
+ };
1558
+ var resolveConflictPlan = (params) => {
1559
+ const { table, values, onConflict, pkNames, uniqueSets, excludedRef, withTarget, buildWhere } = params;
1560
+ const columns = (0, import_drizzle_orm3.getColumns)(table);
1561
+ let target;
1562
+ if (withTarget) {
1563
+ const targetNames2 = onConflict?.target?.length ? onConflict.target : [...pkNames];
1564
+ if (!targetNames2.length) {
1565
+ throw new import_graphql4.GraphQLError(
1566
+ "Unable to upsert: no conflict target was given and this table has no primary key. Pass onConflict.target."
1567
+ );
1568
+ }
1569
+ const requested = [...targetNames2].sort().join(",");
1570
+ if (!uniqueSets.some((set2) => [...set2].sort().join(",") === requested)) {
1571
+ throw new import_graphql4.GraphQLError(
1572
+ `Unable to upsert: [${targetNames2.join(", ")}] is not a unique constraint on this table. Valid conflict targets: ${uniqueSets.map((set2) => `[${set2.join(", ")}]`).join(", ")}.`
1573
+ );
1574
+ }
1575
+ target = targetNames2.map((name) => columns[name]);
1576
+ }
1577
+ if ((onConflict?.action ?? "UPDATE") === "NOTHING") {
1578
+ return { action: "NOTHING", target, set: {}, setWhere: void 0 };
1579
+ }
1580
+ const supplied = new Set(values.flatMap((row) => Object.keys(row)));
1581
+ const targetNames = new Set(withTarget ? onConflict?.target?.length ? onConflict.target : pkNames : []);
1582
+ let updateNames;
1583
+ if (onConflict?.update?.length) {
1584
+ const unsupplied = onConflict.update.filter((name) => !supplied.has(name));
1585
+ if (unsupplied.length) {
1586
+ throw new import_graphql4.GraphQLError(
1587
+ `Unable to upsert: onConflict.update lists ${unsupplied.join(", ")}, which the values do not supply.`
1588
+ );
1589
+ }
1590
+ updateNames = onConflict.update;
1591
+ } else {
1592
+ updateNames = [...supplied].filter((name) => !targetNames.has(name));
1593
+ }
1594
+ if (!updateNames.length) {
1595
+ return { action: "NOTHING", target, set: {}, setWhere: void 0 };
1596
+ }
1597
+ const set = Object.fromEntries(updateNames.map((name) => [name, excludedRef(columns[name].name)]));
1598
+ const setWhere = onConflict?.where && buildWhere ? buildWhere(onConflict.where) : void 0;
1599
+ return { action: "UPDATE", target, set, setWhere };
1600
+ };
1601
+ var excludedColumnRef = (columnName) => import_drizzle_orm3.sql`excluded.${import_drizzle_orm3.sql.identifier(columnName)}`;
1602
+ var mysqlValuesColumnRef = (columnName) => import_drizzle_orm3.sql`values(${import_drizzle_orm3.sql.identifier(columnName)})`;
1603
+ var selectDistinctKeys = async (params) => {
1604
+ const { db, table, tableName, distinct, pkNames, where, orderBy, limit, offset } = params;
1605
+ const cols = (0, import_drizzle_orm3.getColumns)(table);
1606
+ if (!pkNames.length) {
1607
+ throw new import_graphql4.GraphQLError(`Table ${tableName} has no primary key, so 'distinct' cannot be applied to it.`);
1608
+ }
1609
+ const partitionCols = distinct.map((name) => cols[name]).filter(Boolean);
1610
+ if (!partitionCols.length) {
1611
+ throw new import_graphql4.GraphQLError(`No known columns were given to 'distinct' on ${tableName}.`);
1612
+ }
1613
+ const orderEntries = orderBy ? orderByEntries(orderBy) : [];
1614
+ const windowOrder = [
1615
+ ...orderEntries.map(([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)(cols[column]) : (0, import_drizzle_orm3.desc)(cols[column])),
1616
+ ...primaryKeyOrderExprs(table, pkNames)
1617
+ ];
1618
+ const rowNumber = import_drizzle_orm3.sql`row_number() over (partition by ${import_drizzle_orm3.sql.join(partitionCols, import_drizzle_orm3.sql`, `)} order by ${import_drizzle_orm3.sql.join(
1619
+ windowOrder,
1620
+ import_drizzle_orm3.sql`, `
1621
+ )})`.as(DISTINCT_RN);
1622
+ const sub = db.select({ ...cols, [DISTINCT_RN]: rowNumber }).from(table).where(where).as("__dgql_distinct");
1623
+ const outerOrder = [
1624
+ ...orderEntries.map(([column, direction]) => direction === "asc" ? (0, import_drizzle_orm3.asc)(sub[column]) : (0, import_drizzle_orm3.desc)(sub[column])),
1625
+ ...pkNames.filter((name) => sub[name]).map((name) => (0, import_drizzle_orm3.asc)(sub[name]))
1626
+ ];
1627
+ let query = db.select(Object.fromEntries(pkNames.map((name) => [name, sub[name]]))).from(sub).where((0, import_drizzle_orm3.eq)(sub[DISTINCT_RN], 1)).orderBy(...outerOrder);
1628
+ if (offset) {
1629
+ query = query.offset(offset);
1630
+ }
1631
+ if (limit != null) {
1632
+ query = query.limit(limit);
1633
+ }
1634
+ return await query;
1635
+ };
1636
+ var primaryKeyRestriction = (table, pkNames, keys) => {
1637
+ const cols = (0, import_drizzle_orm3.getColumns)(table);
1638
+ if (pkNames.length === 1) {
1639
+ const name = pkNames[0];
1640
+ return (0, import_drizzle_orm3.inArray)(
1641
+ cols[name],
1642
+ keys.map((key) => key[name])
1643
+ );
1644
+ }
1645
+ return (0, import_drizzle_orm3.or)(...keys.map((key) => (0, import_drizzle_orm3.and)(...pkNames.map((name) => (0, import_drizzle_orm3.eq)(cols[name], key[name])))));
1646
+ };
1647
+ var prepareMutationRelationColumns = (params) => {
1648
+ const { relationMap, tables, tableName, typeName, typeNameMapper, table, pkNames, parsedInfo } = params;
1649
+ const withParams = relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper) : void 0;
1650
+ const hasRelations = !!(withParams && Object.keys(withParams).length);
1651
+ const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table, {
1652
+ tableName,
1653
+ relationMap,
1654
+ tables
1655
+ });
1656
+ const columns = hasRelations ? withPrimaryKeyColumns(baseColumns, table, pkNames) : baseColumns;
1657
+ return { columns, hasRelations, withParams };
1658
+ };
1659
+ var toGraphQLError = (e) => {
1660
+ if (e instanceof import_graphql4.GraphQLError) {
1661
+ return e;
1662
+ }
1663
+ return e instanceof Error ? new import_graphql4.GraphQLError(e.message, { originalError: e }) : e;
1664
+ };
1665
+ var defaultErrorMapper = (error) => {
1666
+ if (error instanceof import_graphql4.GraphQLError && !error.originalError) {
1667
+ return error;
1668
+ }
1669
+ return new import_graphql4.GraphQLError("Internal server error", {
1670
+ originalError: error instanceof import_graphql4.GraphQLError ? error.originalError ?? error : error instanceof Error ? error : null,
1671
+ extensions: { code: "INTERNAL_SERVER_ERROR" }
1672
+ });
1673
+ };
1674
+ var applyErrorMapper = (entities, mapError) => {
1675
+ const wrap = (resolve) => (...args) => {
1676
+ try {
1677
+ const result = resolve(...args);
1678
+ if (result && typeof result.then === "function") {
1679
+ return result.then(void 0, (e) => {
1680
+ throw mapError(e);
1681
+ });
1682
+ }
1683
+ return result;
1684
+ } catch (e) {
1685
+ throw mapError(e);
1686
+ }
1687
+ };
1688
+ for (const field of [...Object.values(entities.queries), ...Object.values(entities.mutations)]) {
1689
+ if (field?.resolve) {
1690
+ field.resolve = wrap(field.resolve);
1691
+ }
1692
+ }
1693
+ for (const type of Object.values(entities.types)) {
1694
+ if (typeof type?.getFields !== "function") {
1695
+ continue;
1696
+ }
1697
+ for (const field of Object.values(type.getFields())) {
1698
+ if (field?.resolve) {
1699
+ field.resolve = wrap(field.resolve);
1700
+ }
1701
+ }
1702
+ }
1703
+ for (const tableResolvers of Object.values(entities.fieldResolvers ?? {})) {
1704
+ for (const [relationName, resolve] of Object.entries(tableResolvers)) {
1705
+ tableResolvers[relationName] = wrap(resolve);
1706
+ }
1707
+ }
1708
+ };
1709
+ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes) => {
1710
+ const mapped = typeNameMapper?.(tableName);
1711
+ const typeName = mapped ? capitalize(mapped.singular) : capitalize(tableName);
1712
+ const listFieldName = (mapped?.plural ?? uncapitalize(tableName)) + suffixes.list;
1713
+ const singleFieldName = mapped?.singular ?? uncapitalize(tableName) + suffixes.single;
1714
+ const aggregateFieldName = `${mapped?.plural ?? uncapitalize(tableName)}Aggregate`;
1715
+ const createArrayFieldName = `${prefixes.insert}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
1716
+ const createSingleFieldName = mapped ? `${prefixes.insert}${capitalize(mapped.singular)}` : `${prefixes.insert}${capitalize(tableName)}${suffixes.single}`;
1717
+ const upsertPrefix = prefixes.upsert ?? "upsert";
1718
+ const upsertArrayFieldName = `${upsertPrefix}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
1719
+ const upsertSingleFieldName = mapped ? `${upsertPrefix}${capitalize(mapped.singular)}` : `${upsertPrefix}${capitalize(tableName)}${suffixes.single}`;
1720
+ const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1721
+ const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1722
+ return {
1723
+ typeName,
1724
+ listFieldName,
1725
+ singleFieldName,
1726
+ aggregateFieldName,
1727
+ createArrayFieldName,
1728
+ createSingleFieldName,
1729
+ upsertArrayFieldName,
1730
+ upsertSingleFieldName,
1731
+ updateFieldName,
1732
+ deleteFieldName
1733
+ };
1734
+ };
1735
+ var selectArrayArgs = (orderArgs, filterArgs, distinctEnum) => ({
1736
+ offset: { type: import_graphql4.GraphQLInt },
1737
+ limit: { type: import_graphql4.GraphQLInt },
1738
+ orderBy: { type: orderArgs },
1739
+ where: { type: filterArgs },
1740
+ ...distinctEnum ? { distinct: { type: new import_graphql4.GraphQLList(new import_graphql4.GraphQLNonNull(distinctEnum)) } } : {}
1741
+ });
1742
+ var selectSingleArgs = (orderArgs, filterArgs) => ({
1743
+ offset: { type: import_graphql4.GraphQLInt },
1744
+ orderBy: { type: orderArgs },
1745
+ where: { type: filterArgs }
1746
+ });
1747
+ var runRelationalSelect = async (opts) => {
1748
+ const {
1749
+ queryBase,
1750
+ tables,
1751
+ tableName,
1752
+ table,
1753
+ relationMap,
1754
+ typeName,
1755
+ typeNameMapper,
1756
+ parsedInfo,
1757
+ offset,
1758
+ orderBy,
1759
+ where,
1760
+ single,
1761
+ filterCtx,
1762
+ pkNames
1763
+ } = opts;
1764
+ const distinct = opts.distinct?.length ? opts.distinct : void 0;
1765
+ const needsDefaultOrder = single || offset != null || opts.limit != null;
1766
+ let distinctKeys;
1767
+ if (distinct) {
1768
+ distinctKeys = await selectDistinctKeys({
1769
+ db: opts.db,
1770
+ table,
1771
+ tableName,
1772
+ distinct,
1773
+ pkNames: pkNames ?? [],
1774
+ where: where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0,
1775
+ orderBy,
1776
+ limit: single ? 1 : opts.limit,
1777
+ offset
1778
+ });
1779
+ if (!distinctKeys.length) {
1780
+ return single ? void 0 : [];
1781
+ }
1782
+ }
1783
+ const params = {
1784
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table, {
1785
+ tableName,
1786
+ relationMap,
1787
+ tables
1788
+ }),
1789
+ offset: distinctKeys ? void 0 : offset,
1790
+ // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
1791
+ // directly so column refs match the CTE alias.
1792
+ orderBy: distinctKeys ? (aliasedTable2) => [
1793
+ ...orderBy ? extractOrderBy(aliasedTable2, orderBy) : [],
1794
+ ...primaryKeyOrderExprs(aliasedTable2, pkNames)
1795
+ ] : orderBy ? (aliasedTable2) => extractOrderBy(aliasedTable2, orderBy) : needsDefaultOrder && pkNames?.length ? (aliasedTable2) => primaryKeyOrderExprs(aliasedTable2, pkNames) : void 0,
1796
+ where: distinctKeys ? { RAW: (aliasedTable2) => primaryKeyRestriction(aliasedTable2, pkNames, distinctKeys) } : where ? {
1797
+ RAW: (aliasedTable2) => extractFilters(aliasedTable2, tableName, where, relationFilterCtx(filterCtx, tableName))
1798
+ } : void 0,
1799
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper, filterCtx) : void 0
1800
+ };
1801
+ if (single) {
1802
+ const result2 = await queryBase.findFirst(params);
1803
+ return result2 ? remapToGraphQLSingleOutput(result2, tableName, table, relationMap) : void 0;
1804
+ }
1805
+ params.limit = distinctKeys ? void 0 : opts.limit;
1806
+ const result = await queryBase.findMany(params);
1807
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1808
+ };
1809
+ var eagerLoadMutationRelations = async (db, tableName, rows, pkNames, withParams) => {
1810
+ if (!rows.length || !pkNames.length || !withParams || !Object.keys(withParams).length) {
1811
+ return rows;
1812
+ }
1813
+ const queryBase = db.query?.[tableName];
1814
+ if (!queryBase) {
1815
+ return rows;
1816
+ }
1817
+ const keyableRows = rows.filter((row) => pkNames.every((n) => row[n] != null));
1818
+ if (!keyableRows.length) {
1819
+ return rows;
1820
+ }
1821
+ const pkColumns = {};
1822
+ for (const pk of pkNames) {
1823
+ pkColumns[pk] = true;
1824
+ }
1825
+ const relationNames = Object.keys(withParams);
1826
+ const keyOf = (row) => JSON.stringify(pkNames.map((n) => typeof row[n] === "bigint" ? row[n].toString() : row[n]));
1827
+ let whereRaw;
1828
+ if (pkNames.length === 1) {
1829
+ const pkName = pkNames[0];
1830
+ const ids = keyableRows.map((r) => r[pkName]);
1831
+ whereRaw = (aliased) => (0, import_drizzle_orm3.inArray)(aliased[pkName], ids);
1832
+ } else {
1833
+ whereRaw = (aliased) => {
1834
+ const lhs = import_drizzle_orm3.sql.join(
1835
+ pkNames.map((n) => import_drizzle_orm3.sql`${aliased[n]}`),
1836
+ import_drizzle_orm3.sql`, `
1837
+ );
1838
+ const tuples = import_drizzle_orm3.sql.join(
1839
+ keyableRows.map(
1840
+ (row) => import_drizzle_orm3.sql`(${import_drizzle_orm3.sql.join(
1841
+ pkNames.map((n) => import_drizzle_orm3.sql`${row[n]}`),
1842
+ import_drizzle_orm3.sql`, `
1843
+ )})`
1844
+ ),
1845
+ import_drizzle_orm3.sql`, `
1846
+ );
1847
+ return import_drizzle_orm3.sql`(${lhs}) in (${tuples})`;
1848
+ };
1849
+ }
1850
+ let enriched;
1851
+ try {
1852
+ enriched = await queryBase.findMany({
1853
+ columns: pkColumns,
1854
+ where: { RAW: whereRaw },
1855
+ with: withParams
1856
+ });
1857
+ } catch (err) {
1858
+ console.warn(
1859
+ `[drizzle-graphql] eager-loading relations for a "${tableName}" mutation failed; falling back to lazy resolution.`,
1860
+ err
1861
+ );
1862
+ return rows;
1863
+ }
1864
+ const byKey = new Map(enriched.map((e) => [keyOf(e), e]));
1865
+ for (const row of rows) {
1866
+ const match = byKey.get(keyOf(row));
1867
+ if (!match) {
1868
+ continue;
1869
+ }
1870
+ for (const rel of relationNames) {
1871
+ row[rel] = match[rel];
1872
+ }
1873
+ }
1874
+ return rows;
1875
+ };
1876
+
1877
+ // src/util/builders/mysql.ts
1878
+ var import_drizzle_orm5 = require("drizzle-orm");
1879
+ var import_mysql_core2 = require("drizzle-orm/mysql-core");
1880
+ var import_graphql6 = require("graphql");
1881
+ var import_graphql_parse_resolve_info2 = require("graphql-parse-resolve-info");
1882
+
1883
+ // src/util/builders/aggregates.ts
1884
+ var import_drizzle_orm4 = require("drizzle-orm");
1885
+ var import_graphql5 = require("graphql");
1886
+ var import_graphql_parse_resolve_info = require("graphql-parse-resolve-info");
1887
+ var AGGREGATE_OPS = ["avg", "sum", "min", "max", "countNonNull", "countDistinct"];
1888
+ var COUNT_OPS = /* @__PURE__ */ new Set(["countNonNull", "countDistinct"]);
1889
+ var OP_FNS = {
1890
+ avg: import_drizzle_orm4.avg,
1891
+ sum: import_drizzle_orm4.sum,
1892
+ min: import_drizzle_orm4.min,
1893
+ max: import_drizzle_orm4.max,
1894
+ countNonNull: import_drizzle_orm4.count,
1895
+ countDistinct: import_drizzle_orm4.countDistinct
1896
+ };
1897
+ var SEP = "__";
1898
+ var classifyAggregateColumns = (table, tableName) => {
1899
+ const numeric = {};
1900
+ const orderable = {};
1901
+ const all = {};
1902
+ for (const [columnName, column] of Object.entries((0, import_drizzle_orm4.getColumns)(table))) {
1903
+ all[columnName] = column;
1904
+ const converted = drizzleColumnToGraphQLType(column, columnName, tableName, true, false, false);
1905
+ const gqlType = converted.type;
1906
+ if (gqlType instanceof import_graphql5.GraphQLList || gqlType instanceof import_graphql5.GraphQLObjectType) {
1907
+ continue;
1908
+ }
1909
+ const { type: dataType, constraint } = (0, import_drizzle_orm4.extractExtendedColumnType)(column);
1910
+ if (dataType === "boolean" || dataType === "array" || dataType === "custom") {
1911
+ continue;
1912
+ }
1913
+ if (dataType === "object" && constraint !== "date") {
1914
+ continue;
1915
+ }
1916
+ orderable[columnName] = { column, converted };
1917
+ if (dataType === "number") {
1918
+ numeric[columnName] = column;
1919
+ }
1920
+ }
1921
+ return { numeric, orderable, all };
1922
+ };
1923
+ var generateAggregateTypes = (table, tableName, typeName, cacheCtx) => {
1924
+ const cached = cacheCtx?.aggregateTypeCache.get(tableName);
1925
+ if (cached) {
1926
+ return cached;
1927
+ }
1928
+ const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
1929
+ const fields = {
1930
+ count: { type: new import_graphql5.GraphQLNonNull(import_graphql5.GraphQLInt) }
1931
+ };
1932
+ if (Object.keys(numeric).length) {
1933
+ for (const op of ["avg", "sum"]) {
1934
+ fields[op] = {
1935
+ type: new import_graphql5.GraphQLObjectType({
1936
+ name: `${typeName}${capitalize(op)}Aggregate`,
1937
+ fields: Object.fromEntries(Object.keys(numeric).map((columnName) => [columnName, { type: import_graphql5.GraphQLFloat }]))
1938
+ })
1939
+ };
1940
+ }
1941
+ }
1942
+ if (Object.keys(orderable).length) {
1943
+ for (const op of ["min", "max"]) {
1944
+ fields[op] = {
1945
+ type: new import_graphql5.GraphQLObjectType({
1946
+ name: `${typeName}${capitalize(op)}Aggregate`,
1947
+ fields: Object.fromEntries(
1948
+ Object.entries(orderable).map(([columnName, { converted }]) => [
1949
+ columnName,
1950
+ { type: converted.type, description: converted.description }
1951
+ ])
1952
+ )
1953
+ })
1954
+ };
1955
+ }
1956
+ }
1957
+ const countSets = { countNonNull: all, countDistinct: orderable };
1958
+ for (const [op, columns] of Object.entries(countSets)) {
1959
+ const columnNames = Object.keys(columns);
1960
+ if (!columnNames.length) {
1961
+ continue;
1962
+ }
1963
+ fields[op] = {
1964
+ type: new import_graphql5.GraphQLObjectType({
1965
+ name: `${typeName}${capitalize(op)}Aggregate`,
1966
+ fields: Object.fromEntries(
1967
+ columnNames.map((columnName) => [columnName, { type: new import_graphql5.GraphQLNonNull(import_graphql5.GraphQLInt) }])
1968
+ )
1969
+ })
1970
+ };
1971
+ }
1972
+ const aggregateType = new import_graphql5.GraphQLObjectType({
1973
+ name: `${typeName}Aggregate`,
1974
+ fields
1975
+ });
1976
+ cacheCtx?.aggregateTypeCache.set(tableName, aggregateType);
1977
+ return aggregateType;
1978
+ };
1979
+ var parseDriverDateTime = (raw) => {
1980
+ let v = raw.includes(" ") ? raw.replace(" ", "T") : raw;
1981
+ if (!v.includes("T")) {
1982
+ v = `${v}T00:00:00`;
1983
+ }
1984
+ if (!/(?:[Zz]|[+-]\d{2}(?::?\d{2})?)$/.test(v)) {
1985
+ v = `${v}Z`;
1986
+ }
1987
+ const parsed = new Date(v);
1988
+ return Number.isNaN(parsed.getTime()) ? new Date(raw) : parsed;
1989
+ };
1990
+ var aggregateTarget = (table, tableName, typeName) => {
1991
+ const { orderable } = classifyAggregateColumns(table, tableName);
1992
+ return {
1993
+ tableName,
1994
+ typeName,
1995
+ columns: (0, import_drizzle_orm4.getColumns)(table),
1996
+ dateTimeColumns: new Set(
1997
+ Object.entries(orderable).filter(([, { converted }]) => converted.description === "DateTime").map(([columnName]) => columnName)
1998
+ )
1999
+ };
2000
+ };
2001
+ var parseAggregateRequest = (info, target) => {
2002
+ const parsedInfo = (0, import_graphql_parse_resolve_info.parseResolveInfo)(info, { deep: true });
2003
+ const selectionTree = parsedInfo.fieldsByTypeName[`${target.typeName}Aggregate`] ?? {};
2004
+ const request = {
2005
+ count: false,
2006
+ ops: { avg: [], sum: [], min: [], max: [], countNonNull: [], countDistinct: [] },
2007
+ selection: {}
2008
+ };
2009
+ for (const field of Object.values(selectionTree)) {
2010
+ if (field.name === "count") {
2011
+ request.count = true;
2012
+ request.selection.count = (0, import_drizzle_orm4.count)();
2013
+ continue;
2014
+ }
2015
+ if (!AGGREGATE_OPS.includes(field.name)) {
2016
+ continue;
2017
+ }
2018
+ const op = field.name;
2019
+ const subTree = field.fieldsByTypeName[`${target.typeName}${capitalize(op)}Aggregate`];
2020
+ if (!subTree) {
2021
+ continue;
2022
+ }
2023
+ for (const subField of Object.values(subTree)) {
2024
+ const columnName = subField.name;
2025
+ const column = target.columns[columnName];
2026
+ if (!column || request.ops[op].includes(columnName)) {
2027
+ continue;
2028
+ }
2029
+ request.ops[op].push(columnName);
2030
+ request.selection[`${op}${SEP}${columnName}`] = OP_FNS[op](column);
2031
+ }
2032
+ }
2033
+ return request;
2034
+ };
2035
+ var assembleAggregateRow = (row, request, target) => {
2036
+ const result = {};
2037
+ if (request.count) {
2038
+ result.count = row.count == null ? 0 : Number(row.count);
2039
+ }
2040
+ for (const op of AGGREGATE_OPS) {
2041
+ if (!request.ops[op].length) {
2042
+ continue;
2043
+ }
2044
+ const opResult = {};
2045
+ for (const columnName of request.ops[op]) {
2046
+ const value = row[`${op}${SEP}${columnName}`];
2047
+ if (COUNT_OPS.has(op)) {
2048
+ opResult[columnName] = value == null ? 0 : Number(value);
2049
+ } else if (value == null) {
2050
+ opResult[columnName] = null;
2051
+ } else if (op === "avg" || op === "sum") {
2052
+ opResult[columnName] = Number(value);
2053
+ } else {
2054
+ const column = target.columns[columnName];
2055
+ const decoded = typeof value === "string" && target.dateTimeColumns.has(columnName) ? parseDriverDateTime(value) : value;
2056
+ opResult[columnName] = remapToGraphQLCore(columnName, decoded, target.tableName, column);
2057
+ }
2058
+ }
2059
+ result[op] = opResult;
2060
+ }
2061
+ return result;
2062
+ };
2063
+ var generateAggregate = (db, tableName, table, typeName, fieldName, filterArgs, filterCtx) => {
2064
+ const target = aggregateTarget(table, tableName, typeName);
2065
+ const queryArgs = {
2066
+ where: { type: filterArgs }
2067
+ };
2068
+ return {
2069
+ name: fieldName,
2070
+ resolver: async (_source, args, context, info) => {
2071
+ try {
2072
+ const request = parseAggregateRequest(info, target);
2073
+ if (!Object.keys(request.selection).length) {
2074
+ return {};
2075
+ }
2076
+ let query = resolveExecutor(db, context).select(request.selection).from(table);
2077
+ if (args.where) {
2078
+ query = query.where(extractFilters(table, tableName, args.where, relationFilterCtx(filterCtx, tableName)));
2079
+ }
2080
+ const rows = await query;
2081
+ return assembleAggregateRow(rows[0] ?? {}, request, target);
2082
+ } catch (e) {
2083
+ throw toGraphQLError(e);
2084
+ }
2085
+ },
2086
+ args: queryArgs
2087
+ };
2088
+ };
2089
+ var GROUP_KEY = "__dgql_group_key";
2090
+ var createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, filterCtx) => {
2091
+ return ({ tableName, relationName, relEntry }) => {
2092
+ const parentTable = tables[tableName];
2093
+ const targetTableName = relEntry.targetTableName;
2094
+ const targetTable = tables[targetTableName];
2095
+ if (!parentTable || !targetTable) {
2096
+ return void 0;
2097
+ }
2098
+ const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
2099
+ if (!joinCols) {
2100
+ return void 0;
2101
+ }
2102
+ const { localColPropName, foreignCol } = joinCols;
2103
+ const targetTypeName = resolveTypeName(targetTableName, typeNameMapper);
2104
+ const type = generateAggregateTypes(targetTable, targetTableName, targetTypeName, cacheCtx);
2105
+ const target = aggregateTarget(targetTable, targetTableName, targetTypeName);
2106
+ const resolve = async (parent, args, context, info) => {
2107
+ try {
2108
+ const request = parseAggregateRequest(info, target);
2109
+ if (!Object.keys(request.selection).length) {
2110
+ return {};
2111
+ }
2112
+ const localValue = parent[localColPropName];
2113
+ if (localValue == null) {
2114
+ return assembleAggregateRow({}, request, target);
2115
+ }
2116
+ const whereArg = args?.where;
2117
+ const argsKey = JSON.stringify({
2118
+ where: whereArg ?? null,
2119
+ selection: Object.keys(request.selection).sort()
2120
+ });
2121
+ const loaderKey = `${tableName}::${relationName}::aggregate::${argsKey}`;
2122
+ const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
2123
+ const executor = resolveExecutor(db, context);
2124
+ const uniqueIds = [...new Set(parentIds)];
2125
+ const whereCondition = (0, import_drizzle_orm4.and)(
2126
+ (0, import_drizzle_orm4.inArray)(foreignCol, uniqueIds),
2127
+ whereArg ? extractFilters(targetTable, targetTableName, whereArg, relationFilterCtx(filterCtx, targetTableName)) : void 0
2128
+ );
2129
+ const rows = await executor.select({ [GROUP_KEY]: foreignCol, ...request.selection }).from(targetTable).where(whereCondition).groupBy(foreignCol);
2130
+ const byKey = new Map(rows.map((row) => [row[GROUP_KEY], row]));
2131
+ return parentIds.map((id) => byKey.get(id) ?? {});
2132
+ });
2133
+ return assembleAggregateRow(await loader.load(localValue), request, target);
2134
+ } catch (e) {
2135
+ throw toGraphQLError(e);
2136
+ }
2137
+ };
2138
+ return { type, resolve };
2139
+ };
2140
+ };
2141
+
2142
+ // src/util/builders/mysql.ts
2143
+ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
2144
+ const queryBase = db.query[tableName];
2145
+ if (!queryBase) {
2146
+ throw new Error(
2147
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
2148
+ );
2149
+ }
2150
+ const table = tables[tableName];
2151
+ const pkNames = mysqlPrimaryKeyPropNames(table);
2152
+ const queryArgs = selectArrayArgs(
2153
+ orderArgs,
2154
+ filterArgs,
2155
+ distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
2156
+ );
2157
+ return {
2158
+ name: fieldName,
2159
+ resolver: async (_source, args, context, info) => {
2160
+ try {
2161
+ const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, { deep: true });
2162
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
2163
+ return await runRelationalSelect({
2164
+ queryBase: requestQueryBase,
2165
+ tables,
2166
+ tableName,
2167
+ table,
2168
+ relationMap,
2169
+ typeName,
2170
+ typeNameMapper,
2171
+ parsedInfo,
2172
+ ...args,
2173
+ single: false,
2174
+ filterCtx,
2175
+ pkNames,
2176
+ db: executor
2177
+ });
2178
+ } catch (e) {
2179
+ throw toGraphQLError(e);
2180
+ }
2181
+ },
2182
+ args: queryArgs
1120
2183
  };
2184
+ };
2185
+ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
2186
+ const queryBase = db.query[tableName];
2187
+ if (!queryBase) {
2188
+ throw new Error(
2189
+ `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
2190
+ );
2191
+ }
2192
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
2193
+ const table = tables[tableName];
2194
+ const pkNames = mysqlPrimaryKeyPropNames(table);
1121
2195
  return {
1122
- name: queryName,
1123
- resolver: async (_source, args, _context, _info) => {
2196
+ name: fieldName,
2197
+ resolver: async (_source, args, context, info) => {
2198
+ try {
2199
+ const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, { deep: true });
2200
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
2201
+ return await runRelationalSelect({
2202
+ queryBase: requestQueryBase,
2203
+ tables,
2204
+ tableName,
2205
+ table,
2206
+ relationMap,
2207
+ typeName,
2208
+ typeNameMapper,
2209
+ parsedInfo,
2210
+ ...args,
2211
+ single: true,
2212
+ filterCtx,
2213
+ pkNames,
2214
+ db: executor
2215
+ });
2216
+ } catch (e) {
2217
+ throw toGraphQLError(e);
2218
+ }
2219
+ },
2220
+ args: queryArgs
2221
+ };
2222
+ };
2223
+ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
2224
+ const queryArgs = {
2225
+ values: {
2226
+ type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(baseType)))
2227
+ }
2228
+ };
2229
+ return {
2230
+ name: fieldName,
2231
+ resolver: async (_source, args, context, _info) => {
1124
2232
  try {
1125
2233
  const input = remapFromGraphQLArrayInput(args.values, table);
1126
2234
  if (!input.length) {
1127
- throw new import_graphql4.GraphQLError("No values were provided!");
2235
+ throw new import_graphql6.GraphQLError("No values were provided!");
1128
2236
  }
1129
- await db.insert(table).values(input);
2237
+ await resolveExecutor(db, context).insert(table).values(input);
1130
2238
  return { isSuccess: true };
1131
2239
  } catch (e) {
1132
- if (e instanceof Error) {
1133
- throw new import_graphql4.GraphQLError(e.message);
1134
- }
1135
- throw e;
2240
+ throw toGraphQLError(e);
1136
2241
  }
1137
2242
  },
1138
2243
  args: queryArgs
1139
2244
  };
1140
2245
  };
1141
- var generateInsertSingle = (db, tableName, table, baseType) => {
1142
- const queryName = `insertInto${capitalize(tableName)}Single`;
2246
+ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
1143
2247
  const queryArgs = {
1144
2248
  values: {
1145
- type: new import_graphql4.GraphQLNonNull(baseType)
2249
+ type: new import_graphql6.GraphQLNonNull(baseType)
1146
2250
  }
1147
2251
  };
1148
2252
  return {
1149
- name: queryName,
1150
- resolver: async (_source, args, _context, _info) => {
2253
+ name: fieldName,
2254
+ resolver: async (_source, args, context, _info) => {
1151
2255
  try {
1152
2256
  const input = remapFromGraphQLSingleInput(args.values, table);
1153
- await db.insert(table).values(input);
2257
+ await resolveExecutor(db, context).insert(table).values(input);
1154
2258
  return { isSuccess: true };
1155
2259
  } catch (e) {
1156
- if (e instanceof Error) {
1157
- throw new import_graphql4.GraphQLError(e.message);
2260
+ throw toGraphQLError(e);
2261
+ }
2262
+ },
2263
+ args: queryArgs
2264
+ };
2265
+ };
2266
+ var generateUpsert = (db, table, baseType, onConflictType, fieldName, single) => {
2267
+ const queryArgs = {
2268
+ values: {
2269
+ type: single ? new import_graphql6.GraphQLNonNull(baseType) : new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(baseType)))
2270
+ },
2271
+ onConflict: {
2272
+ type: onConflictType,
2273
+ description: "How a conflicting row is resolved. Defaults to overwriting it."
2274
+ }
2275
+ };
2276
+ const pkNames = mysqlPrimaryKeyPropNames(table);
2277
+ return {
2278
+ name: fieldName,
2279
+ resolver: async (_source, args, context, _info) => {
2280
+ try {
2281
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
2282
+ if (!input.length) {
2283
+ throw new import_graphql6.GraphQLError("No values were provided!");
1158
2284
  }
1159
- throw e;
2285
+ const plan = resolveConflictPlan({
2286
+ table,
2287
+ values: input,
2288
+ onConflict: args.onConflict,
2289
+ pkNames,
2290
+ uniqueSets: [],
2291
+ excludedRef: mysqlValuesColumnRef,
2292
+ withTarget: false
2293
+ });
2294
+ const executor = resolveExecutor(db, context);
2295
+ if (plan.action === "NOTHING") {
2296
+ await executor.insert(table).ignore().values(input);
2297
+ } else {
2298
+ await executor.insert(table).values(input).onDuplicateKeyUpdate({ set: plan.set });
2299
+ }
2300
+ return { isSuccess: true };
2301
+ } catch (e) {
2302
+ throw toGraphQLError(e);
1160
2303
  }
1161
2304
  },
1162
2305
  args: queryArgs
1163
2306
  };
1164
2307
  };
1165
- var generateUpdate = (db, tableName, table, setArgs, filterArgs) => {
1166
- const queryName = `update${capitalize(tableName)}`;
2308
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName, filterCtx) => {
1167
2309
  const queryArgs = {
1168
2310
  set: {
1169
- type: new import_graphql4.GraphQLNonNull(setArgs)
2311
+ type: new import_graphql6.GraphQLNonNull(setArgs)
1170
2312
  },
1171
2313
  where: {
1172
2314
  type: filterArgs
1173
2315
  }
1174
2316
  };
1175
2317
  return {
1176
- name: queryName,
1177
- resolver: async (_source, args, _context, _info) => {
2318
+ name: fieldName,
2319
+ resolver: async (_source, args, context, _info) => {
1178
2320
  try {
1179
2321
  const { where, set } = args;
1180
2322
  const input = remapFromGraphQLSingleInput(set, table);
1181
2323
  if (!Object.keys(input).length) {
1182
- throw new import_graphql4.GraphQLError("Unable to update with no values specified!");
2324
+ throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
1183
2325
  }
1184
- let query = db.update(table).set(input);
2326
+ const executor = resolveExecutor(db, context);
2327
+ let query = executor.update(table).set(input);
1185
2328
  if (where) {
1186
- const filters = extractFilters(table, tableName, where);
2329
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
1187
2330
  query = query.where(filters);
1188
2331
  }
1189
2332
  await query;
1190
2333
  return { isSuccess: true };
1191
2334
  } catch (e) {
1192
- if (e instanceof Error) {
1193
- throw new import_graphql4.GraphQLError(e.message);
1194
- }
1195
- throw e;
2335
+ throw toGraphQLError(e);
1196
2336
  }
1197
2337
  },
1198
2338
  args: queryArgs
1199
2339
  };
1200
2340
  };
1201
- var generateDelete = (db, tableName, table, filterArgs) => {
1202
- const queryName = `deleteFrom${capitalize(tableName)}`;
2341
+ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) => {
1203
2342
  const queryArgs = {
1204
2343
  where: {
1205
2344
  type: filterArgs
1206
2345
  }
1207
2346
  };
1208
2347
  return {
1209
- name: queryName,
1210
- resolver: async (_source, args, _context, _info) => {
2348
+ name: fieldName,
2349
+ resolver: async (_source, args, context, _info) => {
1211
2350
  try {
1212
2351
  const { where } = args;
1213
- let query = db.delete(table);
2352
+ const executor = resolveExecutor(db, context);
2353
+ let query = executor.delete(table);
1214
2354
  if (where) {
1215
- const filters = extractFilters(table, tableName, where);
2355
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
1216
2356
  query = query.where(filters);
1217
2357
  }
1218
2358
  await query;
1219
2359
  return { isSuccess: true };
1220
2360
  } catch (e) {
1221
- if (e instanceof Error) {
1222
- throw new import_graphql4.GraphQLError(e.message);
1223
- }
1224
- throw e;
2361
+ throw toGraphQLError(e);
1225
2362
  }
1226
2363
  },
1227
2364
  args: queryArgs
1228
2365
  };
1229
2366
  };
1230
- var buildNamedRelations2 = (relations, tableEntries) => {
1231
- const namedRelations = {};
1232
- for (const [relTableName, relConfig] of Object.entries(relations)) {
1233
- if (!relConfig?.relations) {
1234
- continue;
1235
- }
1236
- const namedConfig = {};
1237
- for (const [innerRelName, innerRelValue] of Object.entries(relConfig.relations)) {
1238
- const targetTable = innerRelValue.targetTable ?? innerRelValue.referencedTable;
1239
- const directTargetName = innerRelValue.targetTableName;
1240
- let targetTableName;
1241
- if (directTargetName) {
1242
- const targetEntry = tableEntries.find(([key]) => key === directTargetName);
1243
- targetTableName = targetEntry?.[0];
1244
- } else if (targetTable) {
1245
- const targetEntry = tableEntries.find(([, tableValue]) => tableValue === targetTable);
1246
- targetTableName = targetEntry?.[0];
1247
- }
1248
- if (!targetTableName) {
1249
- continue;
1250
- }
1251
- namedConfig[innerRelName] = {
1252
- relation: innerRelValue,
1253
- targetTableName
1254
- };
1255
- }
1256
- if (Object.keys(namedConfig).length > 0) {
1257
- namedRelations[relTableName] = namedConfig;
1258
- }
1259
- }
1260
- return namedRelations;
1261
- };
1262
- var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, singularTypes = false) => {
2367
+ var mysqlPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_mysql_core2.getTableConfig);
2368
+ var generateSchemaData = (db, schema, relations, options) => {
2369
+ const { relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad, features } = options;
1263
2370
  const rawSchema = schema;
1264
2371
  const schemaEntries = Object.entries(rawSchema);
1265
- const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm4.is)(value, import_mysql_core2.MySqlTable));
2372
+ const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm5.is)(value, import_mysql_core2.MySqlTable));
1266
2373
  const tables = Object.fromEntries(tableEntries);
1267
2374
  if (!tableEntries.length) {
1268
2375
  throw new Error(
1269
2376
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
1270
2377
  );
1271
2378
  }
1272
- const namedRelations = buildNamedRelations2(relations ?? {}, tableEntries);
2379
+ const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
2380
+ attachTargetPrimaryKeys(namedRelations, tables, mysqlPrimaryKeyPropNames);
2381
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
2382
+ const filterCtx = { tables, relationMap: namedRelations };
2383
+ const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
1273
2384
  const cacheCtx = {
1274
2385
  genericFilterCache: /* @__PURE__ */ new Map(),
1275
2386
  objectTypeCache: /* @__PURE__ */ new Map(),
1276
2387
  relationFieldContainers: /* @__PURE__ */ new Map(),
1277
2388
  fullyBuiltTables: /* @__PURE__ */ new Set(),
1278
- relationTypeCache: /* @__PURE__ */ new Map()
2389
+ relationTypeCache: /* @__PURE__ */ new Map(),
2390
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
2391
+ filterTypeCache: /* @__PURE__ */ new WeakMap(),
2392
+ listRelationFilterCache: /* @__PURE__ */ new Map(),
2393
+ aggregateTypeCache: /* @__PURE__ */ new Map()
1279
2394
  };
2395
+ const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
1280
2396
  const queries = {};
1281
2397
  const mutations = {};
1282
2398
  const gqlSchemaTypes = Object.fromEntries(
@@ -1289,51 +2405,98 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
1289
2405
  false,
1290
2406
  relationsDepthLimit,
1291
2407
  cacheCtx,
1292
- singularTypes,
2408
+ typeNameMapper,
1293
2409
  prefixes.insert,
1294
- prefixes.update
2410
+ prefixes.update,
2411
+ resolverFactory,
2412
+ relationAggregateFactory
1295
2413
  )
1296
2414
  ])
1297
2415
  );
1298
- const mutationReturnType = new import_graphql4.GraphQLObjectType({
2416
+ const mutationReturnType = new import_graphql6.GraphQLObjectType({
1299
2417
  name: "MutationReturn",
1300
2418
  fields: {
1301
2419
  isSuccess: {
1302
- type: new import_graphql4.GraphQLNonNull(import_graphql4.GraphQLBoolean)
2420
+ type: new import_graphql6.GraphQLNonNull(import_graphql6.GraphQLBoolean)
1303
2421
  }
1304
2422
  }
1305
2423
  });
1306
2424
  const inputs = {};
1307
- const outputs = {
1308
- MutationReturn: mutationReturnType
1309
- };
2425
+ const outputs = {};
2426
+ if (features.insert || features.upsert || features.update || features.delete) {
2427
+ outputs.MutationReturn = mutationReturnType;
2428
+ }
1310
2429
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1311
2430
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1312
2431
  const { selectSingleOutput, selectArrOutput } = tableTypes.outputs;
2432
+ const {
2433
+ typeName,
2434
+ listFieldName,
2435
+ singleFieldName,
2436
+ aggregateFieldName,
2437
+ createArrayFieldName,
2438
+ createSingleFieldName,
2439
+ upsertArrayFieldName,
2440
+ upsertSingleFieldName,
2441
+ updateFieldName,
2442
+ deleteFieldName
2443
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
1313
2444
  const selectArrGenerated = generateSelectArray(
1314
2445
  db,
1315
2446
  tableName,
1316
2447
  tables,
1317
- namedRelations,
2448
+ eagerRelations,
1318
2449
  tableOrder,
1319
2450
  tableFilters,
1320
- suffixes.list,
1321
- singularTypes
2451
+ listFieldName,
2452
+ typeName,
2453
+ typeNameMapper,
2454
+ filterCtx,
2455
+ features.distinct
1322
2456
  );
1323
2457
  const selectSingleGenerated = generateSelectSingle(
1324
2458
  db,
1325
2459
  tableName,
1326
2460
  tables,
1327
- namedRelations,
2461
+ eagerRelations,
1328
2462
  tableOrder,
1329
2463
  tableFilters,
1330
- suffixes.single,
1331
- singularTypes
2464
+ singleFieldName,
2465
+ typeName,
2466
+ typeNameMapper,
2467
+ filterCtx
1332
2468
  );
1333
- const insertArrGenerated = generateInsertArray(db, tableName, schema[tableName], insertInput);
1334
- const insertSingleGenerated = generateInsertSingle(db, tableName, schema[tableName], insertInput);
1335
- const updateGenerated = generateUpdate(db, tableName, schema[tableName], updateInput, tableFilters);
1336
- const deleteGenerated = generateDelete(db, tableName, schema[tableName], tableFilters);
2469
+ const insertArrGenerated = features.insert ? generateInsertArray(db, tableName, schema[tableName], insertInput, createArrayFieldName) : void 0;
2470
+ const insertSingleGenerated = features.insert ? generateInsertSingle(db, tableName, schema[tableName], insertInput, createSingleFieldName) : void 0;
2471
+ const onConflictInput = features.upsert ? generateOnConflictInput({
2472
+ table: schema[tableName],
2473
+ typeName,
2474
+ uniqueSets: [],
2475
+ tableFilters,
2476
+ withTarget: false
2477
+ }) : void 0;
2478
+ const upsertArrGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertArrayFieldName, false) : void 0;
2479
+ const upsertSingleGenerated = onConflictInput ? generateUpsert(db, schema[tableName], insertInput, onConflictInput, upsertSingleFieldName, true) : void 0;
2480
+ const updateGenerated = features.update ? generateUpdate(
2481
+ db,
2482
+ tableName,
2483
+ schema[tableName],
2484
+ updateInput,
2485
+ tableFilters,
2486
+ updateFieldName,
2487
+ filterCtx
2488
+ ) : void 0;
2489
+ const deleteGenerated = features.delete ? generateDelete(db, tableName, schema[tableName], tableFilters, deleteFieldName, filterCtx) : void 0;
2490
+ const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
2491
+ const aggregateGenerated = features.aggregates ? generateAggregate(
2492
+ db,
2493
+ tableName,
2494
+ schema[tableName],
2495
+ typeName,
2496
+ aggregateFieldName,
2497
+ tableFilters,
2498
+ filterCtx
2499
+ ) : void 0;
1337
2500
  queries[selectArrGenerated.name] = {
1338
2501
  type: selectArrOutput,
1339
2502
  args: selectArrGenerated.args,
@@ -1344,235 +2507,280 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
1344
2507
  args: selectSingleGenerated.args,
1345
2508
  resolve: selectSingleGenerated.resolver
1346
2509
  };
1347
- mutations[insertArrGenerated.name] = {
1348
- type: mutationReturnType,
1349
- args: insertArrGenerated.args,
1350
- resolve: insertArrGenerated.resolver
1351
- };
1352
- mutations[insertSingleGenerated.name] = {
1353
- type: mutationReturnType,
1354
- args: insertSingleGenerated.args,
1355
- resolve: insertSingleGenerated.resolver
1356
- };
1357
- mutations[updateGenerated.name] = {
1358
- type: mutationReturnType,
1359
- args: updateGenerated.args,
1360
- resolve: updateGenerated.resolver
1361
- };
1362
- mutations[deleteGenerated.name] = {
1363
- type: mutationReturnType,
1364
- args: deleteGenerated.args,
1365
- resolve: deleteGenerated.resolver
1366
- };
1367
- [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
2510
+ if (aggregateGenerated && aggregateType) {
2511
+ queries[aggregateGenerated.name] = {
2512
+ type: new import_graphql6.GraphQLNonNull(aggregateType),
2513
+ args: aggregateGenerated.args,
2514
+ resolve: aggregateGenerated.resolver
2515
+ };
2516
+ }
2517
+ for (const generated of [
2518
+ insertArrGenerated,
2519
+ insertSingleGenerated,
2520
+ upsertArrGenerated,
2521
+ upsertSingleGenerated,
2522
+ updateGenerated,
2523
+ deleteGenerated
2524
+ ]) {
2525
+ if (generated) {
2526
+ mutations[generated.name] = {
2527
+ type: mutationReturnType,
2528
+ args: generated.args,
2529
+ resolve: generated.resolver
2530
+ };
2531
+ }
2532
+ }
2533
+ const activeInputs = [
2534
+ // The insert input types the upsert mutations too, so either feature keeps it.
2535
+ ...features.insert || onConflictInput ? [insertInput] : [],
2536
+ ...onConflictInput ? [onConflictInput] : [],
2537
+ ...features.update ? [updateInput] : [],
2538
+ tableFilters,
2539
+ tableOrder
2540
+ ];
2541
+ activeInputs.forEach((e) => {
1368
2542
  inputs[e.name] = e;
1369
2543
  });
1370
2544
  outputs[selectSingleOutput.name] = selectSingleOutput;
2545
+ if (aggregateType) {
2546
+ outputs[aggregateType.name] = aggregateType;
2547
+ }
2548
+ }
2549
+ const fieldResolvers = {};
2550
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
2551
+ const relResolvers = {};
2552
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
2553
+ const isOne = (0, import_drizzle_orm5.is)(relEntry.relation ?? relEntry, import_drizzle_orm5.One);
2554
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
2555
+ if (resolver) {
2556
+ relResolvers[relName] = resolver;
2557
+ }
2558
+ }
2559
+ if (Object.keys(relResolvers).length > 0) {
2560
+ fieldResolvers[tableName] = relResolvers;
2561
+ }
1371
2562
  }
1372
- return { queries, mutations, inputs, types: outputs };
2563
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
1373
2564
  };
1374
2565
 
1375
2566
  // src/util/builders/pg.ts
1376
- var import_drizzle_orm5 = require("drizzle-orm");
2567
+ var import_drizzle_orm6 = require("drizzle-orm");
1377
2568
  var import_pg_core2 = require("drizzle-orm/pg-core");
1378
- var import_graphql5 = require("graphql");
1379
- var import_graphql_parse_resolve_info2 = require("graphql-parse-resolve-info");
1380
- var toTypeName3 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1381
- var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1382
- const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1383
- const queryName = `${queryEntityBase}${listSuffix}`;
2569
+ var import_graphql7 = require("graphql");
2570
+ var import_graphql_parse_resolve_info3 = require("graphql-parse-resolve-info");
2571
+ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
1384
2572
  const queryBase = db.query[tableName];
1385
- const queryArgs = {
1386
- offset: {
1387
- type: import_graphql5.GraphQLInt
1388
- },
1389
- limit: {
1390
- type: import_graphql5.GraphQLInt
1391
- },
1392
- orderBy: {
1393
- type: orderArgs
1394
- },
1395
- where: {
1396
- type: filterArgs
1397
- }
1398
- };
1399
- const typeName = toTypeName3(tableName, singularTypes);
1400
2573
  const table = tables[tableName];
2574
+ const pkNames = pgPrimaryKeyPropNames(table);
2575
+ const queryArgs = selectArrayArgs(
2576
+ orderArgs,
2577
+ filterArgs,
2578
+ distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
2579
+ );
1401
2580
  return {
1402
- name: queryName,
1403
- resolver: async (_source, args, _context, info) => {
2581
+ name: fieldName,
2582
+ resolver: async (_source, args, context, info) => {
1404
2583
  try {
1405
- const { offset, limit, orderBy, where } = args;
1406
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
1407
- deep: true
1408
- });
1409
- const selectedColumns = extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table);
1410
- let result;
1411
- if (queryBase) {
1412
- const withParams = relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0;
1413
- result = await queryBase.findMany({
1414
- columns: selectedColumns,
1415
- offset,
2584
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
2585
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
2586
+ if (requestQueryBase) {
2587
+ return await runRelationalSelect({
2588
+ queryBase: requestQueryBase,
2589
+ tables,
2590
+ tableName,
2591
+ table,
2592
+ relationMap,
2593
+ typeName,
2594
+ typeNameMapper,
2595
+ parsedInfo,
2596
+ ...args,
2597
+ single: false,
2598
+ filterCtx,
2599
+ pkNames,
2600
+ db: executor
2601
+ });
2602
+ }
2603
+ const { offset, limit, orderBy, where, distinct } = args;
2604
+ const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
2605
+ parsedInfo.fieldsByTypeName[typeName],
2606
+ table,
2607
+ { tableName, relationMap, tables }
2608
+ );
2609
+ const whereSql = where ? extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)) : void 0;
2610
+ let distinctKeys;
2611
+ if (distinct?.length) {
2612
+ distinctKeys = await selectDistinctKeys({
2613
+ db: executor,
2614
+ table,
2615
+ tableName,
2616
+ distinct,
2617
+ pkNames,
2618
+ where: whereSql,
2619
+ orderBy,
1416
2620
  limit,
1417
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy (e.g.
1418
- // d0, d1) — use it directly so column refs match the CTE alias.
1419
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1420
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1421
- with: withParams
2621
+ offset
1422
2622
  });
1423
- } else {
1424
- let q = db.select(selectedColumns).from(table);
1425
- if (where) {
1426
- q = q.where(extractFilters(table, tableName, where));
1427
- }
1428
- if (orderBy) {
1429
- q = q.orderBy(...extractOrderBy(table, orderBy));
2623
+ if (!distinctKeys.length) {
2624
+ return [];
1430
2625
  }
2626
+ }
2627
+ let q = executor.select(selectedColumnsSql).from(table);
2628
+ if (distinctKeys) {
2629
+ q = q.where(primaryKeyRestriction(table, pkNames, distinctKeys));
2630
+ } else if (whereSql) {
2631
+ q = q.where(whereSql);
2632
+ }
2633
+ if (orderBy) {
2634
+ q = q.orderBy(
2635
+ ...extractOrderBy(table, orderBy),
2636
+ ...distinctKeys ? primaryKeyOrderExprs(table, pkNames) : []
2637
+ );
2638
+ } else if ((distinctKeys || offset != null || limit != null) && pkNames.length) {
2639
+ q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
2640
+ }
2641
+ if (!distinctKeys) {
1431
2642
  if (offset) {
1432
2643
  q = q.offset(offset);
1433
2644
  }
1434
2645
  if (limit) {
1435
2646
  q = q.limit(limit);
1436
2647
  }
1437
- result = await q;
1438
2648
  }
1439
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
2649
+ return remapToGraphQLArrayOutput(await q, tableName, table, relationMap);
1440
2650
  } catch (e) {
1441
- if (e instanceof Error) {
1442
- throw new import_graphql5.GraphQLError(e.message);
1443
- }
1444
- throw e;
2651
+ throw toGraphQLError(e);
1445
2652
  }
1446
2653
  },
1447
2654
  args: queryArgs
1448
2655
  };
1449
2656
  };
1450
- var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1451
- const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1452
- const queryName = `${queryEntityBase}${singleSuffix}`;
2657
+ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
1453
2658
  const queryBase = db.query[tableName];
1454
- const queryArgs = {
1455
- offset: {
1456
- type: import_graphql5.GraphQLInt
1457
- },
1458
- orderBy: {
1459
- type: orderArgs
1460
- },
1461
- where: {
1462
- type: filterArgs
1463
- }
1464
- };
1465
- const typeName = toTypeName3(tableName, singularTypes);
2659
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
1466
2660
  const table = tables[tableName];
2661
+ const pkNames = pgPrimaryKeyPropNames(table);
1467
2662
  return {
1468
- name: queryName,
1469
- resolver: async (_source, args, _context, info) => {
2663
+ name: fieldName,
2664
+ resolver: async (_source, args, context, info) => {
1470
2665
  try {
1471
- const { offset, orderBy, where } = args;
1472
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
1473
- deep: true
1474
- });
1475
- const selectedColumns = extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table);
1476
- let result;
1477
- if (queryBase) {
1478
- result = await queryBase.findFirst({
1479
- columns: selectedColumns,
1480
- offset,
1481
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy (e.g.
1482
- // d0, d1) — use it directly so column refs match the CTE alias.
1483
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1484
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1485
- with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
2666
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
2667
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
2668
+ if (requestQueryBase) {
2669
+ return await runRelationalSelect({
2670
+ queryBase: requestQueryBase,
2671
+ tables,
2672
+ tableName,
2673
+ table,
2674
+ relationMap,
2675
+ typeName,
2676
+ typeNameMapper,
2677
+ parsedInfo,
2678
+ ...args,
2679
+ single: true,
2680
+ filterCtx,
2681
+ pkNames,
2682
+ db: executor
1486
2683
  });
1487
- } else {
1488
- let q = db.select(selectedColumns).from(table);
1489
- if (where) {
1490
- q = q.where(extractFilters(table, tableName, where));
1491
- }
1492
- if (orderBy) {
1493
- q = q.orderBy(...extractOrderBy(table, orderBy));
1494
- }
1495
- if (offset) {
1496
- q = q.offset(offset);
1497
- }
1498
- const rows = await q.limit(1);
1499
- result = rows[0];
1500
2684
  }
1501
- if (!result) {
1502
- return void 0;
2685
+ const { offset, orderBy, where } = args;
2686
+ const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
2687
+ parsedInfo.fieldsByTypeName[typeName],
2688
+ table,
2689
+ { tableName, relationMap, tables }
2690
+ );
2691
+ let q = executor.select(selectedColumnsSql).from(table);
2692
+ if (where) {
2693
+ q = q.where(extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName)));
1503
2694
  }
1504
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1505
- } catch (e) {
1506
- if (e instanceof Error) {
1507
- throw new import_graphql5.GraphQLError(e.message);
2695
+ if (orderBy) {
2696
+ q = q.orderBy(...extractOrderBy(table, orderBy));
2697
+ } else if (pkNames.length) {
2698
+ q = q.orderBy(...primaryKeyOrderExprs(table, pkNames));
2699
+ }
2700
+ if (offset) {
2701
+ q = q.offset(offset);
1508
2702
  }
1509
- throw e;
2703
+ const rows = await q.limit(1);
2704
+ const result = rows[0];
2705
+ return result ? remapToGraphQLSingleOutput(result, tableName, table, relationMap) : void 0;
2706
+ } catch (e) {
2707
+ throw toGraphQLError(e);
1510
2708
  }
1511
2709
  },
1512
2710
  args: queryArgs
1513
2711
  };
1514
2712
  };
1515
- var generateInsertArray2 = (db, tableName, table, baseType, prefix, conflictDoNothing = false, singularTypes = false) => {
1516
- const queryName = `${prefix}${capitalize(tableName)}`;
1517
- const typeName = toTypeName3(tableName, singularTypes);
2713
+ var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_pg_core2.getTableConfig);
2714
+ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1518
2715
  const queryArgs = {
1519
2716
  values: {
1520
- type: new import_graphql5.GraphQLNonNull(new import_graphql5.GraphQLList(new import_graphql5.GraphQLNonNull(baseType)))
2717
+ type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(baseType)))
1521
2718
  }
1522
2719
  };
2720
+ const pkNames = pgPrimaryKeyPropNames(table);
1523
2721
  return {
1524
- name: queryName,
1525
- resolver: async (_source, args, _context, info) => {
2722
+ name: fieldName,
2723
+ resolver: async (_source, args, context, info) => {
1526
2724
  try {
1527
2725
  const input = remapFromGraphQLArrayInput(args.values, table);
1528
2726
  if (!input.length) {
1529
- throw new import_graphql5.GraphQLError("No values were provided!");
2727
+ throw new import_graphql7.GraphQLError("No values were provided!");
1530
2728
  }
1531
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
2729
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1532
2730
  deep: true
1533
2731
  });
1534
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1535
- parsedInfo.fieldsByTypeName[typeName],
1536
- table
1537
- );
1538
- let query = db.insert(table).values(input).returning(columns);
2732
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2733
+ relationMap,
2734
+ tables,
2735
+ tableName,
2736
+ typeName,
2737
+ typeNameMapper,
2738
+ table,
2739
+ pkNames,
2740
+ parsedInfo
2741
+ });
2742
+ const executor = resolveExecutor(db, context);
2743
+ let query = executor.insert(table).values(input).returning(columns);
1539
2744
  if (conflictDoNothing) {
1540
2745
  query = query.onConflictDoNothing();
1541
2746
  }
1542
2747
  const result = await query;
1543
- return remapToGraphQLArrayOutput(result, tableName, table);
2748
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
2749
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
1544
2750
  } catch (e) {
1545
- if (e instanceof Error) {
1546
- throw new import_graphql5.GraphQLError(e.message);
1547
- }
1548
- throw e;
2751
+ throw toGraphQLError(e);
1549
2752
  }
1550
2753
  },
1551
2754
  args: queryArgs
1552
2755
  };
1553
2756
  };
1554
- var generateInsertSingle2 = (db, tableName, table, baseType, prefix, conflictDoNothing = false, singularTypes = false) => {
1555
- const queryEntityBase = singularTypes ? singularize(capitalize(tableName)) : capitalize(tableName);
1556
- const queryName = singularTypes ? `${prefix}${queryEntityBase}` : `${prefix}${queryEntityBase}Single`;
1557
- const typeName = toTypeName3(tableName, singularTypes);
2757
+ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1558
2758
  const queryArgs = {
1559
2759
  values: {
1560
- type: new import_graphql5.GraphQLNonNull(baseType)
2760
+ type: new import_graphql7.GraphQLNonNull(baseType)
1561
2761
  }
1562
2762
  };
2763
+ const pkNames = pgPrimaryKeyPropNames(table);
1563
2764
  return {
1564
- name: queryName,
1565
- resolver: async (_source, args, _context, info) => {
2765
+ name: fieldName,
2766
+ resolver: async (_source, args, context, info) => {
1566
2767
  try {
1567
2768
  const input = remapFromGraphQLSingleInput(args.values, table);
1568
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
2769
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1569
2770
  deep: true
1570
2771
  });
1571
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1572
- parsedInfo.fieldsByTypeName[typeName],
1573
- table
1574
- );
1575
- let query = db.insert(table).values(input).returning(columns);
2772
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2773
+ relationMap,
2774
+ tables,
2775
+ tableName,
2776
+ typeName,
2777
+ typeNameMapper,
2778
+ table,
2779
+ pkNames,
2780
+ parsedInfo
2781
+ });
2782
+ const executor = resolveExecutor(db, context);
2783
+ let query = executor.insert(table).values(input).returning(columns);
1576
2784
  if (conflictDoNothing) {
1577
2785
  query = query.onConflictDoNothing();
1578
2786
  }
@@ -1580,103 +2788,159 @@ var generateInsertSingle2 = (db, tableName, table, baseType, prefix, conflictDoN
1580
2788
  if (!result[0]) {
1581
2789
  return void 0;
1582
2790
  }
1583
- return remapToGraphQLSingleOutput(result[0], tableName, table);
2791
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
2792
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
1584
2793
  } catch (e) {
1585
- if (e instanceof Error) {
1586
- throw new import_graphql5.GraphQLError(e.message);
2794
+ throw toGraphQLError(e);
2795
+ }
2796
+ },
2797
+ args: queryArgs
2798
+ };
2799
+ };
2800
+ var generateUpsert2 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
2801
+ const queryArgs = {
2802
+ values: {
2803
+ type: single ? new import_graphql7.GraphQLNonNull(baseType) : new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(baseType)))
2804
+ },
2805
+ onConflict: {
2806
+ type: onConflictType,
2807
+ description: "How a conflicting row is resolved. Defaults to overwriting it on the primary key."
2808
+ }
2809
+ };
2810
+ const pkNames = pgPrimaryKeyPropNames(table);
2811
+ return {
2812
+ name: fieldName,
2813
+ resolver: async (_source, args, context, info) => {
2814
+ try {
2815
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
2816
+ if (!input.length) {
2817
+ throw new import_graphql7.GraphQLError("No values were provided!");
2818
+ }
2819
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, { deep: true });
2820
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2821
+ relationMap,
2822
+ tables,
2823
+ tableName,
2824
+ typeName,
2825
+ typeNameMapper,
2826
+ table,
2827
+ pkNames,
2828
+ parsedInfo
2829
+ });
2830
+ const plan = resolveConflictPlan({
2831
+ table,
2832
+ values: input,
2833
+ onConflict: args.onConflict,
2834
+ pkNames,
2835
+ uniqueSets,
2836
+ excludedRef: excludedColumnRef,
2837
+ withTarget: true,
2838
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
2839
+ });
2840
+ const executor = resolveExecutor(db, context);
2841
+ let query = executor.insert(table).values(input).returning(columns);
2842
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
2843
+ const result = await query;
2844
+ if (single && !result[0]) {
2845
+ return void 0;
1587
2846
  }
1588
- throw e;
2847
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
2848
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
2849
+ } catch (e) {
2850
+ throw toGraphQLError(e);
1589
2851
  }
1590
2852
  },
1591
2853
  args: queryArgs
1592
2854
  };
1593
2855
  };
1594
- var generateUpdate2 = (db, tableName, table, setArgs, filterArgs, prefix, singularTypes = false) => {
1595
- const queryName = `${prefix}${capitalize(tableName)}`;
1596
- const typeName = toTypeName3(tableName, singularTypes);
2856
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
1597
2857
  const queryArgs = {
1598
2858
  set: {
1599
- type: new import_graphql5.GraphQLNonNull(setArgs)
2859
+ type: new import_graphql7.GraphQLNonNull(setArgs)
1600
2860
  },
1601
2861
  where: {
1602
2862
  type: filterArgs
1603
2863
  }
1604
2864
  };
2865
+ const pkNames = pgPrimaryKeyPropNames(table);
1605
2866
  return {
1606
- name: queryName,
1607
- resolver: async (_source, args, _context, info) => {
2867
+ name: fieldName,
2868
+ resolver: async (_source, args, context, info) => {
1608
2869
  try {
1609
2870
  const { where, set } = args;
1610
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
2871
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1611
2872
  deep: true
1612
2873
  });
1613
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1614
- parsedInfo.fieldsByTypeName[typeName],
1615
- table
1616
- );
2874
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2875
+ relationMap,
2876
+ tables,
2877
+ tableName,
2878
+ typeName,
2879
+ typeNameMapper,
2880
+ table,
2881
+ pkNames,
2882
+ parsedInfo
2883
+ });
1617
2884
  const input = remapFromGraphQLSingleInput(set, table);
1618
2885
  if (!Object.keys(input).length) {
1619
- throw new import_graphql5.GraphQLError("Unable to update with no values specified!");
2886
+ throw new import_graphql7.GraphQLError("Unable to update with no values specified!");
1620
2887
  }
1621
- let query = db.update(table).set(input);
2888
+ const executor = resolveExecutor(db, context);
2889
+ let query = executor.update(table).set(input);
1622
2890
  if (where) {
1623
- const filters = extractFilters(table, tableName, where);
2891
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
1624
2892
  query = query.where(filters);
1625
2893
  }
1626
2894
  query = query.returning(columns);
1627
2895
  const result = await query;
1628
- return remapToGraphQLArrayOutput(result, tableName, table);
2896
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
2897
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
1629
2898
  } catch (e) {
1630
- if (e instanceof Error) {
1631
- throw new import_graphql5.GraphQLError(e.message);
1632
- }
1633
- throw e;
2899
+ throw toGraphQLError(e);
1634
2900
  }
1635
2901
  },
1636
2902
  args: queryArgs
1637
2903
  };
1638
2904
  };
1639
- var generateDelete2 = (db, tableName, table, filterArgs, prefix, singularTypes = false) => {
1640
- const queryName = `${prefix}${capitalize(tableName)}`;
1641
- const typeName = toTypeName3(tableName, singularTypes);
2905
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
1642
2906
  const queryArgs = {
1643
2907
  where: {
1644
2908
  type: filterArgs
1645
2909
  }
1646
2910
  };
1647
2911
  return {
1648
- name: queryName,
1649
- resolver: async (_source, args, _context, info) => {
2912
+ name: fieldName,
2913
+ resolver: async (_source, args, context, info) => {
1650
2914
  try {
1651
2915
  const { where } = args;
1652
- const parsedInfo = (0, import_graphql_parse_resolve_info2.parseResolveInfo)(info, {
2916
+ const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1653
2917
  deep: true
1654
2918
  });
1655
2919
  const columns = extractSelectedColumnsFromTreeSQLFormat(
1656
2920
  parsedInfo.fieldsByTypeName[typeName],
1657
- table
2921
+ table,
2922
+ selectionCtx
1658
2923
  );
1659
- let query = db.delete(table);
2924
+ const executor = resolveExecutor(db, context);
2925
+ let query = executor.delete(table);
1660
2926
  if (where) {
1661
- const filters = extractFilters(table, tableName, where);
2927
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
1662
2928
  query = query.where(filters);
1663
2929
  }
1664
2930
  query = query.returning(columns);
1665
2931
  const result = await query;
1666
2932
  return remapToGraphQLArrayOutput(result, tableName, table);
1667
2933
  } catch (e) {
1668
- if (e instanceof Error) {
1669
- throw new import_graphql5.GraphQLError(e.message);
1670
- }
1671
- throw e;
2934
+ throw toGraphQLError(e);
1672
2935
  }
1673
2936
  },
1674
2937
  args: queryArgs
1675
2938
  };
1676
2939
  };
1677
- function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixes, suffixes, conflictDoNothing = false, singularTypes = false) {
2940
+ function generateSchemaData2(db, schema, relations, options) {
2941
+ const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
1678
2942
  const schemaEntries = Object.entries(schema);
1679
- const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm5.is)(value, import_pg_core2.PgTable));
2943
+ const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm6.is)(value, import_pg_core2.PgTable));
1680
2944
  const tables = Object.fromEntries(tableEntries);
1681
2945
  if (!tableEntries.length) {
1682
2946
  throw new Error(
@@ -1684,13 +2948,22 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1684
2948
  );
1685
2949
  }
1686
2950
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
2951
+ attachTargetPrimaryKeys(namedRelations, tables, pgPrimaryKeyPropNames);
2952
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
2953
+ const filterCtx = { tables, relationMap: namedRelations };
2954
+ const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
1687
2955
  const cacheCtx = {
1688
2956
  genericFilterCache: /* @__PURE__ */ new Map(),
1689
2957
  objectTypeCache: /* @__PURE__ */ new Map(),
1690
2958
  relationFieldContainers: /* @__PURE__ */ new Map(),
1691
2959
  fullyBuiltTables: /* @__PURE__ */ new Set(),
1692
- relationTypeCache: /* @__PURE__ */ new Map()
2960
+ relationTypeCache: /* @__PURE__ */ new Map(),
2961
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
2962
+ filterTypeCache: /* @__PURE__ */ new WeakMap(),
2963
+ listRelationFilterCache: /* @__PURE__ */ new Map(),
2964
+ aggregateTypeCache: /* @__PURE__ */ new Map()
1693
2965
  };
2966
+ const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
1694
2967
  const queries = {};
1695
2968
  const mutations = {};
1696
2969
  const gqlSchemaTypes = Object.fromEntries(
@@ -1703,9 +2976,11 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1703
2976
  true,
1704
2977
  relationsDepthLimit,
1705
2978
  cacheCtx,
1706
- singularTypes,
2979
+ typeNameMapper,
1707
2980
  prefixes.insert,
1708
- prefixes.update
2981
+ prefixes.update,
2982
+ resolverFactory,
2983
+ relationAggregateFactory
1709
2984
  )
1710
2985
  ])
1711
2986
  );
@@ -1714,61 +2989,138 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1714
2989
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1715
2990
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1716
2991
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
2992
+ const {
2993
+ typeName,
2994
+ listFieldName,
2995
+ singleFieldName,
2996
+ aggregateFieldName,
2997
+ createArrayFieldName,
2998
+ createSingleFieldName,
2999
+ upsertArrayFieldName,
3000
+ upsertSingleFieldName,
3001
+ updateFieldName,
3002
+ deleteFieldName
3003
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
1717
3004
  const selectArrGenerated = generateSelectArray2(
1718
3005
  db,
1719
3006
  tableName,
1720
3007
  tables,
1721
- namedRelations,
3008
+ eagerRelations,
1722
3009
  tableOrder,
1723
3010
  tableFilters,
1724
- suffixes.list,
1725
- singularTypes
3011
+ listFieldName,
3012
+ typeName,
3013
+ typeNameMapper,
3014
+ filterCtx,
3015
+ features.distinct
1726
3016
  );
1727
3017
  const selectSingleGenerated = generateSelectSingle2(
1728
3018
  db,
1729
3019
  tableName,
1730
3020
  tables,
1731
- namedRelations,
3021
+ eagerRelations,
1732
3022
  tableOrder,
1733
3023
  tableFilters,
1734
- suffixes.single,
1735
- singularTypes
3024
+ singleFieldName,
3025
+ typeName,
3026
+ typeNameMapper,
3027
+ filterCtx
1736
3028
  );
1737
- const insertArrGenerated = generateInsertArray2(
3029
+ const insertArrGenerated = features.insert ? generateInsertArray2(
1738
3030
  db,
1739
3031
  tableName,
1740
3032
  schema[tableName],
3033
+ tables,
3034
+ eagerRelations,
1741
3035
  insertInput,
1742
- prefixes.insert,
1743
- conflictDoNothing,
1744
- singularTypes
1745
- );
1746
- const insertSingleGenerated = generateInsertSingle2(
3036
+ createArrayFieldName,
3037
+ typeName,
3038
+ typeNameMapper,
3039
+ conflictDoNothing
3040
+ ) : void 0;
3041
+ const insertSingleGenerated = features.insert ? generateInsertSingle2(
1747
3042
  db,
1748
3043
  tableName,
1749
3044
  schema[tableName],
3045
+ tables,
3046
+ eagerRelations,
1750
3047
  insertInput,
1751
- prefixes.insert,
1752
- conflictDoNothing,
1753
- singularTypes
1754
- );
1755
- const updateGenerated = generateUpdate2(
3048
+ createSingleFieldName,
3049
+ typeName,
3050
+ typeNameMapper,
3051
+ conflictDoNothing
3052
+ ) : void 0;
3053
+ const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_pg_core2.getTableConfig) : [];
3054
+ const onConflictInput = features.upsert ? generateOnConflictInput({
3055
+ table: schema[tableName],
3056
+ typeName,
3057
+ uniqueSets,
3058
+ tableFilters,
3059
+ withTarget: true
3060
+ }) : void 0;
3061
+ const upsertArrGenerated = onConflictInput ? generateUpsert2(
3062
+ db,
3063
+ tableName,
3064
+ schema[tableName],
3065
+ tables,
3066
+ eagerRelations,
3067
+ insertInput,
3068
+ onConflictInput,
3069
+ uniqueSets,
3070
+ upsertArrayFieldName,
3071
+ typeName,
3072
+ false,
3073
+ typeNameMapper,
3074
+ filterCtx
3075
+ ) : void 0;
3076
+ const upsertSingleGenerated = onConflictInput ? generateUpsert2(
3077
+ db,
3078
+ tableName,
3079
+ schema[tableName],
3080
+ tables,
3081
+ eagerRelations,
3082
+ insertInput,
3083
+ onConflictInput,
3084
+ uniqueSets,
3085
+ upsertSingleFieldName,
3086
+ typeName,
3087
+ true,
3088
+ typeNameMapper,
3089
+ filterCtx
3090
+ ) : void 0;
3091
+ const updateGenerated = features.update ? generateUpdate2(
1756
3092
  db,
1757
3093
  tableName,
1758
3094
  schema[tableName],
3095
+ tables,
3096
+ eagerRelations,
1759
3097
  updateInput,
1760
3098
  tableFilters,
1761
- prefixes.update,
1762
- singularTypes
1763
- );
1764
- const deleteGenerated = generateDelete2(
3099
+ updateFieldName,
3100
+ typeName,
3101
+ typeNameMapper,
3102
+ filterCtx
3103
+ ) : void 0;
3104
+ const deleteGenerated = features.delete ? generateDelete2(
1765
3105
  db,
1766
3106
  tableName,
1767
3107
  schema[tableName],
1768
3108
  tableFilters,
1769
- prefixes.delete,
1770
- singularTypes
1771
- );
3109
+ deleteFieldName,
3110
+ typeName,
3111
+ filterCtx,
3112
+ { tableName, relationMap: namedRelations, tables }
3113
+ ) : void 0;
3114
+ const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3115
+ const aggregateGenerated = features.aggregates ? generateAggregate(
3116
+ db,
3117
+ tableName,
3118
+ schema[tableName],
3119
+ typeName,
3120
+ aggregateFieldName,
3121
+ tableFilters,
3122
+ filterCtx
3123
+ ) : void 0;
1772
3124
  queries[selectArrGenerated.name] = {
1773
3125
  type: selectArrOutput,
1774
3126
  args: selectArrGenerated.args,
@@ -1779,308 +3131,406 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1779
3131
  args: selectSingleGenerated.args,
1780
3132
  resolve: selectSingleGenerated.resolver
1781
3133
  };
1782
- mutations[insertArrGenerated.name] = {
1783
- type: arrTableItemOutput,
1784
- args: insertArrGenerated.args,
1785
- resolve: insertArrGenerated.resolver
1786
- };
1787
- mutations[insertSingleGenerated.name] = {
1788
- type: singleTableItemOutput,
1789
- args: insertSingleGenerated.args,
1790
- resolve: insertSingleGenerated.resolver
1791
- };
1792
- mutations[updateGenerated.name] = {
1793
- type: arrTableItemOutput,
1794
- args: updateGenerated.args,
1795
- resolve: updateGenerated.resolver
1796
- };
1797
- mutations[deleteGenerated.name] = {
1798
- type: arrTableItemOutput,
1799
- args: deleteGenerated.args,
1800
- resolve: deleteGenerated.resolver
1801
- };
1802
- [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
3134
+ if (aggregateGenerated && aggregateType) {
3135
+ queries[aggregateGenerated.name] = {
3136
+ type: new import_graphql7.GraphQLNonNull(aggregateType),
3137
+ args: aggregateGenerated.args,
3138
+ resolve: aggregateGenerated.resolver
3139
+ };
3140
+ }
3141
+ if (insertArrGenerated) {
3142
+ mutations[insertArrGenerated.name] = {
3143
+ type: arrTableItemOutput,
3144
+ args: insertArrGenerated.args,
3145
+ resolve: insertArrGenerated.resolver
3146
+ };
3147
+ }
3148
+ if (insertSingleGenerated) {
3149
+ mutations[insertSingleGenerated.name] = {
3150
+ type: singleTableItemOutput,
3151
+ args: insertSingleGenerated.args,
3152
+ resolve: insertSingleGenerated.resolver
3153
+ };
3154
+ }
3155
+ if (upsertArrGenerated) {
3156
+ mutations[upsertArrGenerated.name] = {
3157
+ type: arrTableItemOutput,
3158
+ args: upsertArrGenerated.args,
3159
+ resolve: upsertArrGenerated.resolver
3160
+ };
3161
+ }
3162
+ if (upsertSingleGenerated) {
3163
+ mutations[upsertSingleGenerated.name] = {
3164
+ type: singleTableItemOutput,
3165
+ args: upsertSingleGenerated.args,
3166
+ resolve: upsertSingleGenerated.resolver
3167
+ };
3168
+ }
3169
+ if (updateGenerated) {
3170
+ mutations[updateGenerated.name] = {
3171
+ type: arrTableItemOutput,
3172
+ args: updateGenerated.args,
3173
+ resolve: updateGenerated.resolver
3174
+ };
3175
+ }
3176
+ if (deleteGenerated) {
3177
+ mutations[deleteGenerated.name] = {
3178
+ type: arrTableItemOutput,
3179
+ args: deleteGenerated.args,
3180
+ resolve: deleteGenerated.resolver
3181
+ };
3182
+ }
3183
+ const activeInputs = [
3184
+ // The insert input types the upsert mutations too, so either feature keeps it.
3185
+ ...features.insert || onConflictInput ? [insertInput] : [],
3186
+ ...onConflictInput ? [onConflictInput] : [],
3187
+ ...features.update ? [updateInput] : [],
3188
+ tableFilters,
3189
+ tableOrder
3190
+ ];
3191
+ activeInputs.forEach((e) => {
1803
3192
  inputs[e.name] = e;
1804
3193
  });
1805
3194
  outputs[selectSingleOutput.name] = selectSingleOutput;
1806
3195
  outputs[singleTableItemOutput.name] = singleTableItemOutput;
3196
+ if (aggregateType) {
3197
+ outputs[aggregateType.name] = aggregateType;
3198
+ }
3199
+ }
3200
+ const fieldResolvers = {};
3201
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
3202
+ const relResolvers = {};
3203
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
3204
+ const isOne = (0, import_drizzle_orm6.is)(relEntry.relation ?? relEntry, import_drizzle_orm6.One);
3205
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
3206
+ if (resolver) {
3207
+ relResolvers[relName] = resolver;
3208
+ }
3209
+ }
3210
+ if (Object.keys(relResolvers).length > 0) {
3211
+ fieldResolvers[tableName] = relResolvers;
3212
+ }
1807
3213
  }
1808
- return { queries, mutations, inputs, types: outputs };
3214
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
1809
3215
  }
1810
3216
 
1811
3217
  // src/util/builders/sqlite.ts
1812
- var import_drizzle_orm6 = require("drizzle-orm");
3218
+ var import_drizzle_orm7 = require("drizzle-orm");
1813
3219
  var import_sqlite_core2 = require("drizzle-orm/sqlite-core");
1814
- var import_graphql6 = require("graphql");
1815
- var import_graphql_parse_resolve_info3 = require("graphql-parse-resolve-info");
1816
- var toTypeName4 = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
1817
- var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, listSuffix, singularTypes) => {
1818
- const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1819
- const queryName = `${queryEntityBase}${listSuffix}`;
3220
+ var import_graphql8 = require("graphql");
3221
+ var import_graphql_parse_resolve_info4 = require("graphql-parse-resolve-info");
3222
+ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
1820
3223
  const queryBase = db.query[tableName];
1821
3224
  if (!queryBase) {
1822
3225
  throw new Error(
1823
3226
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1824
3227
  );
1825
3228
  }
1826
- const queryArgs = {
1827
- offset: {
1828
- type: import_graphql6.GraphQLInt
1829
- },
1830
- limit: {
1831
- type: import_graphql6.GraphQLInt
1832
- },
1833
- orderBy: {
1834
- type: orderArgs
1835
- },
1836
- where: {
1837
- type: filterArgs
1838
- }
1839
- };
1840
- const typeName = toTypeName4(tableName, singularTypes);
1841
3229
  const table = tables[tableName];
3230
+ const pkNames = sqlitePrimaryKeyPropNames(table);
3231
+ const queryArgs = selectArrayArgs(
3232
+ orderArgs,
3233
+ filterArgs,
3234
+ distinctEnabled ? generateDistinctEnum(table, typeName) : void 0
3235
+ );
1842
3236
  return {
1843
- name: queryName,
1844
- resolver: async (_source, args, _context, info) => {
3237
+ name: fieldName,
3238
+ resolver: async (_source, args, context, info) => {
1845
3239
  try {
1846
- const { offset, limit, orderBy, where } = args;
1847
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1848
- deep: true
3240
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
3241
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
3242
+ return await runRelationalSelect({
3243
+ queryBase: requestQueryBase,
3244
+ tables,
3245
+ tableName,
3246
+ table,
3247
+ relationMap,
3248
+ typeName,
3249
+ typeNameMapper,
3250
+ parsedInfo,
3251
+ ...args,
3252
+ single: false,
3253
+ filterCtx,
3254
+ pkNames,
3255
+ db: executor
1849
3256
  });
1850
- const query = queryBase.findMany({
1851
- columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1852
- offset,
1853
- limit,
1854
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1855
- // use it directly so column refs match the CTE alias.
1856
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1857
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1858
- with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
1859
- });
1860
- const result = await query;
1861
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1862
3257
  } catch (e) {
1863
- if (e instanceof Error) {
1864
- throw new import_graphql6.GraphQLError(e.message);
1865
- }
1866
- throw e;
3258
+ throw toGraphQLError(e);
1867
3259
  }
1868
3260
  },
1869
3261
  args: queryArgs
1870
3262
  };
1871
3263
  };
1872
- var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1873
- const queryEntityBase = singularTypes ? singularize(uncapitalize(tableName)) : uncapitalize(tableName);
1874
- const queryName = `${queryEntityBase}${singleSuffix}`;
3264
+ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
1875
3265
  const queryBase = db.query[tableName];
1876
3266
  if (!queryBase) {
1877
3267
  throw new Error(
1878
3268
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1879
3269
  );
1880
3270
  }
1881
- const queryArgs = {
1882
- offset: {
1883
- type: import_graphql6.GraphQLInt
1884
- },
1885
- orderBy: {
1886
- type: orderArgs
1887
- },
1888
- where: {
1889
- type: filterArgs
1890
- }
1891
- };
1892
- const typeName = toTypeName4(tableName, singularTypes);
3271
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
1893
3272
  const table = tables[tableName];
3273
+ const pkNames = sqlitePrimaryKeyPropNames(table);
1894
3274
  return {
1895
- name: queryName,
1896
- resolver: async (_source, args, _context, info) => {
3275
+ name: fieldName,
3276
+ resolver: async (_source, args, context, info) => {
1897
3277
  try {
1898
- const { offset, orderBy, where } = args;
1899
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
1900
- deep: true
1901
- });
1902
- const query = queryBase.findFirst({
1903
- columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1904
- offset,
1905
- // drizzle-orm v1 RQB calls orderBy with the aliased table proxy —
1906
- // use it directly so column refs match the CTE alias.
1907
- orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1908
- where: where ? { RAW: (aliased) => extractFilters(aliased, tableName, where) } : void 0,
1909
- with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, singularTypes) : void 0
3278
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
3279
+ const { executor, queryBase: requestQueryBase } = resolveQueryExecutor(db, context, tableName, queryBase);
3280
+ return await runRelationalSelect({
3281
+ queryBase: requestQueryBase,
3282
+ tables,
3283
+ tableName,
3284
+ table,
3285
+ relationMap,
3286
+ typeName,
3287
+ typeNameMapper,
3288
+ parsedInfo,
3289
+ ...args,
3290
+ single: true,
3291
+ filterCtx,
3292
+ pkNames,
3293
+ db: executor
1910
3294
  });
1911
- const result = await query;
1912
- if (!result) {
1913
- return void 0;
1914
- }
1915
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1916
3295
  } catch (e) {
1917
- if (e instanceof Error) {
1918
- throw new import_graphql6.GraphQLError(e.message);
1919
- }
1920
- throw e;
3296
+ throw toGraphQLError(e);
1921
3297
  }
1922
3298
  },
1923
3299
  args: queryArgs
1924
3300
  };
1925
3301
  };
1926
- var generateInsertArray3 = (db, tableName, table, baseType, singularTypes = false) => {
1927
- const queryName = `insertInto${capitalize(tableName)}`;
1928
- const typeName = toTypeName4(tableName, singularTypes);
3302
+ var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_sqlite_core2.getTableConfig);
3303
+ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1929
3304
  const queryArgs = {
1930
3305
  values: {
1931
- type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(baseType)))
3306
+ type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(baseType)))
1932
3307
  }
1933
3308
  };
3309
+ const pkNames = sqlitePrimaryKeyPropNames(table);
1934
3310
  return {
1935
- name: queryName,
1936
- resolver: async (_source, args, _context, info) => {
3311
+ name: fieldName,
3312
+ resolver: async (_source, args, context, info) => {
1937
3313
  try {
1938
3314
  const input = remapFromGraphQLArrayInput(args.values, table);
1939
3315
  if (!input.length) {
1940
- throw new import_graphql6.GraphQLError("No values were provided!");
3316
+ throw new import_graphql8.GraphQLError("No values were provided!");
1941
3317
  }
1942
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3318
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
1943
3319
  deep: true
1944
3320
  });
1945
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1946
- parsedInfo.fieldsByTypeName[typeName],
1947
- table
1948
- );
1949
- const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
1950
- return remapToGraphQLArrayOutput(result, tableName, table);
1951
- } catch (e) {
1952
- if (e instanceof Error) {
1953
- throw new import_graphql6.GraphQLError(e.message);
3321
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3322
+ relationMap,
3323
+ tables,
3324
+ tableName,
3325
+ typeName,
3326
+ typeNameMapper,
3327
+ table,
3328
+ pkNames,
3329
+ parsedInfo
3330
+ });
3331
+ const executor = resolveExecutor(db, context);
3332
+ let query = executor.insert(table).values(input).returning(columns);
3333
+ if (conflictDoNothing) {
3334
+ query = query.onConflictDoNothing();
1954
3335
  }
1955
- throw e;
3336
+ const result = await query;
3337
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3338
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3339
+ } catch (e) {
3340
+ throw toGraphQLError(e);
1956
3341
  }
1957
3342
  },
1958
3343
  args: queryArgs
1959
3344
  };
1960
3345
  };
1961
- var generateInsertSingle3 = (db, tableName, table, baseType, singularTypes = false) => {
1962
- const queryEntityBase = singularTypes ? singularize(capitalize(tableName)) : capitalize(tableName);
1963
- const queryName = singularTypes ? `insertInto${queryEntityBase}` : `insertInto${queryEntityBase}Single`;
1964
- const typeName = toTypeName4(tableName, singularTypes);
3346
+ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1965
3347
  const queryArgs = {
1966
3348
  values: {
1967
- type: new import_graphql6.GraphQLNonNull(baseType)
3349
+ type: new import_graphql8.GraphQLNonNull(baseType)
1968
3350
  }
1969
3351
  };
3352
+ const pkNames = sqlitePrimaryKeyPropNames(table);
1970
3353
  return {
1971
- name: queryName,
1972
- resolver: async (_source, args, _context, info) => {
3354
+ name: fieldName,
3355
+ resolver: async (_source, args, context, info) => {
1973
3356
  try {
1974
3357
  const input = remapFromGraphQLSingleInput(args.values, table);
1975
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3358
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
1976
3359
  deep: true
1977
3360
  });
1978
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1979
- parsedInfo.fieldsByTypeName[typeName],
1980
- table
1981
- );
1982
- const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
3361
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3362
+ relationMap,
3363
+ tables,
3364
+ tableName,
3365
+ typeName,
3366
+ typeNameMapper,
3367
+ table,
3368
+ pkNames,
3369
+ parsedInfo
3370
+ });
3371
+ const executor = resolveExecutor(db, context);
3372
+ let query = executor.insert(table).values(input).returning(columns);
3373
+ if (conflictDoNothing) {
3374
+ query = query.onConflictDoNothing();
3375
+ }
3376
+ const result = await query;
1983
3377
  if (!result[0]) {
1984
3378
  return void 0;
1985
3379
  }
1986
- return remapToGraphQLSingleOutput(result[0], tableName, table);
3380
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3381
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
1987
3382
  } catch (e) {
1988
- if (e instanceof Error) {
1989
- throw new import_graphql6.GraphQLError(e.message);
3383
+ throw toGraphQLError(e);
3384
+ }
3385
+ },
3386
+ args: queryArgs
3387
+ };
3388
+ };
3389
+ var generateUpsert3 = (db, tableName, table, tables, relationMap, baseType, onConflictType, uniqueSets, fieldName, typeName, single, typeNameMapper, filterCtx) => {
3390
+ const queryArgs = {
3391
+ values: {
3392
+ type: single ? new import_graphql8.GraphQLNonNull(baseType) : new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(baseType)))
3393
+ },
3394
+ onConflict: {
3395
+ type: onConflictType,
3396
+ description: "How a conflicting row is resolved. Defaults to overwriting it on the primary key."
3397
+ }
3398
+ };
3399
+ const pkNames = sqlitePrimaryKeyPropNames(table);
3400
+ return {
3401
+ name: fieldName,
3402
+ resolver: async (_source, args, context, info) => {
3403
+ try {
3404
+ const input = single ? [remapFromGraphQLSingleInput(args.values, table)] : remapFromGraphQLArrayInput(args.values, table);
3405
+ if (!input.length) {
3406
+ throw new import_graphql8.GraphQLError("No values were provided!");
3407
+ }
3408
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, { deep: true });
3409
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3410
+ relationMap,
3411
+ tables,
3412
+ tableName,
3413
+ typeName,
3414
+ typeNameMapper,
3415
+ table,
3416
+ pkNames,
3417
+ parsedInfo
3418
+ });
3419
+ const plan = resolveConflictPlan({
3420
+ table,
3421
+ values: input,
3422
+ onConflict: args.onConflict,
3423
+ pkNames,
3424
+ uniqueSets,
3425
+ excludedRef: excludedColumnRef,
3426
+ withTarget: true,
3427
+ buildWhere: (where) => extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName))
3428
+ });
3429
+ const executor = resolveExecutor(db, context);
3430
+ let query = executor.insert(table).values(input).returning(columns);
3431
+ query = plan.action === "NOTHING" ? query.onConflictDoNothing(plan.target ? { target: plan.target } : void 0) : query.onConflictDoUpdate({ target: plan.target, set: plan.set, setWhere: plan.setWhere });
3432
+ const result = await query;
3433
+ if (single && !result[0]) {
3434
+ return void 0;
1990
3435
  }
1991
- throw e;
3436
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3437
+ return single ? remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap) : remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
3438
+ } catch (e) {
3439
+ throw toGraphQLError(e);
1992
3440
  }
1993
3441
  },
1994
3442
  args: queryArgs
1995
3443
  };
1996
3444
  };
1997
- var generateUpdate3 = (db, tableName, table, setArgs, filterArgs, singularTypes = false) => {
1998
- const queryName = `update${capitalize(tableName)}`;
1999
- const typeName = toTypeName4(tableName, singularTypes);
3445
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx) => {
2000
3446
  const queryArgs = {
2001
3447
  set: {
2002
- type: new import_graphql6.GraphQLNonNull(setArgs)
3448
+ type: new import_graphql8.GraphQLNonNull(setArgs)
2003
3449
  },
2004
3450
  where: {
2005
3451
  type: filterArgs
2006
3452
  }
2007
3453
  };
3454
+ const pkNames = sqlitePrimaryKeyPropNames(table);
2008
3455
  return {
2009
- name: queryName,
2010
- resolver: async (_source, args, _context, info) => {
3456
+ name: fieldName,
3457
+ resolver: async (_source, args, context, info) => {
2011
3458
  try {
2012
3459
  const { where, set } = args;
2013
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3460
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
2014
3461
  deep: true
2015
3462
  });
2016
- const columns = extractSelectedColumnsFromTreeSQLFormat(
2017
- parsedInfo.fieldsByTypeName[typeName],
2018
- table
2019
- );
3463
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
3464
+ relationMap,
3465
+ tables,
3466
+ tableName,
3467
+ typeName,
3468
+ typeNameMapper,
3469
+ table,
3470
+ pkNames,
3471
+ parsedInfo
3472
+ });
2020
3473
  const input = remapFromGraphQLSingleInput(set, table);
2021
3474
  if (!Object.keys(input).length) {
2022
- throw new import_graphql6.GraphQLError("Unable to update with no values specified!");
3475
+ throw new import_graphql8.GraphQLError("Unable to update with no values specified!");
2023
3476
  }
2024
- let query = db.update(table).set(input);
3477
+ const executor = resolveExecutor(db, context);
3478
+ let query = executor.update(table).set(input);
2025
3479
  if (where) {
2026
- const filters = extractFilters(table, tableName, where);
3480
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2027
3481
  query = query.where(filters);
2028
3482
  }
2029
3483
  query = query.returning(columns);
2030
3484
  const result = await query;
2031
- return remapToGraphQLArrayOutput(result, tableName, table);
3485
+ const enriched = hasRelations ? await eagerLoadMutationRelations(executor, tableName, result, pkNames, withParams) : result;
3486
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
2032
3487
  } catch (e) {
2033
- if (e instanceof Error) {
2034
- throw new import_graphql6.GraphQLError(e.message);
2035
- }
2036
- throw e;
3488
+ throw toGraphQLError(e);
2037
3489
  }
2038
3490
  },
2039
3491
  args: queryArgs
2040
3492
  };
2041
3493
  };
2042
- var generateDelete3 = (db, tableName, table, filterArgs, singularTypes = false) => {
2043
- const queryName = `deleteFrom${capitalize(tableName)}`;
2044
- const typeName = toTypeName4(tableName, singularTypes);
3494
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, filterCtx, selectionCtx) => {
2045
3495
  const queryArgs = {
2046
3496
  where: {
2047
3497
  type: filterArgs
2048
3498
  }
2049
3499
  };
2050
3500
  return {
2051
- name: queryName,
2052
- resolver: async (_source, args, _context, info) => {
3501
+ name: fieldName,
3502
+ resolver: async (_source, args, context, info) => {
2053
3503
  try {
2054
3504
  const { where } = args;
2055
- const parsedInfo = (0, import_graphql_parse_resolve_info3.parseResolveInfo)(info, {
3505
+ const parsedInfo = (0, import_graphql_parse_resolve_info4.parseResolveInfo)(info, {
2056
3506
  deep: true
2057
3507
  });
2058
3508
  const columns = extractSelectedColumnsFromTreeSQLFormat(
2059
3509
  parsedInfo.fieldsByTypeName[typeName],
2060
- table
3510
+ table,
3511
+ selectionCtx
2061
3512
  );
2062
- let query = db.delete(table);
3513
+ const executor = resolveExecutor(db, context);
3514
+ let query = executor.delete(table);
2063
3515
  if (where) {
2064
- const filters = extractFilters(table, tableName, where);
3516
+ const filters = extractFilters(table, tableName, where, relationFilterCtx(filterCtx, tableName));
2065
3517
  query = query.where(filters);
2066
3518
  }
2067
3519
  query = query.returning(columns);
2068
3520
  const result = await query;
2069
3521
  return remapToGraphQLArrayOutput(result, tableName, table);
2070
3522
  } catch (e) {
2071
- if (e instanceof Error) {
2072
- throw new import_graphql6.GraphQLError(e.message);
2073
- }
2074
- throw e;
3523
+ throw toGraphQLError(e);
2075
3524
  }
2076
3525
  },
2077
3526
  args: queryArgs
2078
3527
  };
2079
3528
  };
2080
- var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, singularTypes = false) => {
3529
+ var generateSchemaData3 = (db, schema, relations, options) => {
3530
+ const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
2081
3531
  const rawSchema = schema;
2082
3532
  const schemaEntries = Object.entries(rawSchema);
2083
- const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm6.is)(value, import_sqlite_core2.SQLiteTable));
3533
+ const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm7.is)(value, import_sqlite_core2.SQLiteTable));
2084
3534
  const tables = Object.fromEntries(tableEntries);
2085
3535
  if (!tableEntries.length) {
2086
3536
  throw new Error(
@@ -2088,13 +3538,22 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2088
3538
  );
2089
3539
  }
2090
3540
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
3541
+ attachTargetPrimaryKeys(namedRelations, tables, sqlitePrimaryKeyPropNames);
3542
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
3543
+ const filterCtx = { tables, relationMap: namedRelations };
3544
+ const resolverFactory = createRelationResolverFactory(db, tables, filterCtx);
2091
3545
  const cacheCtx = {
2092
3546
  genericFilterCache: /* @__PURE__ */ new Map(),
2093
3547
  objectTypeCache: /* @__PURE__ */ new Map(),
2094
3548
  relationFieldContainers: /* @__PURE__ */ new Map(),
2095
3549
  fullyBuiltTables: /* @__PURE__ */ new Set(),
2096
- relationTypeCache: /* @__PURE__ */ new Map()
3550
+ relationTypeCache: /* @__PURE__ */ new Map(),
3551
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
3552
+ filterTypeCache: /* @__PURE__ */ new WeakMap(),
3553
+ listRelationFilterCache: /* @__PURE__ */ new Map(),
3554
+ aggregateTypeCache: /* @__PURE__ */ new Map()
2097
3555
  };
3556
+ const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
2098
3557
  const queries = {};
2099
3558
  const mutations = {};
2100
3559
  const gqlSchemaTypes = Object.fromEntries(
@@ -2107,9 +3566,11 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2107
3566
  true,
2108
3567
  relationsDepthLimit,
2109
3568
  cacheCtx,
2110
- singularTypes,
3569
+ typeNameMapper,
2111
3570
  prefixes.insert,
2112
- prefixes.update
3571
+ prefixes.update,
3572
+ resolverFactory,
3573
+ relationAggregateFactory
2113
3574
  )
2114
3575
  ])
2115
3576
  );
@@ -2118,55 +3579,138 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2118
3579
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
2119
3580
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
2120
3581
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
3582
+ const {
3583
+ typeName,
3584
+ listFieldName,
3585
+ singleFieldName,
3586
+ aggregateFieldName,
3587
+ createArrayFieldName,
3588
+ createSingleFieldName,
3589
+ upsertArrayFieldName,
3590
+ upsertSingleFieldName,
3591
+ updateFieldName,
3592
+ deleteFieldName
3593
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
2121
3594
  const selectArrGenerated = generateSelectArray3(
2122
3595
  db,
2123
3596
  tableName,
2124
3597
  tables,
2125
- namedRelations,
3598
+ eagerRelations,
2126
3599
  tableOrder,
2127
3600
  tableFilters,
2128
- suffixes.list,
2129
- singularTypes
3601
+ listFieldName,
3602
+ typeName,
3603
+ typeNameMapper,
3604
+ filterCtx,
3605
+ features.distinct
2130
3606
  );
2131
3607
  const selectSingleGenerated = generateSelectSingle3(
2132
3608
  db,
2133
3609
  tableName,
2134
3610
  tables,
2135
- namedRelations,
3611
+ eagerRelations,
2136
3612
  tableOrder,
2137
3613
  tableFilters,
2138
- suffixes.single,
2139
- singularTypes
3614
+ singleFieldName,
3615
+ typeName,
3616
+ typeNameMapper,
3617
+ filterCtx
2140
3618
  );
2141
- const insertArrGenerated = generateInsertArray3(
3619
+ const insertArrGenerated = features.insert ? generateInsertArray3(
2142
3620
  db,
2143
3621
  tableName,
2144
3622
  schema[tableName],
3623
+ tables,
3624
+ eagerRelations,
2145
3625
  insertInput,
2146
- singularTypes
2147
- );
2148
- const insertSingleGenerated = generateInsertSingle3(
3626
+ createArrayFieldName,
3627
+ typeName,
3628
+ typeNameMapper,
3629
+ conflictDoNothing
3630
+ ) : void 0;
3631
+ const insertSingleGenerated = features.insert ? generateInsertSingle3(
3632
+ db,
3633
+ tableName,
3634
+ schema[tableName],
3635
+ tables,
3636
+ eagerRelations,
3637
+ insertInput,
3638
+ createSingleFieldName,
3639
+ typeName,
3640
+ typeNameMapper,
3641
+ conflictDoNothing
3642
+ ) : void 0;
3643
+ const uniqueSets = features.upsert ? getUniqueColumnSets(schema[tableName], import_sqlite_core2.getTableConfig) : [];
3644
+ const onConflictInput = features.upsert ? generateOnConflictInput({
3645
+ table: schema[tableName],
3646
+ typeName,
3647
+ uniqueSets,
3648
+ tableFilters,
3649
+ withTarget: true
3650
+ }) : void 0;
3651
+ const upsertArrGenerated = onConflictInput ? generateUpsert3(
2149
3652
  db,
2150
3653
  tableName,
2151
3654
  schema[tableName],
3655
+ tables,
3656
+ eagerRelations,
2152
3657
  insertInput,
2153
- singularTypes
2154
- );
2155
- const updateGenerated = generateUpdate3(
3658
+ onConflictInput,
3659
+ uniqueSets,
3660
+ upsertArrayFieldName,
3661
+ typeName,
3662
+ false,
3663
+ typeNameMapper,
3664
+ filterCtx
3665
+ ) : void 0;
3666
+ const upsertSingleGenerated = onConflictInput ? generateUpsert3(
3667
+ db,
3668
+ tableName,
3669
+ schema[tableName],
3670
+ tables,
3671
+ eagerRelations,
3672
+ insertInput,
3673
+ onConflictInput,
3674
+ uniqueSets,
3675
+ upsertSingleFieldName,
3676
+ typeName,
3677
+ true,
3678
+ typeNameMapper,
3679
+ filterCtx
3680
+ ) : void 0;
3681
+ const updateGenerated = features.update ? generateUpdate3(
2156
3682
  db,
2157
3683
  tableName,
2158
3684
  schema[tableName],
3685
+ tables,
3686
+ eagerRelations,
2159
3687
  updateInput,
2160
3688
  tableFilters,
2161
- singularTypes
2162
- );
2163
- const deleteGenerated = generateDelete3(
3689
+ updateFieldName,
3690
+ typeName,
3691
+ typeNameMapper,
3692
+ filterCtx
3693
+ ) : void 0;
3694
+ const deleteGenerated = features.delete ? generateDelete3(
2164
3695
  db,
2165
3696
  tableName,
2166
3697
  schema[tableName],
2167
3698
  tableFilters,
2168
- singularTypes
2169
- );
3699
+ deleteFieldName,
3700
+ typeName,
3701
+ filterCtx,
3702
+ { tableName, relationMap: namedRelations, tables }
3703
+ ) : void 0;
3704
+ const aggregateType = features.aggregates ? generateAggregateTypes(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3705
+ const aggregateGenerated = features.aggregates ? generateAggregate(
3706
+ db,
3707
+ tableName,
3708
+ schema[tableName],
3709
+ typeName,
3710
+ aggregateFieldName,
3711
+ tableFilters,
3712
+ filterCtx
3713
+ ) : void 0;
2170
3714
  queries[selectArrGenerated.name] = {
2171
3715
  type: selectArrOutput,
2172
3716
  args: selectArrGenerated.args,
@@ -2177,33 +3721,87 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2177
3721
  args: selectSingleGenerated.args,
2178
3722
  resolve: selectSingleGenerated.resolver
2179
3723
  };
2180
- mutations[insertArrGenerated.name] = {
2181
- type: arrTableItemOutput,
2182
- args: insertArrGenerated.args,
2183
- resolve: insertArrGenerated.resolver
2184
- };
2185
- mutations[insertSingleGenerated.name] = {
2186
- type: singleTableItemOutput,
2187
- args: insertSingleGenerated.args,
2188
- resolve: insertSingleGenerated.resolver
2189
- };
2190
- mutations[updateGenerated.name] = {
2191
- type: arrTableItemOutput,
2192
- args: updateGenerated.args,
2193
- resolve: updateGenerated.resolver
2194
- };
2195
- mutations[deleteGenerated.name] = {
2196
- type: arrTableItemOutput,
2197
- args: deleteGenerated.args,
2198
- resolve: deleteGenerated.resolver
2199
- };
2200
- [insertInput, updateInput, tableFilters, tableOrder].forEach((e) => {
3724
+ if (aggregateGenerated && aggregateType) {
3725
+ queries[aggregateGenerated.name] = {
3726
+ type: new import_graphql8.GraphQLNonNull(aggregateType),
3727
+ args: aggregateGenerated.args,
3728
+ resolve: aggregateGenerated.resolver
3729
+ };
3730
+ }
3731
+ if (insertArrGenerated) {
3732
+ mutations[insertArrGenerated.name] = {
3733
+ type: arrTableItemOutput,
3734
+ args: insertArrGenerated.args,
3735
+ resolve: insertArrGenerated.resolver
3736
+ };
3737
+ }
3738
+ if (insertSingleGenerated) {
3739
+ mutations[insertSingleGenerated.name] = {
3740
+ type: singleTableItemOutput,
3741
+ args: insertSingleGenerated.args,
3742
+ resolve: insertSingleGenerated.resolver
3743
+ };
3744
+ }
3745
+ if (upsertArrGenerated) {
3746
+ mutations[upsertArrGenerated.name] = {
3747
+ type: arrTableItemOutput,
3748
+ args: upsertArrGenerated.args,
3749
+ resolve: upsertArrGenerated.resolver
3750
+ };
3751
+ }
3752
+ if (upsertSingleGenerated) {
3753
+ mutations[upsertSingleGenerated.name] = {
3754
+ type: singleTableItemOutput,
3755
+ args: upsertSingleGenerated.args,
3756
+ resolve: upsertSingleGenerated.resolver
3757
+ };
3758
+ }
3759
+ if (updateGenerated) {
3760
+ mutations[updateGenerated.name] = {
3761
+ type: arrTableItemOutput,
3762
+ args: updateGenerated.args,
3763
+ resolve: updateGenerated.resolver
3764
+ };
3765
+ }
3766
+ if (deleteGenerated) {
3767
+ mutations[deleteGenerated.name] = {
3768
+ type: arrTableItemOutput,
3769
+ args: deleteGenerated.args,
3770
+ resolve: deleteGenerated.resolver
3771
+ };
3772
+ }
3773
+ const activeInputs = [
3774
+ // The insert input types the upsert mutations too, so either feature keeps it.
3775
+ ...features.insert || onConflictInput ? [insertInput] : [],
3776
+ ...onConflictInput ? [onConflictInput] : [],
3777
+ ...features.update ? [updateInput] : [],
3778
+ tableFilters,
3779
+ tableOrder
3780
+ ];
3781
+ activeInputs.forEach((e) => {
2201
3782
  inputs[e.name] = e;
2202
3783
  });
2203
3784
  outputs[selectSingleOutput.name] = selectSingleOutput;
2204
3785
  outputs[singleTableItemOutput.name] = singleTableItemOutput;
3786
+ if (aggregateType) {
3787
+ outputs[aggregateType.name] = aggregateType;
3788
+ }
3789
+ }
3790
+ const fieldResolvers = {};
3791
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
3792
+ const relResolvers = {};
3793
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
3794
+ const isOne = (0, import_drizzle_orm7.is)(relEntry.relation ?? relEntry, import_drizzle_orm7.One);
3795
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
3796
+ if (resolver) {
3797
+ relResolvers[relName] = resolver;
3798
+ }
3799
+ }
3800
+ if (Object.keys(relResolvers).length > 0) {
3801
+ fieldResolvers[tableName] = relResolvers;
3802
+ }
2205
3803
  }
2206
- return { queries, mutations, inputs, types: outputs };
3804
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
2207
3805
  };
2208
3806
 
2209
3807
  // src/index.ts
@@ -2218,15 +3816,32 @@ var buildSchema = (db, config) => {
2218
3816
  );
2219
3817
  }
2220
3818
  const prefixes = {
2221
- insert: config?.prefixes?.insert ?? "insertInto",
2222
- delete: config?.prefixes?.delete ?? "deleteFrom",
2223
- update: config?.prefixes?.update ?? "update"
3819
+ insert: config?.prefixes?.insert ?? "create",
3820
+ delete: config?.prefixes?.delete ?? "delete",
3821
+ update: config?.prefixes?.update ?? "update",
3822
+ upsert: config?.prefixes?.upsert ?? "upsert"
2224
3823
  };
2225
3824
  const suffixes = {
2226
3825
  list: config?.suffixes?.list ?? "",
2227
3826
  single: config?.suffixes?.single ?? "Single"
2228
3827
  };
2229
- const singularTypes = config?.singularTypes ?? false;
3828
+ const typeNameMapper = config?.typeNameMapper;
3829
+ const features = {
3830
+ aggregates: config?.features?.aggregates ?? true,
3831
+ relationAggregates: config?.features?.relationAggregates ?? true,
3832
+ distinct: config?.features?.distinct ?? true,
3833
+ insert: config?.features?.insert ?? true,
3834
+ update: config?.features?.update ?? true,
3835
+ delete: config?.features?.delete ?? true,
3836
+ upsert: config?.features?.upsert ?? false
3837
+ };
3838
+ const eagerOpt = config?.eagerLoadRelations;
3839
+ const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
3840
+ if (!typeNameMapper && suffixes.list === suffixes.single) {
3841
+ throw new Error(
3842
+ "Drizzle-GraphQL Error: List and single query suffixes cannot be the same. This would create conflicting GraphQL field names."
3843
+ );
3844
+ }
2230
3845
  if (typeof config?.relationsDepthLimit === "number") {
2231
3846
  if (config.relationsDepthLimit < 0) {
2232
3847
  throw new Error(
@@ -2238,69 +3853,62 @@ var buildSchema = (db, config) => {
2238
3853
  "Drizzle-GraphQL Error: config.relationsDepthLimit is supposed to be nonnegative integer or undefined!"
2239
3854
  );
2240
3855
  }
2241
- if (suffixes.list === suffixes.single) {
2242
- throw new Error(
2243
- "Drizzle-GraphQL Error: List and single query suffixes cannot be the same. This would create conflicting GraphQL field names."
2244
- );
2245
- }
2246
3856
  }
3857
+ const generatorOptions = {
3858
+ relationsDepthLimit: config?.relationsDepthLimit,
3859
+ prefixes,
3860
+ suffixes,
3861
+ conflictDoNothing: config?.conflictDoNothing ?? false,
3862
+ typeNameMapper,
3863
+ shouldEagerLoad,
3864
+ features
3865
+ };
2247
3866
  let generatorOutput;
2248
- if ((0, import_drizzle_orm7.is)(db, import_mysql_core3.MySqlDatabase)) {
2249
- generatorOutput = generateSchemaData(
2250
- db,
2251
- schema,
2252
- relations,
2253
- config?.relationsDepthLimit,
2254
- prefixes,
2255
- suffixes,
2256
- singularTypes
2257
- );
2258
- } else if ((0, import_drizzle_orm7.is)(db, import_pg_core3.PgAsyncDatabase)) {
2259
- generatorOutput = generateSchemaData2(
2260
- db,
2261
- schema,
2262
- relations,
2263
- config?.relationsDepthLimit,
2264
- prefixes,
2265
- suffixes,
2266
- config?.conflictDoNothing ?? false,
2267
- singularTypes
2268
- );
2269
- } else if ((0, import_drizzle_orm7.is)(db, import_sqlite_core3.BaseSQLiteDatabase)) {
2270
- generatorOutput = generateSchemaData3(
2271
- db,
2272
- schema,
2273
- relations,
2274
- config?.relationsDepthLimit,
2275
- prefixes,
2276
- suffixes,
2277
- singularTypes
2278
- );
3867
+ if ((0, import_drizzle_orm8.is)(db, import_mysql_core3.MySqlDatabase)) {
3868
+ generatorOutput = generateSchemaData(db, schema, relations, generatorOptions);
3869
+ } else if ((0, import_drizzle_orm8.is)(db, import_pg_core3.PgAsyncDatabase)) {
3870
+ generatorOutput = generateSchemaData2(db, schema, relations, generatorOptions);
3871
+ } else if ((0, import_drizzle_orm8.is)(db, import_sqlite_core3.BaseSQLiteDatabase)) {
3872
+ generatorOutput = generateSchemaData3(db, schema, relations, generatorOptions);
2279
3873
  } else {
2280
3874
  throw new Error("Drizzle-GraphQL Error: Unknown database instance type");
2281
3875
  }
3876
+ const onError = config?.onError;
3877
+ applyErrorMapper(
3878
+ generatorOutput,
3879
+ onError ? (error) => onError(error) ?? defaultErrorMapper(error) : defaultErrorMapper
3880
+ );
2282
3881
  const { queries, mutations, inputs, types } = generatorOutput;
2283
3882
  const graphQLSchemaConfig = {
2284
3883
  types: [...Object.values(inputs), ...Object.values(types)],
2285
- query: new import_graphql7.GraphQLObjectType({
3884
+ query: new import_graphql9.GraphQLObjectType({
2286
3885
  name: "Query",
2287
3886
  fields: queries
2288
3887
  })
2289
3888
  };
2290
- if (config?.mutations !== false) {
2291
- const mutation = new import_graphql7.GraphQLObjectType({
3889
+ if (config?.mutations !== false && Object.keys(mutations).length) {
3890
+ const mutation = new import_graphql9.GraphQLObjectType({
2292
3891
  name: "Mutation",
2293
3892
  fields: mutations
2294
3893
  });
2295
3894
  graphQLSchemaConfig.mutation = mutation;
2296
3895
  }
2297
- const outputSchema = new import_graphql7.GraphQLSchema(graphQLSchemaConfig);
3896
+ const outputSchema = new import_graphql9.GraphQLSchema(graphQLSchemaConfig);
2298
3897
  return { schema: outputSchema, entities: generatorOutput };
2299
3898
  };
2300
3899
  // Annotate the CommonJS export names for ESM import in node:
2301
3900
  0 && (module.exports = {
3901
+ GraphQLBigIntString,
3902
+ GraphQLDate,
3903
+ GraphQLDateTime,
3904
+ GraphQLJSON,
3905
+ GraphQLUUID,
2302
3906
  buildSchema,
3907
+ createRelationResolverFactory,
3908
+ defaultErrorMapper,
3909
+ drizzleExecutorKey,
2303
3910
  extractFilters,
2304
- extractOrderBy
3911
+ extractOrderBy,
3912
+ extractRelationJoinColumns
2305
3913
  });
2306
3914
  //# sourceMappingURL=index.cjs.map