@vantreeseba/drizzle-graphql 1.0.3 → 2.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,5 +1,5 @@
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";
@@ -9,12 +9,11 @@ import {
9
9
  } from "graphql";
10
10
 
11
11
  // src/util/builders/mysql.ts
12
- import { is as is3 } from "drizzle-orm";
13
- import { MySqlTable } from "drizzle-orm/mysql-core";
12
+ import { is as is4, One as One3 } from "drizzle-orm";
13
+ import { getTableConfig, MySqlTable } from "drizzle-orm/mysql-core";
14
14
  import {
15
15
  GraphQLBoolean as GraphQLBoolean3,
16
16
  GraphQLError as GraphQLError3,
17
- GraphQLInt as GraphQLInt3,
18
17
  GraphQLList as GraphQLList3,
19
18
  GraphQLNonNull as GraphQLNonNull3,
20
19
  GraphQLObjectType as GraphQLObjectType3
@@ -27,12 +26,12 @@ import {
27
26
  asc,
28
27
  desc,
29
28
  eq,
30
- getColumns as getColumns2,
29
+ getColumns,
31
30
  gt,
32
31
  gte,
33
32
  ilike,
34
33
  inArray,
35
- is as is2,
34
+ is as is3,
36
35
  isNotNull,
37
36
  isNull,
38
37
  like,
@@ -42,8 +41,9 @@ import {
42
41
  notIlike,
43
42
  notInArray,
44
43
  notLike,
45
- One,
46
- or
44
+ One as One2,
45
+ or,
46
+ sql
47
47
  } from "drizzle-orm";
48
48
  import {
49
49
  GraphQLBoolean as GraphQLBoolean2,
@@ -57,14 +57,59 @@ import {
57
57
  GraphQLString as GraphQLString2
58
58
  } from "graphql";
59
59
 
60
+ // src/util/batch-loader/index.ts
61
+ var DRIZZLE_LOADERS_KEY = /* @__PURE__ */ Symbol("drizzle-graphql-loaders");
62
+ var BatchLoader = class {
63
+ constructor(batchFn) {
64
+ this.batchFn = batchFn;
65
+ }
66
+ batch = [];
67
+ scheduled = false;
68
+ load(key) {
69
+ return new Promise((resolve, reject) => {
70
+ this.batch.push({ key, resolve, reject });
71
+ if (!this.scheduled) {
72
+ this.scheduled = true;
73
+ Promise.resolve().then(() => this.dispatch());
74
+ }
75
+ });
76
+ }
77
+ async dispatch() {
78
+ const current = this.batch.splice(0);
79
+ this.scheduled = false;
80
+ try {
81
+ const results = await this.batchFn(current.map(({ key }) => key));
82
+ for (let i = 0; i < current.length; i++) {
83
+ current[i].resolve(results[i]);
84
+ }
85
+ } catch (err) {
86
+ for (const { reject } of current) {
87
+ reject(err);
88
+ }
89
+ }
90
+ }
91
+ };
92
+ var getOrCreateLoader = (context, key, batchFn) => {
93
+ if (!context || typeof context !== "object") {
94
+ return new BatchLoader(batchFn);
95
+ }
96
+ if (!context[DRIZZLE_LOADERS_KEY]) {
97
+ context[DRIZZLE_LOADERS_KEY] = /* @__PURE__ */ new Map();
98
+ }
99
+ const loaders = context[DRIZZLE_LOADERS_KEY];
100
+ if (!loaders.has(key)) {
101
+ loaders.set(key, new BatchLoader(batchFn));
102
+ }
103
+ return loaders.get(key);
104
+ };
105
+
60
106
  // src/util/case-ops/index.ts
61
107
  import pluralize from "pluralize";
62
108
  var uncapitalize = (input) => input?.length ? `${input[0].toLocaleLowerCase()}${input.length > 1 ? input.slice(1, input.length) : ""}` : input;
63
109
  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
110
 
66
111
  // src/util/data-mappers/index.ts
67
- import { getTableColumns } from "drizzle-orm";
112
+ import { getTableColumns, is, One } from "drizzle-orm";
68
113
  import { GraphQLError } from "graphql";
69
114
  var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
70
115
  if (Array.isArray(value)) {
@@ -121,6 +166,11 @@ var remapToGraphQLCore = (key, value, tableName, column, relationMap) => {
121
166
  var remapToGraphQLSingleOutput = (queryOutput, tableName, table, relationMap) => {
122
167
  for (const [key, value] of Object.entries(queryOutput)) {
123
168
  if (value === void 0 || value === null) {
169
+ const relEntry = value === null ? relationMap?.[tableName]?.[key] : void 0;
170
+ if (relEntry && is(relEntry.relation, One)) {
171
+ queryOutput[key] = null;
172
+ continue;
173
+ }
124
174
  delete queryOutput[key];
125
175
  continue;
126
176
  }
@@ -258,7 +308,7 @@ var remapFromGraphQLArrayInput = (queryInput, table) => {
258
308
  };
259
309
 
260
310
  // src/util/type-converter/index.ts
261
- import { extractExtendedColumnType, getColumns, is } from "drizzle-orm";
311
+ import { extractExtendedColumnType, is as is2 } from "drizzle-orm";
262
312
  import { MySqlInt, MySqlSerial } from "drizzle-orm/mysql-core";
263
313
  import { PgDate, PgDateString, PgInteger, PgSerial, PgTimestamp, PgTimestampString } from "drizzle-orm/pg-core";
264
314
  import { SQLiteInteger } from "drizzle-orm/sqlite-core";
@@ -341,14 +391,14 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
341
391
  case "number": {
342
392
  const dims = column.dimensions;
343
393
  if (dims !== void 0 && dims > 0) {
344
- const baseDesc = is(column, PgInteger) || is(column, PgSerial) ? "Integer" : "Float";
394
+ const baseDesc = is2(column, PgInteger) || is2(column, PgSerial) ? "Integer" : "Float";
345
395
  const baseType2 = baseDesc === "Integer" ? GraphQLInt : GraphQLFloat;
346
396
  return {
347
397
  type: new GraphQLList(new GraphQLNonNull(baseType2)),
348
398
  description: `Array<${baseDesc}>`
349
399
  };
350
400
  }
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" };
401
+ 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
402
  }
353
403
  case "array": {
354
404
  if (column.columnType === "PgVector") {
@@ -378,26 +428,6 @@ var columnToGraphQLCore = (column, columnName, tableName, isInput) => {
378
428
  throw new Error(`Drizzle-GraphQL Error: Type ${column.dataType} is not implemented!`);
379
429
  }
380
430
  };
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
431
  var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable = false, defaultIsNullable = false, isInput = false) => {
402
432
  const typeDesc = columnToGraphQLCore(column, columnName, tableName, isInput);
403
433
  const noDesc = ["string", "boolean", "number"];
@@ -419,7 +449,10 @@ var drizzleColumnToGraphQLType = (column, columnName, tableName, forceNullable =
419
449
 
420
450
  // src/util/builders/common.ts
421
451
  var rqbCrashTypes = ["SQLiteBigInt", "SQLiteBlobJson", "SQLiteBlobBuffer"];
422
- var toTypeName = (name, singular) => singular ? capitalize(singularize(name)) : capitalize(name);
452
+ var resolveTypeName = (name, typeNameMapper) => {
453
+ const mapped = typeNameMapper?.(name);
454
+ return mapped ? capitalize(mapped.singular) : capitalize(name);
455
+ };
423
456
  var buildNamedRelations = (relations, tableEntries) => {
424
457
  const namedRelations = {};
425
458
  for (const [relTableName, relConfig] of Object.entries(relations)) {
@@ -452,8 +485,131 @@ var buildNamedRelations = (relations, tableEntries) => {
452
485
  }
453
486
  return namedRelations;
454
487
  };
488
+ var attachTargetPrimaryKeys = (namedRelations, tables, resolvePkNames) => {
489
+ const cache = /* @__PURE__ */ new Map();
490
+ for (const rels of Object.values(namedRelations)) {
491
+ for (const relEntry of Object.values(rels)) {
492
+ const { targetTableName } = relEntry;
493
+ let pk = cache.get(targetTableName);
494
+ if (!pk) {
495
+ const targetTable = tables[targetTableName];
496
+ pk = targetTable ? resolvePkNames(targetTable) : [];
497
+ cache.set(targetTableName, pk);
498
+ }
499
+ relEntry.targetPkNames = pk;
500
+ }
501
+ }
502
+ };
503
+ var extractRelationJoinColumns = (relEntry, parentTable, targetTable) => {
504
+ const rel = relEntry.relation ?? relEntry;
505
+ const sourceColumns = rel.sourceColumns;
506
+ const targetColumns = rel.targetColumns;
507
+ if (!sourceColumns?.length || !targetColumns?.length) {
508
+ return void 0;
509
+ }
510
+ const sourceCol = sourceColumns[0];
511
+ const targetCol = targetColumns[0];
512
+ const parentCols = getColumns(parentTable);
513
+ const localColPropName = Object.entries(parentCols).find(([, c]) => c === sourceCol)?.[0];
514
+ const targetCols = getColumns(targetTable);
515
+ const foreignColPropName = Object.entries(targetCols).find(([, c]) => c === targetCol)?.[0];
516
+ if (!localColPropName || !foreignColPropName) {
517
+ return void 0;
518
+ }
519
+ return { localColPropName, foreignCol: targetCol, foreignColPropName };
520
+ };
521
+ var batchedPaginatedRelationQuery = async (db, targetTable, foreignCol, whereCondition, orderByArg, limit, offset, pkNames) => {
522
+ const cols = getColumns(targetTable);
523
+ const orderExprs = [
524
+ ...orderByArg ? extractOrderBy(targetTable, orderByArg) : [],
525
+ ...primaryKeyOrderExprs(targetTable, pkNames)
526
+ ];
527
+ const orderClause = orderExprs.length ? sql` order by ${sql.join(orderExprs, sql`, `)}` : sql``;
528
+ const RN = "__drizzle_graphql_rn";
529
+ const rowNumber = sql`row_number() over (partition by ${foreignCol}${orderClause})`.as(RN);
530
+ const sub = db.select({ ...cols, [RN]: rowNumber }).from(targetTable).where(whereCondition).as("__paginated");
531
+ const lower = offset ?? 0;
532
+ const windowConds = [gt(sub[RN], lower)];
533
+ if (limit != null) {
534
+ windowConds.push(lte(sub[RN], lower + limit));
535
+ }
536
+ const rows = await db.select().from(sub).where(and(...windowConds)).orderBy(sub[RN]);
537
+ for (const row of rows) {
538
+ delete row[RN];
539
+ }
540
+ return rows;
541
+ };
542
+ var createRelationResolverFactory = (db, tables) => ({ tableName, relationName, relEntry, isOne }) => {
543
+ const parentTable = tables[tableName];
544
+ const targetTableName = relEntry.targetTableName;
545
+ const targetTable = tables[targetTableName];
546
+ if (!parentTable || !targetTable) {
547
+ return void 0;
548
+ }
549
+ const joinCols = extractRelationJoinColumns(relEntry, parentTable, targetTable);
550
+ if (!joinCols) {
551
+ return void 0;
552
+ }
553
+ const { localColPropName, foreignCol, foreignColPropName } = joinCols;
554
+ const targetPkNames = relEntry.targetPkNames ?? [];
555
+ return async (parent, args, context) => {
556
+ if (parent[relationName] !== void 0) {
557
+ return parent[relationName];
558
+ }
559
+ const localValue = parent[localColPropName];
560
+ if (localValue == null) {
561
+ return isOne ? null : [];
562
+ }
563
+ const { where: whereArg, orderBy: orderByArg, limit, offset } = args ?? {};
564
+ const argsKey = JSON.stringify({
565
+ where: whereArg ?? null,
566
+ orderBy: orderByArg ?? null,
567
+ limit: limit ?? null,
568
+ offset: offset ?? null
569
+ });
570
+ const loaderKey = `${tableName}::${relationName}::${argsKey}`;
571
+ const loader = getOrCreateLoader(context, loaderKey, async (parentIds) => {
572
+ const uniqueIds = [...new Set(parentIds)];
573
+ const whereCondition = and(
574
+ inArray(foreignCol, uniqueIds),
575
+ whereArg ? extractFilters(targetTable, targetTableName, whereArg) : void 0
576
+ );
577
+ let rows;
578
+ if (limit != null || offset != null) {
579
+ rows = await batchedPaginatedRelationQuery(
580
+ db,
581
+ targetTable,
582
+ foreignCol,
583
+ whereCondition,
584
+ orderByArg,
585
+ limit ?? null,
586
+ offset ?? null,
587
+ targetPkNames
588
+ );
589
+ } else {
590
+ let q = db.select().from(targetTable).where(whereCondition);
591
+ if (orderByArg) {
592
+ q = q.orderBy(...extractOrderBy(targetTable, orderByArg));
593
+ }
594
+ rows = await q;
595
+ }
596
+ if (isOne) {
597
+ const byKey = new Map(rows.map((row) => [String(row[foreignColPropName]), row]));
598
+ remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
599
+ return parentIds.map((id) => byKey.get(String(id)) ?? null);
600
+ }
601
+ const grouped = new Map(uniqueIds.map((id) => [String(id), []]));
602
+ for (const row of rows) {
603
+ grouped.get(String(row[foreignColPropName]))?.push(row);
604
+ }
605
+ remapToGraphQLArrayOutput(rows, targetTableName, targetTable);
606
+ return parentIds.map((id) => grouped.get(String(id)) ?? []);
607
+ });
608
+ return loader.load(localValue);
609
+ };
610
+ };
455
611
  var extractSelectedColumnsFromTree = (tree, table) => {
456
- const tableColumns = getColumns2(table);
612
+ const tableColumns = getColumns(table);
457
613
  const treeEntries = Object.entries(tree);
458
614
  const selectedColumns = [];
459
615
  for (const [_fieldName, fieldData] of treeEntries) {
@@ -470,7 +626,7 @@ var extractSelectedColumnsFromTree = (tree, table) => {
470
626
  return Object.fromEntries(selectedColumns);
471
627
  };
472
628
  var extractSelectedColumnsFromTreeSQLFormat = (tree, table) => {
473
- const tableColumns = getColumns2(table);
629
+ const tableColumns = getColumns(table);
474
630
  const treeEntries = Object.entries(tree);
475
631
  const selectedColumns = [];
476
632
  for (const [_fieldName, fieldData] of treeEntries) {
@@ -585,7 +741,7 @@ var generateTableOrderCached = (table) => {
585
741
  }
586
742
  let remapped = {};
587
743
  try {
588
- const columns = getColumns2(table);
744
+ const columns = getColumns(table);
589
745
  const columnEntries = Object.entries(columns);
590
746
  remapped = Object.fromEntries(
591
747
  columnEntries.map(([columnName, _columnDescription]) => [columnName, { type: innerOrder }])
@@ -600,7 +756,7 @@ var generateTableFilterValuesCached = (table, tableName, cacheCtx) => {
600
756
  if (filterMap.has(table)) {
601
757
  return filterMap.get(table);
602
758
  }
603
- const columns = getColumns2(table);
759
+ const columns = getColumns(table);
604
760
  const columnEntries = Object.entries(columns);
605
761
  const remapped = Object.fromEntries(
606
762
  columnEntries.map(([columnName, columnDescription]) => [
@@ -618,7 +774,7 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
618
774
  if (fieldMap.has(table)) {
619
775
  return fieldMap.get(table);
620
776
  }
621
- const columns = getColumns2(table);
777
+ const columns = getColumns(table);
622
778
  const columnEntries = Object.entries(columns);
623
779
  const remapped = Object.fromEntries(
624
780
  columnEntries.map(([columnName, columnDescription]) => [
@@ -629,34 +785,32 @@ var generateTableSelectTypeFieldsCached = (table, tableName) => {
629
785
  fieldMap.set(table, remapped);
630
786
  return remapped;
631
787
  };
632
- var orderTypeMap = /* @__PURE__ */ new WeakMap();
633
- var generateTableOrderTypeCached = (table, tableName, singularTypes) => {
634
- if (orderTypeMap.has(table)) {
635
- return orderTypeMap.get(table);
788
+ var generateTableOrderTypeCached = (table, tableName, typeNameMapper, cacheCtx) => {
789
+ if (cacheCtx.orderTypeCache.has(table)) {
790
+ return cacheCtx.orderTypeCache.get(table);
636
791
  }
637
792
  const orderColumns = generateTableOrderCached(table);
638
793
  const order = new GraphQLInputObjectType2({
639
- name: `${toTypeName(tableName, singularTypes)}OrderBy`,
794
+ name: `${resolveTypeName(tableName, typeNameMapper)}OrderBy`,
640
795
  fields: orderColumns
641
796
  });
642
- orderTypeMap.set(table, order);
797
+ cacheCtx.orderTypeCache.set(table, order);
643
798
  return order;
644
799
  };
645
- var filterTypeMap = /* @__PURE__ */ new WeakMap();
646
- var generateTableFilterTypeCached = (table, tableName, cacheCtx, singularTypes) => {
647
- if (filterTypeMap.has(table)) {
648
- return filterTypeMap.get(table);
800
+ var generateTableFilterTypeCached = (table, tableName, cacheCtx, typeNameMapper) => {
801
+ if (cacheCtx.filterTypeCache.has(table)) {
802
+ return cacheCtx.filterTypeCache.get(table);
649
803
  }
650
804
  const filterColumns = generateTableFilterValuesCached(table, tableName, cacheCtx);
651
805
  const filters = new GraphQLInputObjectType2({
652
- name: `${toTypeName(tableName, singularTypes)}Filters`,
806
+ name: `${resolveTypeName(tableName, typeNameMapper)}Filters`,
653
807
  fields: {
654
808
  ...filterColumns,
655
809
  OR: {
656
810
  type: new GraphQLList2(
657
811
  new GraphQLNonNull2(
658
812
  new GraphQLInputObjectType2({
659
- name: `${toTypeName(tableName, singularTypes)}FiltersOr`,
813
+ name: `${resolveTypeName(tableName, typeNameMapper)}FiltersOr`,
660
814
  fields: filterColumns
661
815
  })
662
816
  )
@@ -664,16 +818,24 @@ var generateTableFilterTypeCached = (table, tableName, cacheCtx, singularTypes)
664
818
  }
665
819
  }
666
820
  });
667
- filterTypeMap.set(table, filters);
821
+ cacheCtx.filterTypeCache.set(table, filters);
668
822
  return filters;
669
823
  };
670
- var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, _relationsDepthLimit, cacheCtx, singularTypes, usedTables = /* @__PURE__ */ new Set()) => {
824
+ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromRelationName, withOrder, relationsDepthLimit, cacheCtx, typeNameMapper, usedTables = /* @__PURE__ */ new Set(), resolverFactory, currentDepth = 0) => {
671
825
  const table = tables[tableName];
672
- const order = withOrder ? generateTableOrderTypeCached(table, tableName, singularTypes) : void 0;
673
- const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, singularTypes);
826
+ const order = withOrder ? generateTableOrderTypeCached(table, tableName, typeNameMapper, cacheCtx) : void 0;
827
+ const filters = generateTableFilterTypeCached(table, tableName, cacheCtx, typeNameMapper);
674
828
  const tableFields = generateTableSelectTypeFieldsCached(table, tableName);
675
829
  const relationsForTable = relationMap[tableName];
676
830
  const relationEntries = relationsForTable ? Object.entries(relationsForTable) : [];
831
+ if (relationsDepthLimit !== void 0 && currentDepth >= relationsDepthLimit) {
832
+ return {
833
+ order,
834
+ filters,
835
+ tableFields,
836
+ relationFields: {}
837
+ };
838
+ }
677
839
  if (usedTables.has(tableName)) {
678
840
  return {
679
841
  order,
@@ -697,7 +859,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
697
859
  cacheCtx.relationFieldContainers.set(tableName, container);
698
860
  }
699
861
  if (isRootCall && !cacheCtx.objectTypeCache.has(tableName)) {
700
- const typeName = toTypeName(tableName, singularTypes);
862
+ const typeName = resolveTypeName(tableName, typeNameMapper);
701
863
  const shell = new GraphQLObjectType2({
702
864
  name: typeName,
703
865
  fields: () => ({ ...tableFields, ...container.fields })
@@ -711,7 +873,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
711
873
  for (const [relationName, relEntry] of relationEntries) {
712
874
  const { targetTableName } = relEntry;
713
875
  const relation = relEntry.relation ?? relEntry;
714
- const isOne = is2(relation, One);
876
+ const isOne = is3(relation, One2);
715
877
  const relSelectData = generateSelectFields(
716
878
  tables,
717
879
  targetTableName,
@@ -721,10 +883,12 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
721
883
  relationName,
722
884
  // fromRelationName for the relation type
723
885
  !isOne,
724
- void 0,
886
+ relationsDepthLimit,
725
887
  cacheCtx,
726
- singularTypes,
727
- nextUsedTables
888
+ typeNameMapper,
889
+ nextUsedTables,
890
+ resolverFactory,
891
+ currentDepth + 1
728
892
  );
729
893
  let relType = cacheCtx.objectTypeCache.get(targetTableName);
730
894
  if (!relType) {
@@ -737,11 +901,12 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
737
901
  }
738
902
  const capturedTargetContainer = targetContainer;
739
903
  relType = new GraphQLObjectType2({
740
- name: toTypeName(targetTableName, singularTypes),
904
+ name: resolveTypeName(targetTableName, typeNameMapper),
741
905
  fields: () => ({ ...targetTableFields, ...capturedTargetContainer.fields })
742
906
  });
743
907
  cacheCtx.objectTypeCache.set(targetTableName, relType);
744
908
  }
909
+ const resolve = resolverFactory?.({ tableName, relationName, relEntry, isOne });
745
910
  if (isOne) {
746
911
  rawRelationFields.push([
747
912
  relationName,
@@ -749,7 +914,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
749
914
  type: relType,
750
915
  args: {
751
916
  where: { type: relSelectData.filters }
752
- }
917
+ },
918
+ resolve
753
919
  }
754
920
  ]);
755
921
  continue;
@@ -763,7 +929,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
763
929
  orderBy: { type: relSelectData.order },
764
930
  offset: { type: GraphQLInt2 },
765
931
  limit: { type: GraphQLInt2 }
766
- }
932
+ },
933
+ resolve
767
934
  }
768
935
  ]);
769
936
  }
@@ -789,7 +956,7 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
789
956
  relationFields: {}
790
957
  };
791
958
  };
792
- var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, singularTypes = false, insertPrefix = "insertInto", updatePrefix = "update") => {
959
+ var generateTableTypes = (tableName, tables, relationMap, withReturning, relationsDepthLimit, cacheCtx, typeNameMapper = void 0, insertPrefix = "create", updatePrefix = "update", resolverFactory) => {
793
960
  const { tableFields, relationFields, filters, order } = generateSelectFields(
794
961
  tables,
795
962
  tableName,
@@ -801,12 +968,14 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
801
968
  true,
802
969
  relationsDepthLimit,
803
970
  cacheCtx,
804
- singularTypes
971
+ typeNameMapper,
972
+ /* @__PURE__ */ new Set(),
973
+ resolverFactory,
974
+ 0
805
975
  );
806
976
  const table = tables[tableName];
807
- const columns = getColumns2(table);
977
+ const columns = getColumns(table);
808
978
  const columnEntries = Object.entries(columns);
809
- const _insertNested = drizzleRelationToGraphQLInsertType(tables, relationMap[tableName] ?? {});
810
979
  const insertFields = Object.fromEntries(
811
980
  columnEntries.map(([columnName, columnDescription]) => [
812
981
  columnName,
@@ -820,15 +989,15 @@ var generateTableTypes = (tableName, tables, relationMap, withReturning, relatio
820
989
  ])
821
990
  );
822
991
  const insertInput = new GraphQLInputObjectType2({
823
- name: `${capitalize(insertPrefix)}${toTypeName(tableName, singularTypes)}Input`,
992
+ name: `${capitalize(insertPrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
824
993
  fields: insertFields
825
994
  });
826
995
  const updateInput = new GraphQLInputObjectType2({
827
- name: `${capitalize(updatePrefix)}${toTypeName(tableName, singularTypes)}Input`,
996
+ name: `${capitalize(updatePrefix)}${resolveTypeName(tableName, typeNameMapper)}Input`,
828
997
  fields: updateFields
829
998
  });
830
999
  const selectSingleOutput = cacheCtx.objectTypeCache.get(tableName) ?? new GraphQLObjectType2({
831
- name: toTypeName(tableName, singularTypes),
1000
+ name: resolveTypeName(tableName, typeNameMapper),
832
1001
  fields: { ...tableFields, ...relationFields }
833
1002
  });
834
1003
  const selectArrOutput = new GraphQLNonNull2(new GraphQLList2(new GraphQLNonNull2(selectSingleOutput)));
@@ -866,7 +1035,7 @@ var extractOrderBy = (table, orderArgs) => {
866
1035
  continue;
867
1036
  }
868
1037
  const { direction } = config;
869
- res.push(direction === "asc" ? asc(getColumns2(table)[column]) : desc(getColumns2(table)[column]));
1038
+ res.push(direction === "asc" ? asc(getColumns(table)[column]) : desc(getColumns(table)[column]));
870
1039
  }
871
1040
  return res;
872
1041
  };
@@ -888,55 +1057,28 @@ var extractFiltersColumn = (column, columnName, operators) => {
888
1057
  }
889
1058
  return variants2.length ? variants2.length > 1 ? or(...variants2) : variants2[0] : void 0;
890
1059
  }
1060
+ const singleValueOps = { eq, ne, gt, gte, lt, lte };
1061
+ const stringValueOps = { like, notLike, ilike, notIlike };
1062
+ const arrayValueOps = { inArray, notInArray };
1063
+ const nullableOps = { isNull, isNotNull };
891
1064
  const variants = [];
892
1065
  for (const [operatorName, operatorValue] of entries) {
893
1066
  if (operatorValue === null || operatorValue === false) {
894
1067
  continue;
895
1068
  }
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;
1069
+ if (operatorName in singleValueOps) {
1070
+ const singleValue = remapFromGraphQLCore(operatorValue, column, columnName);
1071
+ variants.push(singleValueOps[operatorName](column, singleValue));
1072
+ } else if (operatorName in stringValueOps) {
1073
+ variants.push(stringValueOps[operatorName](column, operatorValue));
1074
+ } else if (operatorName in arrayValueOps) {
1075
+ if (!operatorValue.length) {
1076
+ throw new GraphQLError2(`WHERE ${columnName}: Unable to use operator ${operatorName} with an empty array!`);
934
1077
  }
935
- case "isNull":
936
- operator = operator ?? isNull;
937
- case "isNotNull":
938
- operator = operator ?? isNotNull;
939
- variants.push(operator(column));
1078
+ const arrayValue = operatorValue.map((val) => remapFromGraphQLCore(val, column, columnName));
1079
+ variants.push(arrayValueOps[operatorName](column, arrayValue));
1080
+ } else if (operatorName in nullableOps) {
1081
+ variants.push(nullableOps[operatorName](column));
940
1082
  }
941
1083
  }
942
1084
  return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
@@ -967,12 +1109,12 @@ var extractFilters = (table, tableName, filters) => {
967
1109
  if (operators === null) {
968
1110
  continue;
969
1111
  }
970
- const column = getColumns2(table)[columnName];
1112
+ const column = getColumns(table)[columnName];
971
1113
  variants.push(extractFiltersColumn(column, columnName, operators));
972
1114
  }
973
1115
  return variants.length ? variants.length > 1 ? and(...variants) : variants[0] : void 0;
974
1116
  };
975
- var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, singularTypes = false, _isInitial = false) => {
1117
+ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, originField, typeNameMapper, _isInitial = false) => {
976
1118
  const relationsForTable = relationMap[tableName];
977
1119
  if (!relationsForTable) {
978
1120
  return void 0;
@@ -982,8 +1124,9 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
982
1124
  return void 0;
983
1125
  }
984
1126
  const args = {};
985
- for (const [relName, { targetTableName }] of Object.entries(relationsForTable)) {
986
- const relTypeName = toTypeName(targetTableName, singularTypes);
1127
+ for (const [relName, relEntry] of Object.entries(relationsForTable)) {
1128
+ const { targetTableName, targetPkNames } = relEntry;
1129
+ const relTypeName = resolveTypeName(targetTableName, typeNameMapper);
987
1130
  const field = baseField[relName] ?? Object.values(baseField).find((f) => f.name === relName);
988
1131
  if (!field) {
989
1132
  continue;
@@ -1002,140 +1145,279 @@ var extractRelationsParamsInner = (relationMap, tables, tableName, typeName, ori
1002
1145
  const limit = relationArgs?.limit ?? void 0;
1003
1146
  const relWhere = relationArgs?.where;
1004
1147
  thisRecord.where = relWhere ? { RAW: (aliasedTable) => extractFilters(aliasedTable, relName, relWhere) } : void 0;
1005
- thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy) : void 0;
1148
+ const hasPagination = offset != null || limit != null;
1149
+ const pkNames = targetPkNames ?? [];
1150
+ thisRecord.orderBy = relationArgs?.orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, relationArgs.orderBy) : hasPagination && pkNames.length ? (aliasedTable) => primaryKeyOrderExprs(aliasedTable, pkNames) : void 0;
1006
1151
  thisRecord.offset = offset;
1007
1152
  thisRecord.limit = limit;
1008
- const relWith = relationField ? extractRelationsParamsInner(relationMap, tables, targetTableName, relTypeName, relationField, singularTypes) : void 0;
1153
+ const relWith = relationField ? extractRelationsParamsInner(relationMap, tables, targetTableName, relTypeName, relationField, typeNameMapper) : void 0;
1009
1154
  thisRecord.with = relWith;
1010
1155
  args[relName] = thisRecord;
1011
1156
  }
1012
1157
  return args;
1013
1158
  };
1014
- var extractRelationsParams = (relationMap, tables, tableName, info, typeName, singularTypes = false) => {
1159
+ var extractRelationsParams = (relationMap, tables, tableName, info, typeName, typeNameMapper) => {
1015
1160
  if (!info) {
1016
1161
  return void 0;
1017
1162
  }
1018
- return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, singularTypes, true);
1163
+ return extractRelationsParamsInner(relationMap, tables, tableName, typeName, info, typeNameMapper, true);
1164
+ };
1165
+ var pruneNonEagerRelations = (relationMap, shouldEagerLoad) => {
1166
+ const out = {};
1167
+ for (const [tableName, rels] of Object.entries(relationMap)) {
1168
+ out[tableName] = Object.fromEntries(
1169
+ Object.entries(rels).filter(([relationName]) => shouldEagerLoad(tableName, relationName))
1170
+ );
1171
+ }
1172
+ return out;
1173
+ };
1174
+ var getPrimaryKeyPropNames = (table, compositePkColumnNames) => {
1175
+ const cols = getColumns(table);
1176
+ const entries = Object.entries(cols);
1177
+ const inlinePks = entries.filter(([, c]) => c.primary).map(([k]) => k);
1178
+ if (inlinePks.length) {
1179
+ return inlinePks;
1180
+ }
1181
+ if (compositePkColumnNames?.length) {
1182
+ const wanted = new Set(compositePkColumnNames);
1183
+ const fromComposite = entries.filter(([, c]) => wanted.has(c.name)).map(([k]) => k);
1184
+ if (fromComposite.length) {
1185
+ return fromComposite;
1186
+ }
1187
+ }
1188
+ return [];
1189
+ };
1190
+ var withPrimaryKeyColumns = (columns, table, pkNames) => {
1191
+ const allCols = getColumns(table);
1192
+ for (const pk of pkNames) {
1193
+ if (!(pk in columns) && allCols[pk]) {
1194
+ columns[pk] = allCols[pk];
1195
+ }
1196
+ }
1197
+ return columns;
1198
+ };
1199
+ var getPrimaryKeyPropNamesFromConfig = (table, getTableConfig4) => {
1200
+ const compositePkColumnNames = getTableConfig4(table).primaryKeys.flatMap((pk) => pk.columns.map((c) => c.name));
1201
+ return getPrimaryKeyPropNames(table, compositePkColumnNames);
1202
+ };
1203
+ var primaryKeyOrderExprs = (table, pkNames) => {
1204
+ const cols = getColumns(table);
1205
+ return pkNames.map((n) => cols[n]).filter(Boolean).map((col) => asc(col));
1206
+ };
1207
+ var prepareMutationRelationColumns = (params) => {
1208
+ const { relationMap, tables, tableName, typeName, typeNameMapper, table, pkNames, parsedInfo } = params;
1209
+ const withParams = relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper) : void 0;
1210
+ const hasRelations = !!(withParams && Object.keys(withParams).length);
1211
+ const baseColumns = extractSelectedColumnsFromTreeSQLFormat(parsedInfo.fieldsByTypeName[typeName], table);
1212
+ const columns = hasRelations ? withPrimaryKeyColumns(baseColumns, table, pkNames) : baseColumns;
1213
+ return { columns, hasRelations, withParams };
1214
+ };
1215
+ var toGraphQLError = (e) => e instanceof Error ? new GraphQLError2(e.message) : e;
1216
+ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes) => {
1217
+ const mapped = typeNameMapper?.(tableName);
1218
+ const typeName = mapped ? capitalize(mapped.singular) : capitalize(tableName);
1219
+ const listFieldName = (mapped?.plural ?? uncapitalize(tableName)) + suffixes.list;
1220
+ const singleFieldName = mapped?.singular ?? uncapitalize(tableName) + suffixes.single;
1221
+ const createArrayFieldName = `${prefixes.insert}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
1222
+ const createSingleFieldName = mapped ? `${prefixes.insert}${capitalize(mapped.singular)}` : `${prefixes.insert}${capitalize(tableName)}${suffixes.single}`;
1223
+ const updateFieldName = `${prefixes.update}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1224
+ const deleteFieldName = `${prefixes.delete}${mapped ? capitalize(mapped.singular) : capitalize(tableName)}`;
1225
+ return {
1226
+ typeName,
1227
+ listFieldName,
1228
+ singleFieldName,
1229
+ createArrayFieldName,
1230
+ createSingleFieldName,
1231
+ updateFieldName,
1232
+ deleteFieldName
1233
+ };
1234
+ };
1235
+ var selectArrayArgs = (orderArgs, filterArgs) => ({
1236
+ offset: { type: GraphQLInt2 },
1237
+ limit: { type: GraphQLInt2 },
1238
+ orderBy: { type: orderArgs },
1239
+ where: { type: filterArgs }
1240
+ });
1241
+ var selectSingleArgs = (orderArgs, filterArgs) => ({
1242
+ offset: { type: GraphQLInt2 },
1243
+ orderBy: { type: orderArgs },
1244
+ where: { type: filterArgs }
1245
+ });
1246
+ var runRelationalSelect = async (opts) => {
1247
+ const {
1248
+ queryBase,
1249
+ tables,
1250
+ tableName,
1251
+ table,
1252
+ relationMap,
1253
+ typeName,
1254
+ typeNameMapper,
1255
+ parsedInfo,
1256
+ offset,
1257
+ orderBy,
1258
+ where,
1259
+ single
1260
+ } = opts;
1261
+ const params = {
1262
+ columns: extractSelectedColumnsFromTree(parsedInfo.fieldsByTypeName[typeName], table),
1263
+ offset,
1264
+ // drizzle-orm v1 RQB calls orderBy/where with the aliased table proxy — use it
1265
+ // directly so column refs match the CTE alias.
1266
+ orderBy: orderBy ? (aliasedTable) => extractOrderBy(aliasedTable, orderBy) : void 0,
1267
+ where: where ? { RAW: (aliasedTable) => extractFilters(aliasedTable, tableName, where) } : void 0,
1268
+ with: relationMap[tableName] ? extractRelationsParams(relationMap, tables, tableName, parsedInfo, typeName, typeNameMapper) : void 0
1269
+ };
1270
+ if (single) {
1271
+ const result2 = await queryBase.findFirst(params);
1272
+ return result2 ? remapToGraphQLSingleOutput(result2, tableName, table, relationMap) : void 0;
1273
+ }
1274
+ params.limit = opts.limit;
1275
+ const result = await queryBase.findMany(params);
1276
+ return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1277
+ };
1278
+ var eagerLoadMutationRelations = async (db, tableName, rows, pkNames, withParams) => {
1279
+ if (!rows.length || !pkNames.length || !withParams || !Object.keys(withParams).length) {
1280
+ return rows;
1281
+ }
1282
+ const queryBase = db.query?.[tableName];
1283
+ if (!queryBase) {
1284
+ return rows;
1285
+ }
1286
+ const keyableRows = rows.filter((row) => pkNames.every((n) => row[n] != null));
1287
+ if (!keyableRows.length) {
1288
+ return rows;
1289
+ }
1290
+ const pkColumns = {};
1291
+ for (const pk of pkNames) {
1292
+ pkColumns[pk] = true;
1293
+ }
1294
+ const relationNames = Object.keys(withParams);
1295
+ const keyOf = (row) => JSON.stringify(pkNames.map((n) => typeof row[n] === "bigint" ? row[n].toString() : row[n]));
1296
+ let whereRaw;
1297
+ if (pkNames.length === 1) {
1298
+ const pkName = pkNames[0];
1299
+ const ids = keyableRows.map((r) => r[pkName]);
1300
+ whereRaw = (aliased) => inArray(aliased[pkName], ids);
1301
+ } else {
1302
+ whereRaw = (aliased) => {
1303
+ const lhs = sql.join(
1304
+ pkNames.map((n) => sql`${aliased[n]}`),
1305
+ sql`, `
1306
+ );
1307
+ const tuples = sql.join(
1308
+ keyableRows.map(
1309
+ (row) => sql`(${sql.join(
1310
+ pkNames.map((n) => sql`${row[n]}`),
1311
+ sql`, `
1312
+ )})`
1313
+ ),
1314
+ sql`, `
1315
+ );
1316
+ return sql`(${lhs}) in (${tuples})`;
1317
+ };
1318
+ }
1319
+ let enriched;
1320
+ try {
1321
+ enriched = await queryBase.findMany({
1322
+ columns: pkColumns,
1323
+ where: { RAW: whereRaw },
1324
+ with: withParams
1325
+ });
1326
+ } catch (err) {
1327
+ console.warn(
1328
+ `[drizzle-graphql] eager-loading relations for a "${tableName}" mutation failed; falling back to lazy resolution.`,
1329
+ err
1330
+ );
1331
+ return rows;
1332
+ }
1333
+ const byKey = new Map(enriched.map((e) => [keyOf(e), e]));
1334
+ for (const row of rows) {
1335
+ const match = byKey.get(keyOf(row));
1336
+ if (!match) {
1337
+ continue;
1338
+ }
1339
+ for (const rel of relationNames) {
1340
+ row[rel] = match[rel];
1341
+ }
1342
+ }
1343
+ return rows;
1019
1344
  };
1020
1345
 
1021
1346
  // 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}`;
1347
+ var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1025
1348
  const queryBase = db.query[tableName];
1026
1349
  if (!queryBase) {
1027
1350
  throw new Error(
1028
1351
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1029
1352
  );
1030
1353
  }
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);
1354
+ const queryArgs = selectArrayArgs(orderArgs, filterArgs);
1046
1355
  const table = tables[tableName];
1047
1356
  return {
1048
- name: queryName,
1357
+ name: fieldName,
1049
1358
  resolver: async (_source, args, _context, info) => {
1050
1359
  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
1360
+ const parsedInfo = parseResolveInfo(info, { deep: true });
1361
+ return await runRelationalSelect({
1362
+ queryBase,
1363
+ tables,
1364
+ tableName,
1365
+ table,
1366
+ relationMap,
1367
+ typeName,
1368
+ typeNameMapper,
1369
+ parsedInfo,
1370
+ ...args,
1371
+ single: false
1064
1372
  });
1065
- const result = await query;
1066
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1067
1373
  } catch (e) {
1068
- if (e instanceof Error) {
1069
- throw new GraphQLError3(e.message);
1070
- }
1071
- throw e;
1374
+ throw toGraphQLError(e);
1072
1375
  }
1073
1376
  },
1074
1377
  args: queryArgs
1075
1378
  };
1076
1379
  };
1077
- var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, singleSuffix, singularTypes) => {
1078
- const queryName = `${uncapitalize(tableName)}${singleSuffix}`;
1380
+ var generateSelectSingle = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1079
1381
  const queryBase = db.query[tableName];
1080
1382
  if (!queryBase) {
1081
1383
  throw new Error(
1082
1384
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1083
1385
  );
1084
1386
  }
1085
- const queryArgs = {
1086
- offset: {
1087
- type: GraphQLInt3
1088
- },
1089
- orderBy: {
1090
- type: orderArgs
1091
- },
1092
- where: {
1093
- type: filterArgs
1094
- }
1095
- };
1096
- const typeName = toTypeName2(tableName, singularTypes);
1387
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
1097
1388
  const table = tables[tableName];
1098
1389
  return {
1099
- name: queryName,
1390
+ name: fieldName,
1100
1391
  resolver: async (_source, args, _context, info) => {
1101
1392
  try {
1102
- const { offset, orderBy, where } = args;
1103
- const parsedInfo = parseResolveInfo(info, {
1104
- deep: true
1393
+ const parsedInfo = parseResolveInfo(info, { deep: true });
1394
+ return await runRelationalSelect({
1395
+ queryBase,
1396
+ tables,
1397
+ tableName,
1398
+ table,
1399
+ relationMap,
1400
+ typeName,
1401
+ typeNameMapper,
1402
+ parsedInfo,
1403
+ ...args,
1404
+ single: true
1105
1405
  });
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
1406
  } catch (e) {
1121
- if (e instanceof Error) {
1122
- throw new GraphQLError3(e.message);
1123
- }
1124
- throw e;
1407
+ throw toGraphQLError(e);
1125
1408
  }
1126
1409
  },
1127
1410
  args: queryArgs
1128
1411
  };
1129
1412
  };
1130
- var generateInsertArray = (db, tableName, table, baseType) => {
1131
- const queryName = `insertInto${capitalize(tableName)}`;
1413
+ var generateInsertArray = (db, _tableName, table, baseType, fieldName) => {
1132
1414
  const queryArgs = {
1133
1415
  values: {
1134
1416
  type: new GraphQLNonNull3(new GraphQLList3(new GraphQLNonNull3(baseType)))
1135
1417
  }
1136
1418
  };
1137
1419
  return {
1138
- name: queryName,
1420
+ name: fieldName,
1139
1421
  resolver: async (_source, args, _context, _info) => {
1140
1422
  try {
1141
1423
  const input = remapFromGraphQLArrayInput(args.values, table);
@@ -1145,41 +1427,33 @@ var generateInsertArray = (db, tableName, table, baseType) => {
1145
1427
  await db.insert(table).values(input);
1146
1428
  return { isSuccess: true };
1147
1429
  } catch (e) {
1148
- if (e instanceof Error) {
1149
- throw new GraphQLError3(e.message);
1150
- }
1151
- throw e;
1430
+ throw toGraphQLError(e);
1152
1431
  }
1153
1432
  },
1154
1433
  args: queryArgs
1155
1434
  };
1156
1435
  };
1157
- var generateInsertSingle = (db, tableName, table, baseType) => {
1158
- const queryName = `insertInto${capitalize(tableName)}Single`;
1436
+ var generateInsertSingle = (db, _tableName, table, baseType, fieldName) => {
1159
1437
  const queryArgs = {
1160
1438
  values: {
1161
1439
  type: new GraphQLNonNull3(baseType)
1162
1440
  }
1163
1441
  };
1164
1442
  return {
1165
- name: queryName,
1443
+ name: fieldName,
1166
1444
  resolver: async (_source, args, _context, _info) => {
1167
1445
  try {
1168
1446
  const input = remapFromGraphQLSingleInput(args.values, table);
1169
1447
  await db.insert(table).values(input);
1170
1448
  return { isSuccess: true };
1171
1449
  } catch (e) {
1172
- if (e instanceof Error) {
1173
- throw new GraphQLError3(e.message);
1174
- }
1175
- throw e;
1450
+ throw toGraphQLError(e);
1176
1451
  }
1177
1452
  },
1178
1453
  args: queryArgs
1179
1454
  };
1180
1455
  };
1181
- var generateUpdate = (db, tableName, table, setArgs, filterArgs) => {
1182
- const queryName = `update${capitalize(tableName)}`;
1456
+ var generateUpdate = (db, tableName, table, setArgs, filterArgs, fieldName) => {
1183
1457
  const queryArgs = {
1184
1458
  set: {
1185
1459
  type: new GraphQLNonNull3(setArgs)
@@ -1189,7 +1463,7 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs) => {
1189
1463
  }
1190
1464
  };
1191
1465
  return {
1192
- name: queryName,
1466
+ name: fieldName,
1193
1467
  resolver: async (_source, args, _context, _info) => {
1194
1468
  try {
1195
1469
  const { where, set } = args;
@@ -1205,24 +1479,20 @@ var generateUpdate = (db, tableName, table, setArgs, filterArgs) => {
1205
1479
  await query;
1206
1480
  return { isSuccess: true };
1207
1481
  } catch (e) {
1208
- if (e instanceof Error) {
1209
- throw new GraphQLError3(e.message);
1210
- }
1211
- throw e;
1482
+ throw toGraphQLError(e);
1212
1483
  }
1213
1484
  },
1214
1485
  args: queryArgs
1215
1486
  };
1216
1487
  };
1217
- var generateDelete = (db, tableName, table, filterArgs) => {
1218
- const queryName = `deleteFrom${capitalize(tableName)}`;
1488
+ var generateDelete = (db, tableName, table, filterArgs, fieldName) => {
1219
1489
  const queryArgs = {
1220
1490
  where: {
1221
1491
  type: filterArgs
1222
1492
  }
1223
1493
  };
1224
1494
  return {
1225
- name: queryName,
1495
+ name: fieldName,
1226
1496
  resolver: async (_source, args, _context, _info) => {
1227
1497
  try {
1228
1498
  const { where } = args;
@@ -1234,64 +1504,35 @@ var generateDelete = (db, tableName, table, filterArgs) => {
1234
1504
  await query;
1235
1505
  return { isSuccess: true };
1236
1506
  } catch (e) {
1237
- if (e instanceof Error) {
1238
- throw new GraphQLError3(e.message);
1239
- }
1240
- throw e;
1507
+ throw toGraphQLError(e);
1241
1508
  }
1242
1509
  },
1243
1510
  args: queryArgs
1244
1511
  };
1245
1512
  };
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) => {
1513
+ var mysqlPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig);
1514
+ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad = () => true) => {
1279
1515
  const rawSchema = schema;
1280
1516
  const schemaEntries = Object.entries(rawSchema);
1281
- const tableEntries = schemaEntries.filter(([_key, value]) => is3(value, MySqlTable));
1517
+ const tableEntries = schemaEntries.filter(([_key, value]) => is4(value, MySqlTable));
1282
1518
  const tables = Object.fromEntries(tableEntries);
1283
1519
  if (!tableEntries.length) {
1284
1520
  throw new Error(
1285
1521
  "Drizzle-GraphQL Error: No tables detected in Drizzle-ORM's database instance. Did you forget to pass schema to drizzle constructor?"
1286
1522
  );
1287
1523
  }
1288
- const namedRelations = buildNamedRelations2(relations ?? {}, tableEntries);
1524
+ const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
1525
+ attachTargetPrimaryKeys(namedRelations, tables, mysqlPrimaryKeyPropNames);
1526
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
1527
+ const resolverFactory = createRelationResolverFactory(db, tables);
1289
1528
  const cacheCtx = {
1290
1529
  genericFilterCache: /* @__PURE__ */ new Map(),
1291
1530
  objectTypeCache: /* @__PURE__ */ new Map(),
1292
1531
  relationFieldContainers: /* @__PURE__ */ new Map(),
1293
1532
  fullyBuiltTables: /* @__PURE__ */ new Set(),
1294
- relationTypeCache: /* @__PURE__ */ new Map()
1533
+ relationTypeCache: /* @__PURE__ */ new Map(),
1534
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
1535
+ filterTypeCache: /* @__PURE__ */ new WeakMap()
1295
1536
  };
1296
1537
  const queries = {};
1297
1538
  const mutations = {};
@@ -1305,9 +1546,10 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
1305
1546
  false,
1306
1547
  relationsDepthLimit,
1307
1548
  cacheCtx,
1308
- singularTypes,
1549
+ typeNameMapper,
1309
1550
  prefixes.insert,
1310
- prefixes.update
1551
+ prefixes.update,
1552
+ resolverFactory
1311
1553
  )
1312
1554
  ])
1313
1555
  );
@@ -1326,30 +1568,66 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
1326
1568
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1327
1569
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1328
1570
  const { selectSingleOutput, selectArrOutput } = tableTypes.outputs;
1571
+ const {
1572
+ typeName,
1573
+ listFieldName,
1574
+ singleFieldName,
1575
+ createArrayFieldName,
1576
+ createSingleFieldName,
1577
+ updateFieldName,
1578
+ deleteFieldName
1579
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
1329
1580
  const selectArrGenerated = generateSelectArray(
1330
1581
  db,
1331
1582
  tableName,
1332
1583
  tables,
1333
- namedRelations,
1584
+ eagerRelations,
1334
1585
  tableOrder,
1335
1586
  tableFilters,
1336
- suffixes.list,
1337
- singularTypes
1587
+ listFieldName,
1588
+ typeName,
1589
+ typeNameMapper
1338
1590
  );
1339
1591
  const selectSingleGenerated = generateSelectSingle(
1340
1592
  db,
1341
1593
  tableName,
1342
1594
  tables,
1343
- namedRelations,
1595
+ eagerRelations,
1344
1596
  tableOrder,
1345
1597
  tableFilters,
1346
- suffixes.single,
1347
- singularTypes
1598
+ singleFieldName,
1599
+ typeName,
1600
+ typeNameMapper
1601
+ );
1602
+ const insertArrGenerated = generateInsertArray(
1603
+ db,
1604
+ tableName,
1605
+ schema[tableName],
1606
+ insertInput,
1607
+ createArrayFieldName
1608
+ );
1609
+ const insertSingleGenerated = generateInsertSingle(
1610
+ db,
1611
+ tableName,
1612
+ schema[tableName],
1613
+ insertInput,
1614
+ createSingleFieldName
1615
+ );
1616
+ const updateGenerated = generateUpdate(
1617
+ db,
1618
+ tableName,
1619
+ schema[tableName],
1620
+ updateInput,
1621
+ tableFilters,
1622
+ updateFieldName
1623
+ );
1624
+ const deleteGenerated = generateDelete(
1625
+ db,
1626
+ tableName,
1627
+ schema[tableName],
1628
+ tableFilters,
1629
+ deleteFieldName
1348
1630
  );
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);
1353
1631
  queries[selectArrGenerated.name] = {
1354
1632
  type: selectArrOutput,
1355
1633
  args: selectArrGenerated.args,
@@ -1385,164 +1663,139 @@ var generateSchemaData = (db, schema, relations, relationsDepthLimit, prefixes,
1385
1663
  });
1386
1664
  outputs[selectSingleOutput.name] = selectSingleOutput;
1387
1665
  }
1388
- return { queries, mutations, inputs, types: outputs };
1666
+ const fieldResolvers = {};
1667
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
1668
+ const relResolvers = {};
1669
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
1670
+ const isOne = is4(relEntry.relation ?? relEntry, One3);
1671
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
1672
+ if (resolver) {
1673
+ relResolvers[relName] = resolver;
1674
+ }
1675
+ }
1676
+ if (Object.keys(relResolvers).length > 0) {
1677
+ fieldResolvers[tableName] = relResolvers;
1678
+ }
1679
+ }
1680
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
1389
1681
  };
1390
1682
 
1391
1683
  // src/util/builders/pg.ts
1392
- import { is as is4 } from "drizzle-orm";
1393
- import { PgTable } from "drizzle-orm/pg-core";
1684
+ import { is as is5, One as One4 } from "drizzle-orm";
1685
+ import { getTableConfig as getTableConfig2, PgTable } from "drizzle-orm/pg-core";
1394
1686
  import {
1395
1687
  GraphQLError as GraphQLError4,
1396
- GraphQLInt as GraphQLInt4,
1397
1688
  GraphQLList as GraphQLList4,
1398
1689
  GraphQLNonNull as GraphQLNonNull4
1399
1690
  } from "graphql";
1400
1691
  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}`;
1692
+ var generateSelectArray2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1405
1693
  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);
1694
+ const queryArgs = selectArrayArgs(orderArgs, filterArgs);
1421
1695
  const table = tables[tableName];
1422
1696
  return {
1423
- name: queryName,
1697
+ name: fieldName,
1424
1698
  resolver: async (_source, args, _context, info) => {
1425
1699
  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;
1700
+ const parsedInfo = parseResolveInfo2(info, { deep: true });
1432
1701
  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,
1437
- 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
1702
+ return await runRelationalSelect({
1703
+ queryBase,
1704
+ tables,
1705
+ tableName,
1706
+ table,
1707
+ relationMap,
1708
+ typeName,
1709
+ typeNameMapper,
1710
+ parsedInfo,
1711
+ ...args,
1712
+ single: false
1443
1713
  });
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));
1451
- }
1452
- if (offset) {
1453
- q = q.offset(offset);
1454
- }
1455
- if (limit) {
1456
- q = q.limit(limit);
1457
- }
1458
- result = await q;
1459
1714
  }
1460
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1461
- } catch (e) {
1462
- if (e instanceof Error) {
1463
- throw new GraphQLError4(e.message);
1715
+ const { offset, limit, orderBy, where } = args;
1716
+ const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
1717
+ parsedInfo.fieldsByTypeName[typeName],
1718
+ table
1719
+ );
1720
+ let q = db.select(selectedColumnsSql).from(table);
1721
+ if (where) {
1722
+ q = q.where(extractFilters(table, tableName, where));
1723
+ }
1724
+ if (orderBy) {
1725
+ q = q.orderBy(...extractOrderBy(table, orderBy));
1726
+ }
1727
+ if (offset) {
1728
+ q = q.offset(offset);
1464
1729
  }
1465
- throw e;
1730
+ if (limit) {
1731
+ q = q.limit(limit);
1732
+ }
1733
+ return remapToGraphQLArrayOutput(await q, tableName, table, relationMap);
1734
+ } catch (e) {
1735
+ throw toGraphQLError(e);
1466
1736
  }
1467
1737
  },
1468
1738
  args: queryArgs
1469
1739
  };
1470
1740
  };
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}`;
1741
+ var generateSelectSingle2 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1474
1742
  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);
1743
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
1487
1744
  const table = tables[tableName];
1488
1745
  return {
1489
- name: queryName,
1746
+ name: fieldName,
1490
1747
  resolver: async (_source, args, _context, info) => {
1491
1748
  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;
1749
+ const parsedInfo = parseResolveInfo2(info, { deep: true });
1498
1750
  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
1751
+ return await runRelationalSelect({
1752
+ queryBase,
1753
+ tables,
1754
+ tableName,
1755
+ table,
1756
+ relationMap,
1757
+ typeName,
1758
+ typeNameMapper,
1759
+ parsedInfo,
1760
+ ...args,
1761
+ single: true
1507
1762
  });
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
1763
  }
1522
- if (!result) {
1523
- return void 0;
1764
+ const { offset, orderBy, where } = args;
1765
+ const selectedColumnsSql = extractSelectedColumnsFromTreeSQLFormat(
1766
+ parsedInfo.fieldsByTypeName[typeName],
1767
+ table
1768
+ );
1769
+ let q = db.select(selectedColumnsSql).from(table);
1770
+ if (where) {
1771
+ q = q.where(extractFilters(table, tableName, where));
1524
1772
  }
1525
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1526
- } catch (e) {
1527
- if (e instanceof Error) {
1528
- throw new GraphQLError4(e.message);
1773
+ if (orderBy) {
1774
+ q = q.orderBy(...extractOrderBy(table, orderBy));
1529
1775
  }
1530
- throw e;
1776
+ if (offset) {
1777
+ q = q.offset(offset);
1778
+ }
1779
+ const rows = await q.limit(1);
1780
+ const result = rows[0];
1781
+ return result ? remapToGraphQLSingleOutput(result, tableName, table, relationMap) : void 0;
1782
+ } catch (e) {
1783
+ throw toGraphQLError(e);
1531
1784
  }
1532
1785
  },
1533
1786
  args: queryArgs
1534
1787
  };
1535
1788
  };
1536
- var generateInsertArray2 = (db, tableName, table, baseType, prefix, conflictDoNothing = false, singularTypes = false) => {
1537
- const queryName = `${prefix}${capitalize(tableName)}`;
1538
- const typeName = toTypeName3(tableName, singularTypes);
1789
+ var pgPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig2);
1790
+ var generateInsertArray2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1539
1791
  const queryArgs = {
1540
1792
  values: {
1541
1793
  type: new GraphQLNonNull4(new GraphQLList4(new GraphQLNonNull4(baseType)))
1542
1794
  }
1543
1795
  };
1796
+ const pkNames = pgPrimaryKeyPropNames(table);
1544
1797
  return {
1545
- name: queryName,
1798
+ name: fieldName,
1546
1799
  resolver: async (_source, args, _context, info) => {
1547
1800
  try {
1548
1801
  const input = remapFromGraphQLArrayInput(args.values, table);
@@ -1552,47 +1805,55 @@ var generateInsertArray2 = (db, tableName, table, baseType, prefix, conflictDoNo
1552
1805
  const parsedInfo = parseResolveInfo2(info, {
1553
1806
  deep: true
1554
1807
  });
1555
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1556
- parsedInfo.fieldsByTypeName[typeName],
1557
- table
1558
- );
1808
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
1809
+ relationMap,
1810
+ tables,
1811
+ tableName,
1812
+ typeName,
1813
+ typeNameMapper,
1814
+ table,
1815
+ pkNames,
1816
+ parsedInfo
1817
+ });
1559
1818
  let query = db.insert(table).values(input).returning(columns);
1560
1819
  if (conflictDoNothing) {
1561
1820
  query = query.onConflictDoNothing();
1562
1821
  }
1563
1822
  const result = await query;
1564
- return remapToGraphQLArrayOutput(result, tableName, table);
1823
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
1824
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
1565
1825
  } catch (e) {
1566
- if (e instanceof Error) {
1567
- throw new GraphQLError4(e.message);
1568
- }
1569
- throw e;
1826
+ throw toGraphQLError(e);
1570
1827
  }
1571
1828
  },
1572
1829
  args: queryArgs
1573
1830
  };
1574
1831
  };
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);
1832
+ var generateInsertSingle2 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper, conflictDoNothing = false) => {
1579
1833
  const queryArgs = {
1580
1834
  values: {
1581
1835
  type: new GraphQLNonNull4(baseType)
1582
1836
  }
1583
1837
  };
1838
+ const pkNames = pgPrimaryKeyPropNames(table);
1584
1839
  return {
1585
- name: queryName,
1840
+ name: fieldName,
1586
1841
  resolver: async (_source, args, _context, info) => {
1587
1842
  try {
1588
1843
  const input = remapFromGraphQLSingleInput(args.values, table);
1589
1844
  const parsedInfo = parseResolveInfo2(info, {
1590
1845
  deep: true
1591
1846
  });
1592
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1593
- parsedInfo.fieldsByTypeName[typeName],
1594
- table
1595
- );
1847
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
1848
+ relationMap,
1849
+ tables,
1850
+ tableName,
1851
+ typeName,
1852
+ typeNameMapper,
1853
+ table,
1854
+ pkNames,
1855
+ parsedInfo
1856
+ });
1596
1857
  let query = db.insert(table).values(input).returning(columns);
1597
1858
  if (conflictDoNothing) {
1598
1859
  query = query.onConflictDoNothing();
@@ -1601,20 +1862,16 @@ var generateInsertSingle2 = (db, tableName, table, baseType, prefix, conflictDoN
1601
1862
  if (!result[0]) {
1602
1863
  return void 0;
1603
1864
  }
1604
- return remapToGraphQLSingleOutput(result[0], tableName, table);
1865
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
1866
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
1605
1867
  } catch (e) {
1606
- if (e instanceof Error) {
1607
- throw new GraphQLError4(e.message);
1608
- }
1609
- throw e;
1868
+ throw toGraphQLError(e);
1610
1869
  }
1611
1870
  },
1612
1871
  args: queryArgs
1613
1872
  };
1614
1873
  };
1615
- var generateUpdate2 = (db, tableName, table, setArgs, filterArgs, prefix, singularTypes = false) => {
1616
- const queryName = `${prefix}${capitalize(tableName)}`;
1617
- const typeName = toTypeName3(tableName, singularTypes);
1874
+ var generateUpdate2 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1618
1875
  const queryArgs = {
1619
1876
  set: {
1620
1877
  type: new GraphQLNonNull4(setArgs)
@@ -1623,18 +1880,25 @@ var generateUpdate2 = (db, tableName, table, setArgs, filterArgs, prefix, singul
1623
1880
  type: filterArgs
1624
1881
  }
1625
1882
  };
1883
+ const pkNames = pgPrimaryKeyPropNames(table);
1626
1884
  return {
1627
- name: queryName,
1885
+ name: fieldName,
1628
1886
  resolver: async (_source, args, _context, info) => {
1629
1887
  try {
1630
1888
  const { where, set } = args;
1631
1889
  const parsedInfo = parseResolveInfo2(info, {
1632
1890
  deep: true
1633
1891
  });
1634
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1635
- parsedInfo.fieldsByTypeName[typeName],
1636
- table
1637
- );
1892
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
1893
+ relationMap,
1894
+ tables,
1895
+ tableName,
1896
+ typeName,
1897
+ typeNameMapper,
1898
+ table,
1899
+ pkNames,
1900
+ parsedInfo
1901
+ });
1638
1902
  const input = remapFromGraphQLSingleInput(set, table);
1639
1903
  if (!Object.keys(input).length) {
1640
1904
  throw new GraphQLError4("Unable to update with no values specified!");
@@ -1646,27 +1910,23 @@ var generateUpdate2 = (db, tableName, table, setArgs, filterArgs, prefix, singul
1646
1910
  }
1647
1911
  query = query.returning(columns);
1648
1912
  const result = await query;
1649
- return remapToGraphQLArrayOutput(result, tableName, table);
1913
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
1914
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
1650
1915
  } catch (e) {
1651
- if (e instanceof Error) {
1652
- throw new GraphQLError4(e.message);
1653
- }
1654
- throw e;
1916
+ throw toGraphQLError(e);
1655
1917
  }
1656
1918
  },
1657
1919
  args: queryArgs
1658
1920
  };
1659
1921
  };
1660
- var generateDelete2 = (db, tableName, table, filterArgs, prefix, singularTypes = false) => {
1661
- const queryName = `${prefix}${capitalize(tableName)}`;
1662
- const typeName = toTypeName3(tableName, singularTypes);
1922
+ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName) => {
1663
1923
  const queryArgs = {
1664
1924
  where: {
1665
1925
  type: filterArgs
1666
1926
  }
1667
1927
  };
1668
1928
  return {
1669
- name: queryName,
1929
+ name: fieldName,
1670
1930
  resolver: async (_source, args, _context, info) => {
1671
1931
  try {
1672
1932
  const { where } = args;
@@ -1686,18 +1946,15 @@ var generateDelete2 = (db, tableName, table, filterArgs, prefix, singularTypes =
1686
1946
  const result = await query;
1687
1947
  return remapToGraphQLArrayOutput(result, tableName, table);
1688
1948
  } catch (e) {
1689
- if (e instanceof Error) {
1690
- throw new GraphQLError4(e.message);
1691
- }
1692
- throw e;
1949
+ throw toGraphQLError(e);
1693
1950
  }
1694
1951
  },
1695
1952
  args: queryArgs
1696
1953
  };
1697
1954
  };
1698
- function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixes, suffixes, conflictDoNothing = false, singularTypes = false) {
1955
+ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixes, suffixes, conflictDoNothing = false, typeNameMapper, shouldEagerLoad = () => true) {
1699
1956
  const schemaEntries = Object.entries(schema);
1700
- const tableEntries = schemaEntries.filter(([_key, value]) => is4(value, PgTable));
1957
+ const tableEntries = schemaEntries.filter(([_key, value]) => is5(value, PgTable));
1701
1958
  const tables = Object.fromEntries(tableEntries);
1702
1959
  if (!tableEntries.length) {
1703
1960
  throw new Error(
@@ -1705,12 +1962,17 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1705
1962
  );
1706
1963
  }
1707
1964
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
1965
+ attachTargetPrimaryKeys(namedRelations, tables, pgPrimaryKeyPropNames);
1966
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
1967
+ const resolverFactory = createRelationResolverFactory(db, tables);
1708
1968
  const cacheCtx = {
1709
1969
  genericFilterCache: /* @__PURE__ */ new Map(),
1710
1970
  objectTypeCache: /* @__PURE__ */ new Map(),
1711
1971
  relationFieldContainers: /* @__PURE__ */ new Map(),
1712
1972
  fullyBuiltTables: /* @__PURE__ */ new Set(),
1713
- relationTypeCache: /* @__PURE__ */ new Map()
1973
+ relationTypeCache: /* @__PURE__ */ new Map(),
1974
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
1975
+ filterTypeCache: /* @__PURE__ */ new WeakMap()
1714
1976
  };
1715
1977
  const queries = {};
1716
1978
  const mutations = {};
@@ -1724,9 +1986,10 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1724
1986
  true,
1725
1987
  relationsDepthLimit,
1726
1988
  cacheCtx,
1727
- singularTypes,
1989
+ typeNameMapper,
1728
1990
  prefixes.insert,
1729
- prefixes.update
1991
+ prefixes.update,
1992
+ resolverFactory
1730
1993
  )
1731
1994
  ])
1732
1995
  );
@@ -1735,60 +1998,80 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1735
1998
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
1736
1999
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
1737
2000
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
2001
+ const {
2002
+ typeName,
2003
+ listFieldName,
2004
+ singleFieldName,
2005
+ createArrayFieldName,
2006
+ createSingleFieldName,
2007
+ updateFieldName,
2008
+ deleteFieldName
2009
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
1738
2010
  const selectArrGenerated = generateSelectArray2(
1739
2011
  db,
1740
2012
  tableName,
1741
2013
  tables,
1742
- namedRelations,
2014
+ eagerRelations,
1743
2015
  tableOrder,
1744
2016
  tableFilters,
1745
- suffixes.list,
1746
- singularTypes
2017
+ listFieldName,
2018
+ typeName,
2019
+ typeNameMapper
1747
2020
  );
1748
2021
  const selectSingleGenerated = generateSelectSingle2(
1749
2022
  db,
1750
2023
  tableName,
1751
2024
  tables,
1752
- namedRelations,
2025
+ eagerRelations,
1753
2026
  tableOrder,
1754
2027
  tableFilters,
1755
- suffixes.single,
1756
- singularTypes
2028
+ singleFieldName,
2029
+ typeName,
2030
+ typeNameMapper
1757
2031
  );
1758
2032
  const insertArrGenerated = generateInsertArray2(
1759
2033
  db,
1760
2034
  tableName,
1761
2035
  schema[tableName],
2036
+ tables,
2037
+ eagerRelations,
1762
2038
  insertInput,
1763
- prefixes.insert,
1764
- conflictDoNothing,
1765
- singularTypes
2039
+ createArrayFieldName,
2040
+ typeName,
2041
+ typeNameMapper,
2042
+ conflictDoNothing
1766
2043
  );
1767
2044
  const insertSingleGenerated = generateInsertSingle2(
1768
2045
  db,
1769
2046
  tableName,
1770
2047
  schema[tableName],
2048
+ tables,
2049
+ eagerRelations,
1771
2050
  insertInput,
1772
- prefixes.insert,
1773
- conflictDoNothing,
1774
- singularTypes
2051
+ createSingleFieldName,
2052
+ typeName,
2053
+ typeNameMapper,
2054
+ conflictDoNothing
1775
2055
  );
1776
2056
  const updateGenerated = generateUpdate2(
1777
2057
  db,
1778
2058
  tableName,
1779
2059
  schema[tableName],
2060
+ tables,
2061
+ eagerRelations,
1780
2062
  updateInput,
1781
2063
  tableFilters,
1782
- prefixes.update,
1783
- singularTypes
2064
+ updateFieldName,
2065
+ typeName,
2066
+ typeNameMapper
1784
2067
  );
1785
2068
  const deleteGenerated = generateDelete2(
1786
2069
  db,
1787
2070
  tableName,
1788
2071
  schema[tableName],
1789
2072
  tableFilters,
1790
- prefixes.delete,
1791
- singularTypes
2073
+ deleteFieldName,
2074
+ typeName
1792
2075
  );
1793
2076
  queries[selectArrGenerated.name] = {
1794
2077
  type: selectArrOutput,
@@ -1826,139 +2109,108 @@ function generateSchemaData2(db, schema, relations, relationsDepthLimit, prefixe
1826
2109
  outputs[selectSingleOutput.name] = selectSingleOutput;
1827
2110
  outputs[singleTableItemOutput.name] = singleTableItemOutput;
1828
2111
  }
1829
- return { queries, mutations, inputs, types: outputs };
2112
+ const fieldResolvers = {};
2113
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
2114
+ const relResolvers = {};
2115
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
2116
+ const isOne = is5(relEntry.relation ?? relEntry, One4);
2117
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
2118
+ if (resolver) {
2119
+ relResolvers[relName] = resolver;
2120
+ }
2121
+ }
2122
+ if (Object.keys(relResolvers).length > 0) {
2123
+ fieldResolvers[tableName] = relResolvers;
2124
+ }
2125
+ }
2126
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
1830
2127
  }
1831
2128
 
1832
2129
  // src/util/builders/sqlite.ts
1833
- import { is as is5 } from "drizzle-orm";
1834
- import { SQLiteTable } from "drizzle-orm/sqlite-core";
2130
+ import { is as is6, One as One5 } from "drizzle-orm";
2131
+ import { getTableConfig as getTableConfig3, SQLiteTable } from "drizzle-orm/sqlite-core";
1835
2132
  import {
1836
2133
  GraphQLError as GraphQLError5,
1837
- GraphQLInt as GraphQLInt5,
1838
2134
  GraphQLList as GraphQLList5,
1839
2135
  GraphQLNonNull as GraphQLNonNull5
1840
2136
  } from "graphql";
1841
2137
  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}`;
2138
+ var generateSelectArray3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1846
2139
  const queryBase = db.query[tableName];
1847
2140
  if (!queryBase) {
1848
2141
  throw new Error(
1849
2142
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1850
2143
  );
1851
2144
  }
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);
2145
+ const queryArgs = selectArrayArgs(orderArgs, filterArgs);
1867
2146
  const table = tables[tableName];
1868
2147
  return {
1869
- name: queryName,
2148
+ name: fieldName,
1870
2149
  resolver: async (_source, args, _context, info) => {
1871
2150
  try {
1872
- const { offset, limit, orderBy, where } = args;
1873
- const parsedInfo = parseResolveInfo3(info, {
1874
- deep: true
1875
- });
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
2151
+ const parsedInfo = parseResolveInfo3(info, { deep: true });
2152
+ return await runRelationalSelect({
2153
+ queryBase,
2154
+ tables,
2155
+ tableName,
2156
+ table,
2157
+ relationMap,
2158
+ typeName,
2159
+ typeNameMapper,
2160
+ parsedInfo,
2161
+ ...args,
2162
+ single: false
1885
2163
  });
1886
- const result = await query;
1887
- return remapToGraphQLArrayOutput(result, tableName, table, relationMap);
1888
2164
  } catch (e) {
1889
- if (e instanceof Error) {
1890
- throw new GraphQLError5(e.message);
1891
- }
1892
- throw e;
2165
+ throw toGraphQLError(e);
1893
2166
  }
1894
2167
  },
1895
2168
  args: queryArgs
1896
2169
  };
1897
2170
  };
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}`;
2171
+ var generateSelectSingle3 = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
1901
2172
  const queryBase = db.query[tableName];
1902
2173
  if (!queryBase) {
1903
2174
  throw new Error(
1904
2175
  `Drizzle-GraphQL Error: Table ${tableName} not found in drizzle instance. Did you forget to pass schema to drizzle constructor?`
1905
2176
  );
1906
2177
  }
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);
2178
+ const queryArgs = selectSingleArgs(orderArgs, filterArgs);
1919
2179
  const table = tables[tableName];
1920
2180
  return {
1921
- name: queryName,
2181
+ name: fieldName,
1922
2182
  resolver: async (_source, args, _context, info) => {
1923
2183
  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
2184
+ const parsedInfo = parseResolveInfo3(info, { deep: true });
2185
+ return await runRelationalSelect({
2186
+ queryBase,
2187
+ tables,
2188
+ tableName,
2189
+ table,
2190
+ relationMap,
2191
+ typeName,
2192
+ typeNameMapper,
2193
+ parsedInfo,
2194
+ ...args,
2195
+ single: true
1936
2196
  });
1937
- const result = await query;
1938
- if (!result) {
1939
- return void 0;
1940
- }
1941
- return remapToGraphQLSingleOutput(result, tableName, table, relationMap);
1942
2197
  } catch (e) {
1943
- if (e instanceof Error) {
1944
- throw new GraphQLError5(e.message);
1945
- }
1946
- throw e;
2198
+ throw toGraphQLError(e);
1947
2199
  }
1948
2200
  },
1949
2201
  args: queryArgs
1950
2202
  };
1951
2203
  };
1952
- var generateInsertArray3 = (db, tableName, table, baseType, singularTypes = false) => {
1953
- const queryName = `insertInto${capitalize(tableName)}`;
1954
- const typeName = toTypeName4(tableName, singularTypes);
2204
+ var sqlitePrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, getTableConfig3);
2205
+ var generateInsertArray3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper) => {
1955
2206
  const queryArgs = {
1956
2207
  values: {
1957
2208
  type: new GraphQLNonNull5(new GraphQLList5(new GraphQLNonNull5(baseType)))
1958
2209
  }
1959
2210
  };
2211
+ const pkNames = sqlitePrimaryKeyPropNames(table);
1960
2212
  return {
1961
- name: queryName,
2213
+ name: fieldName,
1962
2214
  resolver: async (_source, args, _context, info) => {
1963
2215
  try {
1964
2216
  const input = remapFromGraphQLArrayInput(args.values, table);
@@ -1968,61 +2220,65 @@ var generateInsertArray3 = (db, tableName, table, baseType, singularTypes = fals
1968
2220
  const parsedInfo = parseResolveInfo3(info, {
1969
2221
  deep: true
1970
2222
  });
1971
- const columns = extractSelectedColumnsFromTreeSQLFormat(
1972
- parsedInfo.fieldsByTypeName[typeName],
1973
- table
1974
- );
2223
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2224
+ relationMap,
2225
+ tables,
2226
+ tableName,
2227
+ typeName,
2228
+ typeNameMapper,
2229
+ table,
2230
+ pkNames,
2231
+ parsedInfo
2232
+ });
1975
2233
  const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
1976
- return remapToGraphQLArrayOutput(result, tableName, table);
2234
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
2235
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
1977
2236
  } catch (e) {
1978
- if (e instanceof Error) {
1979
- throw new GraphQLError5(e.message);
1980
- }
1981
- throw e;
2237
+ throw toGraphQLError(e);
1982
2238
  }
1983
2239
  },
1984
2240
  args: queryArgs
1985
2241
  };
1986
2242
  };
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);
2243
+ var generateInsertSingle3 = (db, tableName, table, tables, relationMap, baseType, fieldName, typeName, typeNameMapper) => {
1991
2244
  const queryArgs = {
1992
2245
  values: {
1993
2246
  type: new GraphQLNonNull5(baseType)
1994
2247
  }
1995
2248
  };
2249
+ const pkNames = sqlitePrimaryKeyPropNames(table);
1996
2250
  return {
1997
- name: queryName,
2251
+ name: fieldName,
1998
2252
  resolver: async (_source, args, _context, info) => {
1999
2253
  try {
2000
2254
  const input = remapFromGraphQLSingleInput(args.values, table);
2001
2255
  const parsedInfo = parseResolveInfo3(info, {
2002
2256
  deep: true
2003
2257
  });
2004
- const columns = extractSelectedColumnsFromTreeSQLFormat(
2005
- parsedInfo.fieldsByTypeName[typeName],
2006
- table
2007
- );
2258
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2259
+ relationMap,
2260
+ tables,
2261
+ tableName,
2262
+ typeName,
2263
+ typeNameMapper,
2264
+ table,
2265
+ pkNames,
2266
+ parsedInfo
2267
+ });
2008
2268
  const result = await db.insert(table).values(input).returning(columns).onConflictDoNothing();
2009
2269
  if (!result[0]) {
2010
2270
  return void 0;
2011
2271
  }
2012
- return remapToGraphQLSingleOutput(result[0], tableName, table);
2272
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
2273
+ return remapToGraphQLSingleOutput(enriched[0], tableName, table, relationMap);
2013
2274
  } catch (e) {
2014
- if (e instanceof Error) {
2015
- throw new GraphQLError5(e.message);
2016
- }
2017
- throw e;
2275
+ throw toGraphQLError(e);
2018
2276
  }
2019
2277
  },
2020
2278
  args: queryArgs
2021
2279
  };
