@supalive/core 0.1.4 → 0.1.5

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 (212) hide show
  1. package/README.md +17 -2
  2. package/dist/helper-CiacMqje.d.ts +14 -0
  3. package/dist/helper-CiacMqje.d.ts.map +1 -0
  4. package/dist/helper-zdJT5FUc.js +58 -0
  5. package/dist/helper-zdJT5FUc.js.map +1 -0
  6. package/dist/index-CTyXKcq_.d.ts +1736 -0
  7. package/dist/index-CTyXKcq_.d.ts.map +1 -0
  8. package/dist/mysql-C8SN443m.d.ts +104 -0
  9. package/dist/mysql-C8SN443m.d.ts.map +1 -0
  10. package/dist/mysql-DELSRrpY.js +569 -0
  11. package/dist/mysql-DELSRrpY.js.map +1 -0
  12. package/dist/overlap-checker-CVkbbuEQ.js +187 -0
  13. package/dist/overlap-checker-CVkbbuEQ.js.map +1 -0
  14. package/dist/postgres-DE-XyNAQ.js +823 -0
  15. package/dist/postgres-DE-XyNAQ.js.map +1 -0
  16. package/dist/postgres-D_gwCHx-.d.ts +108 -0
  17. package/dist/postgres-D_gwCHx-.d.ts.map +1 -0
  18. package/dist/query-CbQLjeME.js +713 -0
  19. package/dist/query-CbQLjeME.js.map +1 -0
  20. package/dist/realtime_db-D9p2X2PH.js +246 -0
  21. package/dist/realtime_db-D9p2X2PH.js.map +1 -0
  22. package/dist/router-DlTYWpop.js +81 -0
  23. package/dist/router-DlTYWpop.js.map +1 -0
  24. package/dist/schema-SKcIWHfo.js +167 -0
  25. package/dist/schema-SKcIWHfo.js.map +1 -0
  26. package/dist/src/client/index.d.ts +2 -17
  27. package/dist/src/client/index.js +1151 -18
  28. package/dist/src/client/index.js.map +1 -1
  29. package/dist/src/exports/mysql.d.ts +2 -2
  30. package/dist/src/exports/mysql.js +2 -2
  31. package/dist/src/exports/postgres.d.ts +2 -2
  32. package/dist/src/exports/postgres.js +2 -2
  33. package/dist/src/exports/procedure.d.ts +3 -5
  34. package/dist/src/exports/procedure.js +5 -5
  35. package/dist/src/exports/server.d.ts +368 -2
  36. package/dist/src/exports/server.d.ts.map +1 -1
  37. package/dist/src/exports/server.js +1346 -2
  38. package/dist/src/exports/server.js.map +1 -1
  39. package/dist/src/exports/subscription-manager-worker-entry.d.ts +1 -0
  40. package/dist/src/exports/subscription-manager-worker-entry.js +115 -0
  41. package/dist/src/exports/subscription-manager-worker-entry.js.map +1 -0
  42. package/dist/src/exports/types.d.ts +4 -6
  43. package/dist/src/exports/types.js +5 -6
  44. package/dist/subscription-worker-BurdPO8d.js +511 -0
  45. package/dist/subscription-worker-BurdPO8d.js.map +1 -0
  46. package/dist/types_client_rpc-CIsjQQGG.js +105 -0
  47. package/dist/types_client_rpc-CIsjQQGG.js.map +1 -0
  48. package/dist/types_db-Ctf-ksoy.js +168 -0
  49. package/dist/types_db-Ctf-ksoy.js.map +1 -0
  50. package/dist/types_server-Ch56y8L3.d.ts +216 -0
  51. package/dist/types_server-Ch56y8L3.d.ts.map +1 -0
  52. package/dist/types_server-Dk6o_B7N.js +24 -0
  53. package/dist/types_server-Dk6o_B7N.js.map +1 -0
  54. package/package.json +3 -3
  55. package/dist/src/client/caller_client.d.ts +0 -42
  56. package/dist/src/client/caller_client.d.ts.map +0 -1
  57. package/dist/src/client/caller_client.js +0 -77
  58. package/dist/src/client/caller_client.js.map +0 -1
  59. package/dist/src/client/client.d.ts +0 -149
  60. package/dist/src/client/client.d.ts.map +0 -1
  61. package/dist/src/client/client.js +0 -308
  62. package/dist/src/client/client.js.map +0 -1
  63. package/dist/src/client/index.d.ts.map +0 -1
  64. package/dist/src/client/sub_key.d.ts +0 -20
  65. package/dist/src/client/sub_key.d.ts.map +0 -1
  66. package/dist/src/client/sub_key.js +0 -37
  67. package/dist/src/client/sub_key.js.map +0 -1
  68. package/dist/src/client/ws_client_manager.d.ts +0 -268
  69. package/dist/src/client/ws_client_manager.d.ts.map +0 -1
  70. package/dist/src/client/ws_client_manager.js +0 -1013
  71. package/dist/src/client/ws_client_manager.js.map +0 -1
  72. package/dist/src/config.d.ts +0 -117
  73. package/dist/src/config.d.ts.map +0 -1
  74. package/dist/src/config.js +0 -2
  75. package/dist/src/config.js.map +0 -1
  76. package/dist/src/db/bytes.d.ts +0 -4
  77. package/dist/src/db/bytes.d.ts.map +0 -1
  78. package/dist/src/db/bytes.js +0 -24
  79. package/dist/src/db/bytes.js.map +0 -1
  80. package/dist/src/db/cache.d.ts +0 -30
  81. package/dist/src/db/cache.d.ts.map +0 -1
  82. package/dist/src/db/cache.js +0 -153
  83. package/dist/src/db/cache.js.map +0 -1
  84. package/dist/src/db/codec.d.ts +0 -10
  85. package/dist/src/db/codec.d.ts.map +0 -1
  86. package/dist/src/db/codec.js +0 -73
  87. package/dist/src/db/codec.js.map +0 -1
  88. package/dist/src/db/context.d.ts +0 -28
  89. package/dist/src/db/context.d.ts.map +0 -1
  90. package/dist/src/db/context.js +0 -147
  91. package/dist/src/db/context.js.map +0 -1
  92. package/dist/src/db/db.d.ts +0 -154
  93. package/dist/src/db/db.d.ts.map +0 -1
  94. package/dist/src/db/db.js +0 -23
  95. package/dist/src/db/db.js.map +0 -1
  96. package/dist/src/db/mysql.d.ts +0 -120
  97. package/dist/src/db/mysql.d.ts.map +0 -1
  98. package/dist/src/db/mysql.js +0 -708
  99. package/dist/src/db/mysql.js.map +0 -1
  100. package/dist/src/db/postgres.d.ts +0 -116
  101. package/dist/src/db/postgres.d.ts.map +0 -1
  102. package/dist/src/db/postgres.js +0 -998
  103. package/dist/src/db/postgres.js.map +0 -1
  104. package/dist/src/db/query.d.ts +0 -174
  105. package/dist/src/db/query.d.ts.map +0 -1
  106. package/dist/src/db/query.js +0 -790
  107. package/dist/src/db/query.js.map +0 -1
  108. package/dist/src/db/query_definition.d.ts +0 -54
  109. package/dist/src/db/query_definition.d.ts.map +0 -1
  110. package/dist/src/db/query_definition.js +0 -47
  111. package/dist/src/db/query_definition.js.map +0 -1
  112. package/dist/src/db/realtime_db.d.ts +0 -19
  113. package/dist/src/db/realtime_db.d.ts.map +0 -1
  114. package/dist/src/db/realtime_db.js +0 -98
  115. package/dist/src/db/realtime_db.js.map +0 -1
  116. package/dist/src/db/schema.d.ts +0 -110
  117. package/dist/src/db/schema.d.ts.map +0 -1
  118. package/dist/src/db/schema.js +0 -47
  119. package/dist/src/db/schema.js.map +0 -1
  120. package/dist/src/db/types_client_rpc.d.ts +0 -157
  121. package/dist/src/db/types_client_rpc.d.ts.map +0 -1
  122. package/dist/src/db/types_client_rpc.js +0 -106
  123. package/dist/src/db/types_client_rpc.js.map +0 -1
  124. package/dist/src/db/types_db.d.ts +0 -236
  125. package/dist/src/db/types_db.d.ts.map +0 -1
  126. package/dist/src/db/types_db.js +0 -188
  127. package/dist/src/db/types_db.js.map +0 -1
  128. package/dist/src/exports/mysql.d.ts.map +0 -1
  129. package/dist/src/exports/mysql.js.map +0 -1
  130. package/dist/src/exports/postgres.d.ts.map +0 -1
  131. package/dist/src/exports/postgres.js.map +0 -1
  132. package/dist/src/exports/procedure.d.ts.map +0 -1
  133. package/dist/src/exports/procedure.js.map +0 -1
  134. package/dist/src/exports/types.d.ts.map +0 -1
  135. package/dist/src/exports/types.js.map +0 -1
  136. package/dist/src/helper.d.ts +0 -11
  137. package/dist/src/helper.d.ts.map +0 -1
  138. package/dist/src/helper.js +0 -45
  139. package/dist/src/helper.js.map +0 -1
  140. package/dist/src/logger.d.ts +0 -7
  141. package/dist/src/logger.d.ts.map +0 -1
  142. package/dist/src/logger.js +0 -47
  143. package/dist/src/logger.js.map +0 -1
  144. package/dist/src/router/index.d.ts +0 -4
  145. package/dist/src/router/index.d.ts.map +0 -1
  146. package/dist/src/router/index.js +0 -4
  147. package/dist/src/router/index.js.map +0 -1
  148. package/dist/src/router/procedure.d.ts +0 -204
  149. package/dist/src/router/procedure.d.ts.map +0 -1
  150. package/dist/src/router/procedure.js +0 -122
  151. package/dist/src/router/procedure.js.map +0 -1
  152. package/dist/src/router/router.d.ts +0 -88
  153. package/dist/src/router/router.d.ts.map +0 -1
  154. package/dist/src/router/router.js +0 -88
  155. package/dist/src/router/router.js.map +0 -1
  156. package/dist/src/server/hash.d.ts +0 -12
  157. package/dist/src/server/hash.d.ts.map +0 -1
  158. package/dist/src/server/hash.js +0 -20
  159. package/dist/src/server/hash.js.map +0 -1
  160. package/dist/src/server/hash.test.d.ts +0 -2
  161. package/dist/src/server/hash.test.d.ts.map +0 -1
  162. package/dist/src/server/hash.test.js +0 -43
  163. package/dist/src/server/hash.test.js.map +0 -1
  164. package/dist/src/server/index.d.ts +0 -9
  165. package/dist/src/server/index.d.ts.map +0 -1
  166. package/dist/src/server/index.js +0 -8
  167. package/dist/src/server/index.js.map +0 -1
  168. package/dist/src/server/overlap-checker.d.ts +0 -18
  169. package/dist/src/server/overlap-checker.d.ts.map +0 -1
  170. package/dist/src/server/overlap-checker.js +0 -247
  171. package/dist/src/server/overlap-checker.js.map +0 -1
  172. package/dist/src/server/sub_hash.d.ts +0 -23
  173. package/dist/src/server/sub_hash.d.ts.map +0 -1
  174. package/dist/src/server/sub_hash.js +0 -38
  175. package/dist/src/server/sub_hash.js.map +0 -1
  176. package/dist/src/server/subscription-manager-client.d.ts +0 -120
  177. package/dist/src/server/subscription-manager-client.d.ts.map +0 -1
  178. package/dist/src/server/subscription-manager-client.js +0 -207
  179. package/dist/src/server/subscription-manager-client.js.map +0 -1
  180. package/dist/src/server/subscription-manager-types.d.ts +0 -168
  181. package/dist/src/server/subscription-manager-types.d.ts.map +0 -1
  182. package/dist/src/server/subscription-manager-types.js +0 -94
  183. package/dist/src/server/subscription-manager-types.js.map +0 -1
  184. package/dist/src/server/subscription-manager-worker-entry.d.ts +0 -2
  185. package/dist/src/server/subscription-manager-worker-entry.d.ts.map +0 -1
  186. package/dist/src/server/subscription-manager-worker-entry.js +0 -127
  187. package/dist/src/server/subscription-manager-worker-entry.js.map +0 -1
  188. package/dist/src/server/subscription-manager-worker-protocol.d.ts +0 -40
  189. package/dist/src/server/subscription-manager-worker-protocol.d.ts.map +0 -1
  190. package/dist/src/server/subscription-manager-worker-protocol.js +0 -20
  191. package/dist/src/server/subscription-manager-worker-protocol.js.map +0 -1
  192. package/dist/src/server/subscription-manager.d.ts +0 -32
  193. package/dist/src/server/subscription-manager.d.ts.map +0 -1
  194. package/dist/src/server/subscription-manager.js +0 -249
  195. package/dist/src/server/subscription-manager.js.map +0 -1
  196. package/dist/src/server/subscription-manager.test.d.ts +0 -2
  197. package/dist/src/server/subscription-manager.test.d.ts.map +0 -1
  198. package/dist/src/server/subscription-manager.test.js +0 -610
  199. package/dist/src/server/subscription-manager.test.js.map +0 -1
  200. package/dist/src/server/subscription-worker.d.ts +0 -32
  201. package/dist/src/server/subscription-worker.d.ts.map +0 -1
  202. package/dist/src/server/subscription-worker.js +0 -190
  203. package/dist/src/server/subscription-worker.js.map +0 -1
  204. package/dist/src/server/supalive-server.d.ts +0 -158
  205. package/dist/src/server/supalive-server.d.ts.map +0 -1
  206. package/dist/src/server/supalive-server.js +0 -1048
  207. package/dist/src/server/supalive-server.js.map +0 -1
  208. package/dist/src/server/types_server.d.ts +0 -96
  209. package/dist/src/server/types_server.d.ts.map +0 -1
  210. package/dist/src/server/types_server.js +0 -36
  211. package/dist/src/server/types_server.js.map +0 -1
  212. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,713 @@
