prisma-sql 1.29.0 → 1.32.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/generator.js CHANGED
@@ -54,7 +54,7 @@ var require_package = __commonJS({
54
54
  "package.json"(exports$1, module) {
55
55
  module.exports = {
56
56
  name: "prisma-sql",
57
- version: "1.29.0",
57
+ version: "1.32.0",
58
58
  description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
59
59
  main: "dist/index.cjs",
60
60
  module: "dist/index.js",
@@ -119,7 +119,7 @@ var require_package = __commonJS({
119
119
  author: "multipliedtwice <multipliedtwice@gmail.com>",
120
120
  license: "MIT",
121
121
  dependencies: {
122
- "@dee-wan/schema-parser": "1.3.0",
122
+ "@dee-wan/schema-parser": "1.4.0",
123
123
  "@prisma/generator-helper": "^7.2.0",
124
124
  "@prisma/internals": "^7.2.0"
125
125
  },
@@ -943,14 +943,54 @@ function quote(id) {
943
943
  }
944
944
  return id;
945
945
  }
946
- function col(alias, field) {
946
+ function pickDbFieldName(field) {
947
+ const candidates = [
948
+ field == null ? void 0 : field.dbName,
949
+ field == null ? void 0 : field.columnName,
950
+ field == null ? void 0 : field.databaseName,
951
+ field == null ? void 0 : field.mappedName
952
+ ];
953
+ for (const c of candidates) {
954
+ if (typeof c === "string") {
955
+ const s = c.trim();
956
+ if (s.length > 0) return s;
957
+ }
958
+ }
959
+ return void 0;
960
+ }
961
+ function resolveColumnName(model, fieldName) {
962
+ var _a;
963
+ if (!model) return fieldName;
964
+ const f = model.fields.find((x) => (x == null ? void 0 : x.name) === fieldName);
965
+ if (!f) return fieldName;
966
+ return (_a = pickDbFieldName(f)) != null ? _a : fieldName;
967
+ }
968
+ function quoteColumn(model, fieldName) {
969
+ return quote(resolveColumnName(model, fieldName));
970
+ }
971
+ function col(alias, field, model) {
947
972
  if (isEmptyString(alias)) {
948
973
  throw new Error("col: alias is required and cannot be empty");
949
974
  }
950
975
  if (isEmptyString(field)) {
951
976
  throw new Error("col: field is required and cannot be empty");
952
977
  }
953
- return `${alias}.${quote(field)}`;
978
+ const columnName = resolveColumnName(model, field);
979
+ return `${alias}.${quote(columnName)}`;
980
+ }
981
+ function colWithAlias(alias, field, model) {
982
+ if (isEmptyString(alias)) {
983
+ throw new Error("colWithAlias: alias is required and cannot be empty");
984
+ }
985
+ if (isEmptyString(field)) {
986
+ throw new Error("colWithAlias: field is required and cannot be empty");
987
+ }
988
+ const columnName = resolveColumnName(model, field);
989
+ const columnRef = `${alias}.${quote(columnName)}`;
990
+ if (columnName !== field) {
991
+ return `${columnRef} AS ${quote(field)}`;
992
+ }
993
+ return columnRef;
954
994
  }
955
995
  function sqlStringLiteral(value) {
956
996
  if (containsControlChars(value)) {
@@ -1053,7 +1093,7 @@ function getReferenceFieldNames(field, foreignKeyCount) {
1053
1093
  if (refs.length !== foreignKeyCount) return [];
1054
1094
  return refs;
1055
1095
  }
1056
- function joinCondition(field, parentAlias, childAlias) {
1096
+ function joinCondition(field, parentModel, childModel, parentAlias, childAlias) {
1057
1097
  const fkFields = normalizeKeyList(field.foreignKey);
1058
1098
  if (fkFields.length === 0) {
1059
1099
  throw createError(
@@ -1072,8 +1112,8 @@ function joinCondition(field, parentAlias, childAlias) {
1072
1112
  for (let i = 0; i < fkFields.length; i++) {
1073
1113
  const fk = fkFields[i];
1074
1114
  const ref = refFields[i];
1075
- const left = field.isForeignKeyLocal ? `${childAlias}.${quote(ref)}` : `${childAlias}.${quote(fk)}`;
1076
- const right = field.isForeignKeyLocal ? `${parentAlias}.${quote(fk)}` : `${parentAlias}.${quote(ref)}`;
1115
+ const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, ref)}` : `${childAlias}.${quoteColumn(childModel, fk)}`;
1116
+ const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, fk)}` : `${parentAlias}.${quoteColumn(parentModel, ref)}`;
1077
1117
  parts.push(`${left} = ${right}`);
1078
1118
  }
1079
1119
  return parts.length === 1 ? parts[0] : `(${parts.join(" AND ")})`;
@@ -1678,7 +1718,7 @@ function buildRelation(fieldName, value, ctx, whereBuilder) {
1678
1718
  ctx.dialect
1679
1719
  );
1680
1720
  const relAlias = ctx.aliasGen.next(fieldName);
1681
- const join3 = joinCondition(field, ctx.alias, relAlias);
1721
+ const join3 = joinCondition(field, ctx.model, relModel, ctx.alias, relAlias);
1682
1722
  const args = {
1683
1723
  fieldName,
1684
1724
  value,
@@ -2423,12 +2463,12 @@ function readSkipTake(relArgs) {
2423
2463
  const takeVal = hasTake ? normalizeIntegerOrDynamic("take", obj.take) : void 0;
2424
2464
  return { hasSkip, hasTake, skipVal, takeVal };
2425
2465
  }
2426
- function buildOrderByFragment(entries, alias, dialect) {
2466
+ function buildOrderByFragment(entries, alias, dialect, model) {
2427
2467
  if (entries.length === 0) return "";
2428
2468
  const out = [];
2429
2469
  for (const e of entries) {
2430
2470
  const dir = e.direction.toUpperCase();
2431
- const c = col(alias, e.field);
2471
+ const c = col(alias, e.field, model);
2432
2472
  if (dialect === "postgres") {
2433
2473
  const nulls = isNotNullish(e.nulls) ? ` NULLS ${e.nulls.toUpperCase()}` : "";
2434
2474
  out.push(`${c} ${dir}${nulls}`);
@@ -2463,7 +2503,7 @@ function ensureCursorFieldsInOrder(orderEntries, cursorEntries) {
2463
2503
  }
2464
2504
  return out;
2465
2505
  }
2466
- function buildCursorFilterParts(cursor, cursorAlias, params) {
2506
+ function buildCursorFilterParts(cursor, cursorAlias, params, model) {
2467
2507
  const entries = Object.entries(cursor);
2468
2508
  if (entries.length === 0) {
2469
2509
  throw new Error("cursor must have at least one field");
@@ -2485,8 +2525,9 @@ function buildCursorFilterParts(cursor, cursorAlias, params) {
2485
2525
  placeholdersByField
2486
2526
  };
2487
2527
  }
2488
- function cursorValueExpr(tableName, cursorAlias, cursorWhereSql, field) {
2489
- return `(SELECT ${cursorAlias}.${quote(field)} ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
2528
+ function cursorValueExpr(tableName, cursorAlias, cursorWhereSql, field, model) {
2529
+ const colName = quote(field);
2530
+ return `(SELECT ${cursorAlias}.${colName} ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
2490
2531
  }
2491
2532
  function buildCursorRowExistsExpr(tableName, cursorAlias, cursorWhereSql) {
2492
2533
  return `EXISTS (${SQL_TEMPLATES.SELECT} 1 ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
@@ -2501,10 +2542,10 @@ function buildCursorInequalityExpr(columnExpr, direction, nulls, valueExpr) {
2501
2542
  }
2502
2543
  return `(CASE WHEN ${valueExpr} IS NULL THEN 0=1 ELSE ((${columnExpr} ${op} ${valueExpr}) OR (${columnExpr} IS NULL)) END)`;
2503
2544
  }
2504
- function buildOuterCursorMatch(cursor, outerAlias, placeholdersByField, params) {
2545
+ function buildOuterCursorMatch(cursor, outerAlias, placeholdersByField, params, model) {
2505
2546
  const parts = [];
2506
2547
  for (const [field, value] of Object.entries(cursor)) {
2507
- const c = col(outerAlias, field);
2548
+ const c = col(outerAlias, field, model);
2508
2549
  if (value === null) {
2509
2550
  parts.push(`${c} IS NULL`);
2510
2551
  continue;
@@ -2537,7 +2578,7 @@ function buildOrderEntries(orderBy) {
2537
2578
  }
2538
2579
  return entries;
2539
2580
  }
2540
- function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect) {
2581
+ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect, model) {
2541
2582
  var _a;
2542
2583
  const d = dialect != null ? dialect : getGlobalDialect();
2543
2584
  const cursorEntries = Object.entries(cursor);
@@ -2564,20 +2605,29 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
2564
2605
  cursor,
2565
2606
  alias,
2566
2607
  placeholdersByField,
2567
- params
2608
+ params,
2609
+ model
2568
2610
  );
2569
2611
  const orClauses = [];
2570
2612
  for (let level = 0; level < orderEntries.length; level++) {
2571
2613
  const andParts = [];
2572
2614
  for (let i = 0; i < level; i++) {
2573
2615
  const e2 = orderEntries[i];
2574
- const c2 = col(alias, e2.field);
2575
- const v2 = cursorValueExpr(tableName, cursorAlias, cursorWhereSql, e2.field);
2616
+ const c2 = col(alias, e2.field, model);
2617
+ const v2 = cursorValueExpr(
2618
+ tableName,
2619
+ cursorAlias,
2620
+ cursorWhereSql,
2621
+ e2.field);
2576
2622
  andParts.push(buildCursorEqualityExpr(c2, v2));
2577
2623
  }
2578
2624
  const e = orderEntries[level];
2579
- const c = col(alias, e.field);
2580
- const v = cursorValueExpr(tableName, cursorAlias, cursorWhereSql, e.field);
2625
+ const c = col(alias, e.field, model);
2626
+ const v = cursorValueExpr(
2627
+ tableName,
2628
+ cursorAlias,
2629
+ cursorWhereSql,
2630
+ e.field);
2581
2631
  const nulls = (_a = e.nulls) != null ? _a : defaultNullsFor(d, e.direction);
2582
2632
  andParts.push(buildCursorInequalityExpr(c, e.direction, nulls, v));
2583
2633
  orClauses.push(`(${andParts.join(SQL_SEPARATORS.CONDITION_AND)})`);
@@ -2585,15 +2635,15 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
2585
2635
  const exclusive = orClauses.join(SQL_SEPARATORS.CONDITION_OR);
2586
2636
  return `(${existsExpr} ${SQL_SEPARATORS.CONDITION_AND} ((${exclusive})${SQL_SEPARATORS.CONDITION_OR}(${outerCursorMatch})))`;
2587
2637
  }
2588
- function buildOrderBy(orderBy, alias, dialect) {
2638
+ function buildOrderBy(orderBy, alias, dialect, model) {
2589
2639
  const entries = buildOrderEntries(orderBy);
2590
2640
  if (entries.length === 0) return "";
2591
2641
  const d = dialect != null ? dialect : getGlobalDialect();
2592
- return buildOrderByFragment(entries, alias, d);
2642
+ return buildOrderByFragment(entries, alias, d, model);
2593
2643
  }
2594
- function buildOrderByClause(args, alias, dialect) {
2644
+ function buildOrderByClause(args, alias, dialect, model) {
2595
2645
  if (!isNotNullish(args.orderBy)) return "";
2596
- const result = buildOrderBy(args.orderBy, alias, dialect);
2646
+ const result = buildOrderBy(args.orderBy, alias, dialect, model);
2597
2647
  if (!isNonEmptyString(result)) {
2598
2648
  throw new Error(
2599
2649
  "buildOrderByClause: orderBy specified but produced empty result"
@@ -2678,7 +2728,7 @@ function buildDefaultScalarFields(model, alias) {
2678
2728
  for (const f of model.fields) {
2679
2729
  if (f.isRelation) continue;
2680
2730
  const excluded = excludedPrefixes.some((p) => f.name.startsWith(p));
2681
- if (!excluded) out.push(col(alias, f.name));
2731
+ if (!excluded) out.push(colWithAlias(alias, f.name, model));
2682
2732
  }
2683
2733
  if (!isNonEmptyArray(out)) {
2684
2734
  throw new Error(`Model ${model.name} has no selectable fields`);
@@ -2696,7 +2746,9 @@ function buildSelectFields(args, model, alias) {
2696
2746
  const entries = toSelectEntries(args.select);
2697
2747
  validateSelectKeys(entries, scalarSet, relationSet);
2698
2748
  const { scalarSelected, hasRelationSelection, hasCount } = analyzeSelectEntries(entries, scalarSet, relationSet);
2699
- const fields = scalarSelected.map((field) => col(alias, field));
2749
+ const fields = scalarSelected.map(
2750
+ (field) => colWithAlias(alias, field, model)
2751
+ );
2700
2752
  if (!isNonEmptyArray(fields)) {
2701
2753
  if (hasRelationSelection) return "";
2702
2754
  if (!hasCount) {
@@ -2712,7 +2764,9 @@ function buildAllScalarParts(model, alias) {
2712
2764
  }
2713
2765
  const parts = [];
2714
2766
  for (const field of scalarFields) {
2715
- parts.push(`${sqlStringLiteral(field.name)}, ${col(alias, field.name)}`);
2767
+ parts.push(
2768
+ `${sqlStringLiteral(field.name)}, ${col(alias, field.name, model)}`
2769
+ );
2716
2770
  }
2717
2771
  return parts;
2718
2772
  }
@@ -2725,12 +2779,12 @@ function validateRelationSelectKeys(entries, scalarNames, relationNames) {
2725
2779
  throw new Error(`Select contains unknown fields: ${unknown.join(", ")}`);
2726
2780
  }
2727
2781
  }
2728
- function buildSelectedScalarParts(entries, scalarNames, alias) {
2782
+ function buildSelectedScalarParts(entries, scalarNames, alias, model) {
2729
2783
  const parts = [];
2730
2784
  for (const [key, value] of entries) {
2731
2785
  if (!scalarNames.has(key)) continue;
2732
2786
  if (value === true) {
2733
- parts.push(`${sqlStringLiteral(key)}, ${col(alias, key)}`);
2787
+ parts.push(`${sqlStringLiteral(key)}, ${col(alias, key, model)}`);
2734
2788
  }
2735
2789
  }
2736
2790
  return parts;
@@ -2756,9 +2810,12 @@ function buildRelationSelect(relArgs, relModel, relAlias) {
2756
2810
  );
2757
2811
  const entries = toSelectEntries(sel);
2758
2812
  validateRelationSelectKeys(entries, scalarNames, relationNames);
2759
- return buildSelectedScalarParts(entries, scalarNames, relAlias).join(
2760
- SQL_SEPARATORS.FIELD_LIST
2761
- );
2813
+ return buildSelectedScalarParts(
2814
+ entries,
2815
+ scalarNames,
2816
+ relAlias,
2817
+ relModel
2818
+ ).join(SQL_SEPARATORS.FIELD_LIST);
2762
2819
  }
2763
2820
  return buildAllScalarParts(relModel, relAlias).join(SQL_SEPARATORS.FIELD_LIST);
2764
2821
  }
@@ -3045,8 +3102,8 @@ function limitOneSql(sql, params, skipVal, scope) {
3045
3102
  }
3046
3103
  return `${sql} ${SQL_TEMPLATES.LIMIT} 1`;
3047
3104
  }
3048
- function buildOrderBySql(finalOrderByInput, relAlias, dialect) {
3049
- return isNotNullish(finalOrderByInput) ? buildOrderBy(finalOrderByInput, relAlias, dialect) : "";
3105
+ function buildOrderBySql(finalOrderByInput, relAlias, dialect, relModel) {
3106
+ return isNotNullish(finalOrderByInput) ? buildOrderBy(finalOrderByInput, relAlias, dialect, relModel) : "";
3050
3107
  }
3051
3108
  function buildBaseSql(args) {
3052
3109
  return `${SQL_TEMPLATES.SELECT} ${args.selectExpr} ${SQL_TEMPLATES.FROM} ${args.relTable} ${args.relAlias} ${args.joins} ${SQL_TEMPLATES.WHERE} ${args.joinPredicate}${args.whereClause}`;
@@ -3133,7 +3190,13 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3133
3190
  const relTable = getRelationTableReference(relModel, ctx.dialect);
3134
3191
  const relAlias = ctx.aliasGen.next(relName);
3135
3192
  const isList = typeof field.type === "string" && field.type.endsWith("[]");
3136
- const joinPredicate = joinCondition(field, ctx.parentAlias, relAlias);
3193
+ const joinPredicate = joinCondition(
3194
+ field,
3195
+ ctx.model,
3196
+ relModel,
3197
+ ctx.parentAlias,
3198
+ relAlias
3199
+ );
3137
3200
  const whereInput = readWhereInput(relArgs);
3138
3201
  const relSelect = buildSelectWithNestedIncludes(
3139
3202
  relArgs,
@@ -3158,7 +3221,12 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3158
3221
  adjusted.orderByInput,
3159
3222
  hasPagination
3160
3223
  );
3161
- const orderBySql = buildOrderBySql(finalOrderByInput, relAlias, ctx.dialect);
3224
+ const orderBySql = buildOrderBySql(
3225
+ finalOrderByInput,
3226
+ relAlias,
3227
+ ctx.dialect,
3228
+ relModel
3229
+ );
3162
3230
  if (!isList) {
3163
3231
  const sql = buildOneToOneIncludeSql({
3164
3232
  relName,
@@ -4521,9 +4589,9 @@ function generateClient(options) {
4521
4589
  if (!modelQueries.has(method)) {
4522
4590
  modelQueries.set(method, /* @__PURE__ */ new Map());
4523
4591
  }
4524
- const methodQueries = modelQueries.get(method);
4592
+ const methodQueriesMap = modelQueries.get(method);
4525
4593
  const queryKey = createQueryKey(directive.query.processed);
4526
- methodQueries.set(queryKey, {
4594
+ methodQueriesMap.set(queryKey, {
4527
4595
  sql: sqlDirective.sql,
4528
4596
  params: sqlDirective.staticParams,
4529
4597
  dynamicKeys: sqlDirective.dynamicKeys,
@@ -4546,7 +4614,9 @@ function generateClient(options) {
4546
4614
  ),
4547
4615
  0
4548
4616
  );
4549
- console.log(`\u2713 Generated ${queries.size} models, ${totalQueries} queries`);
4617
+ console.log(
4618
+ `\u2713 Generated ${queries.size} models, ${totalQueries} prebaked queries`
4619
+ );
4550
4620
  console.log(`\u2713 Output: ${outputPath}`);
4551
4621
  });
4552
4622
  }
@@ -4569,7 +4639,10 @@ function generateCode(models, queries, dialect) {
4569
4639
  return `// Generated by @prisma-sql/generator - DO NOT EDIT
4570
4640
  import { buildSQL, transformQueryResults, type PrismaMethod } from 'prisma-sql'
4571
4641
 
4572
- const MODELS = ${JSON.stringify(cleanModels, null, 2)}
4642
+ // Export models for advanced use cases (createToSQL, etc)
4643
+ export const MODELS = ${JSON.stringify(cleanModels, null, 2)} as const
4644
+
4645
+ export type Models = typeof MODELS
4573
4646
 
4574
4647
  const QUERIES: Record<string, Record<string, Record<string, {
4575
4648
  sql: string
@@ -4581,17 +4654,14 @@ const QUERIES: Record<string, Record<string, Record<string, {
4581
4654
  const DIALECT = ${JSON.stringify(dialect)}
4582
4655
 
4583
4656
  function isDynamicParam(key: string): boolean {
4584
- // Common dynamic parameters that should be replaced with markers
4585
4657
  return key === 'skip' || key === 'take' || key === 'cursor'
4586
4658
  }
4587
4659
 
4588
4660
  function normalizeQuery(args: any): string {
4589
4661
  if (!args) return '{}'
4590
4662
 
4591
- // Clone and normalize the args
4592
4663
  const normalized = JSON.parse(JSON.stringify(args))
4593
4664
 
4594
- // Replace dynamic params with markers to match prebaked keys
4595
4665
  function replaceDynamicParams(obj: any): any {
4596
4666
  if (!obj || typeof obj !== 'object') return obj
4597
4667
 
@@ -4601,7 +4671,6 @@ function normalizeQuery(args: any): string {
4601
4671
 
4602
4672
  const result: any = {}
4603
4673
  for (const [key, value] of Object.entries(obj)) {
4604
- // Replace top-level dynamic params with markers
4605
4674
  if (isDynamicParam(key)) {
4606
4675
  result[key] = \`__DYNAMIC_\${key}__\`
4607
4676
  } else {
@@ -4613,13 +4682,11 @@ function normalizeQuery(args: any): string {
4613
4682
 
4614
4683
  const withMarkers = replaceDynamicParams(normalized)
4615
4684
 
4616
- // Remove empty objects to match prebaked keys
4617
4685
  function removeEmptyObjects(obj: any): any {
4618
4686
  if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return obj
4619
4687
 
4620
4688
  const result: any = {}
4621
4689
  for (const [key, value] of Object.entries(obj)) {
4622
- // Skip empty objects (but keep empty arrays)
4623
4690
  if (value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) {
4624
4691
  continue
4625
4692
  }
@@ -4630,7 +4697,6 @@ function normalizeQuery(args: any): string {
4630
4697
 
4631
4698
  const cleaned = removeEmptyObjects(withMarkers)
4632
4699
 
4633
- // Sort keys recursively for deterministic matching
4634
4700
  return JSON.stringify(cleaned, (key, value) => {
4635
4701
  if (value && typeof value === 'object' && !Array.isArray(value)) {
4636
4702
  const sorted: Record<string, unknown> = {}
@@ -4648,9 +4714,7 @@ function extractDynamicParams(args: any, dynamicKeys: string[]): unknown[] {
4648
4714
 
4649
4715
  for (const key of dynamicKeys) {
4650
4716
  const parts = key.split(':')
4651
-
4652
4717
  const lookupKey = parts.length === 2 ? parts[1] : key
4653
-
4654
4718
  const value = args[lookupKey]
4655
4719
 
4656
4720
  if (value === undefined) {
@@ -4677,7 +4741,7 @@ async function executeQuery(client: any, sql: string, params: unknown[]): Promis
4677
4741
  return stmt.all(...params)
4678
4742
  }
4679
4743
 
4680
- export function createExtension(config: {
4744
+ export function speedExtension(config: {
4681
4745
  postgres?: any
4682
4746
  sqlite?: any
4683
4747
  debug?: boolean
@@ -4690,10 +4754,11 @@ export function createExtension(config: {
4690
4754
  prebaked: boolean
4691
4755
  }) => void
4692
4756
  }) {
4757
+ // models is NOT a parameter - uses internal MODELS
4693
4758
  const { postgres, sqlite, debug, onQuery } = config
4694
4759
 
4695
4760
  if (!postgres && !sqlite) {
4696
- throw new Error('Extension requires postgres or sqlite client')
4761
+ throw new Error('speedExtension requires postgres or sqlite client')
4697
4762
  }
4698
4763
 
4699
4764
  const client = postgres || sqlite
@@ -4720,6 +4785,7 @@ export function createExtension(config: {
4720
4785
  params = [...prebakedQuery.params, ...extractDynamicParams(args, prebakedQuery.dynamicKeys)]
4721
4786
  prebaked = true
4722
4787
  } else {
4788
+ // Use internal MODELS directly
4723
4789
  const model = MODELS.find((m: any) => m.name === modelName)
4724
4790
 
4725
4791
  if (!model) {