2022
2280
  };
2023
- var generateUpdate3 = (db, tableName, table, setArgs, filterArgs, singularTypes = false) => {
2024
- const queryName = `update${capitalize(tableName)}`;
2025
- const typeName = toTypeName4(tableName, singularTypes);
2281
+ var generateUpdate3 = (db, tableName, table, tables, relationMap, setArgs, filterArgs, fieldName, typeName, typeNameMapper) => {
2026
2282
  const queryArgs = {
2027
2283
  set: {
2028
2284
  type: new GraphQLNonNull5(setArgs)
@@ -2031,18 +2287,25 @@ var generateUpdate3 = (db, tableName, table, setArgs, filterArgs, singularTypes
2031
2287
  type: filterArgs
2032
2288
  }
2033
2289
  };
2290
+ const pkNames = sqlitePrimaryKeyPropNames(table);
2034
2291
  return {
2035
- name: queryName,
2292
+ name: fieldName,
2036
2293
  resolver: async (_source, args, _context, info) => {
2037
2294
  try {
2038
2295
  const { where, set } = args;
2039
2296
  const parsedInfo = parseResolveInfo3(info, {
2040
2297
  deep: true
2041
2298
  });
2042
- const columns = extractSelectedColumnsFromTreeSQLFormat(
2043
- parsedInfo.fieldsByTypeName[typeName],
2044
- table
2045
- );
2299
+ const { columns, hasRelations, withParams } = prepareMutationRelationColumns({
2300
+ relationMap,
2301
+ tables,
2302
+ tableName,
2303
+ typeName,
2304
+ typeNameMapper,
2305
+ table,
2306
+ pkNames,
2307
+ parsedInfo
2308
+ });
2046
2309
  const input = remapFromGraphQLSingleInput(set, table);
2047
2310
  if (!Object.keys(input).length) {
2048
2311
  throw new GraphQLError5("Unable to update with no values specified!");
@@ -2054,27 +2317,23 @@ var generateUpdate3 = (db, tableName, table, setArgs, filterArgs, singularTypes
2054
2317
  }
2055
2318
  query = query.returning(columns);
2056
2319
  const result = await query;
2057
- return remapToGraphQLArrayOutput(result, tableName, table);
2320
+ const enriched = hasRelations ? await eagerLoadMutationRelations(db, tableName, result, pkNames, withParams) : result;
2321
+ return remapToGraphQLArrayOutput(enriched, tableName, table, relationMap);
2058
2322
  } catch (e) {
2059
- if (e instanceof Error) {
2060
- throw new GraphQLError5(e.message);
2061
- }
2062
- throw e;
2323
+ throw toGraphQLError(e);
2063
2324
  }
2064
2325
  },
2065
2326
  args: queryArgs
2066
2327
  };
2067
2328
  };
2068
- var generateDelete3 = (db, tableName, table, filterArgs, singularTypes = false) => {
2069
- const queryName = `deleteFrom${capitalize(tableName)}`;
2070
- const typeName = toTypeName4(tableName, singularTypes);
2329
+ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName) => {
2071
2330
  const queryArgs = {
2072
2331
  where: {
2073
2332
  type: filterArgs
2074
2333
  }
2075
2334
  };
2076
2335
  return {
2077
- name: queryName,
2336
+ name: fieldName,
2078
2337
  resolver: async (_source, args, _context, info) => {
2079
2338
  try {
2080
2339
  const { where } = args;
@@ -2094,19 +2353,16 @@ var generateDelete3 = (db, tableName, table, filterArgs, singularTypes = false)
2094
2353
  const result = await query;
2095
2354
  return remapToGraphQLArrayOutput(result, tableName, table);
2096
2355
  } catch (e) {
2097
- if (e instanceof Error) {
2098
- throw new GraphQLError5(e.message);
2099
- }
2100
- throw e;
2356
+ throw toGraphQLError(e);
2101
2357
  }
2102
2358
  },
2103
2359
  args: queryArgs
2104
2360
  };
2105
2361
  };
2106
- var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, singularTypes = false) => {
2362
+ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad = () => true) => {
2107
2363
  const rawSchema = schema;
2108
2364
  const schemaEntries = Object.entries(rawSchema);
2109
- const tableEntries = schemaEntries.filter(([_key, value]) => is5(value, SQLiteTable));
2365
+ const tableEntries = schemaEntries.filter(([_key, value]) => is6(value, SQLiteTable));
2110
2366
  const tables = Object.fromEntries(tableEntries);
2111
2367
  if (!tableEntries.length) {
2112
2368
  throw new Error(
@@ -2114,12 +2370,17 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2114
2370
  );
2115
2371
  }
2116
2372
  const namedRelations = buildNamedRelations(relations ?? {}, tableEntries);
2373
+ attachTargetPrimaryKeys(namedRelations, tables, sqlitePrimaryKeyPropNames);
2374
+ const eagerRelations = pruneNonEagerRelations(namedRelations, shouldEagerLoad);
2375
+ const resolverFactory = createRelationResolverFactory(db, tables);
2117
2376
  const cacheCtx = {
2118
2377
  genericFilterCache: /* @__PURE__ */ new Map(),
2119
2378
  objectTypeCache: /* @__PURE__ */ new Map(),
2120
2379
  relationFieldContainers: /* @__PURE__ */ new Map(),
2121
2380
  fullyBuiltTables: /* @__PURE__ */ new Set(),
2122
- relationTypeCache: /* @__PURE__ */ new Map()
2381
+ relationTypeCache: /* @__PURE__ */ new Map(),
2382
+ orderTypeCache: /* @__PURE__ */ new WeakMap(),
2383
+ filterTypeCache: /* @__PURE__ */ new WeakMap()
2123
2384
  };
2124
2385
  const queries = {};
2125
2386
  const mutations = {};
@@ -2133,9 +2394,10 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2133
2394
  true,
2134
2395
  relationsDepthLimit,
2135
2396
  cacheCtx,
2136
- singularTypes,
2397
+ typeNameMapper,
2137
2398
  prefixes.insert,
2138
- prefixes.update
2399
+ prefixes.update,
2400
+ resolverFactory
2139
2401
  )
2140
2402
  ])