1
+ import { i as bytesEqual } from "./helper-zdJT5FUc.js";
2
+ import z, { z as z$1 } from "zod";
3
+ //#region src/db/codec.ts
4
+ const commitTsCodec = {
5
+ encode: (value) => value,
6
+ decode: (value) => {
7
+ if (typeof value === "string") return BigInt(value);
8
+ switch (typeof value) {
9
+ case "string":
10
+ case "number":
11
+ case "boolean":
12
+ case "bigint": return BigInt(value);
13
+ default: throw new Error(`Unsupported commitTs type: ${typeof value}`);
14
+ }
15
+ }
16
+ };
17
+ const identityCodec = {
18
+ encode: (value) => value,
19
+ decode: (value) => value
20
+ };
21
+ const numberCodec = {
22
+ encode: (value) => value,
23
+ decode: (value) => typeof value === "string" ? Number(value) : value
24
+ };
25
+ const booleanCodec = {
26
+ encode: (value) => value,
27
+ decode: (value) => {
28
+ if (typeof value === "boolean") return value;
29
+ if (typeof value === "number") return value !== 0;
30
+ if (typeof value === "string") {
31
+ const normalized = value.toLowerCase();
32
+ return normalized === "t" || normalized === "1" || normalized === "true";
33
+ }
34
+ return Boolean(value);
35
+ }
36
+ };
37
+ const dateCodec = {
38
+ encode: (value) => value,
39
+ decode: (value) => value instanceof Date ? value : new Date(value)
40
+ };
41
+ function unwrapZodType(field) {
42
+ let current = field;
43
+ while (current instanceof z.ZodOptional || current instanceof z.ZodNullable || current instanceof z.ZodDefault || current instanceof z.ZodCatch || current instanceof z.ZodReadonly) current = current._def.innerType;
44
+ return current;
45
+ }
46
+ function getDefaultCodec(field) {
47
+ if (field instanceof z.ZodNumber) return numberCodec;
48
+ if (field instanceof z.ZodBoolean) return booleanCodec;
49
+ if (field instanceof z.ZodDate) return dateCodec;
50
+ return identityCodec;
51
+ }
52
+ function normalizeCodec(codec, zodField) {
53
+ const fallback = getDefaultCodec(zodField);
54
+ if (!codec) return fallback;
55
+ return {
56
+ encode: codec.encode ?? fallback.encode,
57
+ decode: codec.decode ?? fallback.decode
58
+ };
59
+ }
60
+ //#endregion
61
+ //#region src/db/query.ts
62
+ function jsonKeysToPath(keys) {
63
+ let out = "$";
64
+ for (const k of keys) out += `."${k.replace(/"/g, "\\\"")}"`;
65
+ return out;
66
+ }
67
+ function resolveJsonPath(opts) {
68
+ if (opts?.path !== void 0 && opts?.pathRaw !== void 0) throw new Error("jsonContains: pass either `path` or `pathRaw`, not both");
69
+ if (opts?.pathRaw !== void 0) return opts.pathRaw;
70
+ if (opts?.path !== void 0) return jsonKeysToPath(Array.isArray(opts.path) ? opts.path : [opts.path]);
71
+ }
72
+ var QueryBuilder = class {
73
+ ctx;
74
+ model;
75
+ constructor(ctx, model) {
76
+ this.ctx = ctx;
77
+ this.model = model;
78
+ }
79
+ getColumnName(key) {
80
+ return this.model.columns[key] ?? key;
81
+ }
82
+ select(...columns) {
83
+ const selectedProps = columns.length > 0 ? columns : Object.keys(this.model.columns);
84
+ return new SelectQueryBuilder(this.ctx, this.model, [], null, null, null, selectedProps);
85
+ }
86
+ };
87
+ var SelectQueryBuilder = class SelectQueryBuilder {
88
+ ctx;
89
+ model;
90
+ filters = [];
91
+ orderByClause = null;
92
+ limitVal = null;
93
+ offsetVal = null;
94
+ selectedProps = [];
95
+ computedFields = [];
96
+ constructor(ctx, model, filters = [], orderByClause = null, limitVal = null, offsetVal = null, selectedProps = [], computedFields = []) {
97
+ this.ctx = ctx;
98
+ this.model = model;
99
+ this.filters = filters;
100
+ this.orderByClause = orderByClause;
101
+ this.limitVal = limitVal;
102
+ this.offsetVal = offsetVal;
103
+ this.selectedProps = selectedProps;
104
+ this.computedFields = computedFields;
105
+ }
106
+ getColumnName(key) {
107
+ return this.model.columns[key] ?? key;
108
+ }
109
+ getPropertyName(column) {
110
+ return this.model.reverseColumns[column] ?? this.computedFields.find((f) => f.alias === column)?.field ?? column;
111
+ }
112
+ mapRowToSchema(row) {
113
+ const result = {};
114
+ for (const [col, value] of Object.entries(row)) {
115
+ const prop = this.getPropertyName(col);
116
+ const codec = this.model.codecs[prop] ?? this.computedFields.find((f) => f.alias === col)?.codec;
117
+ result[prop] = codec?.decode && value !== void 0 && value !== null ? codec.decode(value) : value;
118
+ }
119
+ return result;
120
+ }
121
+ where(filterFn) {
122
+ this.filters.push(filterFn);
123
+ return this;
124
+ }
125
+ orderBy(column, direction = "asc") {
126
+ this.orderByClause = `${this.getColumnName(column)} ${direction}`;
127
+ return this;
128
+ }
129
+ limit(n) {
130
+ this.limitVal = n;
131
+ return this;
132
+ }
133
+ offset(n) {
134
+ this.offsetVal = n;
135
+ return this;
136
+ }
137
+ computed(config) {
138
+ const computed = {
139
+ field: config.field,
140
+ sql: config.sql,
141
+ alias: config.alias ?? config.field,
142
+ codec: normalizeCodec(config.codec, config.type)
143
+ };
144
+ this.computedFields.push(computed);
145
+ return new SelectQueryBuilder(this.ctx, this.model, this.filters, this.orderByClause, this.limitVal, this.offsetVal, [...this.selectedProps, config.field], this.computedFields);
146
+ }
147
+ async first() {
148
+ return (await this.limit(1).get())[0] ?? null;
149
+ }
150
+ async exists() {
151
+ return await this.count() > 0;
152
+ }
153
+ static defaultCountType = z$1.coerce.number();
154
+ async count(parser) {
155
+ const predicate = this.buildPredicate() ?? {
156
+ kind: "leaf",
157
+ column: "1",
158
+ operator: "=",
159
+ value: "1"
160
+ };
161
+ const table = this.model.table;
162
+ const querySpec = {
163
+ kind: "range",
164
+ table,
165
+ tableId: this.model.tableId,
166
+ predicate,
167
+ columns: ["count"],
168
+ orderBy: null,
169
+ limit: null,
170
+ offset: null
171
+ };
172
+ const params = [];
173
+ const sql = `SELECT COUNT(*) as count FROM ${table} WHERE (${buildPredicateSql(predicate, params, this.ctx.db.sqlBuilder)})`;
174
+ const raw = (await this.ctx.db.query(sql, params)).rows[0]?.count ?? "0";
175
+ this.ctx.internalGetReadSet().push({
176
+ ...querySpec,
177
+ tableId: this.model.tableId
178
+ });
179
+ if (parser) return parser.parse(raw);
180
+ else return SelectQueryBuilder.defaultCountType.parse(raw);
181
+ }
182
+ async find(id) {
183
+ if (this.filters.length > 0) throw new Error(`Cannot use find() after where() - find() is meant for primary key lookups without additional filters`);
184
+ const table = this.model.table;
185
+ const tableId = this.model.tableId;
186
+ const pendingWrite = this.ctx.internalGetWriteSet().find((w) => w.id === id && bytesEqual(w.tableId, tableId));
187
+ if (pendingWrite) {
188
+ if (pendingWrite.op === "delete") return null;
189
+ return this.mapRowToSchema({
190
+ ...pendingWrite.data,
191
+ id,
192
+ commit_ts: this.ctx.beginTs
193
+ });
194
+ }
195
+ const computedCols = this.computedFields.map((f) => `${f.sql} as ${f.alias}`);
196
+ const selectPropsWithComputed = this.selectedProps.slice(0, this.selectedProps.length - this.computedFields.length);
197
+ const sql = `SELECT ${selectPropsWithComputed.length > 0 ? [
198
+ "id",
199
+ ...selectPropsWithComputed.map((p) => this.getColumnName(p)),
200
+ ...computedCols,
201
+ "commit_ts"
202
+ ].join(", ") : "*"} FROM ${table} WHERE id = ${this.ctx.db.sqlBuilder.placeholder(1)}`;
203
+ const row = (await this.ctx.db.query(sql, [id])).rows[0] ?? null;
204
+ const expectedCommitTs = row ? BigInt(row.commit_ts) : null;
205
+ this.ctx.internalGetReadSet().push({
206
+ kind: "point",
207
+ table,
208
+ tableId,
209
+ id,
210
+ expectedCommitTs
211
+ });
212
+ return row ? this.mapRowToSchema(row) : null;
213
+ }
214
+ async get() {
215
+ const predicate = this.buildPredicate() ?? {
216
+ kind: "leaf",
217
+ column: "1",
218
+ operator: "=",
219
+ value: "1"
220
+ };
221
+ const table = this.model.table;
222
+ const tableId = this.model.tableId;
223
+ const querySpec = {
224
+ kind: "range",
225
+ table,
226
+ tableId,
227
+ predicate,
228
+ columns: this.selectedProps,
229
+ orderBy: this.orderByClause,
230
+ limit: this.limitVal,
231
+ offset: this.offsetVal
232
+ };
233
+ const params = [];
234
+ const whereSql = buildPredicateSql(predicate, params, this.ctx.db.sqlBuilder);
235
+ const computedCols = this.computedFields.map((f) => `${f.sql} as ${f.alias}`);
236
+ const selectPropsWithComputed = this.selectedProps.slice(0, this.selectedProps.length - this.computedFields.length);
237
+ const selectColsNames = selectPropsWithComputed.length > 0 ? [
238
+ "id",
239
+ ...selectPropsWithComputed.map((p) => this.getColumnName(p)),
240
+ ...computedCols,
241
+ "commit_ts"
242
+ ] : "*";
243
+ let sql = `SELECT ${Array.from(new Set(selectColsNames).values()).join(", ")} FROM ${table} WHERE (${whereSql})`;
244
+ if (this.orderByClause) sql += ` ORDER BY ${this.orderByClause}`;
245
+ if (this.limitVal !== null) sql += ` LIMIT ${this.limitVal}`;
246
+ if (this.offsetVal !== null) sql += ` OFFSET ${this.offsetVal}`;
247
+ const result = await this.ctx.db.query(sql, params);
248
+ this.ctx.internalGetReadSet().push({
249
+ ...querySpec,
250
+ tableId
251
+ });
252
+ return result.rows.map((row) => this.mapRowToSchema(row));
253
+ }
254
+ buildPredicate() {
255
+ if (this.filters.length === 0) return null;
256
+ const predicates = [];
257
+ const fb = new FilterBuilder(this.model.columns, this.model.codecs);
258
+ for (const filterFn of this.filters) {
259
+ filterFn(fb);
260
+ if (fb.predicates.length > 0) {
261
+ if (fb.predicates.some((p) => p.kind === "or")) predicates.push(...fb.predicates);
262
+ else predicates.push({
263
+ kind: "and",
264
+ children: fb.predicates
265
+ });
266
+ fb.predicates = [];
267
+ }
268
+ }
269
+ if (predicates.length === 0) return null;
270
+ if (predicates.length === 1) return predicates[0] ?? null;
271
+ return {
272
+ kind: "and",
273
+ children: predicates
274
+ };
275
+ }
276
+ };
277
+ var FilterBuilder = class FilterBuilder {
278
+ columns;
279
+ codecs;
280
+ predicates = [];
281
+ constructor(columns, codecs) {
282
+ this.columns = columns;
283
+ this.codecs = codecs;
284
+ }
285
+ add(column, operator, value, value2, raw) {
286
+ const leaf = {
287
+ kind: "leaf",
288
+ column,
289
+ operator,
290
+ value,
291
+ value2
292
+ };
293
+ if (raw) leaf.raw = true;
294
+ this.predicates.push(leaf);
295
+ }
296
+ addJsonContains(operator, key, value, opts) {
297
+ const leaf = {
298
+ kind: "leaf",
299
+ column: this.getColumnName(key),
300
+ operator,
301
+ value: this.encodeJson(value, opts?.raw)
302
+ };
303
+ if (opts?.raw) leaf.raw = true;
304
+ const path = resolveJsonPath(opts);
305
+ if (path !== void 0) leaf.path = path;
306
+ this.predicates.push(leaf);
307
+ }
308
+ getColumnName(key) {
309
+ return this.columns[key] ?? key;
310
+ }
311
+ encode(key, value) {
312
+ const codec = this.codecs[key];
313
+ if (!codec?.encode || value === void 0 || value === null) return value;
314
+ return codec.encode(value);
315
+ }
316
+ encodeJson(value, raw) {
317
+ if (value === null || value === void 0) return value;
318
+ if (raw) return value;
319
+ return JSON.stringify(value);
320
+ }
321
+ eq(key, value) {
322
+ this.add(this.getColumnName(key), "=", this.encode(key, value));
323
+ return this;
324
+ }
325
+ neq(key, value) {
326
+ this.add(this.getColumnName(key), "!=", this.encode(key, value));
327
+ return this;
328
+ }
329
+ gt(key, value) {
330
+ this.add(this.getColumnName(key), ">", this.encode(key, value));
331
+ return this;
332
+ }
333
+ gte(key, value) {
334
+ this.add(this.getColumnName(key), ">=", this.encode(key, value));
335
+ return this;
336
+ }
337
+ lt(key, value) {
338
+ this.add(this.getColumnName(key), "<", this.encode(key, value));
339
+ return this;
340
+ }
341
+ lte(key, value) {
342
+ this.add(this.getColumnName(key), "<=", this.encode(key, value));
343
+ return this;
344
+ }
345
+ like(key, pattern) {
346
+ this.add(this.getColumnName(key), "like", this.encode(key, pattern));
347
+ return this;
348
+ }
349
+ ilike(key, pattern) {
350
+ this.add(this.getColumnName(key), "ilike", this.encode(key, pattern));
351
+ return this;
352
+ }
353
+ contains(key, value) {
354
+ this.add(this.getColumnName(key), "contains", this.encode(key, value));
355
+ return this;
356
+ }
357
+ icontains(key, value) {
358
+ this.add(this.getColumnName(key), "icontains", this.encode(key, value));
359
+ return this;
360
+ }
361
+ /**
362
+ * JSON containment. Targets a JSON/JSONB column and asserts the document
363
+ * contains the given candidate (object-key subset for objects,
364
+ * element-subset for arrays — see dialect-specific docs for edge cases).
365
+ * Pass `{ raw: true }` if `value` is already a JSON-encoded string.
366
+ * Pass `{ path: ... }` to scope the check to a sub-document of the
367
+ * target (jsonb_path_query_first on PG, JSON_CONTAINS path arg on MySQL).
368
+ */
369
+ jsonContains(key, value, opts) {
370
+ this.addJsonContains("jsonContains", key, value, opts);
371
+ return this;
372
+ }
373
+ /** Inverse of {@link jsonContains}: column is contained in the given value. */
374
+ jsonContainedBy(key, value, opts) {
375
+ this.addJsonContains("jsonContainedBy", key, value, opts);
376
+ return this;
377
+ }
378
+ jsonHasKey(key, value, opts) {
379
+ const col = this.getColumnName(key);
380
+ if (opts?.mode && Array.isArray(value)) {
381
+ const leaf = {
382
+ kind: "leaf",
383
+ column: col,
384
+ operator: "jsonHasKey",
385
+ value: value.map((p) => opts.raw && typeof p === "string" ? p : jsonKeysToPath(Array.isArray(p) ? p : [p])),
386
+ mode: opts.mode
387
+ };
388
+ this.predicates.push(leaf);
389
+ return this;
390
+ }
391
+ if (Array.isArray(value)) this.add(col, "jsonHasKey", jsonKeysToPath(value), void 0, true);
392
+ else if (opts?.raw) this.add(col, "jsonHasKey", value, void 0, true);
393
+ else this.add(col, "jsonHasKey", value, void 0, false);
394
+ return this;
395
+ }
396
+ /**
397
+ * Array element containment: target column is a JSON array; the given
398
+ * `value` (any JSON-encodable type) must appear as one of its elements.
399
+ * Pass `{ raw: true }` if `value` is already a JSON-encoded string.
400
+ * Pass `{ path: ... }` to scope the check to a sub-array of the column.
401
+ */
402
+ jsonArrayContains(key, value, opts) {
403
+ this.addJsonContains("jsonArrayContains", key, value, opts);
404
+ return this;
405
+ }
406
+ between(key, lo, hi) {
407
+ this.add(this.getColumnName(key), "between", this.encode(key, lo), this.encode(key, hi));
408
+ return this;
409
+ }
410
+ isNull(key) {
411
+ this.add(this.getColumnName(key), "isNull", null);
412
+ return this;
413
+ }
414
+ notNull(key) {
415
+ this.add(this.getColumnName(key), "isNotNull", null);
416
+ return this;
417
+ }
418
+ /**
419
+ * Compose an OR clause. Each callback fills a fresh sub-FilterBuilder
420
+ * with predicates that are AND-ed together within that branch; the
421
+ * branches themselves are OR-ed. Example:
422
+ * f.or([
423
+ * b => b.eq("tag", "a"),
424
+ * b => b.eq("tag", "b").gt("qty", 3), // (tag=b AND qty>3)
425
+ * ])
426
+ * produces (tag=a) OR (tag=b AND qty>3).
427
+ */
428
+ or(branches) {
429
+ const children = [];
430
+ for (const fn of branches) {
431
+ const sub = new FilterBuilder(this.columns, this.codecs);
432
+ fn(sub);
433
+ if (sub.predicates.length === 1) children.push(sub.predicates[0]);
434
+ else if (sub.predicates.length > 1) children.push({
435
+ kind: "and",
436
+ children: sub.predicates
437
+ });
438
+ }
439
+ if (children.length > 0) this.predicates.push({
440
+ kind: "or",
441
+ children
442
+ });
443
+ return this;
444
+ }
445
+ };
446
+ function buildPredicateSql(predicate, params, sql) {
447
+ switch (predicate.kind) {
448
+ case "and": return `(${predicate.children.map((c) => buildPredicateSql(c, params, sql)).join(" AND ")})`;
449
+ case "or": return `(${predicate.children.map((c) => buildPredicateSql(c, params, sql)).join(" OR ")})`;
450
+ case "leaf": return buildLeafSql(predicate, params, sql);
451
+ }
452
+ }
453
+ function buildLeafSql(leaf, params, sql) {
454
+ const col = leaf.column;
455
+ switch (leaf.operator) {
456
+ case "=":
457
+ case "!=":
458
+ case ">":
459
+ case ">=":
460
+ case "<":
461
+ case "<=":
462
+ params.push(leaf.value);
463
+ return `${col} ${leaf.operator} ${sql.placeholder(params.length)}`;
464
+ case "between": {
465
+ params.push(leaf.value);
466
+ const p1 = sql.placeholder(params.length);
467
+ params.push(leaf.value2);
468
+ return `${col} BETWEEN ${p1} AND ${sql.placeholder(params.length)}`;
469
+ }
470
+ case "like":
471
+ params.push(leaf.value);
472
+ return `${col} LIKE ${sql.placeholder(params.length)}`;
473
+ case "ilike":
474
+ params.push(leaf.value);
475
+ return sql.ilike(col, params.length);
476
+ case "contains":
477
+ params.push(`%${leaf.value}%`);
478
+ return `${col} LIKE ${sql.placeholder(params.length)}`;
479
+ case "icontains":
480
+ params.push(`%${leaf.value}%`);
481
+ return sql.icontains(col, params.length);
482
+ case "jsonContains": {
483
+ params.push(leaf.value);
484
+ const valIdx = params.length;
485
+ let pathIndex;
486
+ if (leaf.path !== void 0) {
487
+ params.push(leaf.path);
488
+ pathIndex = params.length;
489
+ }
490
+ return sql.jsonContains(col, valIdx, {
491
+ raw: leaf.raw,
492
+ pathIndex
493
+ });
494
+ }
495
+ case "jsonContainedBy": {
496
+ params.push(leaf.value);
497
+ const valIdx = params.length;
498
+ let pathIndex;
499
+ if (leaf.path !== void 0) {
500
+ params.push(leaf.path);
501
+ pathIndex = params.length;
502
+ }
503
+ return sql.jsonContainedBy(col, valIdx, {
504
+ raw: leaf.raw,
505
+ pathIndex
506
+ });
507
+ }
508
+ case "jsonHasKey":
509
+ if (leaf.mode && Array.isArray(leaf.value)) {
510
+ const paths = leaf.value;
511
+ const startIdx = params.length + 1;
512
+ for (const p of paths) params.push(p);
513
+ return sql.jsonHasKey(col, startIdx, {
514
+ raw: true,
515
+ mode: leaf.mode,
516
+ pathCount: paths.length
517
+ });
518
+ }
519
+ params.push(leaf.value);
520
+ return sql.jsonHasKey(col, params.length, { raw: leaf.raw });
521
+ case "jsonArrayContains": {
522
+ params.push(leaf.value);
523
+ const valIdx = params.length;
524
+ let pathIndex;
525
+ if (leaf.path !== void 0) {
526
+ params.push(leaf.path);
527
+ pathIndex = params.length;
528
+ }
529
+ return sql.jsonArrayContains(col, valIdx, {
530
+ raw: leaf.raw,
531
+ pathIndex
532
+ });
533
+ }
534
+ case "isNull": return `${col} IS NULL`;
535
+ case "isNotNull": return `${col} IS NOT NULL`;
536
+ }
537
+ }
538
+ function matchesPredicate(row, predicate) {
539
+ switch (predicate.kind) {
540
+ case "and": return predicate.children.every((c) => matchesPredicate(row, c));
541
+ case "or": return predicate.children.some((c) => matchesPredicate(row, c));
542
+ case "leaf": return matchesLeaf(row, predicate);
543
+ }
544
+ }
545
+ function matchesLeaf(row, leaf) {
546
+ const val = row[leaf.column];
547
+ switch (leaf.operator) {
548
+ case "=": return val === leaf.value;
549
+ case "!=": return val !== leaf.value;
550
+ case ">": return val > leaf.value;
551
+ case ">=": return val >= leaf.value;
552
+ case "<": return val < leaf.value;
553
+ case "<=": return val <= leaf.value;
554
+ case "between": return val >= leaf.value && val <= leaf.value2;
555
+ case "like":
556
+ case "contains":
557
+ case "ilike":
558
+ case "icontains": {
559
+ if (typeof val !== "string" || typeof leaf.value !== "string") return false;
560
+ const haystack = leaf.operator === "ilike" || leaf.operator === "icontains" ? val.toLowerCase() : val;
561
+ const raw = leaf.value;
562
+ const needle = leaf.operator === "ilike" || leaf.operator === "icontains" ? raw.toLowerCase() : raw;
563
+ const pattern = leaf.operator === "contains" || leaf.operator === "icontains" ? `%${needle}%` : needle;
564
+ return new RegExp("^" + pattern.replace(/%/g, ".*").replace(/_/g, ".") + "$").test(haystack);
565
+ }
566
+ case "jsonContains": {
567
+ const candidate = decodeJsonLeafValue(leaf);
568
+ const target = leaf.path !== void 0 ? jsonPathExtract(val, leaf.path) : val;
569
+ if (target === void 0) return false;
570
+ return jsonContains(target, candidate);
571
+ }
572
+ case "jsonContainedBy": {
573
+ const candidate = decodeJsonLeafValue(leaf);
574
+ const target = leaf.path !== void 0 ? jsonPathExtract(val, leaf.path) : val;
575
+ if (target === void 0) return false;
576
+ return jsonContains(candidate, target);
577
+ }
578
+ case "jsonHasKey": {
579
+ if (leaf.mode && Array.isArray(leaf.value)) {
580
+ const paths = leaf.value;
581
+ if (paths.length === 0) return false;
582
+ return leaf.mode === "all" ? paths.every((p) => jsonPathExists(val, p)) : paths.some((p) => jsonPathExists(val, p));
583
+ }
584
+ if (leaf.raw) return jsonPathExists(val, leaf.value);
585
+ const key = leaf.value;
586
+ if (val === null || typeof val !== "object") return false;
587
+ if (Array.isArray(val)) return val.includes(key);
588
+ return key in val;
589
+ }
590
+ case "jsonArrayContains": {
591
+ const candidate = decodeJsonLeafValue(leaf);
592
+ const target = leaf.path !== void 0 ? jsonPathExtract(val, leaf.path) : val;
593
+ if (!Array.isArray(target)) return false;
594
+ return target.some((el) => jsonContains(el, candidate));
595
+ }
596
+ case "isNull": return val === null;
597
+ case "isNotNull": return val !== null;
598
+ default: return false;
599
+ }
600
+ }
601
+ function decodeJsonLeafValue(leaf) {
602
+ if (!leaf.raw) return leaf.value;
603
+ if (typeof leaf.value !== "string") return leaf.value;
604
+ try {
605
+ return JSON.parse(leaf.value);
606
+ } catch {
607
+ return leaf.value;
608
+ }
609
+ }
610
+ function jsonContains(target, candidate) {
611
+ if (candidate === target) return true;
612
+ if (target === null || candidate === null) return target === candidate;
613
+ if (target === void 0 || candidate === void 0) return false;
614
+ const tArr = Array.isArray(target);
615
+ const cArr = Array.isArray(candidate);
616
+ const tObj = !tArr && typeof target === "object";
617
+ const cObj = !cArr && typeof candidate === "object";
618
+ if (!cArr && !cObj && tArr) return target.some((el) => jsonContains(el, candidate));
619
+ if (cArr && tArr) {
620
+ const t = target;
621
+ return candidate.every((c) => t.some((el) => jsonContains(el, c)));
622
+ }
623
+ if (cObj && tObj) {
624
+ const t = target;
625
+ const c = candidate;
626
+ for (const k of Object.keys(c)) {
627
+ if (!(k in t)) return false;
628
+ if (!jsonContains(t[k], c[k])) return false;
629
+ }
630
+ return true;
631
+ }
632
+ return false;
633
+ }
634
+ function jsonPathExtract(val, path) {
635
+ let p = path;
636
+ if (p.startsWith("$")) p = p.slice(1);
637
+ let cur = val;
638
+ while (p.length > 0) if (p.startsWith(".\"")) {
639
+ let end = 2;
640
+ while (end < p.length) {
641
+ if (p[end] === "\\" && end + 1 < p.length) {
642
+ end += 2;
643
+ continue;
644
+ }
645
+ if (p[end] === "\"") break;
646
+ end++;
647
+ }
648
+ if (end >= p.length) return void 0;
649
+ const key = p.slice(2, end).replace(/\\"/g, "\"").replace(/\\\\/g, "\\");
650
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) return void 0;
651
+ if (!(key in cur)) return void 0;
652
+ cur = cur[key];
653
+ p = p.slice(end + 1);
654
+ } else if (p.startsWith(".")) {
655
+ const m = p.slice(1).match(/^([^.[]+)/);
656
+ if (!m) return void 0;
657
+ const key = m[1];
658
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) return void 0;
659
+ if (!(key in cur)) return void 0;
660
+ cur = cur[key];
661
+ p = p.slice(1 + key.length);
662
+ } else if (p.startsWith("[")) {
663
+ const end = p.indexOf("]");
664
+ if (end === -1) return void 0;
665
+ const idx = parseInt(p.slice(1, end), 10);
666
+ if (!Array.isArray(cur) || idx < 0 || idx >= cur.length) return void 0;
667
+ cur = cur[idx];
668
+ p = p.slice(end + 1);
669
+ } else return;
670
+ return cur;
671
+ }
672
+ function jsonPathExists(val, path) {
673
+ let p = path;
674
+ if (p.startsWith("$")) p = p.slice(1);
675
+ let cur = val;
676
+ while (p.length > 0) if (p.startsWith(".\"")) {
677
+ let end = 2;
678
+ while (end < p.length) {
679
+ if (p[end] === "\\" && end + 1 < p.length) {
680
+ end += 2;
681
+ continue;
682
+ }
683
+ if (p[end] === "\"") break;
684
+ end++;
685
+ }
686
+ if (end >= p.length) return false;
687
+ const key = p.slice(2, end).replace(/\\"/g, "\"").replace(/\\\\/g, "\\");
688
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) return false;
689
+ if (!(key in cur)) return false;
690
+ cur = cur[key];
691
+ p = p.slice(end + 1);
692
+ } else if (p.startsWith(".")) {
693
+ const m = p.slice(1).match(/^([^.[]+)/);
694
+ if (!m) return false;
695
+ const key = m[1];
696
+ if (cur === null || typeof cur !== "object" || Array.isArray(cur)) return false;
697
+ if (!(key in cur)) return false;
698
+ cur = cur[key];
699
+ p = p.slice(1 + key.length);
700
+ } else if (p.startsWith("[")) {
701
+ const end = p.indexOf("]");
702
+ if (end === -1) return false;
703
+ const idx = parseInt(p.slice(1, end), 10);
704
+ if (!Array.isArray(cur) || idx < 0 || idx >= cur.length) return false;
705
+ cur = cur[idx];
706
+ p = p.slice(end + 1);
707
+ } else return false;
708
+ return cur !== void 0;
709
+ }
710
+ //#endregion
711
+ export { jsonPathExtract as a, normalizeCodec as c, jsonPathExists as i, unwrapZodType as l, buildPredicateSql as n, matchesPredicate as o, jsonContains as r, commitTsCodec as s, QueryBuilder as t };
712
+
713
+ //# sourceMappingURL=query-CbQLjeME.js.map