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