2141
2403
  );
@@ -2144,54 +2406,78 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2144
2406
  for (const [tableName, tableTypes] of Object.entries(gqlSchemaTypes)) {
2145
2407
  const { insertInput, updateInput, tableFilters, tableOrder } = tableTypes.inputs;
2146
2408
  const { selectSingleOutput, selectArrOutput, singleTableItemOutput, arrTableItemOutput } = tableTypes.outputs;
2409
+ const {
2410
+ typeName,
2411
+ listFieldName,
2412
+ singleFieldName,
2413
+ createArrayFieldName,
2414
+ createSingleFieldName,
2415
+ updateFieldName,
2416
+ deleteFieldName
2417
+ } = computeResolverFieldNames(tableName, typeNameMapper, prefixes, suffixes);
2147
2418
  const selectArrGenerated = generateSelectArray3(
2148
2419
  db,
2149
2420
  tableName,
2150
2421
  tables,
2151
- namedRelations,
2422
+ eagerRelations,
2152
2423
  tableOrder,
2153
2424
  tableFilters,
2154
- suffixes.list,
2155
- singularTypes
2425
+ listFieldName,
2426
+ typeName,
2427
+ typeNameMapper
2156
2428
  );
2157
2429
  const selectSingleGenerated = generateSelectSingle3(
2158
2430
  db,
2159
2431
  tableName,
2160
2432
  tables,
2161
- namedRelations,
2433
+ eagerRelations,
2162
2434
  tableOrder,
2163
2435
  tableFilters,
2164
- suffixes.single,
2165
- singularTypes
2436
+ singleFieldName,
2437
+ typeName,
2438
+ typeNameMapper
2166
2439
  );
2167
2440
  const insertArrGenerated = generateInsertArray3(
2168
2441
  db,
2169
2442
  tableName,
2170
2443
  schema[tableName],
2444
+ tables,
2445
+ eagerRelations,
2171
2446
  insertInput,
2172
- singularTypes
2447
+ createArrayFieldName,
2448
+ typeName,
2449
+ typeNameMapper
2173
2450
  );
2174
2451
  const insertSingleGenerated = generateInsertSingle3(
2175
2452
  db,
2176
2453
  tableName,
2177
2454
  schema[tableName],
2455
+ tables,
2456
+ eagerRelations,
2178
2457
  insertInput,
2179
- singularTypes
2458
+ createSingleFieldName,
2459
+ typeName,
2460
+ typeNameMapper
2180
2461
  );
2181
2462
  const updateGenerated = generateUpdate3(
2182
2463
  db,
2183
2464
  tableName,
2184
2465
  schema[tableName],
2466
+ tables,
2467
+ eagerRelations,
2185
2468
  updateInput,
2186
2469
  tableFilters,
2187
- singularTypes
2470
+ updateFieldName,
2471
+ typeName,
2472
+ typeNameMapper
2188
2473
  );
2189
2474
  const deleteGenerated = generateDelete3(
2190
2475
  db,
2191
2476
  tableName,
2192
2477
  schema[tableName],
2193
2478
  tableFilters,
2194
- singularTypes
2479
+ deleteFieldName,
2480
+ typeName
2195
2481
  );
2196
2482
  queries[selectArrGenerated.name] = {
2197
2483
  type: selectArrOutput,
@@ -2229,7 +2515,21 @@ var generateSchemaData3 = (db, schema, relations, relationsDepthLimit, prefixes,
2229
2515
  outputs[selectSingleOutput.name] = selectSingleOutput;
2230
2516
  outputs[singleTableItemOutput.name] = singleTableItemOutput;
2231
2517
  }
2232
- return { queries, mutations, inputs, types: outputs };
2518
+ const fieldResolvers = {};
2519
+ for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
2520
+ const relResolvers = {};
2521
+ for (const [relName, relEntry] of Object.entries(tableRelations)) {
2522
+ const isOne = is6(relEntry.relation ?? relEntry, One5);
2523
+ const resolver = resolverFactory({ tableName, relationName: relName, relEntry, isOne });
2524
+ if (resolver) {
2525
+ relResolvers[relName] = resolver;
2526
+ }
2527
+ }
2528
+ if (Object.keys(relResolvers).length > 0) {
2529
+ fieldResolvers[tableName] = relResolvers;
2530
+ }
2531
+ }
2532
+ return { queries, mutations, inputs, types: outputs, fieldResolvers };
2233
2533
  };
