@vantreeseba/drizzle-graphql 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -650,6 +650,12 @@ var createRelationResolverFactory = (db, tables, filterCtx) => ({ tableName, rel
650
650
  return loader.load(localValue);
651
651
  };
652
652
  };
653
+ var listFieldComplexity = (options) => ({ args, childComplexity }) => {
654
+ const limit = args["limit"];
655
+ const rows = typeof limit === "number" && limit > 0 ? limit : options.defaultListSize;
656
+ return rows * Math.max(childComplexity, 1);
657
+ };
658
+ var aggregateFieldComplexity = (options) => ({ childComplexity }) => options.aggregateCost + childComplexity;
653
659
  var AGGREGATE_FIELD_SUFFIX = "Aggregate";
654
660
  var relationAggregateJoinColumns = (tree, table, selectionCtx) => {
655
661
  const relations = selectionCtx?.relationMap[selectionCtx.tableName];
@@ -1071,7 +1077,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1071
1077
  offset: { type: import_graphql4.GraphQLInt },
1072
1078
  limit: { type: import_graphql4.GraphQLInt }
1073
1079
  },
1074
- resolve
1080
+ resolve,
1081
+ ...cacheCtx.complexity ? { extensions: { complexity: listFieldComplexity(cacheCtx.complexity) } } : {}
1075
1082
  }
1076
1083
  ]);
1077
1084
  const aggregateFieldName = `${relationName}Aggregate`;
@@ -1089,7 +1096,8 @@ var generateSelectFields = (tables, tableName, relationMap, fromTableName, fromR
1089
1096
  args: {
1090
1097
  where: { type: relSelectData.filters }
1091
1098
  },
1092
- resolve: relationAggregate.resolve
1099
+ resolve: relationAggregate.resolve,
1100
+ ...cacheCtx.complexity ? { extensions: { complexity: aggregateFieldComplexity(cacheCtx.complexity) } } : {}
1093
1101
  }
1094
1102
  ]);
1095
1103
  }
@@ -1712,6 +1720,7 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1712
1720
  const listFieldName = (mapped?.plural ?? uncapitalize(tableName)) + suffixes.list;
1713
1721
  const singleFieldName = mapped?.singular ?? uncapitalize(tableName) + suffixes.single;
1714
1722
  const aggregateFieldName = `${mapped?.plural ?? uncapitalize(tableName)}Aggregate`;
1723
+ const groupByFieldName = `${mapped?.plural ?? uncapitalize(tableName)}GroupBy`;
1715
1724
  const createArrayFieldName = `${prefixes.insert}${mapped ? capitalize(mapped.plural) : capitalize(tableName)}`;
1716
1725
  const createSingleFieldName = mapped ? `${prefixes.insert}${capitalize(mapped.singular)}` : `${prefixes.insert}${capitalize(tableName)}${suffixes.single}`;
1717
1726
  const upsertPrefix = prefixes.upsert ?? "upsert";
@@ -1724,6 +1733,7 @@ var computeResolverFieldNames = (tableName, typeNameMapper, prefixes, suffixes)
1724
1733
  listFieldName,
1725
1734
  singleFieldName,
1726
1735
  aggregateFieldName,
1736
+ groupByFieldName,
1727
1737
  createArrayFieldName,
1728
1738
  createSingleFieldName,
1729
1739
  upsertArrayFieldName,
@@ -1998,9 +2008,9 @@ var aggregateTarget = (table, tableName, typeName) => {
1998
2008
  )
1999
2009
  };
2000
2010
  };
