prisma-sql 1.30.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/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ParamMap, DirectiveProps, Model as Model$1 } from '@dee-wan/schema-parser';
2
2
  export { convertDMMFToModels } from '@dee-wan/schema-parser';
3
+ import { DMMF } from '@prisma/generator-helper';
3
4
 
4
5
  type SqlDialect = 'postgres' | 'sqlite';
5
6
  declare function setGlobalDialect(dialect: SqlDialect): void;
@@ -64,7 +65,8 @@ interface SqlResult {
64
65
  interface SpeedExtensionConfig {
65
66
  postgres?: any;
66
67
  sqlite?: any;
67
- models: Model$1[];
68
+ models?: Model$1[];
69
+ dmmf?: DMMF.Document;
68
70
  debug?: boolean;
69
71
  allowedModels?: string[];
70
72
  onQuery?: (info: QueryInfo) => void;
@@ -77,14 +79,73 @@ interface QueryInfo {
77
79
  duration: number;
78
80
  }
79
81
  declare function buildSQL(model: Model$1, models: Model$1[], method: PrismaMethod, args: Record<string, unknown>, dialect: SqlDialect): SqlResult;
82
+ /**
83
+ * Runtime-only Prisma extension for SQL acceleration.
84
+ *
85
+ * ⚠️ RECOMMENDED: Use generated extension instead for zero overhead!
86
+ *
87
+ * @example
88
+ * // RECOMMENDED: Generated extension (no models/dmmf needed)
89
+ * import { speedExtension } from './generated/sql'
90
+ * const prisma = new PrismaClient().$extends(
91
+ * speedExtension({ postgres: sql })
92
+ * )
93
+ *
94
+ * @example
95
+ * // Runtime with pre-converted models
96
+ * import { speedExtension } from 'prisma-sql'
97
+ * import { MODELS } from './generated/sql'
98
+ * const prisma = new PrismaClient().$extends(
99
+ * speedExtension({ postgres: sql, models: MODELS })
100
+ * )
101
+ *
102
+ * @example
103
+ * // Runtime with DMMF (auto-converts on startup)
104
+ * import { speedExtension } from 'prisma-sql'
105
+ * import { Prisma } from '@prisma/client'
106
+ * const prisma = new PrismaClient().$extends(
107
+ * speedExtension({ postgres: sql, dmmf: Prisma.dmmf })
108
+ * )
109
+ */
80
110
  declare function speedExtension(config: SpeedExtensionConfig): (prisma: any) => any;
81
- declare function createToSQL(models: Model$1[], dialect: SqlDialect): (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
111
+ /**
112
+ * Create a SQL generator function from models.
113
+ *
114
+ * @example
115
+ * import { createToSQL } from 'prisma-sql'
116
+ * import { MODELS } from './generated/sql'
117
+ *
118
+ * const toSQL = createToSQL(MODELS, 'postgres')
119
+ * const { sql, params } = toSQL('User', 'findMany', {
120
+ * where: { status: 'ACTIVE' }
121
+ * })
122
+ */
123
+ declare function createToSQL(modelsOrDmmf: Model$1[] | DMMF.Document, dialect: SqlDialect): (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
82
124
  interface PrismaSQLConfig<TClient> {
83
125
  client: TClient;
84
- models: Model$1[];
126
+ models?: Model$1[];
127
+ dmmf?: DMMF.Document;
85
128
  dialect: SqlDialect;
86
129
  execute: (client: TClient, sql: string, params: unknown[]) => Promise<unknown[]>;
87
130
  }
131
+ /**
132
+ * Create a Prisma SQL client for environments where extensions aren't supported.
133
+ *
134
+ * @example
135
+ * import { createPrismaSQL } from 'prisma-sql'
136
+ * import { MODELS } from './generated/sql'
137
+ *
138
+ * const prismaSQL = createPrismaSQL({
139
+ * client: sql,
140
+ * models: MODELS,
141
+ * dialect: 'postgres',
142
+ * execute: (client, sql, params) => client.unsafe(sql, params)
143
+ * })
144
+ *
145
+ * const users = await prismaSQL.query('User', 'findMany', {
146
+ * where: { status: 'ACTIVE' }
147
+ * })
148
+ */
88
149
  declare function createPrismaSQL<TClient>(config: PrismaSQLConfig<TClient>): {
89
150
  toSQL: (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
90
151
  query: <T = unknown[]>(model: string, method: PrismaMethod, args?: Record<string, unknown>) => Promise<T>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ParamMap, DirectiveProps, Model as Model$1 } from '@dee-wan/schema-parser';
2
2
  export { convertDMMFToModels } from '@dee-wan/schema-parser';
3
+ import { DMMF } from '@prisma/generator-helper';
3
4
 
4
5
  type SqlDialect = 'postgres' | 'sqlite';
5
6
  declare function setGlobalDialect(dialect: SqlDialect): void;
@@ -64,7 +65,8 @@ interface SqlResult {
64
65
  interface SpeedExtensionConfig {
65
66
  postgres?: any;
66
67
  sqlite?: any;
67
- models: Model$1[];
68
+ models?: Model$1[];
69
+ dmmf?: DMMF.Document;
68
70
  debug?: boolean;
69
71
  allowedModels?: string[];
70
72
  onQuery?: (info: QueryInfo) => void;
@@ -77,14 +79,73 @@ interface QueryInfo {
77
79
  duration: number;
78
80
  }
79
81
  declare function buildSQL(model: Model$1, models: Model$1[], method: PrismaMethod, args: Record<string, unknown>, dialect: SqlDialect): SqlResult;
82
+ /**
83
+ * Runtime-only Prisma extension for SQL acceleration.
84
+ *
85
+ * ⚠️ RECOMMENDED: Use generated extension instead for zero overhead!
86
+ *
87
+ * @example
88
+ * // RECOMMENDED: Generated extension (no models/dmmf needed)
89
+ * import { speedExtension } from './generated/sql'
90
+ * const prisma = new PrismaClient().$extends(
91
+ * speedExtension({ postgres: sql })
92
+ * )
93
+ *
94
+ * @example
95
+ * // Runtime with pre-converted models
96
+ * import { speedExtension } from 'prisma-sql'
97
+ * import { MODELS } from './generated/sql'
98
+ * const prisma = new PrismaClient().$extends(
99
+ * speedExtension({ postgres: sql, models: MODELS })
100
+ * )
101
+ *
102
+ * @example
103
+ * // Runtime with DMMF (auto-converts on startup)
104
+ * import { speedExtension } from 'prisma-sql'
105
+ * import { Prisma } from '@prisma/client'
106
+ * const prisma = new PrismaClient().$extends(
107
+ * speedExtension({ postgres: sql, dmmf: Prisma.dmmf })
108
+ * )
109
+ */
80
110
  declare function speedExtension(config: SpeedExtensionConfig): (prisma: any) => any;
81
- declare function createToSQL(models: Model$1[], dialect: SqlDialect): (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
111
+ /**
112
+ * Create a SQL generator function from models.
113
+ *
114
+ * @example
115
+ * import { createToSQL } from 'prisma-sql'
116
+ * import { MODELS } from './generated/sql'
117
+ *
118
+ * const toSQL = createToSQL(MODELS, 'postgres')
119
+ * const { sql, params } = toSQL('User', 'findMany', {
120
+ * where: { status: 'ACTIVE' }
121
+ * })
122
+ */
123
+ declare function createToSQL(modelsOrDmmf: Model$1[] | DMMF.Document, dialect: SqlDialect): (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
82
124
  interface PrismaSQLConfig<TClient> {
83
125
  client: TClient;
84
- models: Model$1[];
126
+ models?: Model$1[];
127
+ dmmf?: DMMF.Document;
85
128
  dialect: SqlDialect;
86
129
  execute: (client: TClient, sql: string, params: unknown[]) => Promise<unknown[]>;
87
130
  }
131
+ /**
132
+ * Create a Prisma SQL client for environments where extensions aren't supported.
133
+ *
134
+ * @example
135
+ * import { createPrismaSQL } from 'prisma-sql'
136
+ * import { MODELS } from './generated/sql'
137
+ *
138
+ * const prismaSQL = createPrismaSQL({
139
+ * client: sql,
140
+ * models: MODELS,
141
+ * dialect: 'postgres',
142
+ * execute: (client, sql, params) => client.unsafe(sql, params)
143
+ * })
144
+ *
145
+ * const users = await prismaSQL.query('User', 'findMany', {
146
+ * where: { status: 'ACTIVE' }
147
+ * })
148
+ */
88
149
  declare function createPrismaSQL<TClient>(config: PrismaSQLConfig<TClient>): {
89
150
  toSQL: (model: string, method: PrismaMethod, args?: Record<string, unknown>) => SqlResult;
90
151
  query: <T = unknown[]>(model: string, method: PrismaMethod, args?: Record<string, unknown>) => Promise<T>;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { isDynamicParameter, convertDMMFToModels, extractDynamicName } from '@dee-wan/schema-parser';
1
+ import { convertDMMFToModels, isDynamicParameter, extractDynamicName } from '@dee-wan/schema-parser';
2
2
  export { convertDMMFToModels } from '@dee-wan/schema-parser';
3
3
 
4
4
  var __defProp = Object.defineProperty;
@@ -836,14 +836,54 @@ function quote(id) {
836
836
  }
837
837
  return id;
838
838
  }
839
- function col(alias, field) {
839
+ function pickDbFieldName(field) {
840
+ const candidates = [
841
+ field == null ? void 0 : field.dbName,
842
+ field == null ? void 0 : field.columnName,
843
+ field == null ? void 0 : field.databaseName,
844
+ field == null ? void 0 : field.mappedName
845
+ ];
846
+ for (const c of candidates) {
847
+ if (typeof c === "string") {
848
+ const s = c.trim();
849
+ if (s.length > 0) return s;
850
+ }
851
+ }
852
+ return void 0;
853
+ }
854
+ function resolveColumnName(model, fieldName) {
855
+ var _a;
856
+ if (!model) return fieldName;
857
+ const f = model.fields.find((x) => (x == null ? void 0 : x.name) === fieldName);
858
+ if (!f) return fieldName;
859
+ return (_a = pickDbFieldName(f)) != null ? _a : fieldName;
860
+ }
861
+ function quoteColumn(model, fieldName) {
862
+ return quote(resolveColumnName(model, fieldName));
863
+ }
864
+ function col(alias, field, model) {
840
865
  if (isEmptyString(alias)) {
841
866
  throw new Error("col: alias is required and cannot be empty");
842
867
  }
843
868
  if (isEmptyString(field)) {
844
869
  throw new Error("col: field is required and cannot be empty");
845
870
  }
846
- return `${alias}.${quote(field)}`;
871
+ const columnName = resolveColumnName(model, field);
872
+ return `${alias}.${quote(columnName)}`;
873
+ }
874
+ function colWithAlias(alias, field, model) {
875
+ if (isEmptyString(alias)) {
876
+ throw new Error("colWithAlias: alias is required and cannot be empty");
877
+ }
878
+ if (isEmptyString(field)) {
879
+ throw new Error("colWithAlias: field is required and cannot be empty");
880
+ }
881
+ const columnName = resolveColumnName(model, field);
882
+ const columnRef = `${alias}.${quote(columnName)}`;
883
+ if (columnName !== field) {
884
+ return `${columnRef} AS ${quote(field)}`;
885
+ }
886
+ return columnRef;
847
887
  }
848
888
  function sqlStringLiteral(value) {
849
889
  if (containsControlChars(value)) {
@@ -946,7 +986,7 @@ function getReferenceFieldNames(field, foreignKeyCount) {
946
986
  if (refs.length !== foreignKeyCount) return [];
947
987
  return refs;
948
988
  }
949
- function joinCondition(field, parentAlias, childAlias) {
989
+ function joinCondition(field, parentModel, childModel, parentAlias, childAlias) {
950
990
  const fkFields = normalizeKeyList(field.foreignKey);
951
991
  if (fkFields.length === 0) {
952
992
  throw createError(
@@ -965,8 +1005,8 @@ function joinCondition(field, parentAlias, childAlias) {
965
1005
  for (let i = 0; i < fkFields.length; i++) {
966
1006
  const fk = fkFields[i];
967
1007
  const ref = refFields[i];
968
- const left = field.isForeignKeyLocal ? `${childAlias}.${quote(ref)}` : `${childAlias}.${quote(fk)}`;
969
- const right = field.isForeignKeyLocal ? `${parentAlias}.${quote(fk)}` : `${parentAlias}.${quote(ref)}`;
1008
+ const left = field.isForeignKeyLocal ? `${childAlias}.${quoteColumn(childModel, ref)}` : `${childAlias}.${quoteColumn(childModel, fk)}`;
1009
+ const right = field.isForeignKeyLocal ? `${parentAlias}.${quoteColumn(parentModel, fk)}` : `${parentAlias}.${quoteColumn(parentModel, ref)}`;
970
1010
  parts.push(`${left} = ${right}`);
971
1011
  }
972
1012
  return parts.length === 1 ? parts[0] : `(${parts.join(" AND ")})`;
@@ -1571,7 +1611,7 @@ function buildRelation(fieldName, value, ctx, whereBuilder) {
1571
1611
  ctx.dialect
1572
1612
  );
1573
1613
  const relAlias = ctx.aliasGen.next(fieldName);
1574
- const join = joinCondition(field, ctx.alias, relAlias);
1614
+ const join = joinCondition(field, ctx.model, relModel, ctx.alias, relAlias);
1575
1615
  const args = {
1576
1616
  fieldName,
1577
1617
  value,
@@ -2316,12 +2356,12 @@ function readSkipTake(relArgs) {
2316
2356
  const takeVal = hasTake ? normalizeIntegerOrDynamic("take", obj.take) : void 0;
2317
2357
  return { hasSkip, hasTake, skipVal, takeVal };
2318
2358
  }
2319
- function buildOrderByFragment(entries, alias, dialect) {
2359
+ function buildOrderByFragment(entries, alias, dialect, model) {
2320
2360
  if (entries.length === 0) return "";
2321
2361
  const out = [];
2322
2362
  for (const e of entries) {
2323
2363
  const dir = e.direction.toUpperCase();
2324
- const c = col(alias, e.field);
2364
+ const c = col(alias, e.field, model);
2325
2365
  if (dialect === "postgres") {
2326
2366
  const nulls = isNotNullish(e.nulls) ? ` NULLS ${e.nulls.toUpperCase()}` : "";
2327
2367
  out.push(`${c} ${dir}${nulls}`);
@@ -2356,7 +2396,7 @@ function ensureCursorFieldsInOrder(orderEntries, cursorEntries) {
2356
2396
  }
2357
2397
  return out;
2358
2398
  }
2359
- function buildCursorFilterParts(cursor, cursorAlias, params) {
2399
+ function buildCursorFilterParts(cursor, cursorAlias, params, model) {
2360
2400
  const entries = Object.entries(cursor);
2361
2401
  if (entries.length === 0) {
2362
2402
  throw new Error("cursor must have at least one field");
@@ -2378,8 +2418,9 @@ function buildCursorFilterParts(cursor, cursorAlias, params) {
2378
2418
  placeholdersByField
2379
2419
  };
2380
2420
  }
2381
- function cursorValueExpr(tableName, cursorAlias, cursorWhereSql, field) {
2382
- return `(SELECT ${cursorAlias}.${quote(field)} ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
2421
+ function cursorValueExpr(tableName, cursorAlias, cursorWhereSql, field, model) {
2422
+ const colName = quote(field);
2423
+ return `(SELECT ${cursorAlias}.${colName} ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
2383
2424
  }
2384
2425
  function buildCursorRowExistsExpr(tableName, cursorAlias, cursorWhereSql) {
2385
2426
  return `EXISTS (${SQL_TEMPLATES.SELECT} 1 ${SQL_TEMPLATES.FROM} ${tableName} ${cursorAlias} ${SQL_TEMPLATES.WHERE} ${cursorWhereSql} ${SQL_TEMPLATES.LIMIT} 1)`;
@@ -2394,10 +2435,10 @@ function buildCursorInequalityExpr(columnExpr, direction, nulls, valueExpr) {
2394
2435
  }
2395
2436
  return `(CASE WHEN ${valueExpr} IS NULL THEN 0=1 ELSE ((${columnExpr} ${op} ${valueExpr}) OR (${columnExpr} IS NULL)) END)`;
2396
2437
  }
2397
- function buildOuterCursorMatch(cursor, outerAlias, placeholdersByField, params) {
2438
+ function buildOuterCursorMatch(cursor, outerAlias, placeholdersByField, params, model) {
2398
2439
  const parts = [];
2399
2440
  for (const [field, value] of Object.entries(cursor)) {
2400
- const c = col(outerAlias, field);
2441
+ const c = col(outerAlias, field, model);
2401
2442
  if (value === null) {
2402
2443
  parts.push(`${c} IS NULL`);
2403
2444
  continue;
@@ -2430,7 +2471,7 @@ function buildOrderEntries(orderBy) {
2430
2471
  }
2431
2472
  return entries;
2432
2473
  }
2433
- function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect) {
2474
+ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect, model) {
2434
2475
  var _a;
2435
2476
  const d = dialect != null ? dialect : getGlobalDialect();
2436
2477
  const cursorEntries = Object.entries(cursor);
@@ -2457,20 +2498,29 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
2457
2498
  cursor,
2458
2499
  alias,
2459
2500
  placeholdersByField,
2460
- params
2501
+ params,
2502
+ model
2461
2503
  );
2462
2504
  const orClauses = [];
2463
2505
  for (let level = 0; level < orderEntries.length; level++) {
2464
2506
  const andParts = [];
2465
2507
  for (let i = 0; i < level; i++) {
2466
2508
  const e2 = orderEntries[i];
2467
- const c2 = col(alias, e2.field);
2468
- const v2 = cursorValueExpr(tableName, cursorAlias, cursorWhereSql, e2.field);
2509
+ const c2 = col(alias, e2.field, model);
2510
+ const v2 = cursorValueExpr(
2511
+ tableName,
2512
+ cursorAlias,
2513
+ cursorWhereSql,
2514
+ e2.field);
2469
2515
  andParts.push(buildCursorEqualityExpr(c2, v2));
2470
2516
  }
2471
2517
  const e = orderEntries[level];
2472
- const c = col(alias, e.field);
2473
- const v = cursorValueExpr(tableName, cursorAlias, cursorWhereSql, e.field);
2518
+ const c = col(alias, e.field, model);
2519
+ const v = cursorValueExpr(
2520
+ tableName,
2521
+ cursorAlias,
2522
+ cursorWhereSql,
2523
+ e.field);
2474
2524
  const nulls = (_a = e.nulls) != null ? _a : defaultNullsFor(d, e.direction);
2475
2525
  andParts.push(buildCursorInequalityExpr(c, e.direction, nulls, v));
2476
2526
  orClauses.push(`(${andParts.join(SQL_SEPARATORS.CONDITION_AND)})`);
@@ -2478,15 +2528,15 @@ function buildCursorCondition(cursor, orderBy, tableName, alias, params, dialect
2478
2528
  const exclusive = orClauses.join(SQL_SEPARATORS.CONDITION_OR);
2479
2529
  return `(${existsExpr} ${SQL_SEPARATORS.CONDITION_AND} ((${exclusive})${SQL_SEPARATORS.CONDITION_OR}(${outerCursorMatch})))`;
2480
2530
  }
2481
- function buildOrderBy(orderBy, alias, dialect) {
2531
+ function buildOrderBy(orderBy, alias, dialect, model) {
2482
2532
  const entries = buildOrderEntries(orderBy);
2483
2533
  if (entries.length === 0) return "";
2484
2534
  const d = dialect != null ? dialect : getGlobalDialect();
2485
- return buildOrderByFragment(entries, alias, d);
2535
+ return buildOrderByFragment(entries, alias, d, model);
2486
2536
  }
2487
- function buildOrderByClause(args, alias, dialect) {
2537
+ function buildOrderByClause(args, alias, dialect, model) {
2488
2538
  if (!isNotNullish(args.orderBy)) return "";
2489
- const result = buildOrderBy(args.orderBy, alias, dialect);
2539
+ const result = buildOrderBy(args.orderBy, alias, dialect, model);
2490
2540
  if (!isNonEmptyString(result)) {
2491
2541
  throw new Error(
2492
2542
  "buildOrderByClause: orderBy specified but produced empty result"
@@ -2571,7 +2621,7 @@ function buildDefaultScalarFields(model, alias) {
2571
2621
  for (const f of model.fields) {
2572
2622
  if (f.isRelation) continue;
2573
2623
  const excluded = excludedPrefixes.some((p) => f.name.startsWith(p));
2574
- if (!excluded) out.push(col(alias, f.name));
2624
+ if (!excluded) out.push(colWithAlias(alias, f.name, model));
2575
2625
  }
2576
2626
  if (!isNonEmptyArray(out)) {
2577
2627
  throw new Error(`Model ${model.name} has no selectable fields`);
@@ -2589,7 +2639,9 @@ function buildSelectFields(args, model, alias) {
2589
2639
  const entries = toSelectEntries(args.select);
2590
2640
  validateSelectKeys(entries, scalarSet, relationSet);
2591
2641
  const { scalarSelected, hasRelationSelection, hasCount } = analyzeSelectEntries(entries, scalarSet, relationSet);
2592
- const fields = scalarSelected.map((field) => col(alias, field));
2642
+ const fields = scalarSelected.map(
2643
+ (field) => colWithAlias(alias, field, model)
2644
+ );
2593
2645
  if (!isNonEmptyArray(fields)) {
2594
2646
  if (hasRelationSelection) return "";
2595
2647
  if (!hasCount) {
@@ -2605,7 +2657,9 @@ function buildAllScalarParts(model, alias) {
2605
2657
  }
2606
2658
  const parts = [];
2607
2659
  for (const field of scalarFields) {
2608
- parts.push(`${sqlStringLiteral(field.name)}, ${col(alias, field.name)}`);
2660
+ parts.push(
2661
+ `${sqlStringLiteral(field.name)}, ${col(alias, field.name, model)}`
2662
+ );
2609
2663
  }
2610
2664
  return parts;
2611
2665
  }
@@ -2618,12 +2672,12 @@ function validateRelationSelectKeys(entries, scalarNames, relationNames) {
2618
2672
  throw new Error(`Select contains unknown fields: ${unknown.join(", ")}`);
2619
2673
  }
2620
2674
  }
2621
- function buildSelectedScalarParts(entries, scalarNames, alias) {
2675
+ function buildSelectedScalarParts(entries, scalarNames, alias, model) {
2622
2676
  const parts = [];
2623
2677
  for (const [key, value] of entries) {
2624
2678
  if (!scalarNames.has(key)) continue;
2625
2679
  if (value === true) {
2626
- parts.push(`${sqlStringLiteral(key)}, ${col(alias, key)}`);
2680
+ parts.push(`${sqlStringLiteral(key)}, ${col(alias, key, model)}`);
2627
2681
  }
2628
2682
  }
2629
2683
  return parts;
@@ -2649,9 +2703,12 @@ function buildRelationSelect(relArgs, relModel, relAlias) {
2649
2703
  );
2650
2704
  const entries = toSelectEntries(sel);
2651
2705
  validateRelationSelectKeys(entries, scalarNames, relationNames);
2652
- return buildSelectedScalarParts(entries, scalarNames, relAlias).join(
2653
- SQL_SEPARATORS.FIELD_LIST
2654
- );
2706
+ return buildSelectedScalarParts(
2707
+ entries,
2708
+ scalarNames,
2709
+ relAlias,
2710
+ relModel
2711
+ ).join(SQL_SEPARATORS.FIELD_LIST);
2655
2712
  }
2656
2713
  return buildAllScalarParts(relModel, relAlias).join(SQL_SEPARATORS.FIELD_LIST);
2657
2714
  }
@@ -2938,8 +2995,8 @@ function limitOneSql(sql, params, skipVal, scope) {
2938
2995
  }
2939
2996
  return `${sql} ${SQL_TEMPLATES.LIMIT} 1`;
2940
2997
  }
2941
- function buildOrderBySql(finalOrderByInput, relAlias, dialect) {
2942
- return isNotNullish(finalOrderByInput) ? buildOrderBy(finalOrderByInput, relAlias, dialect) : "";
2998
+ function buildOrderBySql(finalOrderByInput, relAlias, dialect, relModel) {
2999
+ return isNotNullish(finalOrderByInput) ? buildOrderBy(finalOrderByInput, relAlias, dialect, relModel) : "";
2943
3000
  }
2944
3001
  function buildBaseSql(args) {
2945
3002
  return `${SQL_TEMPLATES.SELECT} ${args.selectExpr} ${SQL_TEMPLATES.FROM} ${args.relTable} ${args.relAlias} ${args.joins} ${SQL_TEMPLATES.WHERE} ${args.joinPredicate}${args.whereClause}`;
@@ -3026,7 +3083,13 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3026
3083
  const relTable = getRelationTableReference(relModel, ctx.dialect);
3027
3084
  const relAlias = ctx.aliasGen.next(relName);
3028
3085
  const isList = typeof field.type === "string" && field.type.endsWith("[]");
3029
- const joinPredicate = joinCondition(field, ctx.parentAlias, relAlias);
3086
+ const joinPredicate = joinCondition(
3087
+ field,
3088
+ ctx.model,
3089
+ relModel,
3090
+ ctx.parentAlias,
3091
+ relAlias
3092
+ );
3030
3093
  const whereInput = readWhereInput(relArgs);
3031
3094
  const relSelect = buildSelectWithNestedIncludes(
3032
3095
  relArgs,
@@ -3051,7 +3114,12 @@ function buildSingleInclude(relName, relArgs, field, relModel, ctx) {
3051
3114
  adjusted.orderByInput,
3052
3115
  hasPagination
3053
3116
  );
3054
- const orderBySql = buildOrderBySql(finalOrderByInput, relAlias, ctx.dialect);
3117
+ const orderBySql = buildOrderBySql(
3118
+ finalOrderByInput,
3119
+ relAlias,
3120
+ ctx.dialect,
3121
+ relModel
3122
+ );
3055
3123
  if (!isList) {
3056
3124
  const sql = buildOneToOneIncludeSql({
3057
3125
  relName,
@@ -4638,7 +4706,8 @@ function speedExtension(config) {
4638
4706
  const {
4639
4707
  postgres,
4640
4708
  sqlite,
4641
- models,
4709
+ models: providedModels,
4710
+ dmmf,
4642
4711
  debug = false,
4643
4712
  allowedModels,
4644
4713
  onQuery
@@ -4651,11 +4720,19 @@ function speedExtension(config) {
4651
4720
  "speedExtension cannot use both postgres and sqlite clients"
4652
4721
  );
4653
4722
  }
4654
- if (!models || !Array.isArray(models) || models.length === 0) {
4723
+ let models;
4724
+ if (providedModels) {
4725
+ models = providedModels;
4726
+ } else if (dmmf) {
4727
+ models = convertDMMFToModels(dmmf.datamodel);
4728
+ } else {
4655
4729
  throw new Error(
4656
- "speedExtension requires models parameter. Convert DMMF first: speedExtension({ models: convertDMMFToModels(Prisma.dmmf.datamodel) })"
4730
+ 'speedExtension requires either models or dmmf parameter.\n\n\u26A0\uFE0F RECOMMENDED APPROACH:\n Use the generated extension for zero runtime overhead:\n\n import { speedExtension } from "./generated/sql"\n const prisma = new PrismaClient().$extends(\n speedExtension({ postgres: sql })\n )\n\n 1. Add generator to schema.prisma:\n generator sql {\n provider = "prisma-sql-generator"\n }\n\n 2. Run: npx prisma generate\n\n 3. Import from generated file\n\n\u274C RUNTIME-ONLY MODE:\n If you cannot use the generator, provide models or dmmf:\n\n import { speedExtension } from "prisma-sql"\n import { MODELS } from "./generated/sql"\n const prisma = new PrismaClient().$extends(\n speedExtension({ postgres: sql, models: MODELS })\n )\n\n Or with DMMF (auto-converts on startup):\n\n import { Prisma } from "@prisma/client"\n const prisma = new PrismaClient().$extends(\n speedExtension({ postgres: sql, dmmf: Prisma.dmmf })\n )'
4657
4731
  );
4658
4732
  }
4733
+ if (!Array.isArray(models) || models.length === 0) {
4734
+ throw new Error("speedExtension: models array is empty or invalid");
4735
+ }
4659
4736
  const dialect = postgres ? "postgres" : "sqlite";
4660
4737
  const client = postgres || sqlite;
4661
4738
  setGlobalDialect(dialect);
@@ -4683,7 +4760,7 @@ function speedExtension(config) {
4683
4760
  methodHandlers[method] = createMethodHandler(method);
4684
4761
  }
4685
4762
  return prisma.$extends({
4686
- name: "speed-extension",
4763
+ name: "prisma-sql-speed",
4687
4764
  client: {
4688
4765
  $original: prisma
4689
4766
  },
@@ -4709,13 +4786,22 @@ function createToSQLFunction(models, dialect) {
4709
4786
  return buildSQL(m, models, method, args, dialect);
4710
4787
  };
4711
4788
  }
4712
- function createToSQL(models, dialect) {
4789
+ function createToSQL(modelsOrDmmf, dialect) {
4790
+ const models = Array.isArray(modelsOrDmmf) ? modelsOrDmmf : convertDMMFToModels(modelsOrDmmf.datamodel);
4713
4791
  return createToSQLFunction(models, dialect);
4714
4792
  }
4715
4793
  function createPrismaSQL(config) {
4716
- const { client, models, dialect, execute } = config;
4717
- if (!models || !Array.isArray(models) || models.length === 0) {
4718
- throw new Error("createPrismaSQL requires non-empty models array");
4794
+ const { client, models: providedModels, dmmf, dialect, execute } = config;
4795
+ let models;
4796
+ if (providedModels) {
4797
+ models = providedModels;
4798
+ } else if (dmmf) {
4799
+ models = convertDMMFToModels(dmmf.datamodel);
4800
+ } else {
4801
+ throw new Error("createPrismaSQL requires either models or dmmf parameter");
4802
+ }
4803
+ if (!Array.isArray(models) || models.length === 0) {
4804
+ throw new Error("createPrismaSQL: models array is empty or invalid");
4719
4805
  }
4720
4806
  const toSQL = createToSQLFunction(models, dialect);
4721
4807
  function query(_0, _1) {