2234
2534
 
2235
2535
  // src/index.ts
@@ -2244,15 +2544,22 @@ var buildSchema = (db, config) => {
2244
2544
  );
2245
2545
  }
2246
2546
  const prefixes = {
2247
- insert: config?.prefixes?.insert ?? "insertInto",
2248
- delete: config?.prefixes?.delete ?? "deleteFrom",
2547
+ insert: config?.prefixes?.insert ?? "create",
2548
+ delete: config?.prefixes?.delete ?? "delete",
2249
2549
  update: config?.prefixes?.update ?? "update"
2250
2550
  };
2251
2551
  const suffixes = {
2252
2552
  list: config?.suffixes?.list ?? "",
2253
2553
  single: config?.suffixes?.single ?? "Single"
2254
2554
  };
2255
- const singularTypes = config?.singularTypes ?? false;
2555
+ const typeNameMapper = config?.typeNameMapper;
2556
+ const eagerOpt = config?.eagerLoadRelations;
2557
+ const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
2558
+ if (!typeNameMapper && suffixes.list === suffixes.single) {
2559
+ throw new Error(
2560
+ "Drizzle-GraphQL Error: List and single query suffixes cannot be the same. This would create conflicting GraphQL field names."
2561
+ );
2562
+ }
2256
2563
  if (typeof config?.relationsDepthLimit === "number") {
2257
2564
  if (config.relationsDepthLimit < 0) {
2258
2565
  throw new Error(
@@ -2264,14 +2571,9 @@ var buildSchema = (db, config) => {
2264
2571
  "Drizzle-GraphQL Error: config.relationsDepthLimit is supposed to be nonnegative integer or undefined!"
2265
2572
  );
2266
2573
  }
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
2574
  }
2273
2575
  let generatorOutput;
2274
- if (is6(db, MySqlDatabase)) {
2576
+ if (is7(db, MySqlDatabase)) {
2275
2577
  generatorOutput = generateSchemaData(
2276
2578
  db,
2277
2579
  schema,
@@ -2279,9 +2581,10 @@ var buildSchema = (db, config) => {
2279
2581
  config?.relationsDepthLimit,
2280
2582
  prefixes,
2281
2583
  suffixes,
2282
- singularTypes
2584
+ typeNameMapper,
2585
+ shouldEagerLoad
2283
2586
  );
2284
- } else if (is6(db, PgAsyncDatabase)) {
2587
+ } else if (is7(db, PgAsyncDatabase)) {
2285
2588
  generatorOutput = generateSchemaData2(
2286
2589
  db,
2287
2590
  schema,
@@ -2290,9 +2593,10 @@ var buildSchema = (db, config) => {
2290
2593
  prefixes,
2291
2594
  suffixes,
2292
2595
  config?.conflictDoNothing ?? false,
2293
- singularTypes
2596
+ typeNameMapper,
2597
+ shouldEagerLoad
2294
2598
  );
2295
- } else if (is6(db, BaseSQLiteDatabase)) {
2599
+ } else if (is7(db, BaseSQLiteDatabase)) {
2296
2600
  generatorOutput = generateSchemaData3(
2297
2601
  db,
2298
2602
  schema,
@@ -2300,7 +2604,8 @@ var buildSchema = (db, config) => {
2300
2604
  config?.relationsDepthLimit,
2301
2605
  prefixes,
2302
2606
  suffixes,
2303
- singularTypes
2607
+ typeNameMapper,
2608
+ shouldEagerLoad
2304
2609
  );
2305
2610
  } else {
2306
2611
  throw new Error("Drizzle-GraphQL Error: Unknown database instance type");
@@ -2325,7 +2630,9 @@ var buildSchema = (db, config) => {
2325
2630
  };
2326
2631
  export {
2327
2632
  buildSchema,
2633
+ createRelationResolverFactory,
2328
2634
  extractFilters,
2329
- extractOrderBy
2635
+ extractOrderBy,
2636
+ extractRelationJoinColumns
2330
2637
  };
2331
2638
  //# sourceMappingURL=index.js.map