prisma-ts-select 0.0.34 → 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.
- package/LICENSE +21 -0
- package/README.md +1242 -315
- package/assets/groupBy.gif +0 -0
- package/assets/joinUnsafeIgnoreType.gif +0 -0
- package/assets/joinUnsafeTypeEnforced.gif +0 -0
- package/assets/typesafe-join.gif +0 -0
- package/assets/typesafe-join.png +0 -0
- package/assets/whereNotNull.gif +0 -0
- package/assets/whereisNull.gif +0 -0
- package/dist/bin.cjs +1 -1
- package/dist/bin.js +1 -1
- package/dist/chunk-47KZVQLD.js +283 -0
- package/dist/chunk-54D2J5AR.cjs +291 -0
- package/dist/extend/dialects/index.d.ts +13 -0
- package/dist/extend/dialects/index.js +186 -0
- package/dist/extend/dialects/mysql-v6.d.ts +100 -0
- package/dist/extend/dialects/mysql-v6.js +152 -0
- package/dist/extend/dialects/mysql-v7.d.ts +6 -0
- package/dist/extend/dialects/mysql-v7.js +138 -0
- package/dist/extend/dialects/mysql.d.ts +90 -0
- package/dist/extend/dialects/mysql.js +156 -0
- package/dist/extend/dialects/postgresql-v6.d.ts +97 -0
- package/dist/extend/dialects/postgresql-v6.js +136 -0
- package/dist/extend/dialects/postgresql-v7.d.ts +97 -0
- package/dist/extend/dialects/postgresql-v7.js +136 -0
- package/dist/extend/dialects/postgresql.d.ts +89 -0
- package/dist/extend/dialects/postgresql.js +147 -0
- package/dist/extend/dialects/shared.d.ts +6 -0
- package/dist/extend/dialects/shared.js +5 -0
- package/dist/extend/dialects/sqlite.d.ts +63 -0
- package/dist/extend/dialects/sqlite.js +138 -0
- package/dist/extend/dialects/types.d.ts +12 -0
- package/dist/extend/dialects/types.js +4 -0
- package/dist/extend/extend.d.ts +286 -43
- package/dist/extend/extend.js +735 -163
- package/dist/extend/sql-expr-BaKWzJ-r.d.ts +10 -0
- package/dist/extend/types-D84lxYVc.d.ts +5 -0
- package/dist/generator.cjs +1 -1
- package/dist/generator.js +1 -1
- package/package.json +46 -42
- package/built/extend.cjs +0 -680
- package/built/extend.d.cts +0 -520
- package/built/extend.d.ts +0 -520
- package/built/extend.js +0 -678
- package/dist/chunk-TBO3MX7Q.cjs +0 -195
- package/dist/chunk-X3N5N5KQ.js +0 -187
- package/dist/extend/extend.cjs +0 -357
- package/dist/extend/extend.d.cts +0 -264
package/dist/extend/extend.js
CHANGED
|
@@ -1,8 +1,290 @@
|
|
|
1
1
|
import { Prisma } from '@prisma/client/extension';
|
|
2
|
-
import {
|
|
2
|
+
import { dialectContextFns, dialect } from './dialects/index.js';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
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
|
}
|
|
@@ -15,18 +297,148 @@ class DbSelect {
|
|
|
15
297
|
selects: []
|
|
16
298
|
});
|
|
17
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() + ")";
|
|
18
351
|
}
|
|
19
|
-
|
|
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();
|
|
390
|
+
}
|
|
391
|
+
return results.join((formatted ? "\n" : " ") + joinType + (formatted ? "\n" : " ")).trim();
|
|
392
|
+
}
|
|
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 {
|
|
20
398
|
constructor(db, values) {
|
|
21
399
|
this.db = db;
|
|
22
400
|
this.values = values;
|
|
23
401
|
this.values.limit = typeof this.values.limit === "number" ? this.values.limit : void 0;
|
|
24
402
|
this.values.offset = typeof this.values.offset === "number" ? this.values.offset : void 0;
|
|
25
403
|
}
|
|
26
|
-
run() {
|
|
27
|
-
|
|
404
|
+
async run() {
|
|
405
|
+
const results = await this.db.$queryRawUnsafe(
|
|
28
406
|
this.getSQL()
|
|
29
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;
|
|
30
442
|
}
|
|
31
443
|
getTables() {
|
|
32
444
|
return {};
|
|
@@ -38,137 +450,109 @@ class _fRun {
|
|
|
38
450
|
return {};
|
|
39
451
|
}
|
|
40
452
|
getSQL(formatted = false) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value) && "op" in value) {
|
|
45
|
-
switch (value.op) {
|
|
46
|
-
case "IN":
|
|
47
|
-
case "NOT IN":
|
|
48
|
-
const valuesList = value.values.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
|
|
49
|
-
return `${String(field)} ${value.op} (${valuesList})`;
|
|
50
|
-
case "BETWEEN":
|
|
51
|
-
if (value.values.length > 2) throw new Error("Too many items supplied to op BETWEEN");
|
|
52
|
-
const [start, end] = value.values;
|
|
53
|
-
return `${String(field)} BETWEEN ${typeof start === "string" ? `'${start}'` : start} AND ${typeof end === "string" ? `'${end}'` : end}`;
|
|
54
|
-
case "LIKE":
|
|
55
|
-
case "NOT LIKE":
|
|
56
|
-
return `${String(field)} ${value.op} '${value.value}'`;
|
|
57
|
-
case "IS NULL":
|
|
58
|
-
case "IS NOT NULL":
|
|
59
|
-
return `${String(field)} ${value.op}`;
|
|
60
|
-
case ">":
|
|
61
|
-
case ">=":
|
|
62
|
-
case "<":
|
|
63
|
-
case "<=":
|
|
64
|
-
case "!=":
|
|
65
|
-
return `${String(field)} ${value.op} ${typeof value.value === "string" ? `'${value.value}'` : value.value}`;
|
|
66
|
-
default:
|
|
67
|
-
throw new Error(`Unsupported operation: ${value.op}`);
|
|
68
|
-
}
|
|
69
|
-
} else if (Array.isArray(value)) {
|
|
70
|
-
const valuesList = value.map((v) => typeof v === "string" ? `'${v}'` : v).join(", ");
|
|
71
|
-
return `${String(field)} IN (${valuesList})`;
|
|
72
|
-
} else if (value === null) {
|
|
73
|
-
return `${String(field)} IS NULL`;
|
|
74
|
-
} else {
|
|
75
|
-
return `${String(field)} = ${typeof value === "string" ? `'${value}'` : value}`;
|
|
76
|
-
}
|
|
77
|
-
}).join(" AND " + (" ")) + " )";
|
|
78
|
-
}
|
|
79
|
-
function processCriteria(main, joinType = "AND", formatted2 = false) {
|
|
80
|
-
const results = [];
|
|
81
|
-
for (const criteria of main) {
|
|
82
|
-
if (typeof criteria === "string") {
|
|
83
|
-
results.push(criteria);
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
for (const criterion in criteria) {
|
|
87
|
-
results.push(match(criterion).returnType().with("$AND", (criterion2) => {
|
|
88
|
-
return "(" + //@ts-expect-error criterion
|
|
89
|
-
processCriteria(criteria[criterion2], "AND", formatted2) + ")";
|
|
90
|
-
}).with("$OR", (criterion2) => {
|
|
91
|
-
return "(" + //@ts-expect-error criterion
|
|
92
|
-
processCriteria(criteria[criterion2], "OR", formatted2) + ")";
|
|
93
|
-
}).with("$NOT", (criterion2) => {
|
|
94
|
-
return "(NOT(" + //@ts-expect-error criterion
|
|
95
|
-
processCriteria(criteria[criterion2], "AND", formatted2) + "))";
|
|
96
|
-
}).with("$NOR", (criterion2) => {
|
|
97
|
-
return "(NOT(" + //@ts-expect-error criterion
|
|
98
|
-
processCriteria(criteria[criterion2], "OR", formatted2) + "))";
|
|
99
|
-
}).with(P.string, () => {
|
|
100
|
-
return processCondition(criteria);
|
|
101
|
-
}).exhaustive());
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
return results.join((formatted2 ? "\n" : " ") + joinType + (formatted2 ? "\n" : " "));
|
|
105
|
-
}
|
|
453
|
+
const withClause = this.values.withs?.length ? `WITH ${this.values.withs.map(
|
|
454
|
+
(w2) => `${dialect.quoteTableIdentifier(w2.name, false)} AS (${w2.sql})`
|
|
455
|
+
).join(", ")}` : "";
|
|
106
456
|
const whereClause = this.values.where !== void 0 ? processCriteria(this.values.where, "AND", formatted) : void 0;
|
|
107
457
|
const havingClause = this.values.having !== void 0 ? processCriteria(this.values.having, "AND", formatted) : void 0;
|
|
108
458
|
const [base, ...joins] = this.values.tables;
|
|
109
|
-
const
|
|
459
|
+
const quotedTable = dialect.quoteTableIdentifier(base.table, false);
|
|
460
|
+
const baseTable = base.alias ? `${quotedTable} AS ${dialect.quoteTableIdentifier(base.alias, true)}` : quotedTable;
|
|
110
461
|
return [
|
|
462
|
+
withClause,
|
|
111
463
|
this.values.selects.length === 0 ? "" : "SELECT " + (this.values.selectDistinct === true ? "DISTINCT " : "") + this.values.selects.join(", "),
|
|
112
464
|
`FROM ${baseTable}`,
|
|
113
465
|
joins.map(({
|
|
114
466
|
table,
|
|
115
467
|
local,
|
|
116
468
|
remote,
|
|
117
|
-
alias
|
|
469
|
+
alias,
|
|
470
|
+
joinWhere,
|
|
471
|
+
joinType
|
|
118
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
|
+
}
|
|
119
479
|
const tLocal = (alias || table) + "." + local;
|
|
120
|
-
|
|
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}`;
|
|
121
485
|
}).join(formatted ? "\n" : " ") ?? "",
|
|
122
486
|
!whereClause ? "" : `WHERE ${whereClause}`,
|
|
123
|
-
!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(", ")}`,
|
|
124
488
|
!havingClause ? "" : `HAVING ${havingClause}`,
|
|
125
|
-
!(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(", "),
|
|
126
490
|
!this.values.limit ? "" : `LIMIT ${this.values.limit}`,
|
|
127
491
|
!this.values.offset ? "" : `OFFSET ${this.values.offset}`
|
|
128
492
|
].filter(Boolean).join(formatted ? "\n" : " ").trim() + ";";
|
|
129
493
|
}
|
|
130
|
-
}
|
|
131
|
-
|
|
494
|
+
};
|
|
495
|
+
var _fOffset = class extends _fRun {
|
|
132
496
|
offset(offset) {
|
|
133
497
|
return new _fRun(this.db, { ...this.values, offset });
|
|
134
498
|
}
|
|
135
|
-
}
|
|
136
|
-
|
|
499
|
+
};
|
|
500
|
+
var _fLimit = class extends _fRun {
|
|
137
501
|
limit(limit) {
|
|
138
502
|
return new _fOffset(this.db, { ...this.values, limit });
|
|
139
503
|
}
|
|
140
|
-
}
|
|
141
|
-
|
|
504
|
+
};
|
|
505
|
+
var _fOrderBy = class extends _fLimit {
|
|
142
506
|
orderBy(orderBy) {
|
|
143
507
|
return new _fLimit(this.db, { ...this.values, orderBy });
|
|
144
508
|
}
|
|
145
|
-
}
|
|
146
|
-
|
|
509
|
+
};
|
|
510
|
+
var _fSelect = class __fSelect extends _fOrderBy {
|
|
511
|
+
// Implementation (not visible to callers)
|
|
147
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
|
+
}
|
|
148
523
|
const tableColMatch = select.match(/^(\w+)\.(.*?)$/);
|
|
149
524
|
if (tableColMatch) {
|
|
150
525
|
const [, tableName, colName] = tableColMatch;
|
|
151
|
-
const tableObject = this.values.tables.find((
|
|
526
|
+
const tableObject = this.values.tables.find((t2) => (t2.alias || t2.table) === tableName);
|
|
152
527
|
if (!tableObject) throw new Error(`Table "${tableName}" not found in query`);
|
|
153
528
|
const tableFields = DB[tableObject.table];
|
|
154
529
|
if (!tableFields) {
|
|
155
|
-
|
|
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
|
+
});
|
|
156
537
|
}
|
|
157
538
|
if (colName === "*") {
|
|
158
539
|
const hasMultipleTables = this.values.tables && this.values.tables.length > 1 || false;
|
|
159
540
|
const expandedSelects = Object.keys(tableFields.fields).map((field) => {
|
|
160
541
|
if (hasMultipleTables) {
|
|
161
|
-
|
|
542
|
+
const tableIdentifier = tableObject.alias || tableName;
|
|
543
|
+
const qualifiedCol = `${tableIdentifier}.${field}`;
|
|
544
|
+
return `${dialect.quoteQualifiedColumn(qualifiedCol)} AS ${dialect.quote(`${tableName}.${field}`, true)}`;
|
|
162
545
|
}
|
|
163
|
-
return
|
|
546
|
+
return field === "*" ? "*" : dialect.quote(field, false);
|
|
164
547
|
});
|
|
165
|
-
return new
|
|
548
|
+
return new __fSelect(this.db, {
|
|
166
549
|
...this.values,
|
|
167
550
|
selects: [...this.values.selects, ...expandedSelects]
|
|
168
551
|
});
|
|
169
552
|
} else if (!alias && !!colName) {
|
|
170
553
|
const currentTablesWithFields = this.values.tables.reduce((acc, table) => {
|
|
171
554
|
const { table: real } = table;
|
|
555
|
+
if (!DB[real]) return acc;
|
|
172
556
|
for (const col in DB[real].fields) {
|
|
173
557
|
acc[col] = acc[col] ? acc[col] + 1 : 1;
|
|
174
558
|
}
|
|
@@ -178,105 +562,148 @@ class _fSelect extends _fOrderBy {
|
|
|
178
562
|
throw new Error(`Column "${colName}" not found in database schema`);
|
|
179
563
|
}
|
|
180
564
|
if (currentTablesWithFields[colName] > 1) {
|
|
181
|
-
return new
|
|
565
|
+
return new __fSelect(this.db, {
|
|
182
566
|
...this.values,
|
|
183
|
-
selects: [...this.values.selects, `${select} AS
|
|
567
|
+
selects: [...this.values.selects, `${dialect.quoteQualifiedColumn(select)} AS ${dialect.quote(select, true)}`]
|
|
184
568
|
});
|
|
185
569
|
} else {
|
|
186
|
-
return new
|
|
570
|
+
return new __fSelect(this.db, {
|
|
187
571
|
...this.values,
|
|
188
|
-
selects: [...this.values.selects,
|
|
572
|
+
selects: [...this.values.selects, dialect.quote(colName, false)]
|
|
189
573
|
});
|
|
190
574
|
}
|
|
191
575
|
}
|
|
192
576
|
}
|
|
193
577
|
if (alias !== void 0) {
|
|
194
|
-
|
|
578
|
+
const quotedSelect2 = select === "*" ? "*" : select.includes(".") ? dialect.quoteQualifiedColumn(select) : dialect.quote(select, false);
|
|
579
|
+
return new __fSelect(this.db, {
|
|
195
580
|
...this.values,
|
|
196
|
-
selects: [...this.values.selects, `${
|
|
581
|
+
selects: [...this.values.selects, `${quotedSelect2} AS ${dialect.quote(alias, true)}`]
|
|
197
582
|
});
|
|
198
583
|
}
|
|
199
|
-
|
|
584
|
+
const quotedSelect = select === "*" ? "*" : select.includes(".") ? dialect.quoteQualifiedColumn(select) : dialect.quote(select, false);
|
|
585
|
+
return new __fSelect(this.db, {
|
|
200
586
|
...this.values,
|
|
201
|
-
selects: [...this.values.selects,
|
|
587
|
+
selects: [...this.values.selects, quotedSelect]
|
|
202
588
|
});
|
|
203
589
|
}
|
|
204
|
-
}
|
|
205
|
-
|
|
590
|
+
};
|
|
591
|
+
var _fSelectDistinct = class extends _fSelect {
|
|
206
592
|
selectDistinct() {
|
|
207
593
|
return new _fSelect(this.db, { ...this.values, selectDistinct: true });
|
|
208
594
|
}
|
|
209
595
|
selectAll() {
|
|
210
596
|
const selects = function(values) {
|
|
211
597
|
if (values.tables && values.tables.length > 1) {
|
|
212
|
-
return
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return acc.concat(Object.keys(DB[
|
|
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
|
+
}));
|
|
217
606
|
}, []);
|
|
218
607
|
}
|
|
219
|
-
|
|
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));
|
|
220
611
|
}(this.values);
|
|
221
612
|
return new _fOrderBy(this.db, {
|
|
222
613
|
...this.values,
|
|
223
614
|
selects
|
|
224
615
|
});
|
|
225
616
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
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, {
|
|
236
637
|
...this.values,
|
|
237
|
-
|
|
638
|
+
selects
|
|
238
639
|
});
|
|
239
640
|
}
|
|
240
|
-
}
|
|
241
|
-
class
|
|
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
|
+
}
|
|
242
667
|
//TODO this should only accept columns for tables in play
|
|
243
668
|
groupBy(groupBy) {
|
|
244
669
|
return new _fHaving(this.db, { ...this.values, groupBy });
|
|
245
670
|
}
|
|
246
|
-
}
|
|
247
|
-
|
|
671
|
+
};
|
|
672
|
+
var _fWhere = class __fWhere extends _fGroupBy {
|
|
248
673
|
whereNotNull(col) {
|
|
249
|
-
return new
|
|
674
|
+
return new __fWhere(this.db, {
|
|
250
675
|
...this.values,
|
|
251
676
|
where: [
|
|
252
677
|
...this.values.where || [],
|
|
253
678
|
{
|
|
254
|
-
$AND:
|
|
255
|
-
//@ts-expect-error todo comeback to, col is a string or never
|
|
256
|
-
[{ [col]: { op: "IS NOT NULL" } }]
|
|
257
|
-
)
|
|
679
|
+
$AND: [{ [col]: { op: "IS NOT NULL" } }]
|
|
258
680
|
}
|
|
259
681
|
]
|
|
260
682
|
});
|
|
261
683
|
}
|
|
262
684
|
whereIsNull(col) {
|
|
263
|
-
return new
|
|
685
|
+
return new __fWhere(this.db, {
|
|
264
686
|
...this.values,
|
|
265
687
|
where: [
|
|
266
688
|
...this.values.where || [],
|
|
267
689
|
{
|
|
268
|
-
$AND:
|
|
269
|
-
//@ts-expect-error todo comeback to, col is a string or never
|
|
270
|
-
[{ [col]: { op: "IS NULL" } }]
|
|
271
|
-
)
|
|
690
|
+
$AND: [{ [col]: { op: "IS NULL" } }]
|
|
272
691
|
}
|
|
273
692
|
]
|
|
274
693
|
});
|
|
275
694
|
}
|
|
276
|
-
where(
|
|
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
|
+
}
|
|
277
704
|
return new _fGroupBy(this.db, {
|
|
278
705
|
...this.values,
|
|
279
|
-
where: [...this.values.where || [],
|
|
706
|
+
where: [...this.values.where || [], criteriaOrFn]
|
|
280
707
|
});
|
|
281
708
|
}
|
|
282
709
|
whereRaw(where) {
|
|
@@ -285,71 +712,216 @@ class _fWhere extends _fGroupBy {
|
|
|
285
712
|
where: [...this.values.where || [], where.replace(/^\s*where\s*/i, "").trim()]
|
|
286
713
|
});
|
|
287
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
|
+
};
|
|
288
742
|
}
|
|
289
|
-
|
|
743
|
+
var _fJoin = class __fJoin extends _fWhere {
|
|
290
744
|
// Implementation
|
|
291
|
-
join(tableOrOptions, field, reference) {
|
|
745
|
+
join(tableOrOptions, field, reference, _opts) {
|
|
746
|
+
return this._joinImpl(void 0, tableOrOptions, field, reference, _opts);
|
|
747
|
+
}
|
|
748
|
+
_joinImpl(joinType, tableOrOptions, field, reference, _opts) {
|
|
292
749
|
let table;
|
|
293
750
|
let local;
|
|
294
751
|
let remote;
|
|
295
752
|
let tableAlias;
|
|
753
|
+
let joinWhere;
|
|
296
754
|
if (typeof tableOrOptions === "object" && "table" in tableOrOptions) {
|
|
297
755
|
table = tableOrOptions.table.trim();
|
|
298
756
|
local = tableOrOptions.src;
|
|
299
757
|
remote = tableOrOptions.on;
|
|
300
758
|
tableAlias = tableOrOptions.alias?.trim();
|
|
759
|
+
joinWhere = tableOrOptions.where ? [tableOrOptions.where] : void 0;
|
|
760
|
+
joinType = tableOrOptions.joinType ?? joinType;
|
|
301
761
|
} else {
|
|
302
762
|
const parts = tableOrOptions.split(" ");
|
|
303
763
|
table = parts[0];
|
|
304
764
|
tableAlias = parts[1]?.trim();
|
|
305
|
-
local = field;
|
|
306
|
-
remote = reference;
|
|
765
|
+
local = field ?? "";
|
|
766
|
+
remote = reference ?? "";
|
|
767
|
+
joinWhere = _opts?.where ? [_opts.where] : void 0;
|
|
768
|
+
joinType = _opts?.joinType ?? joinType;
|
|
307
769
|
}
|
|
308
|
-
return new
|
|
770
|
+
return new __fJoin(this.db, {
|
|
309
771
|
...this.values,
|
|
310
772
|
tables: [...this.values.tables || [], {
|
|
311
773
|
table,
|
|
312
774
|
local,
|
|
313
775
|
remote,
|
|
314
|
-
alias: tableAlias
|
|
776
|
+
alias: tableAlias,
|
|
777
|
+
...joinWhere ? { joinWhere } : {},
|
|
778
|
+
...joinType ? { joinType } : {}
|
|
315
779
|
}]
|
|
316
780
|
});
|
|
317
781
|
}
|
|
318
782
|
// Implementation
|
|
319
|
-
joinUnsafeTypeEnforced(tableOrOptions, field, reference) {
|
|
320
|
-
return this.join(tableOrOptions, field, reference);
|
|
783
|
+
joinUnsafeTypeEnforced(tableOrOptions, field, reference, _opts) {
|
|
784
|
+
return this.join(tableOrOptions, field, reference, _opts);
|
|
321
785
|
}
|
|
322
786
|
// Implementation
|
|
323
|
-
joinUnsafeIgnoreType(tableOrOptions, field, reference) {
|
|
324
|
-
return this.join(tableOrOptions, field, reference);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
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) {
|
|
904
|
+
return new _fJoin(this.db, {
|
|
905
|
+
tables: [{ table: baseTableOrCTE, alias }],
|
|
906
|
+
selects: [],
|
|
907
|
+
withs: this._withs
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
};
|
|
911
|
+
var extendedPrismaClient = {
|
|
912
|
+
name: "prisma-ts-select",
|
|
346
913
|
client: {
|
|
347
914
|
$from(table) {
|
|
348
915
|
const client = Prisma.getExtensionContext(this);
|
|
349
916
|
const [base, ...aliases] = table.split(" ");
|
|
350
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(/;$/, "") }]);
|
|
351
922
|
}
|
|
352
923
|
}
|
|
353
924
|
};
|
|
925
|
+
var extend_default = extendedPrismaClient;
|
|
354
926
|
|
|
355
927
|
export { extend_default as default };
|