prisma-ts-select 0.0.34 → 0.1.3

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 (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1343 -362
  3. package/assets/groupBy.gif +0 -0
  4. package/assets/joinUnsafeIgnoreType.gif +0 -0
  5. package/assets/joinUnsafeTypeEnforced.gif +0 -0
  6. package/assets/typesafe-join.gif +0 -0
  7. package/assets/typesafe-join.png +0 -0
  8. package/assets/{whereisNull.gif → whereIsNull.gif} +0 -0
  9. package/assets/whereNotNull.gif +0 -0
  10. package/dist/bin.cjs +1 -1
  11. package/dist/bin.js +1 -1
  12. package/dist/chunk-47KZVQLD.js +283 -0
  13. package/dist/chunk-54D2J5AR.cjs +291 -0
  14. package/dist/extend/dialects/index.d.ts +13 -0
  15. package/dist/extend/dialects/index.js +194 -0
  16. package/dist/extend/dialects/mysql-v6.d.ts +103 -0
  17. package/dist/extend/dialects/mysql-v6.js +157 -0
  18. package/dist/extend/dialects/mysql-v7.d.ts +6 -0
  19. package/dist/extend/dialects/mysql-v7.js +143 -0
  20. package/dist/extend/dialects/mysql.d.ts +93 -0
  21. package/dist/extend/dialects/mysql.js +161 -0
  22. package/dist/extend/dialects/postgresql-v6.d.ts +101 -0
  23. package/dist/extend/dialects/postgresql-v6.js +147 -0
  24. package/dist/extend/dialects/postgresql-v7.d.ts +101 -0
  25. package/dist/extend/dialects/postgresql-v7.js +147 -0
  26. package/dist/extend/dialects/postgresql.d.ts +92 -0
  27. package/dist/extend/dialects/postgresql.js +158 -0
  28. package/dist/extend/dialects/shared.d.ts +10 -0
  29. package/dist/extend/dialects/shared.js +14 -0
  30. package/dist/extend/dialects/sqlite.d.ts +68 -0
  31. package/dist/extend/dialects/sqlite.js +146 -0
  32. package/dist/extend/dialects/types.d.ts +13 -0
  33. package/dist/extend/dialects/types.js +4 -0
  34. package/dist/extend/extend.d.ts +292 -46
  35. package/dist/extend/extend.js +769 -162
  36. package/dist/extend/sql-expr-BaKWzJ-r.d.ts +10 -0
  37. package/dist/extend/types-B0F8m0ok.d.ts +8 -0
  38. package/dist/generator.cjs +1 -1
  39. package/dist/generator.js +1 -1
  40. package/package.json +44 -42
  41. package/built/extend.cjs +0 -680
  42. package/built/extend.d.cts +0 -520
  43. package/built/extend.d.ts +0 -520
  44. package/built/extend.js +0 -678
  45. package/dist/chunk-TBO3MX7Q.cjs +0 -195
  46. package/dist/chunk-X3N5N5KQ.js +0 -187
  47. package/dist/extend/extend.cjs +0 -357
  48. package/dist/extend/extend.d.cts +0 -264
@@ -0,0 +1,147 @@
1
+ // src/sql-expr.ts
2
+ function sqlExpr(sql) {
3
+ return { sql, toString() {
4
+ return sql;
5
+ } };
6
+ }
7
+ function resolveArg(arg, quoteFn) {
8
+ if (typeof arg !== "string") return arg.sql;
9
+ return quoteFn(arg);
10
+ }
11
+
12
+ // src/dialects/shared.ts
13
+ var esc = (s) => s.replace(/'/g, "''");
14
+ var flattenJsonObjectPairs = (pairs, quoteFn) => pairs.flatMap(([k, v]) => [`'${esc(k)}'`, resolveArg(v, quoteFn)]);
15
+
16
+ // src/dialects/postgresql.ts
17
+ var PG_CAST_TYPES = /* @__PURE__ */ new Set(["INTEGER", "TEXT", "BIGINT", "BOOLEAN", "REAL", "NUMERIC", "DATE", "TIMESTAMP", "JSON", "JSONB"]);
18
+ var postgresqlContextFns = (quoteFn) => ({
19
+ avg: (col) => sqlExpr(`AVG(${resolveArg(col, quoteFn)})`),
20
+ sum: (col) => sqlExpr(`SUM(${resolveArg(col, quoteFn)})`),
21
+ countAll: () => sqlExpr("COUNT(*)"),
22
+ count: (col) => sqlExpr(col === "*" ? "COUNT(*)" : `COUNT(${quoteFn(col)})`),
23
+ countDistinct: (col) => sqlExpr(`COUNT(DISTINCT ${quoteFn(col)})`),
24
+ length: (col) => sqlExpr(`LENGTH(${resolveArg(col, quoteFn)})`),
25
+ stringAgg: (col, sep) => sqlExpr(`STRING_AGG(${quoteFn(col)}, '${esc(sep)}')`),
26
+ arrayAgg: (col) => sqlExpr(`ARRAY_AGG(${quoteFn(col)})`),
27
+ stddevPop: (col) => sqlExpr(`STDDEV_POP(${quoteFn(col)})`),
28
+ stddevSamp: (col) => sqlExpr(`STDDEV_SAMP(${quoteFn(col)})`),
29
+ varPop: (col) => sqlExpr(`VAR_POP(${quoteFn(col)})`),
30
+ varSamp: (col) => sqlExpr(`VAR_SAMP(${quoteFn(col)})`),
31
+ boolAnd: (col) => sqlExpr(`BOOL_AND(${quoteFn(col)})`),
32
+ boolOr: (col) => sqlExpr(`BOOL_OR(${quoteFn(col)})`),
33
+ jsonAgg: (col) => sqlExpr(`JSON_AGG(${quoteFn(col)})`),
34
+ bitAnd: (col) => sqlExpr(`BIT_AND(${quoteFn(col)})`),
35
+ bitOr: (col) => sqlExpr(`BIT_OR(${quoteFn(col)})`),
36
+ jsonObjectAgg: (key, val) => sqlExpr(`JSON_OBJECT_AGG(${quoteFn(key)}, ${quoteFn(val)})`),
37
+ concat: (...args) => {
38
+ if (args.length === 0) throw new Error("concat: requires at least one argument");
39
+ return sqlExpr(`CONCAT(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
40
+ },
41
+ substring: (col, start, len) => sqlExpr(`SUBSTRING(${resolveArg(col, quoteFn)}, ${start}${len !== void 0 ? `, ${len}` : ""})`),
42
+ left: (col, n) => sqlExpr(`LEFT(${resolveArg(col, quoteFn)}, ${n})`),
43
+ right: (col, n) => sqlExpr(`RIGHT(${resolveArg(col, quoteFn)}, ${n})`),
44
+ repeat: (col, n) => sqlExpr(`REPEAT(${resolveArg(col, quoteFn)}, ${n})`),
45
+ reverse: (col) => sqlExpr(`REVERSE(${resolveArg(col, quoteFn)})`),
46
+ lpad: (col, len, pad) => sqlExpr(`LPAD(${resolveArg(col, quoteFn)}, ${len}, '${esc(pad)}')`),
47
+ rpad: (col, len, pad) => sqlExpr(`RPAD(${resolveArg(col, quoteFn)}, ${len}, '${esc(pad)}')`),
48
+ initcap: (col) => sqlExpr(`INITCAP(${resolveArg(col, quoteFn)})`),
49
+ strpos: (col, substr) => sqlExpr(`STRPOS(${resolveArg(col, quoteFn)}, '${esc(substr)}')`),
50
+ splitPart: (col, delimiter, field) => sqlExpr(`SPLIT_PART(${resolveArg(col, quoteFn)}, '${esc(delimiter)}', ${field})`),
51
+ btrim: (col, chars) => sqlExpr(`BTRIM(${resolveArg(col, quoteFn)}${chars !== void 0 ? `, '${esc(chars)}'` : ""})`),
52
+ md5: (col) => sqlExpr(`MD5(${resolveArg(col, quoteFn)})`),
53
+ // Control flow
54
+ greatest: (...args) => {
55
+ if (args.length === 0) throw new Error("greatest: requires at least one argument");
56
+ return sqlExpr(`GREATEST(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
57
+ },
58
+ least: (...args) => {
59
+ if (args.length === 0) throw new Error("least: requires at least one argument");
60
+ return sqlExpr(`LEAST(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
61
+ },
62
+ // DateTime overrides
63
+ now: () => sqlExpr("NOW()"),
64
+ curDate: () => sqlExpr("CURRENT_DATE"),
65
+ year: (col) => sqlExpr(`EXTRACT(YEAR FROM ${resolveArg(col, quoteFn)})::integer`),
66
+ month: (col) => sqlExpr(`EXTRACT(MONTH FROM ${resolveArg(col, quoteFn)})::integer`),
67
+ day: (col) => sqlExpr(`EXTRACT(DAY FROM ${resolveArg(col, quoteFn)})::integer`),
68
+ hour: (col) => sqlExpr(`EXTRACT(HOUR FROM ${resolveArg(col, quoteFn)})::integer`),
69
+ minute: (col) => sqlExpr(`EXTRACT(MINUTE FROM ${resolveArg(col, quoteFn)})::integer`),
70
+ second: (col) => sqlExpr(`EXTRACT(SECOND FROM ${resolveArg(col, quoteFn)})::integer`),
71
+ // PG-only DateTime fns
72
+ extract: (field, col) => sqlExpr(`EXTRACT(${field} FROM ${resolveArg(col, quoteFn)})`),
73
+ dateTrunc: (unit, col) => sqlExpr(`DATE_TRUNC('${unit}', ${resolveArg(col, quoteFn)})`),
74
+ /**
75
+ * PG `AGE()` returns an `interval`. Typed as `string` since node-postgres serializes
76
+ * intervals as strings (e.g. `"1 year 2 mons 3 days"`). Arithmetic on the result
77
+ * must be done in SQL, not JS — use `sqlExpr` to compose further expressions.
78
+ */
79
+ age: (ts1, ts2) => sqlExpr(ts2 !== void 0 ? `AGE(${resolveArg(ts1, quoteFn)}, ${resolveArg(ts2, quoteFn)})` : `AGE(${resolveArg(ts1, quoteFn)})`),
80
+ toDate: (text, fmt) => sqlExpr(`TO_DATE(${resolveArg(text, quoteFn)}, '${esc(fmt)}')`),
81
+ // ── Math ─────────────────────────────────────────────────────────────────
82
+ abs: (col) => sqlExpr(`ABS(${resolveArg(col, quoteFn)})`),
83
+ ceil: (col) => sqlExpr(`CEIL(${resolveArg(col, quoteFn)})`),
84
+ floor: (col) => sqlExpr(`FLOOR(${resolveArg(col, quoteFn)})`),
85
+ round: (col, decimals) => sqlExpr(decimals !== void 0 ? `ROUND(${resolveArg(col, quoteFn)}, ${decimals})` : `ROUND(${resolveArg(col, quoteFn)})`),
86
+ power: (base, exp) => sqlExpr(`POWER(${resolveArg(base, quoteFn)}, ${typeof exp === "number" ? exp : exp.sql})`),
87
+ sqrt: (col) => sqlExpr(`SQRT(${resolveArg(col, quoteFn)})`),
88
+ mod: (col, divisor) => sqlExpr(`MOD(${resolveArg(col, quoteFn)}, ${divisor})`),
89
+ sign: (col) => sqlExpr(`SIGN(${resolveArg(col, quoteFn)})`),
90
+ exp: (col) => sqlExpr(`EXP(${resolveArg(col, quoteFn)})`),
91
+ // ── Math (PostgreSQL-specific) ────────────────────────────────────────────
92
+ pi: () => sqlExpr("PI()"),
93
+ ln: (x) => sqlExpr(`LN(${resolveArg(x, quoteFn)})`),
94
+ log: (x) => sqlExpr(`LOG(${resolveArg(x, quoteFn)})`),
95
+ logBase: (base, x) => sqlExpr(`LOG(${base}, ${resolveArg(x, quoteFn)})`),
96
+ trunc: (x, n) => sqlExpr(n !== void 0 ? `TRUNC(${resolveArg(x, quoteFn)}, ${n})` : `TRUNC(${resolveArg(x, quoteFn)})`),
97
+ div: (x, y) => sqlExpr(`DIV(${resolveArg(x, quoteFn)}, ${y})`),
98
+ random: () => sqlExpr("RANDOM()"),
99
+ // ── JSON scalar fns ───────────────────────────────────────────────────────
100
+ /**
101
+ * Uses jsonb_path_query_first — requires PG 12+ (Prisma 5+ minimum).
102
+ * @note PG uses JSONPath syntax (e.g. `$.tags[0]`, `$.name`).
103
+ * MySQL/SQLite use SQL/JSON path syntax — paths are NOT cross-dialect compatible.
104
+ * Mismatched paths silently return NULL.
105
+ */
106
+ jsonExtract: (col, path) => sqlExpr(`jsonb_path_query_first(${resolveArg(col, quoteFn)}, '${esc(path)}')`),
107
+ jsonArray: (...args) => sqlExpr(`jsonb_build_array(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`),
108
+ jsonObject: (pairs) => sqlExpr(`jsonb_build_object(${flattenJsonObjectPairs(pairs, quoteFn).join(", ")})`),
109
+ // ── Type coercion ────────────────────────────────────────────────────────
110
+ cast: (expr, type) => {
111
+ if (!PG_CAST_TYPES.has(type)) throw new Error(`cast: invalid cast type '${String(type)}'`);
112
+ return sqlExpr(`CAST(${resolveArg(expr, quoteFn)} AS ${type})`);
113
+ }
114
+ });
115
+ var postgresqlDialect = {
116
+ name: "postgresql",
117
+ needsBooleanCoercion: () => false,
118
+ quote: (id, _isAlias) => `"${id}"`,
119
+ quoteTableIdentifier: (name, _isAlias) => `"${name}"`,
120
+ quoteQualifiedColumn: (ref) => {
121
+ if (!ref.includes(".")) return `"${ref}"`;
122
+ const [table, col] = ref.split(".", 2);
123
+ return `"${table}"."${col}"`;
124
+ },
125
+ quoteOrderByClause: (clause) => {
126
+ const parts = clause.trim().split(/\s+/);
127
+ const colRef = parts[0] ?? "";
128
+ const suffix = parts.slice(1).join(" ");
129
+ const quoted = colRef.includes(".") ? (() => {
130
+ const [table, col] = colRef.split(".", 2);
131
+ return `"${table}"."${col}"`;
132
+ })() : `"${colRef}"`;
133
+ return suffix ? `${quoted} ${suffix}` : quoted;
134
+ }
135
+ };
136
+
137
+ // src/dialects/postgresql-v7.ts
138
+ var postgresqlV7ContextFns = (quoteFn) => ({
139
+ ...postgresqlContextFns(quoteFn),
140
+ countAll: () => sqlExpr("COUNT(*)"),
141
+ count: (col) => sqlExpr(col === "*" ? "COUNT(*)" : `COUNT(${quoteFn(col)})`),
142
+ countDistinct: (col) => sqlExpr(`COUNT(DISTINCT ${quoteFn(col)})`),
143
+ ceil: (col) => sqlExpr(`CEIL(${resolveArg(col, quoteFn)})`),
144
+ floor: (col) => sqlExpr(`FLOOR(${resolveArg(col, quoteFn)})`)
145
+ });
146
+
147
+ export { postgresqlDialect, postgresqlV7ContextFns };
@@ -0,0 +1,92 @@
1
+ import { Dialect } from './types.js';
2
+ import { S as SQLExpr } from '../sql-expr-BaKWzJ-r.js';
3
+ import { J as JSONValue, a as JSONObject } from '../types-B0F8m0ok.js';
4
+ import { FilterCols, ColName, FilterJsonCols } from './shared.js';
5
+ import '@prisma/client/runtime/client';
6
+
7
+ type PgCastTypeMap = {
8
+ INTEGER: number;
9
+ TEXT: string;
10
+ BIGINT: bigint;
11
+ BOOLEAN: boolean;
12
+ REAL: number;
13
+ NUMERIC: number;
14
+ DATE: Date;
15
+ TIMESTAMP: Date;
16
+ JSON: JSONValue;
17
+ JSONB: JSONValue;
18
+ };
19
+ type PgExtractField = 'YEAR' | 'MONTH' | 'DAY' | 'HOUR' | 'MINUTE' | 'SECOND' | 'DOW' | 'DOY' | 'EPOCH' | 'WEEK' | 'QUARTER';
20
+ type PgDateTruncUnit = 'microseconds' | 'milliseconds' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' | 'decade' | 'century' | 'millennium';
21
+ declare const postgresqlContextFns: <TColEntries extends [string, unknown] = never>(quoteFn: (ref: string) => string) => {
22
+ avg: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
23
+ sum: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
24
+ countAll: () => SQLExpr<number>;
25
+ count: (col: ColName<TColEntries> | "*") => SQLExpr<number>;
26
+ countDistinct: (col: ColName<TColEntries>) => SQLExpr<number>;
27
+ length: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<number>;
28
+ stringAgg: (col: ColName<TColEntries>, sep: string) => SQLExpr<string>;
29
+ arrayAgg: (col: ColName<TColEntries>) => SQLExpr<unknown[]>;
30
+ stddevPop: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
31
+ stddevSamp: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
32
+ varPop: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
33
+ varSamp: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
34
+ boolAnd: (col: FilterCols<TColEntries, boolean>) => SQLExpr<boolean>;
35
+ boolOr: (col: FilterCols<TColEntries, boolean>) => SQLExpr<boolean>;
36
+ jsonAgg: (col: ColName<TColEntries>) => SQLExpr<JSONValue[]>;
37
+ bitAnd: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
38
+ bitOr: (col: FilterCols<TColEntries, number>) => SQLExpr<number>;
39
+ jsonObjectAgg: (key: ColName<TColEntries>, val: ColName<TColEntries>) => SQLExpr<JSONValue>;
40
+ concat: (args_0: SQLExpr<string> | FilterCols<TColEntries, string>, ...args: (SQLExpr<string> | FilterCols<TColEntries, string>)[]) => SQLExpr<string>;
41
+ substring: (col: FilterCols<TColEntries, string> | SQLExpr<string>, start: number, len?: number) => SQLExpr<string>;
42
+ left: (col: FilterCols<TColEntries, string> | SQLExpr<string>, n: number) => SQLExpr<string>;
43
+ right: (col: FilterCols<TColEntries, string> | SQLExpr<string>, n: number) => SQLExpr<string>;
44
+ repeat: (col: FilterCols<TColEntries, string> | SQLExpr<string>, n: number) => SQLExpr<string>;
45
+ reverse: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<string>;
46
+ lpad: (col: FilterCols<TColEntries, string> | SQLExpr<string>, len: number, pad: string) => SQLExpr<string>;
47
+ rpad: (col: FilterCols<TColEntries, string> | SQLExpr<string>, len: number, pad: string) => SQLExpr<string>;
48
+ initcap: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<string>;
49
+ strpos: (col: FilterCols<TColEntries, string> | SQLExpr<string>, substr: string) => SQLExpr<number>;
50
+ splitPart: (col: FilterCols<TColEntries, string> | SQLExpr<string>, delimiter: string, field: number) => SQLExpr<string>;
51
+ btrim: (col: FilterCols<TColEntries, string> | SQLExpr<string>, chars?: string) => SQLExpr<string>;
52
+ md5: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<string>;
53
+ greatest: <T>(args_0: FilterCols<TColEntries, T> | SQLExpr<T>, ...args: (FilterCols<TColEntries, T> | SQLExpr<T>)[]) => SQLExpr<T>;
54
+ least: <T>(args_0: FilterCols<TColEntries, T> | SQLExpr<T>, ...args: (FilterCols<TColEntries, T> | SQLExpr<T>)[]) => SQLExpr<T>;
55
+ now: () => SQLExpr<Date>;
56
+ curDate: () => SQLExpr<Date>;
57
+ year: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
58
+ month: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
59
+ day: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
60
+ hour: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
61
+ minute: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
62
+ second: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
63
+ extract: (field: PgExtractField, col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
64
+ dateTrunc: (unit: PgDateTruncUnit, col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<Date>;
65
+ age: (ts1: FilterCols<TColEntries, Date> | SQLExpr<Date>, ts2?: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
66
+ toDate: (text: FilterCols<TColEntries, string> | SQLExpr<string>, fmt: string) => SQLExpr<Date>;
67
+ abs: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
68
+ ceil: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
69
+ floor: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
70
+ round: (col: FilterCols<TColEntries, number> | SQLExpr<number>, decimals?: number) => SQLExpr<number>;
71
+ power: (base: FilterCols<TColEntries, number> | SQLExpr<number>, exp: number | SQLExpr<number>) => SQLExpr<number>;
72
+ sqrt: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
73
+ mod: (col: FilterCols<TColEntries, number> | SQLExpr<number>, divisor: number) => SQLExpr<number>;
74
+ sign: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
75
+ exp: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
76
+ pi: () => SQLExpr<number>;
77
+ ln: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
78
+ log: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
79
+ logBase: (base: number, x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
80
+ trunc: (x: FilterCols<TColEntries, number> | SQLExpr<number>, n?: number) => SQLExpr<number>;
81
+ div: (x: FilterCols<TColEntries, number> | SQLExpr<number>, y: number) => SQLExpr<number>;
82
+ random: () => SQLExpr<number>;
83
+ jsonExtract: (col: FilterJsonCols<TColEntries> | SQLExpr<JSONValue>, path: string) => SQLExpr<JSONValue>;
84
+ jsonArray: (args_0: SQLExpr<unknown> | ColName<TColEntries>, ...args: (SQLExpr<unknown> | ColName<TColEntries>)[]) => SQLExpr<JSONValue[]>;
85
+ jsonObject: (pairs: [string, ColName<TColEntries> | SQLExpr<unknown>][]) => SQLExpr<JSONObject>;
86
+ cast: <T extends keyof PgCastTypeMap>(expr: ColName<TColEntries> | SQLExpr<unknown>, type: T) => SQLExpr<PgCastTypeMap[T]>;
87
+ };
88
+ type DialectFns<TColEntries extends [string, unknown] = never, _TCriteria extends object = object> = ReturnType<typeof postgresqlContextFns<TColEntries>>;
89
+ declare const supportedJoinMethods: readonly ["join", "joinUnsafeTypeEnforced", "joinUnsafeIgnoreType", "innerJoin", "innerJoinUnsafeTypeEnforced", "innerJoinUnsafeIgnoreType", "leftJoin", "leftJoinUnsafeTypeEnforced", "leftJoinUnsafeIgnoreType", "rightJoin", "rightJoinUnsafeTypeEnforced", "rightJoinUnsafeIgnoreType", "fullJoin", "fullJoinUnsafeTypeEnforced", "fullJoinUnsafeIgnoreType", "crossJoin", "crossJoinUnsafeTypeEnforced", "crossJoinUnsafeIgnoreType", "manyToManyJoin"];
90
+ declare const postgresqlDialect: Dialect;
91
+
92
+ export { type DialectFns, type PgDateTruncUnit, type PgExtractField, postgresqlContextFns, postgresqlDialect, supportedJoinMethods };
@@ -0,0 +1,158 @@
1
+ // src/sql-expr.ts
2
+ function sqlExpr(sql) {
3
+ return { sql, toString() {
4
+ return sql;
5
+ } };
6
+ }
7
+ function resolveArg(arg, quoteFn) {
8
+ if (typeof arg !== "string") return arg.sql;
9
+ return quoteFn(arg);
10
+ }
11
+
12
+ // src/dialects/shared.ts
13
+ var esc = (s) => s.replace(/'/g, "''");
14
+ var flattenJsonObjectPairs = (pairs, quoteFn) => pairs.flatMap(([k, v]) => [`'${esc(k)}'`, resolveArg(v, quoteFn)]);
15
+
16
+ // src/dialects/postgresql.ts
17
+ var PG_CAST_TYPES = /* @__PURE__ */ new Set(["INTEGER", "TEXT", "BIGINT", "BOOLEAN", "REAL", "NUMERIC", "DATE", "TIMESTAMP", "JSON", "JSONB"]);
18
+ var postgresqlContextFns = (quoteFn) => ({
19
+ avg: (col) => sqlExpr(`AVG(${resolveArg(col, quoteFn)})`),
20
+ sum: (col) => sqlExpr(`SUM(${resolveArg(col, quoteFn)})`),
21
+ countAll: () => sqlExpr("COUNT(*)"),
22
+ count: (col) => sqlExpr(col === "*" ? "COUNT(*)" : `COUNT(${quoteFn(col)})`),
23
+ countDistinct: (col) => sqlExpr(`COUNT(DISTINCT ${quoteFn(col)})`),
24
+ length: (col) => sqlExpr(`LENGTH(${resolveArg(col, quoteFn)})`),
25
+ stringAgg: (col, sep) => sqlExpr(`STRING_AGG(${quoteFn(col)}, '${esc(sep)}')`),
26
+ arrayAgg: (col) => sqlExpr(`ARRAY_AGG(${quoteFn(col)})`),
27
+ stddevPop: (col) => sqlExpr(`STDDEV_POP(${quoteFn(col)})`),
28
+ stddevSamp: (col) => sqlExpr(`STDDEV_SAMP(${quoteFn(col)})`),
29
+ varPop: (col) => sqlExpr(`VAR_POP(${quoteFn(col)})`),
30
+ varSamp: (col) => sqlExpr(`VAR_SAMP(${quoteFn(col)})`),
31
+ boolAnd: (col) => sqlExpr(`BOOL_AND(${quoteFn(col)})`),
32
+ boolOr: (col) => sqlExpr(`BOOL_OR(${quoteFn(col)})`),
33
+ jsonAgg: (col) => sqlExpr(`JSON_AGG(${quoteFn(col)})`),
34
+ bitAnd: (col) => sqlExpr(`BIT_AND(${quoteFn(col)})`),
35
+ bitOr: (col) => sqlExpr(`BIT_OR(${quoteFn(col)})`),
36
+ jsonObjectAgg: (key, val) => sqlExpr(`JSON_OBJECT_AGG(${quoteFn(key)}, ${quoteFn(val)})`),
37
+ concat: (...args) => {
38
+ if (args.length === 0) throw new Error("concat: requires at least one argument");
39
+ return sqlExpr(`CONCAT(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
40
+ },
41
+ substring: (col, start, len) => sqlExpr(`SUBSTRING(${resolveArg(col, quoteFn)}, ${start}${len !== void 0 ? `, ${len}` : ""})`),
42
+ left: (col, n) => sqlExpr(`LEFT(${resolveArg(col, quoteFn)}, ${n})`),
43
+ right: (col, n) => sqlExpr(`RIGHT(${resolveArg(col, quoteFn)}, ${n})`),
44
+ repeat: (col, n) => sqlExpr(`REPEAT(${resolveArg(col, quoteFn)}, ${n})`),
45
+ reverse: (col) => sqlExpr(`REVERSE(${resolveArg(col, quoteFn)})`),
46
+ lpad: (col, len, pad) => sqlExpr(`LPAD(${resolveArg(col, quoteFn)}, ${len}, '${esc(pad)}')`),
47
+ rpad: (col, len, pad) => sqlExpr(`RPAD(${resolveArg(col, quoteFn)}, ${len}, '${esc(pad)}')`),
48
+ initcap: (col) => sqlExpr(`INITCAP(${resolveArg(col, quoteFn)})`),
49
+ strpos: (col, substr) => sqlExpr(`STRPOS(${resolveArg(col, quoteFn)}, '${esc(substr)}')`),
50
+ splitPart: (col, delimiter, field) => sqlExpr(`SPLIT_PART(${resolveArg(col, quoteFn)}, '${esc(delimiter)}', ${field})`),
51
+ btrim: (col, chars) => sqlExpr(`BTRIM(${resolveArg(col, quoteFn)}${chars !== void 0 ? `, '${esc(chars)}'` : ""})`),
52
+ md5: (col) => sqlExpr(`MD5(${resolveArg(col, quoteFn)})`),
53
+ // Control flow
54
+ greatest: (...args) => {
55
+ if (args.length === 0) throw new Error("greatest: requires at least one argument");
56
+ return sqlExpr(`GREATEST(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
57
+ },
58
+ least: (...args) => {
59
+ if (args.length === 0) throw new Error("least: requires at least one argument");
60
+ return sqlExpr(`LEAST(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`);
61
+ },
62
+ // DateTime overrides
63
+ now: () => sqlExpr("NOW()"),
64
+ curDate: () => sqlExpr("CURRENT_DATE"),
65
+ year: (col) => sqlExpr(`EXTRACT(YEAR FROM ${resolveArg(col, quoteFn)})::integer`),
66
+ month: (col) => sqlExpr(`EXTRACT(MONTH FROM ${resolveArg(col, quoteFn)})::integer`),
67
+ day: (col) => sqlExpr(`EXTRACT(DAY FROM ${resolveArg(col, quoteFn)})::integer`),
68
+ hour: (col) => sqlExpr(`EXTRACT(HOUR FROM ${resolveArg(col, quoteFn)})::integer`),
69
+ minute: (col) => sqlExpr(`EXTRACT(MINUTE FROM ${resolveArg(col, quoteFn)})::integer`),
70
+ second: (col) => sqlExpr(`EXTRACT(SECOND FROM ${resolveArg(col, quoteFn)})::integer`),
71
+ // PG-only DateTime fns
72
+ extract: (field, col) => sqlExpr(`EXTRACT(${field} FROM ${resolveArg(col, quoteFn)})`),
73
+ dateTrunc: (unit, col) => sqlExpr(`DATE_TRUNC('${unit}', ${resolveArg(col, quoteFn)})`),
74
+ /**
75
+ * PG `AGE()` returns an `interval`. Typed as `string` since node-postgres serializes
76
+ * intervals as strings (e.g. `"1 year 2 mons 3 days"`). Arithmetic on the result
77
+ * must be done in SQL, not JS — use `sqlExpr` to compose further expressions.
78
+ */
79
+ age: (ts1, ts2) => sqlExpr(ts2 !== void 0 ? `AGE(${resolveArg(ts1, quoteFn)}, ${resolveArg(ts2, quoteFn)})` : `AGE(${resolveArg(ts1, quoteFn)})`),
80
+ toDate: (text, fmt) => sqlExpr(`TO_DATE(${resolveArg(text, quoteFn)}, '${esc(fmt)}')`),
81
+ // ── Math ─────────────────────────────────────────────────────────────────
82
+ abs: (col) => sqlExpr(`ABS(${resolveArg(col, quoteFn)})`),
83
+ ceil: (col) => sqlExpr(`CEIL(${resolveArg(col, quoteFn)})`),
84
+ floor: (col) => sqlExpr(`FLOOR(${resolveArg(col, quoteFn)})`),
85
+ round: (col, decimals) => sqlExpr(decimals !== void 0 ? `ROUND(${resolveArg(col, quoteFn)}, ${decimals})` : `ROUND(${resolveArg(col, quoteFn)})`),
86
+ power: (base, exp) => sqlExpr(`POWER(${resolveArg(base, quoteFn)}, ${typeof exp === "number" ? exp : exp.sql})`),
87
+ sqrt: (col) => sqlExpr(`SQRT(${resolveArg(col, quoteFn)})`),
88
+ mod: (col, divisor) => sqlExpr(`MOD(${resolveArg(col, quoteFn)}, ${divisor})`),
89
+ sign: (col) => sqlExpr(`SIGN(${resolveArg(col, quoteFn)})`),
90
+ exp: (col) => sqlExpr(`EXP(${resolveArg(col, quoteFn)})`),
91
+ // ── Math (PostgreSQL-specific) ────────────────────────────────────────────
92
+ pi: () => sqlExpr("PI()"),
93
+ ln: (x) => sqlExpr(`LN(${resolveArg(x, quoteFn)})`),
94
+ log: (x) => sqlExpr(`LOG(${resolveArg(x, quoteFn)})`),
95
+ logBase: (base, x) => sqlExpr(`LOG(${base}, ${resolveArg(x, quoteFn)})`),
96
+ trunc: (x, n) => sqlExpr(n !== void 0 ? `TRUNC(${resolveArg(x, quoteFn)}, ${n})` : `TRUNC(${resolveArg(x, quoteFn)})`),
97
+ div: (x, y) => sqlExpr(`DIV(${resolveArg(x, quoteFn)}, ${y})`),
98
+ random: () => sqlExpr("RANDOM()"),
99
+ // ── JSON scalar fns ───────────────────────────────────────────────────────
100
+ /**
101
+ * Uses jsonb_path_query_first — requires PG 12+ (Prisma 5+ minimum).
102
+ * @note PG uses JSONPath syntax (e.g. `$.tags[0]`, `$.name`).
103
+ * MySQL/SQLite use SQL/JSON path syntax — paths are NOT cross-dialect compatible.
104
+ * Mismatched paths silently return NULL.
105
+ */
106
+ jsonExtract: (col, path) => sqlExpr(`jsonb_path_query_first(${resolveArg(col, quoteFn)}, '${esc(path)}')`),
107
+ jsonArray: (...args) => sqlExpr(`jsonb_build_array(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`),
108
+ jsonObject: (pairs) => sqlExpr(`jsonb_build_object(${flattenJsonObjectPairs(pairs, quoteFn).join(", ")})`),
109
+ // ── Type coercion ────────────────────────────────────────────────────────
110
+ cast: (expr, type) => {
111
+ if (!PG_CAST_TYPES.has(type)) throw new Error(`cast: invalid cast type '${String(type)}'`);
112
+ return sqlExpr(`CAST(${resolveArg(expr, quoteFn)} AS ${type})`);
113
+ }
114
+ });
115
+ var supportedJoinMethods = [
116
+ "join",
117
+ "joinUnsafeTypeEnforced",
118
+ "joinUnsafeIgnoreType",
119
+ "innerJoin",
120
+ "innerJoinUnsafeTypeEnforced",
121
+ "innerJoinUnsafeIgnoreType",
122
+ "leftJoin",
123
+ "leftJoinUnsafeTypeEnforced",
124
+ "leftJoinUnsafeIgnoreType",
125
+ "rightJoin",
126
+ "rightJoinUnsafeTypeEnforced",
127
+ "rightJoinUnsafeIgnoreType",
128
+ "fullJoin",
129
+ "fullJoinUnsafeTypeEnforced",
130
+ "fullJoinUnsafeIgnoreType",
131
+ "crossJoin",
132
+ "crossJoinUnsafeTypeEnforced",
133
+ "crossJoinUnsafeIgnoreType",
134
+ "manyToManyJoin"
135
+ ];
136
+ var postgresqlDialect = {
137
+ name: "postgresql",
138
+ needsBooleanCoercion: () => false,
139
+ quote: (id, _isAlias) => `"${id}"`,
140
+ quoteTableIdentifier: (name, _isAlias) => `"${name}"`,
141
+ quoteQualifiedColumn: (ref) => {
142
+ if (!ref.includes(".")) return `"${ref}"`;
143
+ const [table, col] = ref.split(".", 2);
144
+ return `"${table}"."${col}"`;
145
+ },
146
+ quoteOrderByClause: (clause) => {
147
+ const parts = clause.trim().split(/\s+/);
148
+ const colRef = parts[0] ?? "";
149
+ const suffix = parts.slice(1).join(" ");
150
+ const quoted = colRef.includes(".") ? (() => {
151
+ const [table, col] = colRef.split(".", 2);
152
+ return `"${table}"."${col}"`;
153
+ })() : `"${colRef}"`;
154
+ return suffix ? `${quoted} ${suffix}` : quoted;
155
+ }
156
+ };
157
+
158
+ export { postgresqlContextFns, postgresqlDialect, supportedJoinMethods };
@@ -0,0 +1,10 @@
1
+ import { S as SQLExpr } from '../sql-expr-BaKWzJ-r.js';
2
+
3
+ declare const sharedFunctions: {};
4
+ declare const esc: (s: string) => string;
5
+ declare const flattenJsonObjectPairs: (pairs: [string, string | SQLExpr<unknown>][], quoteFn: (ref: string) => string) => string[];
6
+ type FilterCols<TEntries extends [string, unknown], T> = TEntries extends [infer N extends string, infer V] ? NonNullable<V> extends T ? N : never : never;
7
+ type ColName<TEntries extends [string, unknown]> = TEntries extends [infer N extends string, unknown] ? N : never;
8
+ type FilterJsonCols<TEntries extends [string, unknown]> = TEntries extends [infer N extends string, infer V] ? NonNullable<V> extends (string | number | boolean | Date | bigint | Buffer) ? never : N : never;
9
+
10
+ export { type ColName, type FilterCols, type FilterJsonCols, esc, flattenJsonObjectPairs, sharedFunctions };
@@ -0,0 +1,14 @@
1
+ // src/sql-expr.ts
2
+ function resolveArg(arg, quoteFn) {
3
+ if (typeof arg !== "string") return arg.sql;
4
+ return quoteFn(arg);
5
+ }
6
+
7
+ // src/dialects/shared.ts
8
+ var sharedFunctions = {
9
+ // Intentionally empty — placeholder for future cross-dialect functions
10
+ };
11
+ var esc = (s) => s.replace(/'/g, "''");
12
+ var flattenJsonObjectPairs = (pairs, quoteFn) => pairs.flatMap(([k, v]) => [`'${esc(k)}'`, resolveArg(v, quoteFn)]);
13
+
14
+ export { esc, flattenJsonObjectPairs, sharedFunctions };
@@ -0,0 +1,68 @@
1
+ import { Dialect } from './types.js';
2
+ import { S as SQLExpr } from '../sql-expr-BaKWzJ-r.js';
3
+ import { J as JSONValue, a as JSONObject } from '../types-B0F8m0ok.js';
4
+ import { FilterCols, ColName, FilterJsonCols } from './shared.js';
5
+ import '@prisma/client/runtime/client';
6
+
7
+ type SqliteMinMaxResult<TColEntries extends [string, unknown], Col extends string> = TColEntries extends [Col, infer V] ? NonNullable<V> extends number ? bigint | null : V | null : never;
8
+ type SqliteCastTypeMap = {
9
+ INTEGER: bigint;
10
+ TEXT: string;
11
+ REAL: number;
12
+ NUMERIC: number;
13
+ BLOB: Buffer;
14
+ };
15
+ declare const sqliteContextFns: <TColEntries extends [string, unknown] = never, TCriteria extends object = object>(quoteFn: (ref: string) => string, condFn: (criteria: TCriteria) => string) => {
16
+ avg: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
17
+ sum: (col: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<bigint | number>;
18
+ countAll: () => SQLExpr<bigint>;
19
+ count: (col: ColName<TColEntries> | "*") => SQLExpr<bigint>;
20
+ countDistinct: (col: ColName<TColEntries>) => SQLExpr<bigint>;
21
+ length: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<bigint>;
22
+ groupConcat: (col: ColName<TColEntries>, sep?: string) => SQLExpr<string>;
23
+ total: (col: ColName<TColEntries>) => SQLExpr<number>;
24
+ min: <Col extends ColName<TColEntries>>(col: Col) => SQLExpr<SqliteMinMaxResult<TColEntries, Col>>;
25
+ max: <Col extends ColName<TColEntries>>(col: Col) => SQLExpr<SqliteMinMaxResult<TColEntries, Col>>;
26
+ concat: (args_0: FilterCols<TColEntries, string> | SQLExpr<string>, ...args: (FilterCols<TColEntries, string> | SQLExpr<string>)[]) => SQLExpr<string>;
27
+ substr: (col: FilterCols<TColEntries, string> | SQLExpr<string>, start: number, len?: number) => SQLExpr<string>;
28
+ instr: (col: FilterCols<TColEntries, string> | SQLExpr<string>, substr: string) => SQLExpr<bigint>;
29
+ char: (...codes: number[]) => SQLExpr<string>;
30
+ hex: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<string>;
31
+ unicode: (col: FilterCols<TColEntries, string> | SQLExpr<string>) => SQLExpr<bigint>;
32
+ iif: <T>(cond: TCriteria | SQLExpr<unknown>, trueVal: SQLExpr<T>, falseVal: SQLExpr<T>) => SQLExpr<T>;
33
+ ifNull: <T>(col: FilterCols<TColEntries, T> | SQLExpr<T>, fallback: SQLExpr<NonNullable<T>>) => SQLExpr<NonNullable<T>>;
34
+ now: () => SQLExpr<Date>;
35
+ curDate: () => SQLExpr<Date>;
36
+ year: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
37
+ month: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
38
+ day: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
39
+ hour: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
40
+ minute: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
41
+ second: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
42
+ strftime: (fmt: string, col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
43
+ julianday: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<number>;
44
+ date: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
45
+ datetime: (col: FilterCols<TColEntries, Date> | SQLExpr<Date>) => SQLExpr<string>;
46
+ abs: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<bigint | number>;
47
+ ceil: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<bigint | number>;
48
+ floor: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<bigint | number>;
49
+ round: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>, decimals?: number) => SQLExpr<bigint | number>;
50
+ power: (base: FilterCols<TColEntries, number> | SQLExpr<number | bigint>, exp: number | SQLExpr<number | bigint>) => SQLExpr<number>;
51
+ sqrt: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<number>;
52
+ mod: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>, divisor: number) => SQLExpr<bigint | number>;
53
+ sign: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<bigint | number>;
54
+ exp: (col: FilterCols<TColEntries, number> | SQLExpr<number | bigint>) => SQLExpr<number>;
55
+ random: () => SQLExpr<bigint>;
56
+ log: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
57
+ log2: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
58
+ log10: (x: FilterCols<TColEntries, number> | SQLExpr<number>) => SQLExpr<number>;
59
+ jsonExtract: (col: FilterJsonCols<TColEntries> | SQLExpr<JSONValue>, path: string) => SQLExpr<JSONValue>;
60
+ jsonArray: (args_0: SQLExpr<unknown> | ColName<TColEntries>, ...args: (SQLExpr<unknown> | ColName<TColEntries>)[]) => SQLExpr<JSONValue[]>;
61
+ jsonObject: (pairs: [string, ColName<TColEntries> | SQLExpr<unknown>][]) => SQLExpr<JSONObject>;
62
+ cast: <T extends keyof SqliteCastTypeMap>(expr: ColName<TColEntries> | SQLExpr<unknown>, type: T) => SQLExpr<SqliteCastTypeMap[T]>;
63
+ };
64
+ type DialectFns<TColEntries extends [string, unknown] = never, TCriteria extends object = object> = ReturnType<typeof sqliteContextFns<TColEntries, TCriteria>>;
65
+ declare const supportedJoinMethods: readonly ["join", "joinUnsafeTypeEnforced", "joinUnsafeIgnoreType", "innerJoin", "innerJoinUnsafeTypeEnforced", "innerJoinUnsafeIgnoreType", "leftJoin", "leftJoinUnsafeTypeEnforced", "leftJoinUnsafeIgnoreType", "crossJoin", "crossJoinUnsafeTypeEnforced", "crossJoinUnsafeIgnoreType", "manyToManyJoin"];
66
+ declare const sqliteDialect: Dialect;
67
+
68
+ export { type DialectFns, sqliteContextFns, sqliteDialect, supportedJoinMethods };
@@ -0,0 +1,146 @@
1
+ // src/sql-expr.ts
2
+ function sqlExpr(sql) {
3
+ return { sql, toString() {
4
+ return sql;
5
+ } };
6
+ }
7
+ function resolveArg(arg, quoteFn) {
8
+ if (typeof arg !== "string") return arg.sql;
9
+ return quoteFn(arg);
10
+ }
11
+
12
+ // src/dialects/shared.ts
13
+ var esc = (s) => s.replace(/'/g, "''");
14
+ var flattenJsonObjectPairs = (pairs, quoteFn) => pairs.flatMap(([k, v]) => [`'${esc(k)}'`, resolveArg(v, quoteFn)]);
15
+
16
+ // src/dialects/sqlite.ts
17
+ var SQLITE_CAST_TYPES = /* @__PURE__ */ new Set(["INTEGER", "TEXT", "REAL", "NUMERIC", "BLOB"]);
18
+ var dateArg = (col, quoteFn) => {
19
+ if (typeof col !== "string") return col.sql;
20
+ const ref = quoteFn(col);
21
+ return `CASE WHEN typeof(${ref}) = 'integer' THEN datetime(${ref}/1000, 'unixepoch') ELSE ${ref} END`;
22
+ };
23
+ var sqliteContextFns = (quoteFn, condFn) => ({
24
+ avg: (col) => sqlExpr(`AVG(${resolveArg(col, quoteFn)})`),
25
+ // SQLite SUM returns INTEGER (→ bigint) for integer columns, REAL (→ number) for float columns
26
+ sum: (col) => sqlExpr(`SUM(${resolveArg(col, quoteFn)})`),
27
+ // Aggregate integer-result fns — SQLite returns INTEGER → bigint
28
+ countAll: () => sqlExpr("COUNT(*)"),
29
+ count: (col) => sqlExpr(col === "*" ? "COUNT(*)" : `COUNT(${quoteFn(col)})`),
30
+ countDistinct: (col) => sqlExpr(`COUNT(DISTINCT ${quoteFn(col)})`),
31
+ // LENGTH returns INTEGER → bigint in SQLite
32
+ length: (col) => sqlExpr(`LENGTH(${resolveArg(col, quoteFn)})`),
33
+ groupConcat: (col, sep) => sqlExpr(`GROUP_CONCAT(${quoteFn(col)}${sep !== void 0 ? `, '${sep.replace(/'/g, "''")}'` : ""})`),
34
+ total: (col) => sqlExpr(`TOTAL(${quoteFn(col)})`),
35
+ // SQLite MIN/MAX return bigint for integer columns — override base (number) return types
36
+ min: (col) => sqlExpr(`MIN(${quoteFn(col)})`),
37
+ max: (col) => sqlExpr(`MAX(${quoteFn(col)})`),
38
+ concat: (...args) => {
39
+ if (args.length === 0) throw new Error("concat: requires at least one argument");
40
+ return sqlExpr(args.map((a) => resolveArg(a, quoteFn)).join(" || "));
41
+ },
42
+ substr: (col, start, len) => sqlExpr(`SUBSTR(${resolveArg(col, quoteFn)}, ${start}${len !== void 0 ? `, ${len}` : ""})`),
43
+ instr: (col, substr) => sqlExpr(`INSTR(${resolveArg(col, quoteFn)}, '${substr.replace(/'/g, "''")}')`),
44
+ char: (...codes) => sqlExpr(`CHAR(${codes.join(", ")})`),
45
+ hex: (col) => sqlExpr(`HEX(${resolveArg(col, quoteFn)})`),
46
+ unicode: (col) => sqlExpr(`UNICODE(${resolveArg(col, quoteFn)})`),
47
+ // Control flow
48
+ // Note: SQLite has no GREATEST()/LEAST() functions — it uses scalar MAX(a,b)/MIN(a,b) instead.
49
+ // Omitted here because the naming diverges from the MySQL/PG convention.
50
+ iif: (cond, trueVal, falseVal) => {
51
+ const condSql = typeof cond === "object" && cond !== null && "sql" in cond ? cond.sql : condFn(cond);
52
+ return sqlExpr(`IIF(${condSql}, ${trueVal.sql}, ${falseVal.sql})`);
53
+ },
54
+ ifNull: (col, fallback) => sqlExpr(`IFNULL(${resolveArg(col, quoteFn)}, ${fallback.sql})`),
55
+ // DateTime overrides
56
+ now: () => sqlExpr(`datetime('now')`),
57
+ curDate: () => sqlExpr(`date('now')`),
58
+ year: (col) => sqlExpr(`strftime('%Y', ${dateArg(col, quoteFn)})`),
59
+ month: (col) => sqlExpr(`strftime('%m', ${dateArg(col, quoteFn)})`),
60
+ day: (col) => sqlExpr(`strftime('%d', ${dateArg(col, quoteFn)})`),
61
+ hour: (col) => sqlExpr(`strftime('%H', ${dateArg(col, quoteFn)})`),
62
+ minute: (col) => sqlExpr(`strftime('%M', ${dateArg(col, quoteFn)})`),
63
+ second: (col) => sqlExpr(`strftime('%S', ${dateArg(col, quoteFn)})`),
64
+ // SQLite-only DateTime fns
65
+ /**
66
+ * SQLite `strftime` returns `NULL` if the date value is `NULL` or cannot be parsed.
67
+ * Unknown format directives (e.g. `%q`) are passed through literally, not as errors.
68
+ */
69
+ strftime: (fmt, col) => sqlExpr(`strftime('${fmt.replace(/'/g, "''")}', ${dateArg(col, quoteFn)})`),
70
+ julianday: (col) => sqlExpr(`julianday(${dateArg(col, quoteFn)})`),
71
+ date: (col) => sqlExpr(`date(${dateArg(col, quoteFn)})`),
72
+ datetime: (col) => sqlExpr(`datetime(${dateArg(col, quoteFn)})`),
73
+ // ── Math ─────────────────────────────────────────────────────────────────
74
+ // SQLite returns bigint for integer results (ceil, floor, sign, mod) and number for floats.
75
+ // All inputs accept SQLExpr<number | bigint> so composed calls (e.g. sqrt(power(...))) type-check.
76
+ // sqrt/exp always return REAL, so they are typed as number.
77
+ abs: (col) => sqlExpr(`ABS(${resolveArg(col, quoteFn)})`),
78
+ ceil: (col) => sqlExpr(`CEIL(${resolveArg(col, quoteFn)})`),
79
+ floor: (col) => sqlExpr(`FLOOR(${resolveArg(col, quoteFn)})`),
80
+ round: (col, decimals) => sqlExpr(decimals !== void 0 ? `ROUND(${resolveArg(col, quoteFn)}, ${decimals})` : `ROUND(${resolveArg(col, quoteFn)})`),
81
+ // SQLite's POWER() always returns REAL regardless of input type
82
+ power: (base, exp) => sqlExpr(`POWER(${resolveArg(base, quoteFn)}, ${typeof exp === "number" ? exp : exp.sql})`),
83
+ sqrt: (col) => sqlExpr(`SQRT(${resolveArg(col, quoteFn)})`),
84
+ mod: (col, divisor) => sqlExpr(`MOD(${resolveArg(col, quoteFn)}, ${divisor})`),
85
+ sign: (col) => sqlExpr(`SIGN(${resolveArg(col, quoteFn)})`),
86
+ exp: (col) => sqlExpr(`EXP(${resolveArg(col, quoteFn)})`),
87
+ // ── Math (SQLite 3.35+) ──────────────────────────────────────────────────
88
+ // SQLite RANDOM() returns a 64-bit signed integer — always bigint
89
+ random: () => sqlExpr("RANDOM()"),
90
+ log: (x) => sqlExpr(`LOG(${resolveArg(x, quoteFn)})`),
91
+ log2: (x) => sqlExpr(`LOG2(${resolveArg(x, quoteFn)})`),
92
+ log10: (x) => sqlExpr(`LOG10(${resolveArg(x, quoteFn)})`),
93
+ // ── JSON scalar fns ───────────────────────────────────────────────────────
94
+ jsonExtract: (col, path) => sqlExpr(`json_extract(${resolveArg(col, quoteFn)}, '${esc(path)}')`),
95
+ jsonArray: (...args) => sqlExpr(`json_array(${args.map((a) => resolveArg(a, quoteFn)).join(", ")})`),
96
+ jsonObject: (pairs) => sqlExpr(`json_object(${flattenJsonObjectPairs(pairs, quoteFn).join(", ")})`),
97
+ // ── Type coercion ────────────────────────────────────────────────────────
98
+ cast: (expr, type) => {
99
+ if (!SQLITE_CAST_TYPES.has(type)) throw new Error(`cast: invalid cast type '${String(type)}'`);
100
+ return sqlExpr(`CAST(${resolveArg(expr, quoteFn)} AS ${type})`);
101
+ }
102
+ });
103
+ var supportedJoinMethods = [
104
+ "join",
105
+ "joinUnsafeTypeEnforced",
106
+ "joinUnsafeIgnoreType",
107
+ "innerJoin",
108
+ "innerJoinUnsafeTypeEnforced",
109
+ "innerJoinUnsafeIgnoreType",
110
+ "leftJoin",
111
+ "leftJoinUnsafeTypeEnforced",
112
+ "leftJoinUnsafeIgnoreType",
113
+ "crossJoin",
114
+ "crossJoinUnsafeTypeEnforced",
115
+ "crossJoinUnsafeIgnoreType",
116
+ "manyToManyJoin"
117
+ ];
118
+ var sqliteDialect = {
119
+ name: "sqlite",
120
+ needsBooleanCoercion: () => true,
121
+ quote: (name, _isAlias) => {
122
+ if (_isAlias) return "`" + name + "`";
123
+ return name;
124
+ },
125
+ quoteTableIdentifier: (name, _isAlias) => {
126
+ if (_isAlias) return "`" + name + "`";
127
+ return name;
128
+ },
129
+ quoteQualifiedColumn: (ref) => {
130
+ if (!ref.includes(".")) return ref;
131
+ const [table, col] = ref.split(".", 2);
132
+ return `${table}.${col}`;
133
+ },
134
+ quoteOrderByClause: (clause) => {
135
+ const parts = clause.trim().split(/\s+/);
136
+ const colRef = parts[0] ?? "";
137
+ const suffix = parts.slice(1).join(" ");
138
+ const quoted = colRef.includes(".") ? (() => {
139
+ const [table, col] = colRef.split(".", 2);
140
+ return `${table}.${col}`;
141
+ })() : `${colRef}`;
142
+ return suffix ? `${quoted} ${suffix}` : quoted;
143
+ }
144
+ };
145
+
146
+ export { sqliteContextFns, sqliteDialect, supportedJoinMethods };