prisma-ts-select 0.0.33 → 0.1.2

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.
Files changed (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1455 -263
  3. package/dist/bin.cjs +1 -1
  4. package/dist/bin.js +1 -1
  5. package/dist/chunk-47KZVQLD.js +283 -0
  6. package/dist/chunk-54D2J5AR.cjs +291 -0
  7. package/dist/extend/dialects/index.d.ts +13 -0
  8. package/dist/extend/dialects/index.js +186 -0
  9. package/dist/extend/dialects/mysql-v6.d.ts +100 -0
  10. package/dist/extend/dialects/mysql-v6.js +152 -0
  11. package/dist/extend/dialects/mysql-v7.d.ts +6 -0
  12. package/dist/extend/dialects/mysql-v7.js +138 -0
  13. package/dist/extend/dialects/mysql.d.ts +90 -0
  14. package/dist/extend/dialects/mysql.js +156 -0
  15. package/dist/extend/dialects/postgresql-v6.d.ts +97 -0
  16. package/dist/extend/dialects/postgresql-v6.js +136 -0
  17. package/dist/extend/dialects/postgresql-v7.d.ts +97 -0
  18. package/dist/extend/dialects/postgresql-v7.js +136 -0
  19. package/dist/extend/dialects/postgresql.d.ts +89 -0
  20. package/dist/extend/dialects/postgresql.js +147 -0
  21. package/dist/extend/dialects/shared.d.ts +6 -0
  22. package/dist/extend/dialects/shared.js +5 -0
  23. package/dist/extend/dialects/sqlite.d.ts +63 -0
  24. package/dist/extend/dialects/sqlite.js +138 -0
  25. package/dist/extend/dialects/types.d.ts +12 -0
  26. package/dist/extend/dialects/types.js +4 -0
  27. package/dist/extend/extend.d.ts +342 -57
  28. package/dist/extend/extend.js +813 -161
  29. package/dist/extend/sql-expr-BaKWzJ-r.d.ts +10 -0
  30. package/dist/extend/types-D84lxYVc.d.ts +5 -0
  31. package/dist/generator.cjs +1 -1
  32. package/dist/generator.js +1 -1
  33. package/package.json +52 -41
  34. package/built/extend.cjs +0 -565
  35. package/built/extend.d.cts +0 -451
  36. package/built/extend.d.ts +0 -451
  37. package/built/extend.js +0 -563
  38. package/dist/chunk-G66FOFCO.cjs +0 -195
  39. package/dist/chunk-GBXPF5FT.js +0 -187
  40. package/dist/extend/extend.cjs +0 -277
  41. package/dist/extend/extend.d.cts +0 -222
@@ -1,26 +1,444 @@
1
1
  import { Prisma } from '@prisma/client/extension';
2
- import { match, P } from 'ts-pattern';
2
+ import { dialectContextFns, dialect } from './dialects/index.js';
3
3
 
4
- const DB = {};
5
- class DbSelect {
4
+ // src/extend.ts
5
+
6
+ // ../../node_modules/.pnpm/ts-pattern@5.3.1/node_modules/ts-pattern/dist/index.js
7
+ var t = Symbol.for("@ts-pattern/matcher");
8
+ var e = Symbol.for("@ts-pattern/isVariadic");
9
+ var n = "@ts-pattern/anonymous-select-key";
10
+ var r = (t2) => Boolean(t2 && "object" == typeof t2);
11
+ var i = (e2) => e2 && !!e2[t];
12
+ var s = (n2, o2, c2) => {
13
+ if (i(n2)) {
14
+ const e2 = n2[t](), { matched: r2, selections: i2 } = e2.match(o2);
15
+ return r2 && i2 && Object.keys(i2).forEach((t2) => c2(t2, i2[t2])), r2;
16
+ }
17
+ if (r(n2)) {
18
+ if (!r(o2)) return false;
19
+ if (Array.isArray(n2)) {
20
+ if (!Array.isArray(o2)) return false;
21
+ let t2 = [], r2 = [], a2 = [];
22
+ for (const s2 of n2.keys()) {
23
+ const o3 = n2[s2];
24
+ i(o3) && o3[e] ? a2.push(o3) : a2.length ? r2.push(o3) : t2.push(o3);
25
+ }
26
+ if (a2.length) {
27
+ if (a2.length > 1) throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");
28
+ if (o2.length < t2.length + r2.length) return false;
29
+ const e2 = o2.slice(0, t2.length), n3 = 0 === r2.length ? [] : o2.slice(-r2.length), i2 = o2.slice(t2.length, 0 === r2.length ? Infinity : -r2.length);
30
+ return t2.every((t3, n4) => s(t3, e2[n4], c2)) && r2.every((t3, e3) => s(t3, n3[e3], c2)) && (0 === a2.length || s(a2[0], i2, c2));
31
+ }
32
+ return n2.length === o2.length && n2.every((t3, e2) => s(t3, o2[e2], c2));
33
+ }
34
+ return Reflect.ownKeys(n2).every((e2) => {
35
+ const r2 = n2[e2];
36
+ return (e2 in o2 || i(a2 = r2) && "optional" === a2[t]().matcherType) && s(r2, o2[e2], c2);
37
+ var a2;
38
+ });
39
+ }
40
+ return Object.is(o2, n2);
41
+ };
42
+ var o = (e2) => {
43
+ var n2, s2, a2;
44
+ return r(e2) ? i(e2) ? null != (n2 = null == (s2 = (a2 = e2[t]()).getSelectionKeys) ? void 0 : s2.call(a2)) ? n2 : [] : Array.isArray(e2) ? c(e2, o) : c(Object.values(e2), o) : [];
45
+ };
46
+ var c = (t2, e2) => t2.reduce((t3, n2) => t3.concat(e2(n2)), []);
47
+ function a(...t2) {
48
+ if (1 === t2.length) {
49
+ const [e2] = t2;
50
+ return (t3) => s(e2, t3, () => {
51
+ });
52
+ }
53
+ if (2 === t2.length) {
54
+ const [e2, n2] = t2;
55
+ return s(e2, n2, () => {
56
+ });
57
+ }
58
+ throw new Error(`isMatching wasn't given the right number of arguments: expected 1 or 2, received ${t2.length}.`);
59
+ }
60
+ function u(t2) {
61
+ return Object.assign(t2, { optional: () => h(t2), and: (e2) => m(t2, e2), or: (e2) => d(t2, e2), select: (e2) => void 0 === e2 ? y(t2) : y(e2, t2) });
62
+ }
63
+ function l(t2) {
64
+ return Object.assign(((t3) => Object.assign(t3, { [Symbol.iterator]() {
65
+ let n2 = 0;
66
+ const r2 = [{ value: Object.assign(t3, { [e]: true }), done: false }, { done: true, value: void 0 }];
67
+ return { next: () => {
68
+ var t4;
69
+ return null != (t4 = r2[n2++]) ? t4 : r2.at(-1);
70
+ } };
71
+ } }))(t2), { optional: () => l(h(t2)), select: (e2) => l(void 0 === e2 ? y(t2) : y(e2, t2)) });
72
+ }
73
+ function h(e2) {
74
+ return u({ [t]: () => ({ match: (t2) => {
75
+ let n2 = {};
76
+ const r2 = (t3, e3) => {
77
+ n2[t3] = e3;
78
+ };
79
+ return void 0 === t2 ? (o(e2).forEach((t3) => r2(t3, void 0)), { matched: true, selections: n2 }) : { matched: s(e2, t2, r2), selections: n2 };
80
+ }, getSelectionKeys: () => o(e2), matcherType: "optional" }) });
81
+ }
82
+ var f = (t2, e2) => {
83
+ for (const n2 of t2) if (!e2(n2)) return false;
84
+ return true;
85
+ };
86
+ var g = (t2, e2) => {
87
+ for (const [n2, r2] of t2.entries()) if (!e2(r2, n2)) return false;
88
+ return true;
89
+ };
90
+ function m(...e2) {
91
+ return u({ [t]: () => ({ match: (t2) => {
92
+ let n2 = {};
93
+ const r2 = (t3, e3) => {
94
+ n2[t3] = e3;
95
+ };
96
+ return { matched: e2.every((e3) => s(e3, t2, r2)), selections: n2 };
97
+ }, getSelectionKeys: () => c(e2, o), matcherType: "and" }) });
98
+ }
99
+ function d(...e2) {
100
+ return u({ [t]: () => ({ match: (t2) => {
101
+ let n2 = {};
102
+ const r2 = (t3, e3) => {
103
+ n2[t3] = e3;
104
+ };
105
+ return c(e2, o).forEach((t3) => r2(t3, void 0)), { matched: e2.some((e3) => s(e3, t2, r2)), selections: n2 };
106
+ }, getSelectionKeys: () => c(e2, o), matcherType: "or" }) });
107
+ }
108
+ function p(e2) {
109
+ return { [t]: () => ({ match: (t2) => ({ matched: Boolean(e2(t2)) }) }) };
110
+ }
111
+ function y(...e2) {
112
+ const r2 = "string" == typeof e2[0] ? e2[0] : void 0, i2 = 2 === e2.length ? e2[1] : "string" == typeof e2[0] ? void 0 : e2[0];
113
+ return u({ [t]: () => ({ match: (t2) => {
114
+ let e3 = { [null != r2 ? r2 : n]: t2 };
115
+ return { matched: void 0 === i2 || s(i2, t2, (t3, n2) => {
116
+ e3[t3] = n2;
117
+ }), selections: e3 };
118
+ }, getSelectionKeys: () => [null != r2 ? r2 : n].concat(void 0 === i2 ? [] : o(i2)) }) });
119
+ }
120
+ function v(t2) {
121
+ return "number" == typeof t2;
122
+ }
123
+ function b(t2) {
124
+ return "string" == typeof t2;
125
+ }
126
+ function w(t2) {
127
+ return "bigint" == typeof t2;
128
+ }
129
+ var S = u(p(function(t2) {
130
+ return true;
131
+ }));
132
+ var O = S;
133
+ var j = (t2) => Object.assign(u(t2), { startsWith: (e2) => {
134
+ return j(m(t2, (n2 = e2, p((t3) => b(t3) && t3.startsWith(n2)))));
135
+ var n2;
136
+ }, endsWith: (e2) => {
137
+ return j(m(t2, (n2 = e2, p((t3) => b(t3) && t3.endsWith(n2)))));
138
+ var n2;
139
+ }, minLength: (e2) => j(m(t2, ((t3) => p((e3) => b(e3) && e3.length >= t3))(e2))), length: (e2) => j(m(t2, ((t3) => p((e3) => b(e3) && e3.length === t3))(e2))), maxLength: (e2) => j(m(t2, ((t3) => p((e3) => b(e3) && e3.length <= t3))(e2))), includes: (e2) => {
140
+ return j(m(t2, (n2 = e2, p((t3) => b(t3) && t3.includes(n2)))));
141
+ var n2;
142
+ }, regex: (e2) => {
143
+ return j(m(t2, (n2 = e2, p((t3) => b(t3) && Boolean(t3.match(n2))))));
144
+ var n2;
145
+ } });
146
+ var K = j(p(b));
147
+ var x = (t2) => Object.assign(u(t2), { between: (e2, n2) => x(m(t2, ((t3, e3) => p((n3) => v(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => x(m(t2, ((t3) => p((e3) => v(e3) && e3 < t3))(e2))), gt: (e2) => x(m(t2, ((t3) => p((e3) => v(e3) && e3 > t3))(e2))), lte: (e2) => x(m(t2, ((t3) => p((e3) => v(e3) && e3 <= t3))(e2))), gte: (e2) => x(m(t2, ((t3) => p((e3) => v(e3) && e3 >= t3))(e2))), int: () => x(m(t2, p((t3) => v(t3) && Number.isInteger(t3)))), finite: () => x(m(t2, p((t3) => v(t3) && Number.isFinite(t3)))), positive: () => x(m(t2, p((t3) => v(t3) && t3 > 0))), negative: () => x(m(t2, p((t3) => v(t3) && t3 < 0))) });
148
+ var E = x(p(v));
149
+ var A = (t2) => Object.assign(u(t2), { between: (e2, n2) => A(m(t2, ((t3, e3) => p((n3) => w(n3) && t3 <= n3 && e3 >= n3))(e2, n2))), lt: (e2) => A(m(t2, ((t3) => p((e3) => w(e3) && e3 < t3))(e2))), gt: (e2) => A(m(t2, ((t3) => p((e3) => w(e3) && e3 > t3))(e2))), lte: (e2) => A(m(t2, ((t3) => p((e3) => w(e3) && e3 <= t3))(e2))), gte: (e2) => A(m(t2, ((t3) => p((e3) => w(e3) && e3 >= t3))(e2))), positive: () => A(m(t2, p((t3) => w(t3) && t3 > 0))), negative: () => A(m(t2, p((t3) => w(t3) && t3 < 0))) });
150
+ var P = A(p(w));
151
+ var T = u(p(function(t2) {
152
+ return "boolean" == typeof t2;
153
+ }));
154
+ var B = u(p(function(t2) {
155
+ return "symbol" == typeof t2;
156
+ }));
157
+ var _ = u(p(function(t2) {
158
+ return null == t2;
159
+ }));
160
+ var k = u(p(function(t2) {
161
+ return null != t2;
162
+ }));
163
+ var N = { __proto__: null, matcher: t, optional: h, array: function(...e2) {
164
+ return l({ [t]: () => ({ match: (t2) => {
165
+ if (!Array.isArray(t2)) return { matched: false };
166
+ if (0 === e2.length) return { matched: true };
167
+ const n2 = e2[0];
168
+ let r2 = {};
169
+ if (0 === t2.length) return o(n2).forEach((t3) => {
170
+ r2[t3] = [];
171
+ }), { matched: true, selections: r2 };
172
+ const i2 = (t3, e3) => {
173
+ r2[t3] = (r2[t3] || []).concat([e3]);
174
+ };
175
+ return { matched: t2.every((t3) => s(n2, t3, i2)), selections: r2 };
176
+ }, getSelectionKeys: () => 0 === e2.length ? [] : o(e2[0]) }) });
177
+ }, set: function(...e2) {
178
+ return u({ [t]: () => ({ match: (t2) => {
179
+ if (!(t2 instanceof Set)) return { matched: false };
180
+ let n2 = {};
181
+ if (0 === t2.size) return { matched: true, selections: n2 };
182
+ if (0 === e2.length) return { matched: true };
183
+ const r2 = (t3, e3) => {
184
+ n2[t3] = (n2[t3] || []).concat([e3]);
185
+ }, i2 = e2[0];
186
+ return { matched: f(t2, (t3) => s(i2, t3, r2)), selections: n2 };
187
+ }, getSelectionKeys: () => 0 === e2.length ? [] : o(e2[0]) }) });
188
+ }, map: function(...e2) {
189
+ return u({ [t]: () => ({ match: (t2) => {
190
+ if (!(t2 instanceof Map)) return { matched: false };
191
+ let n2 = {};
192
+ if (0 === t2.size) return { matched: true, selections: n2 };
193
+ const r2 = (t3, e3) => {
194
+ n2[t3] = (n2[t3] || []).concat([e3]);
195
+ };
196
+ if (0 === e2.length) return { matched: true };
197
+ var i2;
198
+ if (1 === e2.length) throw new Error(`\`P.map\` wasn't given enough arguments. Expected (key, value), received ${null == (i2 = e2[0]) ? void 0 : i2.toString()}`);
199
+ const [o2, c2] = e2;
200
+ return { matched: g(t2, (t3, e3) => {
201
+ const n3 = s(o2, e3, r2), i3 = s(c2, t3, r2);
202
+ return n3 && i3;
203
+ }), selections: n2 };
204
+ }, getSelectionKeys: () => 0 === e2.length ? [] : [...o(e2[0]), ...o(e2[1])] }) });
205
+ }, intersection: m, union: d, not: function(e2) {
206
+ return u({ [t]: () => ({ match: (t2) => ({ matched: !s(e2, t2, () => {
207
+ }) }), getSelectionKeys: () => [], matcherType: "not" }) });
208
+ }, when: p, select: y, any: S, _: O, string: K, number: E, bigint: P, boolean: T, symbol: B, nullish: _, nonNullable: k, instanceOf: function(t2) {
209
+ return u(p(/* @__PURE__ */ function(t3) {
210
+ return (e2) => e2 instanceof t3;
211
+ }(t2)));
212
+ }, shape: function(t2) {
213
+ return u(p(a(t2)));
214
+ } };
215
+ var W = class extends Error {
216
+ constructor(t2) {
217
+ let e2;
218
+ try {
219
+ e2 = JSON.stringify(t2);
220
+ } catch (n2) {
221
+ e2 = t2;
222
+ }
223
+ super(`Pattern matching error: no pattern matches value ${e2}`), this.input = void 0, this.input = t2;
224
+ }
225
+ };
226
+ var $ = { matched: false, value: void 0 };
227
+ function z(t2) {
228
+ return new I(t2, $);
229
+ }
230
+ var I = class _I {
231
+ constructor(t2, e2) {
232
+ this.input = void 0, this.state = void 0, this.input = t2, this.state = e2;
233
+ }
234
+ with(...t2) {
235
+ if (this.state.matched) return this;
236
+ const e2 = t2[t2.length - 1], r2 = [t2[0]];
237
+ let i2;
238
+ 3 === t2.length && "function" == typeof t2[1] ? i2 = t2[1] : t2.length > 2 && r2.push(...t2.slice(1, t2.length - 1));
239
+ let o2 = false, c2 = {};
240
+ const a2 = (t3, e3) => {
241
+ o2 = true, c2[t3] = e3;
242
+ }, u2 = !r2.some((t3) => s(t3, this.input, a2)) || i2 && !Boolean(i2(this.input)) ? $ : { matched: true, value: e2(o2 ? n in c2 ? c2[n] : c2 : this.input, this.input) };
243
+ return new _I(this.input, u2);
244
+ }
245
+ when(t2, e2) {
246
+ if (this.state.matched) return this;
247
+ const n2 = Boolean(t2(this.input));
248
+ return new _I(this.input, n2 ? { matched: true, value: e2(this.input, this.input) } : $);
249
+ }
250
+ otherwise(t2) {
251
+ return this.state.matched ? this.state.value : t2(this.input);
252
+ }
253
+ exhaustive() {
254
+ if (this.state.matched) return this.state.value;
255
+ throw new W(this.input);
256
+ }
257
+ run() {
258
+ return this.exhaustive();
259
+ }
260
+ returnType() {
261
+ return this;
262
+ }
263
+ };
264
+
265
+ // src/dialects/shared.ts
266
+ var esc = (s2) => s2.replace(/'/g, "''");
267
+
268
+ // src/sql-expr.ts
269
+ function sqlExpr(sql) {
270
+ return { sql, toString() {
271
+ return sql;
272
+ } };
273
+ }
274
+ function lit(value) {
275
+ if (value === null) return sqlExpr("NULL");
276
+ if (typeof value === "boolean") return sqlExpr(value ? "1" : "0");
277
+ if (typeof value === "string") return sqlExpr(`'${value.replace(/'/g, "''")}'`);
278
+ return sqlExpr(String(value));
279
+ }
280
+ function resolveArg(arg, quoteFn) {
281
+ if (typeof arg !== "string") return arg.sql;
282
+ return quoteFn(arg);
283
+ }
284
+
285
+ // src/extend.ts
286
+ var DB = {};
287
+ var DbSelect = class {
6
288
  constructor(db) {
7
289
  this.db = db;
8
290
  }
9
- from(database) {
10
- return new _fJoin(this.db, { database, selects: [] });
291
+ from(baseTable, alias) {
292
+ return new _fJoin(this.db, {
293
+ tables: [{
294
+ table: baseTable,
295
+ alias
296
+ }],
297
+ selects: []
298
+ });
299
+ }
300
+ };
301
+ function applyCondition(quotedField, value) {
302
+ if (typeof value === "object" && value !== null && !Array.isArray(value) && "op" in value) {
303
+ const opObj = value;
304
+ switch (opObj.op) {
305
+ case "IN":
306
+ case "NOT IN": {
307
+ const valuesList = opObj.values.map((v2) => typeof v2 === "string" ? `'${esc(v2)}'` : v2).join(", ");
308
+ return `${quotedField} ${opObj.op} (${valuesList})`;
309
+ }
310
+ case "BETWEEN": {
311
+ const [start, end] = opObj.values;
312
+ return `${quotedField} BETWEEN ${typeof start === "string" ? `'${esc(start)}'` : start} AND ${typeof end === "string" ? `'${esc(end)}'` : end}`;
313
+ }
314
+ case "LIKE":
315
+ case "NOT LIKE":
316
+ return `${quotedField} ${opObj.op} '${esc(opObj.value)}'`;
317
+ case "IS NULL":
318
+ case "IS NOT NULL":
319
+ return `${quotedField} ${opObj.op}`;
320
+ case ">":
321
+ case ">=":
322
+ case "<":
323
+ case "<=":
324
+ case "!=":
325
+ case "=":
326
+ return `${quotedField} ${opObj.op} ${typeof opObj.value === "string" ? `'${esc(opObj.value)}'` : opObj.value}`;
327
+ default:
328
+ throw new Error(`Unsupported operation: ${opObj.op}`);
329
+ }
330
+ } else if (value === null) {
331
+ return `${quotedField} IS NULL`;
332
+ } else if (Array.isArray(value)) {
333
+ if (value.length === 0) throw new Error(`empty array is not allowed for field "${quotedField}"`);
334
+ if (typeof value[0] === "object" && value[0] !== null && "op" in value[0]) {
335
+ const parts = value.map((opObj) => applyCondition(quotedField, opObj));
336
+ return parts.length === 1 ? parts[0] : "(" + parts.join(" OR ") + ")";
337
+ }
338
+ const valuesList = value.map((v2) => typeof v2 === "string" ? `'${esc(v2)}'` : v2).join(", ");
339
+ return `${quotedField} IN (${valuesList})`;
340
+ } else {
341
+ return `${quotedField} = ${typeof value === "string" ? `'${esc(value)}'` : value}`;
342
+ }
343
+ }
344
+ function processConditions(condition, formatted = false) {
345
+ const r2 = Object.keys(condition).map((field) => {
346
+ const value = condition[field];
347
+ const quotedField = dialect.quoteQualifiedColumn(String(field));
348
+ return applyCondition(quotedField, value);
349
+ });
350
+ return r2.length === 1 ? r2[0].trim() : "(" + r2.join(" AND " + (formatted ? "\n" : "")).trim() + ")";
351
+ }
352
+ function processCriteria(main, joinType = "AND", formatted = false) {
353
+ const results = [];
354
+ for (const criteria of main) {
355
+ if (typeof criteria === "string") {
356
+ results.push(criteria);
357
+ continue;
358
+ }
359
+ let toProcess = {};
360
+ const processPending = () => {
361
+ if (Object.keys(toProcess).length > 0) {
362
+ results.push(processConditions(toProcess, formatted));
363
+ toProcess = {};
364
+ }
365
+ };
366
+ for (const criterion in criteria) {
367
+ const r2 = z(criterion).returnType().with("$AND", (criterion2) => {
368
+ processPending();
369
+ return "(" + //@ts-expect-error criterion
370
+ processCriteria(criteria[criterion2], "AND", formatted) + ")";
371
+ }).with("$OR", (criterion2) => {
372
+ processPending();
373
+ return "(" + //@ts-expect-error criterion
374
+ processCriteria(criteria[criterion2], "OR", formatted) + ")";
375
+ }).with("$NOT", (criterion2) => {
376
+ processPending();
377
+ return "(NOT(" + //@ts-expect-error criterion
378
+ processCriteria(criteria[criterion2], "AND", formatted) + "))";
379
+ }).with("$NOR", (criterion2) => {
380
+ processPending();
381
+ return "(NOT(" + //@ts-expect-error criterion
382
+ processCriteria(criteria[criterion2], "OR", formatted) + "))";
383
+ }).with(N.string, (key) => {
384
+ toProcess[key] = criteria[key];
385
+ return "";
386
+ }).exhaustive();
387
+ if (r2) results.push(r2);
388
+ }
389
+ processPending();
11
390
  }
391
+ return results.join((formatted ? "\n" : " ") + joinType + (formatted ? "\n" : " ")).trim();
12
392
  }
13
- class _fRun {
393
+ function processExprPairs(pairs) {
394
+ const parts = pairs.map(([expr, value]) => applyCondition(expr.sql, value));
395
+ return parts.length === 1 ? parts[0] : parts.join(" AND ");
396
+ }
397
+ var _fRun = class {
14
398
  constructor(db, values) {
15
399
  this.db = db;
16
400
  this.values = values;
17
401
  this.values.limit = typeof this.values.limit === "number" ? this.values.limit : void 0;
18
402
  this.values.offset = typeof this.values.offset === "number" ? this.values.offset : void 0;
19
403
  }
20
- run() {
21
- return this.db.$queryRawUnsafe(
404
+ async run() {
405
+ const results = await this.db.$queryRawUnsafe(
22
406
  this.getSQL()
23
407
  );
408
+ if (dialect.needsBooleanCoercion()) {
409
+ return results.map((row) => {
410
+ const coerced = { ...row };
411
+ for (const key in coerced) {
412
+ const value = coerced[key];
413
+ if (typeof value !== "number" || value !== 0 && value !== 1) continue;
414
+ const parts = key.split(".");
415
+ let table;
416
+ let column;
417
+ if (parts.length === 2 && parts[0] && parts[1]) {
418
+ table = parts[0];
419
+ column = parts[1];
420
+ } else {
421
+ column = key;
422
+ let foundTable;
423
+ for (const tableObj of this.values.tables) {
424
+ const tableName = tableObj.table;
425
+ if (DB[tableName]?.fields[column]) {
426
+ foundTable = tableName;
427
+ break;
428
+ }
429
+ }
430
+ if (!foundTable) continue;
431
+ table = foundTable;
432
+ }
433
+ const fieldType = DB[table]?.fields[column];
434
+ if (fieldType && fieldType.replace("?", "") === "Boolean") {
435
+ coerced[key] = value === 1;
436
+ }
437
+ }
438
+ return coerced;
439
+ });
440
+ }
441
+ return results;
24
442
  }
25
443
  getTables() {
26
444
  return {};
@@ -28,186 +446,264 @@ class _fRun {
28
446
  getFields() {
29
447
  return {};
30
448
  }
449
+ getResultType() {
450
+ return {};
451
+ }
31
452
  getSQL(formatted = false) {
32
- function processCondition(condition, formatted2) {
33
- return "(" + Object.keys(condition).map((field) => {
34
- const value = condition[field];
35
- if (typeof value === "object" && value !== null && !Array.isArray(value) && "op" in value) {
36
- switch (value.op) {
37
- case "IN":
38
- case "NOT IN":
39
- const valuesList = value.values.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
40
- return `${String(field)} ${value.op} (${valuesList})`;
41
- case "BETWEEN":
42
- if (value.values.length > 2) throw new Error("Too many items supplied to op BETWEEN");
43
- const [start, end] = value.values;
44
- return `${String(field)} BETWEEN ${typeof start === "string" ? `'${start}'` : start} AND ${typeof end === "string" ? `'${end}'` : end}`;
45
- case "LIKE":
46
- case "NOT LIKE":
47
- return `${String(field)} ${value.op} '${value.value}'`;
48
- case "IS NULL":
49
- case "IS NOT NULL":
50
- return `${String(field)} ${value.op}`;
51
- case ">":
52
- case ">=":
53
- case "<":
54
- case "<=":
55
- case "!=":
56
- return `${String(field)} ${value.op} ${typeof value.value === "string" ? `'${value.value}'` : value.value}`;
57
- default:
58
- throw new Error(`Unsupported operation: ${value.op}`);
59
- }
60
- } else if (Array.isArray(value)) {
61
- const valuesList = value.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
62
- return `${String(field)} IN (${valuesList})`;
63
- } else if (value === null) {
64
- return `${String(field)} IS NULL`;
65
- } else {
66
- return `${String(field)} = ${typeof value === "string" ? `'${value}'` : value}`;
67
- }
68
- }).join(" AND " + (" ")) + " )";
69
- }
70
- function processCriteria(main, joinType = "AND", formatted2 = false) {
71
- const results = [];
72
- for (const criteria of main) {
73
- if (typeof criteria === "string") {
74
- results.push(criteria);
75
- continue;
76
- }
77
- for (const criterion in criteria) {
78
- results.push(match(criterion).returnType().with("$AND", (criterion2) => {
79
- return "(" + //@ts-expect-error criterion
80
- processCriteria(criteria[criterion2], "AND", formatted2) + ")";
81
- }).with("$OR", (criterion2) => {
82
- return "(" + //@ts-expect-error criterion
83
- processCriteria(criteria[criterion2], "OR", formatted2) + ")";
84
- }).with("$NOT", (criterion2) => {
85
- return "(NOT(" + //@ts-expect-error criterion
86
- processCriteria(criteria[criterion2], "AND", formatted2) + "))";
87
- }).with("$NOR", (criterion2) => {
88
- return "(NOT(" + //@ts-expect-error criterion
89
- processCriteria(criteria[criterion2], "OR", formatted2) + "))";
90
- }).with(P.string, () => {
91
- return processCondition(criteria);
92
- }).exhaustive());
93
- }
94
- }
95
- return results.join((formatted2 ? "\n" : " ") + joinType + (formatted2 ? "\n" : " "));
96
- }
453
+ const withClause = this.values.withs?.length ? `WITH ${this.values.withs.map(
454
+ (w2) => `${dialect.quoteTableIdentifier(w2.name, false)} AS (${w2.sql})`
455
+ ).join(", ")}` : "";
97
456
  const whereClause = this.values.where !== void 0 ? processCriteria(this.values.where, "AND", formatted) : void 0;
98
457
  const havingClause = this.values.having !== void 0 ? processCriteria(this.values.having, "AND", formatted) : void 0;
458
+ const [base, ...joins] = this.values.tables;
459
+ const quotedTable = dialect.quoteTableIdentifier(base.table, false);
460
+ const baseTable = base.alias ? `${quotedTable} AS ${dialect.quoteTableIdentifier(base.alias, true)}` : quotedTable;
99
461
  return [
462
+ withClause,
100
463
  this.values.selects.length === 0 ? "" : "SELECT " + (this.values.selectDistinct === true ? "DISTINCT " : "") + this.values.selects.join(", "),
101
- `FROM ${this.values.database}`,
102
- this.values.tables?.map(({
464
+ `FROM ${baseTable}`,
465
+ joins.map(({
103
466
  table,
104
467
  local,
105
- remote
106
- }) => `JOIN ${table} ON ${local} = ${remote}`).join(formatted ? "\n" : " ") ?? "",
468
+ remote,
469
+ alias,
470
+ joinWhere,
471
+ joinType
472
+ }) => {
473
+ const quotedTable2 = dialect.quoteTableIdentifier(table, false);
474
+ const tableStr = alias ? `${quotedTable2} AS ${dialect.quoteTableIdentifier(alias, true)}` : quotedTable2;
475
+ const typePrefix = joinType ? `${joinType} ` : "";
476
+ if (joinType === "CROSS") {
477
+ return `${typePrefix}JOIN ${tableStr}`;
478
+ }
479
+ const tLocal = (alias || table) + "." + local;
480
+ const quotedLocal = dialect.quoteQualifiedColumn(tLocal);
481
+ const quotedRemote = dialect.quoteQualifiedColumn(remote);
482
+ const onClause = `${quotedLocal} = ${quotedRemote}`;
483
+ const joinWhereStr = joinWhere ? ` AND ${processCriteria(joinWhere, "AND", formatted)}` : "";
484
+ return `${typePrefix}JOIN ${tableStr} ON ${onClause}${joinWhereStr}`;
485
+ }).join(formatted ? "\n" : " ") ?? "",
107
486
  !whereClause ? "" : `WHERE ${whereClause}`,
108
- !this.values.groupBy?.length ? "" : `GROUP BY ${this.values.groupBy.join(", ")}`,
487
+ !this.values.groupBy?.length ? "" : `GROUP BY ${this.values.groupBy.map((g2) => dialect.quoteQualifiedColumn(g2)).join(", ")}`,
109
488
  !havingClause ? "" : `HAVING ${havingClause}`,
110
- !(this.values.orderBy && this.values.orderBy.length > 0) ? "" : "ORDER BY " + this.values.orderBy.join(", "),
489
+ !(this.values.orderBy && this.values.orderBy.length > 0) ? "" : "ORDER BY " + this.values.orderBy.map((o2) => dialect.quoteOrderByClause(o2)).join(", "),
111
490
  !this.values.limit ? "" : `LIMIT ${this.values.limit}`,
112
491
  !this.values.offset ? "" : `OFFSET ${this.values.offset}`
113
492
  ].filter(Boolean).join(formatted ? "\n" : " ").trim() + ";";
114
493
  }
115
- }
116
- class _fOffset extends _fRun {
494
+ };
495
+ var _fOffset = class extends _fRun {
117
496
  offset(offset) {
118
497
  return new _fRun(this.db, { ...this.values, offset });
119
498
  }
120
- }
121
- class _fLimit extends _fRun {
499
+ };
500
+ var _fLimit = class extends _fRun {
122
501
  limit(limit) {
123
502
  return new _fOffset(this.db, { ...this.values, limit });
124
503
  }
125
- }
126
- class _fOrderBy extends _fLimit {
504
+ };
505
+ var _fOrderBy = class extends _fLimit {
127
506
  orderBy(orderBy) {
128
507
  return new _fLimit(this.db, { ...this.values, orderBy });
129
508
  }
130
- }
131
- class _fSelect extends _fOrderBy {
132
- select(select) {
133
- return new _fSelect(this.db, {
509
+ };
510
+ var _fSelect = class __fSelect extends _fOrderBy {
511
+ // Implementation (not visible to callers)
512
+ select(select, alias) {
513
+ if (typeof select === "function") {
514
+ const ctx = buildContext(dialect);
515
+ const expr = select(ctx);
516
+ const aliasArg = alias;
517
+ const sqlStr = aliasArg !== void 0 ? `${expr.sql} AS ${dialect.quote(aliasArg, true)}` : expr.sql;
518
+ return new __fSelect(this.db, {
519
+ ...this.values,
520
+ selects: [...this.values.selects, sqlStr]
521
+ });
522
+ }
523
+ const tableColMatch = select.match(/^(\w+)\.(.*?)$/);
524
+ if (tableColMatch) {
525
+ const [, tableName, colName] = tableColMatch;
526
+ const tableObject = this.values.tables.find((t2) => (t2.alias || t2.table) === tableName);
527
+ if (!tableObject) throw new Error(`Table "${tableName}" not found in query`);
528
+ const tableFields = DB[tableObject.table];
529
+ if (!tableFields) {
530
+ if (colName === "*") {
531
+ throw new Error(`Cannot expand "${tableName}.*" \u2014 CTE columns must be selected explicitly`);
532
+ }
533
+ return new __fSelect(this.db, {
534
+ ...this.values,
535
+ selects: [...this.values.selects, `${dialect.quoteQualifiedColumn(select)} AS ${dialect.quote(select, true)}`]
536
+ });
537
+ }
538
+ if (colName === "*") {
539
+ const hasMultipleTables = this.values.tables && this.values.tables.length > 1 || false;
540
+ const expandedSelects = Object.keys(tableFields.fields).map((field) => {
541
+ if (hasMultipleTables) {
542
+ const tableIdentifier = tableObject.alias || tableName;
543
+ const qualifiedCol = `${tableIdentifier}.${field}`;
544
+ return `${dialect.quoteQualifiedColumn(qualifiedCol)} AS ${dialect.quote(`${tableName}.${field}`, true)}`;
545
+ }
546
+ return field === "*" ? "*" : dialect.quote(field, false);
547
+ });
548
+ return new __fSelect(this.db, {
549
+ ...this.values,
550
+ selects: [...this.values.selects, ...expandedSelects]
551
+ });
552
+ } else if (!alias && !!colName) {
553
+ const currentTablesWithFields = this.values.tables.reduce((acc, table) => {
554
+ const { table: real } = table;
555
+ if (!DB[real]) return acc;
556
+ for (const col in DB[real].fields) {
557
+ acc[col] = acc[col] ? acc[col] + 1 : 1;
558
+ }
559
+ return acc;
560
+ }, {});
561
+ if (!currentTablesWithFields[colName]) {
562
+ throw new Error(`Column "${colName}" not found in database schema`);
563
+ }
564
+ if (currentTablesWithFields[colName] > 1) {
565
+ return new __fSelect(this.db, {
566
+ ...this.values,
567
+ selects: [...this.values.selects, `${dialect.quoteQualifiedColumn(select)} AS ${dialect.quote(select, true)}`]
568
+ });
569
+ } else {
570
+ return new __fSelect(this.db, {
571
+ ...this.values,
572
+ selects: [...this.values.selects, dialect.quote(colName, false)]
573
+ });
574
+ }
575
+ }
576
+ }
577
+ if (alias !== void 0) {
578
+ const quotedSelect2 = select === "*" ? "*" : select.includes(".") ? dialect.quoteQualifiedColumn(select) : dialect.quote(select, false);
579
+ return new __fSelect(this.db, {
580
+ ...this.values,
581
+ selects: [...this.values.selects, `${quotedSelect2} AS ${dialect.quote(alias, true)}`]
582
+ });
583
+ }
584
+ const quotedSelect = select === "*" ? "*" : select.includes(".") ? dialect.quoteQualifiedColumn(select) : dialect.quote(select, false);
585
+ return new __fSelect(this.db, {
134
586
  ...this.values,
135
- selects: [...this.values.selects, select]
587
+ selects: [...this.values.selects, quotedSelect]
136
588
  });
137
589
  }
138
- }
139
- class _fSelectDistinct extends _fSelect {
590
+ };
591
+ var _fSelectDistinct = class extends _fSelect {
140
592
  selectDistinct() {
141
593
  return new _fSelect(this.db, { ...this.values, selectDistinct: true });
142
594
  }
143
595
  selectAll() {
144
596
  const selects = function(values) {
145
- if (values.tables && values.tables.length > 0) {
146
- return [values.database, ...values.tables.map((t) => t.table)].reduce((acc, table) => {
147
- return acc.concat(Object.keys(DB[table].fields).map((field) => `${table}.${field} AS \`${table}.${field}\``));
597
+ if (values.tables && values.tables.length > 1) {
598
+ return values.tables.reduce((acc, tableObj) => {
599
+ const tableIdentifier = tableObj.alias || tableObj.table;
600
+ const actualTable = tableObj.table;
601
+ if (!DB[actualTable]) return acc;
602
+ return acc.concat(Object.keys(DB[actualTable].fields).map((field) => {
603
+ const qualifiedCol = `${tableIdentifier}.${field}`;
604
+ return `${dialect.quoteQualifiedColumn(qualifiedCol)} AS ${dialect.quote(`${tableIdentifier}.${field}`, true)}`;
605
+ }));
148
606
  }, []);
149
607
  }
150
- return Object.keys(DB[values.database].fields);
608
+ const t2 = values.tables[0];
609
+ if (!DB[t2.table]) throw new Error(`selectAll() is not supported when the base table is a CTE ("${t2.table}"). Use select() with explicit column references.`);
610
+ return Object.keys(DB[t2.table].fields).map((field) => dialect.quote(field, false));
151
611
  }(this.values);
152
612
  return new _fOrderBy(this.db, {
153
613
  ...this.values,
154
614
  selects
155
615
  });
156
616
  }
157
- //TODO
158
- // selectAllOmit() {
159
- // throw new Error("Not implemented yet")
160
- // }
161
- }
162
- class _fHaving extends _fSelectDistinct {
163
- // TODO Allowed Fields
164
- // - specified in groupBy
165
- having(criteria) {
166
- return new _fSelectDistinct(this.db, {
617
+ selectAllOmit(omit) {
618
+ const omitSet = new Set(omit);
619
+ const selects = function(values) {
620
+ if (values.tables.length === 1) {
621
+ const t2 = values.tables[0];
622
+ const tableIdentifier = t2.alias || t2.table;
623
+ return Object.keys(DB[t2.table].fields).filter((f2) => !omitSet.has(f2) && !omitSet.has(`${tableIdentifier}.${f2}`)).map((f2) => dialect.quote(f2, false));
624
+ }
625
+ return values.tables.reduce((acc, tableObj) => {
626
+ const tableIdentifier = tableObj.alias || tableObj.table;
627
+ if (!DB[tableObj.table]) return acc;
628
+ return acc.concat(
629
+ Object.keys(DB[tableObj.table].fields).filter((f2) => !omitSet.has(f2) && !omitSet.has(`${tableIdentifier}.${f2}`)).map((f2) => {
630
+ const q = `${tableIdentifier}.${f2}`;
631
+ return `${dialect.quoteQualifiedColumn(q)} AS ${dialect.quote(q, true)}`;
632
+ })
633
+ );
634
+ }, []);
635
+ }(this.values);
636
+ return new _fOrderBy(this.db, {
167
637
  ...this.values,
168
- having: [criteria]
638
+ selects
169
639
  });
170
640
  }
171
- }
172
- class _fGroupBy extends _fHaving {
641
+ };
642
+ var _fHaving = class __fHaving extends _fSelect {
643
+ // Keep selectDistinct() available after groupBy(), but not selectAll()
644
+ selectDistinct() {
645
+ return new _fSelect(this.db, { ...this.values, selectDistinct: true });
646
+ }
647
+ having(criteriaOrFn) {
648
+ const existing = this.values.having ?? [];
649
+ if (typeof criteriaOrFn === "function") {
650
+ const ctx = buildContext(dialect);
651
+ const sql = processExprPairs(criteriaOrFn(ctx));
652
+ return new __fHaving(this.db, { ...this.values, having: [...existing, sql] });
653
+ }
654
+ return new __fHaving(this.db, { ...this.values, having: [...existing, criteriaOrFn] });
655
+ }
656
+ };
657
+ var _fGroupBy = class extends _fSelectDistinct {
658
+ having(criteriaOrFn) {
659
+ const existing = this.values.having ?? [];
660
+ if (typeof criteriaOrFn === "function") {
661
+ const ctx = buildContext(dialect);
662
+ const sql = processExprPairs(criteriaOrFn(ctx));
663
+ return new _fSelectDistinct(this.db, { ...this.values, having: [...existing, sql] });
664
+ }
665
+ return new _fSelectDistinct(this.db, { ...this.values, having: [...existing, criteriaOrFn] });
666
+ }
173
667
  //TODO this should only accept columns for tables in play
174
668
  groupBy(groupBy) {
175
669
  return new _fHaving(this.db, { ...this.values, groupBy });
176
670
  }
177
- }
178
- class _fWhere extends _fGroupBy {
671
+ };
672
+ var _fWhere = class __fWhere extends _fGroupBy {
179
673
  whereNotNull(col) {
180
- return new _fWhere(this.db, {
674
+ return new __fWhere(this.db, {
181
675
  ...this.values,
182
676
  where: [
183
677
  ...this.values.where || [],
184
678
  {
185
- $AND: (
186
- //@ts-expect-error todo comeback to, col is a string or never
187
- [{ [col]: { op: "IS NOT NULL" } }]
188
- )
679
+ $AND: [{ [col]: { op: "IS NOT NULL" } }]
189
680
  }
190
681
  ]
191
682
  });
192
683
  }
193
684
  whereIsNull(col) {
194
- return new _fWhere(this.db, {
685
+ return new __fWhere(this.db, {
195
686
  ...this.values,
196
687
  where: [
197
688
  ...this.values.where || [],
198
689
  {
199
- $AND: (
200
- //@ts-expect-error todo comeback to, col is a string or never
201
- [{ [col]: { op: "IS NULL" } }]
202
- )
690
+ $AND: [{ [col]: { op: "IS NULL" } }]
203
691
  }
204
692
  ]
205
693
  });
206
694
  }
207
- where(criteria) {
695
+ where(criteriaOrFn) {
696
+ if (typeof criteriaOrFn === "function") {
697
+ const ctx = buildContext(dialect);
698
+ const sql = processExprPairs(criteriaOrFn(ctx));
699
+ return new _fGroupBy(this.db, {
700
+ ...this.values,
701
+ where: [...this.values.where || [], sql]
702
+ });
703
+ }
208
704
  return new _fGroupBy(this.db, {
209
705
  ...this.values,
210
- where: [...this.values.where || [], criteria]
706
+ where: [...this.values.where || [], criteriaOrFn]
211
707
  });
212
708
  }
213
709
  whereRaw(where) {
@@ -216,60 +712,216 @@ class _fWhere extends _fGroupBy {
216
712
  where: [...this.values.where || [], where.replace(/^\s*where\s*/i, "").trim()]
217
713
  });
218
714
  }
715
+ };
716
+ function buildContext(d2) {
717
+ const quoteFn = (col) => d2.quoteQualifiedColumn(col);
718
+ return {
719
+ lit,
720
+ min: (col) => sqlExpr(`MIN(${resolveArg(col, quoteFn)})`),
721
+ max: (col) => sqlExpr(`MAX(${resolveArg(col, quoteFn)})`),
722
+ replace: (col, from, to) => sqlExpr(`REPLACE(${resolveArg(col, quoteFn)}, '${from.replace(/'/g, "''")}', '${to.replace(/'/g, "''")}')`),
723
+ upper: (col) => sqlExpr(`UPPER(${resolveArg(col, quoteFn)})`),
724
+ lower: (col) => sqlExpr(`LOWER(${resolveArg(col, quoteFn)})`),
725
+ trim: (col) => sqlExpr(`TRIM(${resolveArg(col, quoteFn)})`),
726
+ ltrim: (col) => sqlExpr(`LTRIM(${resolveArg(col, quoteFn)})`),
727
+ rtrim: (col) => sqlExpr(`RTRIM(${resolveArg(col, quoteFn)})`),
728
+ cond: (criteria) => sqlExpr(processCriteria([criteria])),
729
+ coalesce: (...args) => {
730
+ if (args.length === 0) throw new Error("coalesce: requires at least one argument");
731
+ return sqlExpr(`COALESCE(${args.map((a2) => resolveArg(a2, quoteFn)).join(", ")})`);
732
+ },
733
+ nullif: (expr1, expr2) => sqlExpr(`NULLIF(${expr1.sql}, ${expr2.sql})`),
734
+ caseWhen: (cases, elseVal) => {
735
+ if (cases.length === 0) throw new Error("caseWhen: requires at least one WHEN clause");
736
+ const parts = cases.map((c2) => `WHEN ${processCriteria([c2.when])} THEN ${c2.then.sql}`).join(" ");
737
+ return sqlExpr(`CASE ${parts}${elseVal ? ` ELSE ${elseVal.sql}` : ""} END`);
738
+ },
739
+ // Partial<> cast: SelectFnContext is a stub here; generator injects DialectFns at codegen time.
740
+ ...dialectContextFns(quoteFn, (c2) => processCriteria([c2]))
741
+ };
219
742
  }
220
- class _fJoin extends _fWhere {
221
- join(table, field, reference) {
222
- return new _fJoin(this.db, {
223
- ...this.values,
224
- tables: [...this.values.tables || [], { table, local: field, remote: reference }]
225
- });
743
+ var _fJoin = class __fJoin extends _fWhere {
744
+ // Implementation
745
+ join(tableOrOptions, field, reference, _opts) {
746
+ return this._joinImpl(void 0, tableOrOptions, field, reference, _opts);
226
747
  }
227
- joinUnsafeTypeEnforced(table, field, reference) {
228
- return new _fJoin(this.db, {
748
+ _joinImpl(joinType, tableOrOptions, field, reference, _opts) {
749
+ let table;
750
+ let local;
751
+ let remote;
752
+ let tableAlias;
753
+ let joinWhere;
754
+ if (typeof tableOrOptions === "object" && "table" in tableOrOptions) {
755
+ table = tableOrOptions.table.trim();
756
+ local = tableOrOptions.src;
757
+ remote = tableOrOptions.on;
758
+ tableAlias = tableOrOptions.alias?.trim();
759
+ joinWhere = tableOrOptions.where ? [tableOrOptions.where] : void 0;
760
+ joinType = tableOrOptions.joinType ?? joinType;
761
+ } else {
762
+ const parts = tableOrOptions.split(" ");
763
+ table = parts[0];
764
+ tableAlias = parts[1]?.trim();
765
+ local = field ?? "";
766
+ remote = reference ?? "";
767
+ joinWhere = _opts?.where ? [_opts.where] : void 0;
768
+ joinType = _opts?.joinType ?? joinType;
769
+ }
770
+ return new __fJoin(this.db, {
229
771
  ...this.values,
230
772
  tables: [...this.values.tables || [], {
231
773
  table,
232
- local: `${String(table)}.${String(field)}`,
233
- remote: reference
774
+ local,
775
+ remote,
776
+ alias: tableAlias,
777
+ ...joinWhere ? { joinWhere } : {},
778
+ ...joinType ? { joinType } : {}
234
779
  }]
235
780
  });
236
781
  }
237
- joinUnsafeIgnoreType(table, field, reference) {
782
+ // Implementation
783
+ joinUnsafeTypeEnforced(tableOrOptions, field, reference, _opts) {
784
+ return this.join(tableOrOptions, field, reference, _opts);
785
+ }
786
+ // Implementation
787
+ joinUnsafeIgnoreType(tableOrOptions, field, reference, _opts) {
788
+ return this.join(tableOrOptions, field, reference, _opts);
789
+ }
790
+ manyToManyJoin(targetTable, options) {
791
+ const opts = options;
792
+ const refName = opts?.refName;
793
+ const [tbl, alias] = targetTable.split(" ");
794
+ let sourceTableName;
795
+ let sourceAlias;
796
+ let srcLocalCol;
797
+ if (opts?.source) {
798
+ const [srcAliasOrTable, col] = opts.source.split(".");
799
+ const entry = this.values.tables.find((t2) => (t2.alias || t2.table) === srcAliasOrTable);
800
+ sourceTableName = entry?.table ?? srcAliasOrTable;
801
+ sourceAlias = srcAliasOrTable;
802
+ srcLocalCol = col;
803
+ } else {
804
+ const candidates = this.values.tables.filter((entry) => {
805
+ const relations = DB[entry.table]?.relations;
806
+ return relations && Object.keys(relations).some(
807
+ (k2) => k2.startsWith("_") && DB[k2]?.relations?.[tbl] !== void 0
808
+ );
809
+ });
810
+ if (candidates.length === 0) throw new Error(
811
+ `manyToManyJoin: no source with junction to "${tbl}" among joined tables`
812
+ );
813
+ if (candidates.length > 1) {
814
+ const names = candidates.map((c2) => c2.alias ?? c2.table).join(", ");
815
+ throw new Error(`manyToManyJoin: ambiguous source for "${tbl}" (${names}). Pass { source: "alias.col" }.`);
816
+ }
817
+ const found = candidates[0];
818
+ sourceTableName = found.table;
819
+ sourceAlias = found.alias || found.table;
820
+ const srcRelations2 = DB[sourceTableName]?.relations;
821
+ const junctionKey = refName ? `_${refName}` : Object.keys(srcRelations2 ?? {}).find(
822
+ (k2) => k2.startsWith("_") && DB[k2]?.relations?.[tbl] !== void 0
823
+ );
824
+ const junctionRelEntry = junctionKey ? srcRelations2[junctionKey] : void 0;
825
+ srcLocalCol = junctionRelEntry ? Object.keys(junctionRelEntry)[0] : "id";
826
+ }
827
+ const srcEntry = DB[sourceTableName];
828
+ if (!srcEntry) throw new Error(`manyToManyJoin: unknown source table "${sourceTableName}"`);
829
+ const srcRelations = srcEntry.relations;
830
+ const junctionTable = refName ? `_${refName}` : Object.keys(srcRelations).find(
831
+ (k2) => k2.startsWith("_") && DB[k2]?.relations?.[tbl] !== void 0
832
+ );
833
+ if (!junctionTable) throw new Error(
834
+ `manyToManyJoin: no junction between "${sourceTableName}" and "${tbl}"`
835
+ );
836
+ const srcJunctionCol = srcRelations[junctionTable]?.[srcLocalCol]?.[0] ?? "A";
837
+ const tgtRelEntry = DB[junctionTable]?.relations?.[tbl];
838
+ const tgtJunctionCol = tgtRelEntry ? Object.keys(tgtRelEntry)[0] : "B";
839
+ const tgtLocalCol = tgtRelEntry?.[tgtJunctionCol]?.[0] ?? "id";
840
+ const remoteRef = `${sourceAlias}.${srcLocalCol}`;
841
+ return this.joinUnsafeIgnoreType(junctionTable, srcJunctionCol, remoteRef).joinUnsafeIgnoreType(alias ? `${tbl} ${alias}` : tbl, tgtLocalCol, `${junctionTable}.${tgtJunctionCol}`);
842
+ }
843
+ innerJoin(tableOrOptions, field, reference) {
844
+ return this._joinImpl("INNER", tableOrOptions, field, reference);
845
+ }
846
+ leftJoin(tableOrOptions, field, reference) {
847
+ return this._joinImpl("LEFT", tableOrOptions, field, reference);
848
+ }
849
+ rightJoin(tableOrOptions, field, reference) {
850
+ return this._joinImpl("RIGHT", tableOrOptions, field, reference);
851
+ }
852
+ fullJoin(tableOrOptions, field, reference) {
853
+ return this._joinImpl("FULL", tableOrOptions, field, reference);
854
+ }
855
+ // crossJoin: no ON clause — table only (with optional inline alias)
856
+ crossJoin(table) {
857
+ return this._joinImpl("CROSS", table);
858
+ }
859
+ innerJoinUnsafeTypeEnforced(tableOrOptions, field, reference) {
860
+ return this._joinImpl("INNER", tableOrOptions, field, reference);
861
+ }
862
+ innerJoinUnsafeIgnoreType(tableOrOptions, field, reference) {
863
+ return this._joinImpl("INNER", tableOrOptions, field, reference);
864
+ }
865
+ leftJoinUnsafeTypeEnforced(tableOrOptions, field, reference) {
866
+ return this._joinImpl("LEFT", tableOrOptions, field, reference);
867
+ }
868
+ leftJoinUnsafeIgnoreType(tableOrOptions, field, reference) {
869
+ return this._joinImpl("LEFT", tableOrOptions, field, reference);
870
+ }
871
+ rightJoinUnsafeTypeEnforced(tableOrOptions, field, reference) {
872
+ return this._joinImpl("RIGHT", tableOrOptions, field, reference);
873
+ }
874
+ rightJoinUnsafeIgnoreType(tableOrOptions, field, reference) {
875
+ return this._joinImpl("RIGHT", tableOrOptions, field, reference);
876
+ }
877
+ fullJoinUnsafeTypeEnforced(tableOrOptions, field, reference) {
878
+ return this._joinImpl("FULL", tableOrOptions, field, reference);
879
+ }
880
+ fullJoinUnsafeIgnoreType(tableOrOptions, field, reference) {
881
+ return this._joinImpl("FULL", tableOrOptions, field, reference);
882
+ }
883
+ // crossJoinUnsafeTypeEnforced — CROSS semantics, type-enforced columns
884
+ crossJoinUnsafeTypeEnforced(table) {
885
+ return this._joinImpl("CROSS", table);
886
+ }
887
+ // crossJoinUnsafeIgnoreType — CROSS semantics, any columns
888
+ crossJoinUnsafeIgnoreType(table) {
889
+ return this._joinImpl("CROSS", table);
890
+ }
891
+ };
892
+ var DbWith = class _DbWith {
893
+ constructor(db, _withs) {
894
+ this.db = db;
895
+ this._withs = _withs;
896
+ }
897
+ with(name, query) {
898
+ return new _DbWith(this.db, [
899
+ ...this._withs,
900
+ { name, sql: query.getSQL().replace(/;$/, "") }
901
+ ]);
902
+ }
903
+ from(baseTableOrCTE, alias) {
238
904
  return new _fJoin(this.db, {
239
- ...this.values,
240
- tables: [...this.values.tables || [], {
241
- table,
242
- local: `${String(table)}.${String(field)}`,
243
- remote: reference
244
- }]
905
+ tables: [{ table: baseTableOrCTE, alias }],
906
+ selects: [],
907
+ withs: this._withs
245
908
  });
246
909
  }
247
- // innerJoin(table: TTables, col1:string, col2:string){
248
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
249
- // }
250
- // leftJoin(table: TTables, col1:string, col2:string){
251
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
252
- // }
253
- // rightJoin(table: TTables, col1:string, col2:string){
254
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
255
- // }
256
- // fullJoin(table: TTables, col1:string, col2:string){
257
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
258
- // }
259
- // crossJoin(table: TTables, col1:string, col2:string){
260
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
261
- // }
262
- // outerJoin(table: TTables, col1:string, col2:string){
263
- // return new _fJoin<TDBBase>(this.db, {...this.values, tables: [...this.values.tables || [], table]});
264
- // }
265
- }
266
- var extend_default = {
910
+ };
911
+ var extendedPrismaClient = {
912
+ name: "prisma-ts-select",
267
913
  client: {
268
914
  $from(table) {
269
915
  const client = Prisma.getExtensionContext(this);
270
- return new DbSelect(client).from(table);
916
+ const [base, ...aliases] = table.split(" ");
917
+ return new DbSelect(client).from(base.trim(), aliases.join().trim() || void 0);
918
+ },
919
+ $with(name, query) {
920
+ const client = Prisma.getExtensionContext(this);
921
+ return new DbWith(client, [{ name, sql: query.getSQL().replace(/;$/, "") }]);
271
922
  }
272
923
  }
273
924
  };
925
+ var extend_default = extendedPrismaClient;
274
926
 
275
927
  export { extend_default as default };