2001
- var parseAggregateRequest = (info, target) => {
2011
+ var parseAggregateRequest = (info, target, rootTypeName = `${target.typeName}Aggregate`) => {
2002
2012
  const parsedInfo = (0, import_graphql_parse_resolve_info.parseResolveInfo)(info, { deep: true });
2003
- const selectionTree = parsedInfo.fieldsByTypeName[`${target.typeName}Aggregate`] ?? {};
2013
+ const selectionTree = parsedInfo.fieldsByTypeName[rootTypeName] ?? {};
2004
2014
  const request = {
2005
2015
  count: false,
2006
2016
  ops: { avg: [], sum: [], min: [], max: [], countNonNull: [], countDistinct: [] },
@@ -2138,6 +2148,184 @@ var createRelationAggregateFactory = (db, tables, cacheCtx, typeNameMapper, filt
2138
2148
  return { type, resolve };
2139
2149
  };
2140
2150
  };
2151
+ var GROUP_COL = `group${SEP}`;
2152
+ var HAVING_OPS = { eq: import_drizzle_orm4.eq, ne: import_drizzle_orm4.ne, gt: import_drizzle_orm4.gt, gte: import_drizzle_orm4.gte, lt: import_drizzle_orm4.lt, lte: import_drizzle_orm4.lte };
2153
+ var groupableColumns = (table, tableName) => {
2154
+ const { orderable } = classifyAggregateColumns(table, tableName);
2155
+ const groupable = { ...orderable };
2156
+ for (const [columnName, column] of Object.entries((0, import_drizzle_orm4.getColumns)(table))) {
2157
+ if (groupable[columnName]) {
2158
+ continue;
2159
+ }
2160
+ const { type: dataType } = (0, import_drizzle_orm4.extractExtendedColumnType)(column);
2161
+ if (dataType !== "boolean") {
2162
+ continue;
2163
+ }
2164
+ groupable[columnName] = {
2165
+ column,
2166
+ converted: drizzleColumnToGraphQLType(column, columnName, tableName, true, false, false)
2167
+ };
2168
+ }
2169
+ return groupable;
2170
+ };
2171
+ var generateGroupByEnum = (table, tableName, typeName) => {
2172
+ const groupable = groupableColumns(table, tableName);
2173
+ return generateColumnEnum(
2174
+ table,
2175
+ `${typeName}GroupByColumn`,
2176
+ `Columns of ${typeName} that a query can group by`,
2177
+ (_column, columnName) => Boolean(groupable[columnName])
2178
+ );
2179
+ };
2180
+ var aggregateNumberFilter = new import_graphql5.GraphQLInputObjectType({
2181
+ name: "AggregateNumberFilter",
2182
+ description: "Compares an aggregated value. Several operators in one filter are ANDed together.",
2183
+ fields: Object.fromEntries(Object.keys(HAVING_OPS).map((op) => [op, { type: import_graphql5.GraphQLFloat }]))
2184
+ });
2185
+ var generateHavingInput = (table, tableName, typeName) => {
2186
+ const { numeric, orderable, all } = classifyAggregateColumns(table, tableName);
2187
+ const fields = {
2188
+ count: { type: aggregateNumberFilter, description: "Filters groups by how many rows they contain" }
2189
+ };
2190
+ const opColumns = {
2191
+ avg: numeric,
2192
+ sum: numeric,
2193
+ min: numeric,
2194
+ max: numeric,
2195
+ countNonNull: all,
2196
+ countDistinct: orderable
2197
+ };
2198
+ for (const [op, columns] of Object.entries(opColumns)) {
2199
+ const columnNames = Object.keys(columns);
2200
+ if (!columnNames.length) {
2201
+ continue;
2202
+ }
2203
+ fields[op] = {
2204
+ type: new import_graphql5.GraphQLInputObjectType({
2205
+ name: `${typeName}${capitalize(op)}Having`,
2206
+ fields: Object.fromEntries(columnNames.map((columnName) => [columnName, { type: aggregateNumberFilter }]))
2207
+ })
2208
+ };
2209
+ }
2210
+ return new import_graphql5.GraphQLInputObjectType({
2211
+ name: `${typeName}Having`,
2212
+ description: `Filters ${typeName} groups by their aggregated values`,
2213
+ fields
2214
+ });
2215
+ };
2216
+ var generateGroupByType = (table, tableName, typeName, cacheCtx) => {
2217
+ const groupable = groupableColumns(table, tableName);
2218
+ if (!Object.keys(groupable).length) {
2219
+ return void 0;
2220
+ }
2221
+ const keysType = new import_graphql5.GraphQLObjectType({
2222
+ name: `${typeName}GroupKeys`,
2223
+ description: `The grouped column values of one ${typeName} group. A column the query did not group by is null.`,
2224
+ fields: Object.fromEntries(
2225
+ Object.entries(groupable).map(([columnName, { converted }]) => [
2226
+ columnName,
2227
+ { type: converted.type, description: converted.description }
2228
+ ])
2229
+ )
2230
+ });
2231
+ const aggregateType = generateAggregateTypes(table, tableName, typeName, cacheCtx);
2232
+ const aggregateFields = Object.fromEntries(
2233
+ Object.values(aggregateType.getFields()).map((field) => [
2234
+ field.name,
2235
+ { type: field.type, description: field.description ?? void 0 }
2236
+ ])
2237
+ );
2238
+ return new import_graphql5.GraphQLObjectType({
2239
+ name: `${typeName}GroupBy`,
2240
+ fields: { group: { type: new import_graphql5.GraphQLNonNull(keysType) }, ...aggregateFields }
2241
+ });
2242
+ };
2243
+ var havingComparisons = (expression, filter) => Object.entries(filter).filter(([op, value]) => value != null && op in HAVING_OPS).map(([op, value]) => HAVING_OPS[op](expression, value));
2244
+ var buildHavingCondition = (having, columns) => {
2245
+ if (!having) {
2246
+ return void 0;
2247
+ }
2248
+ const conditions = [];
2249
+ for (const [key, value] of Object.entries(having)) {
2250
+ if (value == null) {
2251
+ continue;
2252
+ }
2253
+ if (key === "count") {
2254
+ conditions.push(...havingComparisons((0, import_drizzle_orm4.count)(), value));
2255
+ continue;
2256
+ }
2257
+ if (!AGGREGATE_OPS.includes(key)) {
2258
+ continue;
2259
+ }
2260
+ for (const [columnName, filter] of Object.entries(value)) {
2261
+ const column = columns[columnName];
2262
+ if (!column || filter == null) {
2263
+ continue;
2264
+ }
2265
+ conditions.push(...havingComparisons(OP_FNS[key](column), filter));
2266
+ }
2267
+ }
2268
+ return conditions.length ? (0, import_drizzle_orm4.and)(...conditions) : void 0;
2269
+ };
2270
+ var generateGroupBy = (db, tableName, table, typeName, fieldName, filterArgs, groupByEnum, havingInput, filterCtx) => {
2271
+ const target = aggregateTarget(table, tableName, typeName);
2272
+ const groupable = groupableColumns(table, tableName);
2273
+ const columns = (0, import_drizzle_orm4.getColumns)(table);
2274
+ const rootTypeName = `${typeName}GroupBy`;
2275
+ const queryArgs = {
2276
+ groupBy: {
2277
+ type: new import_graphql5.GraphQLNonNull(new import_graphql5.GraphQLList(new import_graphql5.GraphQLNonNull(groupByEnum))),
2278
+ description: "Columns to group by. One result row per distinct combination of their values."
2279
+ },
2280
+ where: { type: filterArgs, description: "Filters the rows before they are grouped." },
2281
+ having: { type: havingInput, description: "Filters the groups after they are aggregated." }
2282
+ };
2283
+ return {
2284
+ name: fieldName,
2285
+ resolver: async (_source, args, context, info) => {
2286
+ try {
2287
+ const requestedKeys = [...new Set(args.groupBy ?? [])];
2288
+ if (!requestedKeys.length) {
2289
+ throw new import_graphql5.GraphQLError("At least one column to group by is required!");
2290
+ }
2291
+ const keyColumns = requestedKeys.map((columnName) => {
2292
+ const groupableColumn = groupable[columnName];
2293
+ if (!groupableColumn) {
2294
+ throw new import_graphql5.GraphQLError(`Cannot group ${typeName} by ${columnName}!`);
2295
+ }
2296
+ return [columnName, groupableColumn.column];
2297
+ });
2298
+ const request = parseAggregateRequest(info, target, rootTypeName);
2299
+ const selection = {
2300
+ ...Object.fromEntries(keyColumns.map(([columnName, column]) => [`${GROUP_COL}${columnName}`, column])),
2301
+ ...request.selection
2302
+ };
2303
+ let query = resolveExecutor(db, context).select(selection).from(table);
2304
+ if (args.where) {
2305
+ query = query.where(extractFilters(table, tableName, args.where, relationFilterCtx(filterCtx, tableName)));
2306
+ }
2307
+ query = query.groupBy(...keyColumns.map(([, column]) => column));
2308
+ const havingCondition = buildHavingCondition(args.having, columns);
2309
+ if (havingCondition) {
2310
+ query = query.having(havingCondition);
2311
+ }
2312
+ const rows = await query;
2313
+ return rows.map((row) => {
2314
+ const group = {};
2315
+ for (const [columnName, column] of keyColumns) {
2316
+ const value = row[`${GROUP_COL}${columnName}`];
2317
+ const decoded = typeof value === "string" && target.dateTimeColumns.has(columnName) ? parseDriverDateTime(value) : value;
2318
+ group[columnName] = value == null ? null : remapToGraphQLCore(columnName, decoded, tableName, column);
2319
+ }
2320
+ return { group, ...assembleAggregateRow(row, request, target) };
2321
+ });
2322
+ } catch (e) {
2323
+ throw toGraphQLError(e);
2324
+ }
2325
+ },
2326
+ args: queryArgs
2327
+ };
2328
+ };
2141
2329
 
2142
2330
  // src/util/builders/mysql.ts
2143
2331
  var generateSelectArray = (db, tableName, tables, relationMap, orderArgs, filterArgs, fieldName, typeName, typeNameMapper, filterCtx, distinctEnabled = true) => {
@@ -2366,7 +2554,7 @@ var generateDelete = (db, tableName, table, filterArgs, fieldName, filterCtx) =>
2366
2554
  };
2367
2555
  var mysqlPrimaryKeyPropNames = (table) => getPrimaryKeyPropNamesFromConfig(table, import_mysql_core2.getTableConfig);
2368
2556
  var generateSchemaData = (db, schema, relations, options) => {
2369
- const { relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad, features } = options;
2557
+ const { relationsDepthLimit, prefixes, suffixes, typeNameMapper, shouldEagerLoad, features, complexity } = options;
2370
2558
  const rawSchema = schema;
2371
2559
  const schemaEntries = Object.entries(rawSchema);
2372
2560
  const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm5.is)(value, import_mysql_core2.MySqlTable));
@@ -2390,7 +2578,8 @@ var generateSchemaData = (db, schema, relations, options) => {
2390
2578
  orderTypeCache: /* @__PURE__ */ new WeakMap(),
2391
2579
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
2392
2580
  listRelationFilterCache: /* @__PURE__ */ new Map(),
2393
- aggregateTypeCache: /* @__PURE__ */ new Map()
2581
+ aggregateTypeCache: /* @__PURE__ */ new Map(),
2582
+ complexity
2394
2583
  };
2395
2584
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
2396
2585
  const queries = {};
@@ -2434,6 +2623,7 @@ var generateSchemaData = (db, schema, relations, options) => {
2434
2623
  listFieldName,
2435
2624
  singleFieldName,
2436
2625
  aggregateFieldName,
2626
+ groupByFieldName,
2437
2627
  createArrayFieldName,
2438
2628
  createSingleFieldName,
2439
2629
  upsertArrayFieldName,
@@ -2497,10 +2687,25 @@ var generateSchemaData = (db, schema, relations, options) => {
2497
2687
  tableFilters,
2498
2688
  filterCtx
2499
2689
  ) : void 0;
2690
+ const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
2691
+ const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
2692
+ const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
2693
+ const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
2694
+ db,
2695
+ tableName,
2696
+ schema[tableName],
2697
+ typeName,
2698
+ groupByFieldName,
2699
+ tableFilters,
2700
+ groupByEnum,
2701
+ havingInput,
2702
+ filterCtx
2703
+ ) : void 0;
2500
2704
  queries[selectArrGenerated.name] = {
2501
2705
  type: selectArrOutput,
2502
2706
  args: selectArrGenerated.args,
2503
- resolve: selectArrGenerated.resolver
2707
+ resolve: selectArrGenerated.resolver,
2708
+ ...complexity ? { extensions: { complexity: listFieldComplexity(complexity) } } : {}
2504
2709
  };
2505
2710
  queries[selectSingleGenerated.name] = {
2506
2711
  type: selectSingleOutput,
@@ -2511,7 +2716,16 @@ var generateSchemaData = (db, schema, relations, options) => {
2511
2716
  queries[aggregateGenerated.name] = {
2512
2717
  type: new import_graphql6.GraphQLNonNull(aggregateType),
2513
2718
  args: aggregateGenerated.args,
2514
- resolve: aggregateGenerated.resolver
2719
+ resolve: aggregateGenerated.resolver,
2720
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
2721
+ };
2722
+ }
2723
+ if (groupByGenerated && groupByType) {
2724
+ queries[groupByGenerated.name] = {
2725
+ type: new import_graphql6.GraphQLNonNull(new import_graphql6.GraphQLList(new import_graphql6.GraphQLNonNull(groupByType))),
2726
+ args: groupByGenerated.args,
2727
+ resolve: groupByGenerated.resolver,
2728
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
2515
2729
  };
2516
2730
  }
2517
2731
  for (const generated of [
@@ -2545,6 +2759,10 @@ var generateSchemaData = (db, schema, relations, options) => {
2545
2759
  if (aggregateType) {
2546
2760
  outputs[aggregateType.name] = aggregateType;
2547
2761
  }
2762
+ if (groupByType && havingInput) {
2763
+ outputs[groupByType.name] = groupByType;
2764
+ inputs[havingInput.name] = havingInput;
2765
+ }
2548
2766
  }
2549
2767
  const fieldResolvers = {};
2550
2768
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
@@ -2938,7 +3156,16 @@ var generateDelete2 = (db, tableName, table, filterArgs, fieldName, typeName, fi
2938
3156
  };
2939
3157
  };
2940
3158
  function generateSchemaData2(db, schema, relations, options) {
2941
- const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
3159
+ const {
3160
+ relationsDepthLimit,
3161
+ prefixes,
3162
+ suffixes,
3163
+ conflictDoNothing,
3164
+ typeNameMapper,
3165
+ shouldEagerLoad,
3166
+ features,
3167
+ complexity
3168
+ } = options;
2942
3169
  const schemaEntries = Object.entries(schema);
2943
3170
  const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm6.is)(value, import_pg_core2.PgTable));
2944
3171
  const tables = Object.fromEntries(tableEntries);
@@ -2961,7 +3188,8 @@ function generateSchemaData2(db, schema, relations, options) {
2961
3188
  orderTypeCache: /* @__PURE__ */ new WeakMap(),
2962
3189
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
2963
3190
  listRelationFilterCache: /* @__PURE__ */ new Map(),
2964
- aggregateTypeCache: /* @__PURE__ */ new Map()
3191
+ aggregateTypeCache: /* @__PURE__ */ new Map(),
3192
+ complexity
2965
3193
  };
2966
3194
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
2967
3195
  const queries = {};
@@ -2994,6 +3222,7 @@ function generateSchemaData2(db, schema, relations, options) {
2994
3222
  listFieldName,
2995
3223
  singleFieldName,
2996
3224
  aggregateFieldName,
3225
+ groupByFieldName,
2997
3226
  createArrayFieldName,
2998
3227
  createSingleFieldName,
2999
3228
  upsertArrayFieldName,
@@ -3121,10 +3350,25 @@ function generateSchemaData2(db, schema, relations, options) {
3121
3350
  tableFilters,
3122
3351
  filterCtx
3123
3352
  ) : void 0;
3353
+ const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3354
+ const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
3355
+ const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
3356
+ const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
3357
+ db,
3358
+ tableName,
3359
+ schema[tableName],
3360
+ typeName,
3361
+ groupByFieldName,
3362
+ tableFilters,
3363
+ groupByEnum,
3364
+ havingInput,
3365
+ filterCtx
3366
+ ) : void 0;
3124
3367
  queries[selectArrGenerated.name] = {
3125
3368
  type: selectArrOutput,
3126
3369
  args: selectArrGenerated.args,
3127
- resolve: selectArrGenerated.resolver
3370
+ resolve: selectArrGenerated.resolver,
3371
+ ...complexity ? { extensions: { complexity: listFieldComplexity(complexity) } } : {}
3128
3372
  };
3129
3373
  queries[selectSingleGenerated.name] = {
3130
3374
  type: selectSingleOutput,
@@ -3135,7 +3379,16 @@ function generateSchemaData2(db, schema, relations, options) {
3135
3379
  queries[aggregateGenerated.name] = {
3136
3380
  type: new import_graphql7.GraphQLNonNull(aggregateType),
3137
3381
  args: aggregateGenerated.args,
3138
- resolve: aggregateGenerated.resolver
3382
+ resolve: aggregateGenerated.resolver,
3383
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
3384
+ };
3385
+ }
3386
+ if (groupByGenerated && groupByType) {
3387
+ queries[groupByGenerated.name] = {
3388
+ type: new import_graphql7.GraphQLNonNull(new import_graphql7.GraphQLList(new import_graphql7.GraphQLNonNull(groupByType))),
3389
+ args: groupByGenerated.args,
3390
+ resolve: groupByGenerated.resolver,
3391
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
3139
3392
  };
3140
3393
  }
3141
3394
  if (insertArrGenerated) {
@@ -3196,6 +3449,10 @@ function generateSchemaData2(db, schema, relations, options) {
3196
3449
  if (aggregateType) {
3197
3450
  outputs[aggregateType.name] = aggregateType;
3198
3451
  }
3452
+ if (groupByType && havingInput) {
3453
+ outputs[groupByType.name] = groupByType;
3454
+ inputs[havingInput.name] = havingInput;
3455
+ }
3199
3456
  }
3200
3457
  const fieldResolvers = {};
3201
3458
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
@@ -3527,7 +3784,16 @@ var generateDelete3 = (db, tableName, table, filterArgs, fieldName, typeName, fi
3527
3784
  };
3528
3785
  };
3529
3786
  var generateSchemaData3 = (db, schema, relations, options) => {
3530
- const { relationsDepthLimit, prefixes, suffixes, conflictDoNothing, typeNameMapper, shouldEagerLoad, features } = options;
3787
+ const {
3788
+ relationsDepthLimit,
3789
+ prefixes,
3790
+ suffixes,
3791
+ conflictDoNothing,
3792
+ typeNameMapper,
3793
+ shouldEagerLoad,
3794
+ features,
3795
+ complexity
3796
+ } = options;
3531
3797
  const rawSchema = schema;
3532
3798
  const schemaEntries = Object.entries(rawSchema);
3533
3799
  const tableEntries = schemaEntries.filter(([_key, value]) => (0, import_drizzle_orm7.is)(value, import_sqlite_core2.SQLiteTable));
@@ -3551,7 +3817,8 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3551
3817
  orderTypeCache: /* @__PURE__ */ new WeakMap(),
3552
3818
  filterTypeCache: /* @__PURE__ */ new WeakMap(),
3553
3819
  listRelationFilterCache: /* @__PURE__ */ new Map(),
3554
- aggregateTypeCache: /* @__PURE__ */ new Map()
3820
+ aggregateTypeCache: /* @__PURE__ */ new Map(),
3821
+ complexity
3555
3822
  };
3556
3823
  const relationAggregateFactory = features.relationAggregates ? createRelationAggregateFactory(db, tables, cacheCtx, typeNameMapper, filterCtx) : void 0;
3557
3824
  const queries = {};
@@ -3584,6 +3851,7 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3584
3851
  listFieldName,
3585
3852
  singleFieldName,
3586
3853
  aggregateFieldName,
3854
+ groupByFieldName,
3587
3855
  createArrayFieldName,
3588
3856
  createSingleFieldName,
3589
3857
  upsertArrayFieldName,
@@ -3711,10 +3979,25 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3711
3979
  tableFilters,
3712
3980
  filterCtx
3713
3981
  ) : void 0;
3982
+ const groupByType = features.aggregates && features.groupBy ? generateGroupByType(schema[tableName], tableName, typeName, cacheCtx) : void 0;
3983
+ const groupByEnum = groupByType ? generateGroupByEnum(schema[tableName], tableName, typeName) : void 0;
3984
+ const havingInput = groupByEnum ? generateHavingInput(schema[tableName], tableName, typeName) : void 0;
3985
+ const groupByGenerated = groupByType && groupByEnum && havingInput ? generateGroupBy(
3986
+ db,
3987
+ tableName,
3988
+ schema[tableName],
3989
+ typeName,
3990
+ groupByFieldName,
3991
+ tableFilters,
3992
+ groupByEnum,
3993
+ havingInput,
3994
+ filterCtx
3995
+ ) : void 0;
3714
3996
  queries[selectArrGenerated.name] = {
3715
3997
  type: selectArrOutput,
3716
3998
  args: selectArrGenerated.args,
3717
- resolve: selectArrGenerated.resolver
3999
+ resolve: selectArrGenerated.resolver,
4000
+ ...complexity ? { extensions: { complexity: listFieldComplexity(complexity) } } : {}
3718
4001
  };
3719
4002
  queries[selectSingleGenerated.name] = {
3720
4003
  type: selectSingleOutput,
@@ -3725,7 +4008,16 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3725
4008
  queries[aggregateGenerated.name] = {
3726
4009
  type: new import_graphql8.GraphQLNonNull(aggregateType),
3727
4010
  args: aggregateGenerated.args,
3728
- resolve: aggregateGenerated.resolver
4011
+ resolve: aggregateGenerated.resolver,
4012
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
4013
+ };
4014
+ }
4015
+ if (groupByGenerated && groupByType) {
4016
+ queries[groupByGenerated.name] = {
4017
+ type: new import_graphql8.GraphQLNonNull(new import_graphql8.GraphQLList(new import_graphql8.GraphQLNonNull(groupByType))),
4018
+ args: groupByGenerated.args,
4019
+ resolve: groupByGenerated.resolver,
4020
+ ...complexity ? { extensions: { complexity: aggregateFieldComplexity(complexity) } } : {}
3729
4021
  };
3730
4022
  }
3731
4023
  if (insertArrGenerated) {
@@ -3786,6 +4078,10 @@ var generateSchemaData3 = (db, schema, relations, options) => {
3786
4078
  if (aggregateType) {
3787
4079
  outputs[aggregateType.name] = aggregateType;
3788
4080
  }
4081
+ if (groupByType && havingInput) {
4082
+ outputs[groupByType.name] = groupByType;
4083
+ inputs[havingInput.name] = havingInput;
4084
+ }
3789
4085
  }
3790
4086
  const fieldResolvers = {};
3791
4087
  for (const [tableName, tableRelations] of Object.entries(namedRelations)) {
@@ -3828,6 +4124,7 @@ var buildSchema = (db, config) => {
3828
4124
  const typeNameMapper = config?.typeNameMapper;
3829
4125
  const features = {
3830
4126
  aggregates: config?.features?.aggregates ?? true,
4127
+ groupBy: config?.features?.groupBy ?? true,
3831
4128
  relationAggregates: config?.features?.relationAggregates ?? true,
3832
4129
  distinct: config?.features?.distinct ?? true,
3833
4130
  insert: config?.features?.insert ?? true,
@@ -3835,6 +4132,11 @@ var buildSchema = (db, config) => {
3835
4132
  delete: config?.features?.delete ?? true,
3836
4133
  upsert: config?.features?.upsert ?? false
3837
4134
  };
4135
+ const complexityConfig = config?.complexity ?? true;
4136
+ const complexity = complexityConfig === false ? void 0 : {
4137
+ defaultListSize: (complexityConfig === true ? void 0 : complexityConfig.defaultListSize) ?? 10,
4138
+ aggregateCost: (complexityConfig === true ? void 0 : complexityConfig.aggregateCost) ?? 10
4139
+ };
3838
4140
  const eagerOpt = config?.eagerLoadRelations;
3839
4141
  const shouldEagerLoad = eagerOpt === void 0 || eagerOpt === true ? () => true : eagerOpt === false ? () => false : eagerOpt;
3840
4142
  if (!typeNameMapper && suffixes.list === suffixes.single) {
@@ -3861,7 +4163,8 @@ var buildSchema = (db, config) => {
3861
4163
  conflictDoNothing: config?.conflictDoNothing ?? false,
3862
4164
  typeNameMapper,
3863
4165
  shouldEagerLoad,
3864
- features
4166
+ features,
4167
+ complexity
3865
4168
  };
3866
4169
  let generatorOutput;
3867
4170
  if ((0, import_drizzle_orm8.is)(db, import_mysql_core3.MySqlDatabase)) {