@prisma-next/sql-lane 0.3.0-dev.7 → 0.3.0-dev.70

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 (64) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +20 -3
  3. package/dist/builder-DLGrrQ5F.mjs +1254 -0
  4. package/dist/builder-DLGrrQ5F.mjs.map +1 -0
  5. package/dist/builder-DizPddCD.d.mts +121 -0
  6. package/dist/builder-DizPddCD.d.mts.map +1 -0
  7. package/dist/exports/sql.d.mts +3 -0
  8. package/dist/exports/sql.mjs +3 -0
  9. package/dist/index.d.mts +3 -0
  10. package/dist/index.mjs +3 -0
  11. package/package.json +27 -23
  12. package/src/raw.ts +9 -2
  13. package/src/sql/context.ts +3 -3
  14. package/src/sql/include-builder.ts +3 -3
  15. package/src/sql/mutation-builder.ts +61 -10
  16. package/src/sql/plan.ts +117 -102
  17. package/src/sql/predicate-builder.ts +94 -40
  18. package/src/sql/projection.ts +15 -10
  19. package/src/sql/select-builder.ts +26 -41
  20. package/src/types/internal.ts +5 -4
  21. package/src/utils/errors.ts +1 -1
  22. package/src/utils/state.ts +5 -6
  23. package/dist/chunk-AWSKRSFP.js +0 -1569
  24. package/dist/chunk-AWSKRSFP.js.map +0 -1
  25. package/dist/exports/sql.d.ts +0 -5
  26. package/dist/exports/sql.d.ts.map +0 -1
  27. package/dist/exports/sql.js +0 -11
  28. package/dist/exports/sql.js.map +0 -1
  29. package/dist/index.d.ts +0 -5
  30. package/dist/index.d.ts.map +0 -1
  31. package/dist/index.js +0 -11
  32. package/dist/index.js.map +0 -1
  33. package/dist/raw.d.ts +0 -11
  34. package/dist/raw.d.ts.map +0 -1
  35. package/dist/sql/builder.d.ts +0 -11
  36. package/dist/sql/builder.d.ts.map +0 -1
  37. package/dist/sql/context.d.ts +0 -5
  38. package/dist/sql/context.d.ts.map +0 -1
  39. package/dist/sql/include-builder.d.ts +0 -35
  40. package/dist/sql/include-builder.d.ts.map +0 -1
  41. package/dist/sql/join-builder.d.ts +0 -4
  42. package/dist/sql/join-builder.d.ts.map +0 -1
  43. package/dist/sql/mutation-builder.d.ts +0 -64
  44. package/dist/sql/mutation-builder.d.ts.map +0 -1
  45. package/dist/sql/plan.d.ts +0 -4
  46. package/dist/sql/plan.d.ts.map +0 -1
  47. package/dist/sql/predicate-builder.d.ts +0 -11
  48. package/dist/sql/predicate-builder.d.ts.map +0 -1
  49. package/dist/sql/projection.d.ts +0 -18
  50. package/dist/sql/projection.d.ts.map +0 -1
  51. package/dist/sql/select-builder.d.ts +0 -35
  52. package/dist/sql/select-builder.d.ts.map +0 -1
  53. package/dist/types/internal.d.ts +0 -35
  54. package/dist/types/internal.d.ts.map +0 -1
  55. package/dist/types/public.d.ts +0 -18
  56. package/dist/types/public.d.ts.map +0 -1
  57. package/dist/utils/assertions.d.ts +0 -28
  58. package/dist/utils/assertions.d.ts.map +0 -1
  59. package/dist/utils/capabilities.d.ts +0 -4
  60. package/dist/utils/capabilities.d.ts.map +0 -1
  61. package/dist/utils/errors.d.ts +0 -30
  62. package/dist/utils/errors.d.ts.map +0 -1
  63. package/dist/utils/state.d.ts +0 -30
  64. package/dist/utils/state.d.ts.map +0 -1
@@ -0,0 +1,1254 @@
1
+ import { planInvalid } from "@prisma-next/plan";
2
+ import { compact, createBinaryExpr, createColumnRef, createDeleteAst, createInsertAst, createJoin, createJoinOnBuilder, createJoinOnBuilder as createJoinOnBuilder$1, createJoinOnExpr, createNullCheckExpr, createOrderByItem, createParamRef, createSelectAst, createTableRef, createUpdateAst } from "@prisma-next/sql-relational-core/ast";
3
+ import { collectColumnRefs, extractBaseColumnRef, isColumnBuilder, isExpressionBuilder, isExpressionSource, isOperationExpr, isParamPlaceholder } from "@prisma-next/sql-relational-core/utils/guards";
4
+
5
+ //#region src/raw.ts
6
+ const RAW_OPTIONS_SENTINEL = Symbol("rawOptions");
7
+ function ifDefined(key, value) {
8
+ return value !== void 0 ? { [key]: value } : {};
9
+ }
10
+ function createRawFactory(contract) {
11
+ const factory = ((first, ...rest) => {
12
+ if (isTemplateInvocation(first)) {
13
+ const { values, options: options$1 } = splitTemplateValues(rest);
14
+ const compiled = compileTemplateToPositional(first, values);
15
+ return buildRawPlan({
16
+ contract,
17
+ sql: compiled.sql,
18
+ params: compiled.params,
19
+ paramDescriptors: compiled.paramDescriptors,
20
+ ...options$1 ? { options: options$1 } : {}
21
+ });
22
+ }
23
+ const text = first;
24
+ const [options] = rest;
25
+ if (!options) throw planInvalid("Function form requires params option");
26
+ if (!Array.isArray(options.params)) throw planInvalid("Function form params must be an array");
27
+ const paramDescriptors = buildSequentialDescriptors(options.params.length);
28
+ return buildRawPlan({
29
+ contract,
30
+ sql: text,
31
+ params: options.params,
32
+ paramDescriptors,
33
+ options
34
+ });
35
+ });
36
+ factory.with = (options) => {
37
+ return ((strings, ...values) => {
38
+ const compiled = compileTemplateToPositional(strings, values);
39
+ return buildRawPlan({
40
+ contract,
41
+ sql: compiled.sql,
42
+ params: compiled.params,
43
+ paramDescriptors: compiled.paramDescriptors,
44
+ options
45
+ });
46
+ });
47
+ };
48
+ return factory;
49
+ }
50
+ function compileTemplateToPositional(strings, values) {
51
+ let sql$1 = "";
52
+ const params = [];
53
+ const paramDescriptors = [];
54
+ strings.forEach((part, index) => {
55
+ sql$1 += part;
56
+ if (index < values.length) {
57
+ const value = values[index];
58
+ const placeholderIndex = params.push(value);
59
+ sql$1 += `$${placeholderIndex}`;
60
+ paramDescriptors.push({
61
+ index: placeholderIndex,
62
+ name: `p${placeholderIndex}`,
63
+ source: "raw"
64
+ });
65
+ }
66
+ });
67
+ return {
68
+ sql: sql$1,
69
+ params,
70
+ paramDescriptors
71
+ };
72
+ }
73
+ function buildRawPlan(args) {
74
+ const params = Array.from(args.params);
75
+ const descriptors = args.paramDescriptors.map((descriptor) => Object.freeze({
76
+ ...descriptor,
77
+ source: "raw"
78
+ }));
79
+ const meta = buildRawMeta({
80
+ contract: args.contract,
81
+ paramDescriptors: descriptors,
82
+ ...args.options ? { options: args.options } : {}
83
+ });
84
+ return Object.freeze({
85
+ sql: args.sql,
86
+ params: Object.freeze(params),
87
+ meta
88
+ });
89
+ }
90
+ function buildRawMeta(args) {
91
+ const { contract, paramDescriptors, options } = args;
92
+ const meta = {
93
+ target: contract.target,
94
+ targetFamily: contract.targetFamily,
95
+ storageHash: contract.storageHash,
96
+ ...ifDefined("profileHash", contract.profileHash),
97
+ lane: "raw",
98
+ paramDescriptors: Object.freeze([...paramDescriptors]),
99
+ ...options?.annotations ? { annotations: Object.freeze({ ...options.annotations }) } : {},
100
+ ...options?.refs ? { refs: freezeRefs(options.refs) } : {},
101
+ ...options?.projection ? { projection: Object.freeze([...options.projection]) } : {}
102
+ };
103
+ return Object.freeze(meta);
104
+ }
105
+ function freezeRefs(refs) {
106
+ return Object.freeze({
107
+ ...refs.tables ? { tables: Object.freeze([...refs.tables]) } : {},
108
+ ...refs.columns ? { columns: Object.freeze(refs.columns.map((col) => Object.freeze({ ...col }))) } : {},
109
+ ...refs.indexes ? { indexes: Object.freeze(refs.indexes.map((index) => Object.freeze({
110
+ ...index,
111
+ columns: Object.freeze([...index.columns])
112
+ }))) } : {}
113
+ });
114
+ }
115
+ function buildSequentialDescriptors(count) {
116
+ return Array.from({ length: count }, (_, idx) => Object.freeze({
117
+ index: idx + 1,
118
+ name: `p${idx + 1}`,
119
+ source: "raw"
120
+ }));
121
+ }
122
+ function isTemplateInvocation(value) {
123
+ return Array.isArray(value) && Object.hasOwn(value, "raw");
124
+ }
125
+ function rawOptions(options) {
126
+ return Object.freeze({
127
+ [RAW_OPTIONS_SENTINEL]: true,
128
+ value: options
129
+ });
130
+ }
131
+ function splitTemplateValues(values) {
132
+ if (values.length === 0) return { values };
133
+ const last = values[values.length - 1];
134
+ if (!isOptionsSentinel(last)) return { values };
135
+ return {
136
+ values: values.slice(0, values.length - 1),
137
+ options: last.value
138
+ };
139
+ }
140
+ function isOptionsSentinel(value) {
141
+ return typeof value === "object" && value !== null && RAW_OPTIONS_SENTINEL in value;
142
+ }
143
+
144
+ //#endregion
145
+ //#region src/utils/errors.ts
146
+ function errorAliasPathEmpty() {
147
+ throw planInvalid("Alias path cannot be empty");
148
+ }
149
+ function errorAliasCollision(path, alias, existingPath) {
150
+ throw planInvalid(`Alias collision: path ${path.join(".")} would generate alias "${alias}" which conflicts with path ${existingPath?.join(".") ?? "unknown"}`);
151
+ }
152
+ function errorLimitMustBeNonNegativeInteger() {
153
+ throw planInvalid("Limit must be a non-negative integer");
154
+ }
155
+ function errorChildProjectionMustBeSpecified() {
156
+ throw planInvalid("Child projection must be specified");
157
+ }
158
+ function errorIncludeRequiresCapabilities(target) {
159
+ throw planInvalid("includeMany requires lateral and jsonAgg capabilities", target ? { target } : void 0, [
160
+ "Enable capabilities for your target in contract.capabilities[target]",
161
+ "For SQL includes, set both 'lateral' and 'jsonAgg' to true",
162
+ "If your database lacks lateral/json_agg, use explicit joins + group aggregates"
163
+ ], [
164
+ "docs/Architecture Overview.md",
165
+ "docs/reference/extensions-glossary.md",
166
+ "packages/3-targets/6-adapters/postgres/README.md"
167
+ ]);
168
+ }
169
+ function errorIncludeCapabilitiesNotTrue(target, values) {
170
+ throw planInvalid("includeMany requires lateral and jsonAgg capabilities to be true", target ? {
171
+ target,
172
+ values
173
+ } : void 0, ["Set contract.capabilities[target].lateral = true and .jsonAgg = true", "If the target does not support these, avoid includeMany and compose a two-step plan"], [
174
+ "docs/Architecture Overview.md",
175
+ "docs/reference/extensions-glossary.md",
176
+ "packages/3-targets/6-adapters/postgres/README.md"
177
+ ]);
178
+ }
179
+ function errorUnknownTable(tableName) {
180
+ throw planInvalid(`Unknown table ${tableName}`);
181
+ }
182
+ function errorSelfJoinNotSupported() {
183
+ throw planInvalid("Self-joins are not supported in MVP");
184
+ }
185
+ function errorChildProjectionEmpty() {
186
+ throw planInvalid("Child projection must not be empty");
187
+ }
188
+ function errorIncludeAliasCollision(alias, type) {
189
+ throw planInvalid(`Alias collision: include alias "${alias}" conflicts with existing ${type} alias`);
190
+ }
191
+ function errorMissingColumnForAlias(alias, index) {
192
+ throw planInvalid(`Missing column for alias ${alias ?? "unknown"} at index ${index}`);
193
+ }
194
+ function errorMissingAlias(index) {
195
+ throw planInvalid(`Missing alias at index ${index}`);
196
+ }
197
+ function errorFromMustBeCalled() {
198
+ throw planInvalid("from() must be called before building a query");
199
+ }
200
+ function errorSelectMustBeCalled() {
201
+ throw planInvalid("select() must be called before build()");
202
+ }
203
+ function errorMissingParameter(paramName) {
204
+ throw planInvalid(`Missing value for parameter ${paramName}`);
205
+ }
206
+ function errorInvalidProjectionValue(path) {
207
+ throw planInvalid(`Invalid projection value at path ${path.join(".")}: expected ExpressionSource (ColumnBuilder or ExpressionBuilder) or nested object`);
208
+ }
209
+ function errorIncludeAliasNotFound(alias) {
210
+ throw planInvalid(`Include alias "${alias}" not found. Did you call includeMany() with alias "${alias}"?`);
211
+ }
212
+ function errorInvalidProjectionKey(key) {
213
+ throw planInvalid(`Invalid projection value at key "${key}": expected ColumnBuilder, boolean true (for includes), or nested object`);
214
+ }
215
+ function errorProjectionEmpty() {
216
+ throw planInvalid("select() requires at least one column or include");
217
+ }
218
+ function errorReturningRequiresCapability(target) {
219
+ throw planInvalid("returning() requires returning capability", target ? { target } : void 0, [
220
+ "Enable 'returning' for your target in contract.capabilities[target]",
221
+ "PostgreSQL supports RETURNING; MySQL does not",
222
+ "If unsupported, remove returning() and fetch with a follow-up select()"
223
+ ], [
224
+ "docs/Architecture Overview.md",
225
+ "docs/reference/extensions-glossary.md",
226
+ "packages/3-targets/6-adapters/postgres/README.md"
227
+ ]);
228
+ }
229
+ function errorReturningCapabilityNotTrue(target, value) {
230
+ throw planInvalid("returning() requires returning capability to be true", target ? {
231
+ target,
232
+ value
233
+ } : void 0, ["Set contract.capabilities[target].returning = true", "If your database/adapter cannot support RETURNING, remove returning() and select after"], [
234
+ "docs/Architecture Overview.md",
235
+ "docs/reference/extensions-glossary.md",
236
+ "packages/3-targets/6-adapters/postgres/README.md"
237
+ ]);
238
+ }
239
+ function errorUnknownColumn(columnName, tableName) {
240
+ throw planInvalid(`Unknown column ${columnName} in table ${tableName}`);
241
+ }
242
+ function errorWhereMustBeCalledForUpdate() {
243
+ throw planInvalid("where() must be called before building an UPDATE query");
244
+ }
245
+ function errorFailedToBuildWhereClause() {
246
+ throw planInvalid("Failed to build WHERE clause");
247
+ }
248
+ function errorWhereMustBeCalledForDelete() {
249
+ throw planInvalid("where() must be called before building a DELETE query");
250
+ }
251
+
252
+ //#endregion
253
+ //#region src/utils/capabilities.ts
254
+ function checkIncludeCapabilities(contract) {
255
+ const target = contract.target;
256
+ const contractCapabilities = contract.capabilities;
257
+ const declaredTargetCapabilities = contractCapabilities?.[target];
258
+ if (!contractCapabilities || !declaredTargetCapabilities) errorIncludeRequiresCapabilities(target);
259
+ if (declaredTargetCapabilities["lateral"] !== true || declaredTargetCapabilities["jsonAgg"] !== true) errorIncludeCapabilitiesNotTrue(target, {
260
+ lateral: declaredTargetCapabilities["lateral"],
261
+ jsonAgg: declaredTargetCapabilities["jsonAgg"]
262
+ });
263
+ }
264
+ function checkReturningCapability(contract) {
265
+ const target = contract.target;
266
+ const capabilities = contract.capabilities;
267
+ if (!capabilities || !capabilities[target]) errorReturningRequiresCapability(target);
268
+ const targetCapabilities = capabilities[target];
269
+ if (targetCapabilities["returning"] !== true) errorReturningCapabilityNotTrue(target, targetCapabilities["returning"]);
270
+ }
271
+
272
+ //#endregion
273
+ //#region src/utils/assertions.ts
274
+ /**
275
+ * Asserts that a ColumnBuilder has table and column properties.
276
+ */
277
+ function assertColumnBuilder(col, context) {
278
+ if (typeof col === "object" && col !== null && "table" in col && "column" in col && typeof col.table === "string" && typeof col.column === "string") return col;
279
+ throw planInvalid(`ColumnBuilder missing table/column in ${context}`);
280
+ }
281
+
282
+ //#endregion
283
+ //#region src/sql/plan.ts
284
+ /**
285
+ * Extracts column references from an ExpressionSource (ColumnBuilder or ExpressionBuilder).
286
+ */
287
+ function collectRefsFromExpressionSource(source, refsColumns) {
288
+ if (isExpressionBuilder(source)) {
289
+ const allRefs = collectColumnRefs(source.expr);
290
+ for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
291
+ table: ref.table,
292
+ column: ref.column
293
+ });
294
+ } else if (isColumnBuilder(source)) {
295
+ const col = source;
296
+ refsColumns.set(`${col.table}.${col.column}`, {
297
+ table: col.table,
298
+ column: col.column
299
+ });
300
+ }
301
+ }
302
+ /**
303
+ * Extracts column references from an Expression (AST node).
304
+ */
305
+ function collectRefsFromExpression(expr, refsColumns) {
306
+ if (isOperationExpr(expr)) {
307
+ const allRefs = collectColumnRefs(expr);
308
+ for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
309
+ table: ref.table,
310
+ column: ref.column
311
+ });
312
+ } else if (expr.kind === "col") refsColumns.set(`${expr.table}.${expr.column}`, {
313
+ table: expr.table,
314
+ column: expr.column
315
+ });
316
+ }
317
+ function buildMeta(args) {
318
+ const refsColumns = /* @__PURE__ */ new Map();
319
+ const refsTables = new Set([args.table.name]);
320
+ for (const column of args.projection.columns) collectRefsFromExpressionSource(column, refsColumns);
321
+ if (args.joins) for (const join of args.joins) {
322
+ refsTables.add(join.table.name);
323
+ const onLeft = assertColumnBuilder(join.on.left, "join ON left");
324
+ const onRight = assertColumnBuilder(join.on.right, "join ON right");
325
+ refsColumns.set(`${onLeft.table}.${onLeft.column}`, {
326
+ table: onLeft.table,
327
+ column: onLeft.column
328
+ });
329
+ refsColumns.set(`${onRight.table}.${onRight.column}`, {
330
+ table: onRight.table,
331
+ column: onRight.column
332
+ });
333
+ }
334
+ if (args.includes) for (const include of args.includes) {
335
+ refsTables.add(include.table.name);
336
+ const leftCol = assertColumnBuilder(include.on.left, "include ON left");
337
+ const rightCol = assertColumnBuilder(include.on.right, "include ON right");
338
+ refsColumns.set(`${leftCol.table}.${leftCol.column}`, {
339
+ table: leftCol.table,
340
+ column: leftCol.column
341
+ });
342
+ refsColumns.set(`${rightCol.table}.${rightCol.column}`, {
343
+ table: rightCol.table,
344
+ column: rightCol.column
345
+ });
346
+ for (const column of include.childProjection.columns) {
347
+ const col = assertColumnBuilder(column, "include child projection column");
348
+ refsColumns.set(`${col.table}.${col.column}`, {
349
+ table: col.table,
350
+ column: col.column
351
+ });
352
+ }
353
+ if (include.childWhere) if (include.childWhere.kind === "nullCheck") {
354
+ const expr = include.childWhere.expr;
355
+ collectRefsFromExpression(expr, refsColumns);
356
+ } else {
357
+ collectRefsFromExpression(include.childWhere.left, refsColumns);
358
+ const childWhereRight = include.childWhere.right;
359
+ if (isColumnBuilder(childWhereRight) || isExpressionBuilder(childWhereRight)) collectRefsFromExpressionSource(childWhereRight, refsColumns);
360
+ }
361
+ if (include.childOrderBy) collectRefsFromExpression(include.childOrderBy.expr, refsColumns);
362
+ }
363
+ if (args.where) if (args.where.kind === "nullCheck") {
364
+ const expr = args.where.expr;
365
+ collectRefsFromExpression(expr, refsColumns);
366
+ } else {
367
+ const leftExpr = args.where.left;
368
+ if (isOperationExpr(leftExpr)) {
369
+ const allRefs = collectColumnRefs(leftExpr);
370
+ for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
371
+ table: ref.table,
372
+ column: ref.column
373
+ });
374
+ } else refsColumns.set(`${leftExpr.table}.${leftExpr.column}`, {
375
+ table: leftExpr.table,
376
+ column: leftExpr.column
377
+ });
378
+ const whereRight = args.where.right;
379
+ if (isColumnBuilder(whereRight) || isExpressionBuilder(whereRight)) collectRefsFromExpressionSource(whereRight, refsColumns);
380
+ }
381
+ if (args.orderBy) {
382
+ const orderByExpr = args.orderBy.expr;
383
+ if (isOperationExpr(orderByExpr)) {
384
+ const allRefs = collectColumnRefs(orderByExpr);
385
+ for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
386
+ table: ref.table,
387
+ column: ref.column
388
+ });
389
+ } else refsColumns.set(`${orderByExpr.table}.${orderByExpr.column}`, {
390
+ table: orderByExpr.table,
391
+ column: orderByExpr.column
392
+ });
393
+ }
394
+ const includeAliases = new Set(args.includes?.map((inc) => inc.alias) ?? []);
395
+ const projectionMap = Object.fromEntries(args.projection.aliases.map((alias, index) => {
396
+ if (includeAliases.has(alias)) return [alias, `include:${alias}`];
397
+ const column = args.projection.columns[index];
398
+ if (!column) errorMissingColumnForAlias(alias, index);
399
+ if (isExpressionBuilder(column)) return [alias, `operation:${column.expr.method}`];
400
+ const col = column;
401
+ if (!col.table || !col.column) return [alias, `include:${alias}`];
402
+ return [alias, `${col.table}.${col.column}`];
403
+ }));
404
+ const projectionTypes = {};
405
+ for (let i = 0; i < args.projection.aliases.length; i++) {
406
+ const alias = args.projection.aliases[i];
407
+ if (!alias || includeAliases.has(alias)) continue;
408
+ const column = args.projection.columns[i];
409
+ if (!column) continue;
410
+ if (isExpressionBuilder(column)) {
411
+ const operationExpr = column.expr;
412
+ if (operationExpr.returns.kind === "typeId") projectionTypes[alias] = operationExpr.returns.type;
413
+ else if (operationExpr.returns.kind === "builtin") projectionTypes[alias] = operationExpr.returns.type;
414
+ } else {
415
+ const codecId = column.columnMeta?.codecId;
416
+ if (codecId) projectionTypes[alias] = codecId;
417
+ }
418
+ }
419
+ const projectionCodecs = {};
420
+ for (let i = 0; i < args.projection.aliases.length; i++) {
421
+ const alias = args.projection.aliases[i];
422
+ if (!alias || includeAliases.has(alias)) continue;
423
+ const column = args.projection.columns[i];
424
+ if (!column) continue;
425
+ if (isExpressionBuilder(column)) {
426
+ const operationExpr = column.expr;
427
+ if (operationExpr.returns.kind === "typeId") projectionCodecs[alias] = operationExpr.returns.type;
428
+ } else {
429
+ const codecId = column.columnMeta?.codecId;
430
+ if (codecId) projectionCodecs[alias] = codecId;
431
+ }
432
+ }
433
+ const allCodecs = {
434
+ ...projectionCodecs,
435
+ ...args.paramCodecs ? args.paramCodecs : {}
436
+ };
437
+ return Object.freeze(compact({
438
+ target: args.contract.target,
439
+ targetFamily: args.contract.targetFamily,
440
+ storageHash: args.contract.storageHash,
441
+ lane: "dsl",
442
+ refs: {
443
+ tables: Array.from(refsTables),
444
+ columns: Array.from(refsColumns.values())
445
+ },
446
+ projection: projectionMap,
447
+ projectionTypes: Object.keys(projectionTypes).length > 0 ? projectionTypes : void 0,
448
+ annotations: Object.keys(allCodecs).length > 0 ? Object.freeze({ codecs: Object.freeze(allCodecs) }) : void 0,
449
+ paramDescriptors: args.paramDescriptors,
450
+ profileHash: args.contract.profileHash
451
+ }));
452
+ }
453
+
454
+ //#endregion
455
+ //#region src/sql/predicate-builder.ts
456
+ /**
457
+ * Type guard to check if a builder is a NullCheckBuilder (unary).
458
+ */
459
+ function isNullCheckBuilder(builder) {
460
+ return builder.kind === "nullCheck";
461
+ }
462
+ /**
463
+ * Builds a NullCheckExpr from a NullCheckBuilder.
464
+ */
465
+ function buildNullCheckExpr(contract, where) {
466
+ const expr = where.expr;
467
+ if (expr.kind === "col") {
468
+ const { table, column } = expr;
469
+ const contractTable = contract.storage.tables[table];
470
+ if (!contractTable) errorUnknownTable(table);
471
+ if (!contractTable.columns[column]) errorUnknownColumn(column, table);
472
+ }
473
+ return createNullCheckExpr(expr, where.isNull);
474
+ }
475
+ function buildWhereExpr(contract, where, paramsMap, descriptors, values) {
476
+ if (isNullCheckBuilder(where)) return {
477
+ expr: buildNullCheckExpr(contract, where),
478
+ codecId: void 0,
479
+ paramName: ""
480
+ };
481
+ let leftExpr;
482
+ let codecId;
483
+ let rightExpr;
484
+ let paramName;
485
+ if (!where.left || typeof where.left !== "object" || !["col", "operation"].includes(where.left.kind ?? "")) errorFailedToBuildWhereClause();
486
+ leftExpr = where.left;
487
+ if (leftExpr.kind === "col") {
488
+ const { table, column } = leftExpr;
489
+ const contractTable = contract.storage.tables[table];
490
+ if (!contractTable) errorUnknownTable(table);
491
+ const columnMeta = contractTable.columns[column];
492
+ if (!columnMeta) errorUnknownColumn(column, table);
493
+ codecId = columnMeta.codecId;
494
+ }
495
+ if (isParamPlaceholder(where.right)) {
496
+ paramName = where.right.name;
497
+ if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
498
+ const value = paramsMap[paramName];
499
+ const index = values.push(value);
500
+ if (leftExpr.kind === "col") {
501
+ const { table, column } = leftExpr;
502
+ const columnMeta = contract.storage.tables[table]?.columns[column];
503
+ if (columnMeta) descriptors.push({
504
+ name: paramName,
505
+ source: "dsl",
506
+ refs: {
507
+ table,
508
+ column
509
+ },
510
+ nullable: columnMeta.nullable,
511
+ codecId: columnMeta.codecId,
512
+ nativeType: columnMeta.nativeType
513
+ });
514
+ }
515
+ rightExpr = createParamRef(index, paramName);
516
+ } else if (isColumnBuilder(where.right) || isExpressionBuilder(where.right)) {
517
+ rightExpr = where.right.toExpr();
518
+ if (rightExpr.kind === "col") {
519
+ const { table, column } = rightExpr;
520
+ const contractTable = contract.storage.tables[table];
521
+ if (!contractTable) errorUnknownTable(table);
522
+ if (!contractTable.columns[column]) errorUnknownColumn(column, table);
523
+ }
524
+ paramName = "";
525
+ } else errorFailedToBuildWhereClause();
526
+ return {
527
+ expr: createBinaryExpr(where.op, leftExpr, rightExpr),
528
+ codecId,
529
+ paramName
530
+ };
531
+ }
532
+
533
+ //#endregion
534
+ //#region src/sql/mutation-builder.ts
535
+ var InsertBuilderImpl = class InsertBuilderImpl {
536
+ contract;
537
+ context;
538
+ table;
539
+ values;
540
+ returningColumns = [];
541
+ constructor(options, table, values) {
542
+ this.context = options.context;
543
+ this.contract = options.context.contract;
544
+ this.table = table;
545
+ this.values = values;
546
+ }
547
+ returning(...columns) {
548
+ checkReturningCapability(this.contract);
549
+ const builder = new InsertBuilderImpl({ context: this.context }, this.table, this.values);
550
+ builder.returningColumns = [...this.returningColumns, ...columns];
551
+ return builder;
552
+ }
553
+ build(options) {
554
+ const paramsMap = options?.params ?? {};
555
+ const paramDescriptors = [];
556
+ const paramValues = [];
557
+ const paramCodecs = {};
558
+ const contractTable = this.contract.storage.tables[this.table.name];
559
+ if (!contractTable) errorUnknownTable(this.table.name);
560
+ const values = {};
561
+ for (const [columnName, placeholder] of Object.entries(this.values)) {
562
+ if (!contractTable.columns[columnName]) errorUnknownColumn(columnName, this.table.name);
563
+ const paramName = placeholder.name;
564
+ if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
565
+ const value = paramsMap[paramName];
566
+ const index = paramValues.push(value);
567
+ const columnMeta = contractTable.columns[columnName];
568
+ const codecId = columnMeta?.codecId;
569
+ if (paramName && codecId) paramCodecs[paramName] = codecId;
570
+ paramDescriptors.push({
571
+ name: paramName,
572
+ source: "dsl",
573
+ refs: {
574
+ table: this.table.name,
575
+ column: columnName
576
+ },
577
+ ...codecId ? { codecId } : {},
578
+ ...columnMeta?.nativeType ? { nativeType: columnMeta.nativeType } : {},
579
+ ...columnMeta?.nullable !== void 0 ? { nullable: columnMeta.nullable } : {}
580
+ });
581
+ values[columnName] = createParamRef(index, paramName);
582
+ }
583
+ const appliedDefaults = this.context.applyMutationDefaults({
584
+ op: "create",
585
+ table: this.table.name,
586
+ values
587
+ });
588
+ for (const defaultValue of appliedDefaults) {
589
+ const columnMeta = contractTable.columns[defaultValue.column];
590
+ if (!columnMeta) errorUnknownColumn(defaultValue.column, this.table.name);
591
+ const index = paramValues.push(defaultValue.value);
592
+ paramCodecs[defaultValue.column] = columnMeta.codecId;
593
+ paramDescriptors.push({
594
+ name: defaultValue.column,
595
+ source: "dsl",
596
+ refs: {
597
+ table: this.table.name,
598
+ column: defaultValue.column
599
+ },
600
+ codecId: columnMeta.codecId,
601
+ nativeType: columnMeta.nativeType,
602
+ nullable: columnMeta.nullable
603
+ });
604
+ values[defaultValue.column] = createParamRef(index, defaultValue.column);
605
+ }
606
+ const returning = this.returningColumns.map((col) => {
607
+ const c = col;
608
+ return createColumnRef(c.table, c.column);
609
+ });
610
+ const ast = createInsertAst({
611
+ table: createTableRef(this.table.name),
612
+ values,
613
+ returning
614
+ });
615
+ const returningProjection = {
616
+ aliases: this.returningColumns.map((col) => {
617
+ return col.column;
618
+ }),
619
+ columns: this.returningColumns
620
+ };
621
+ const planMeta = buildMeta({
622
+ contract: this.contract,
623
+ table: this.table,
624
+ projection: returning.length > 0 ? returningProjection : {
625
+ aliases: [],
626
+ columns: []
627
+ },
628
+ paramDescriptors,
629
+ ...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {}
630
+ });
631
+ return Object.freeze({
632
+ ast,
633
+ params: paramValues,
634
+ meta: {
635
+ ...planMeta,
636
+ lane: "dsl",
637
+ annotations: {
638
+ ...planMeta.annotations,
639
+ intent: "write",
640
+ isMutation: true
641
+ }
642
+ }
643
+ });
644
+ }
645
+ };
646
+ var UpdateBuilderImpl = class UpdateBuilderImpl {
647
+ contract;
648
+ context;
649
+ table;
650
+ set;
651
+ wherePredicate;
652
+ returningColumns = [];
653
+ constructor(options, table, set) {
654
+ this.context = options.context;
655
+ this.contract = options.context.contract;
656
+ this.table = table;
657
+ this.set = set;
658
+ }
659
+ where(predicate) {
660
+ const builder = new UpdateBuilderImpl({ context: this.context }, this.table, this.set);
661
+ builder.wherePredicate = predicate;
662
+ builder.returningColumns = [...this.returningColumns];
663
+ return builder;
664
+ }
665
+ returning(...columns) {
666
+ checkReturningCapability(this.contract);
667
+ const builder = new UpdateBuilderImpl({ context: this.context }, this.table, this.set);
668
+ if (this.wherePredicate) builder.wherePredicate = this.wherePredicate;
669
+ builder.returningColumns = [...this.returningColumns, ...columns];
670
+ return builder;
671
+ }
672
+ build(options) {
673
+ if (!this.wherePredicate) errorWhereMustBeCalledForUpdate();
674
+ const paramsMap = options?.params ?? {};
675
+ const paramDescriptors = [];
676
+ const paramValues = [];
677
+ const paramCodecs = {};
678
+ const contractTable = this.contract.storage.tables[this.table.name];
679
+ if (!contractTable) errorUnknownTable(this.table.name);
680
+ const set = {};
681
+ for (const [columnName, placeholder] of Object.entries(this.set)) {
682
+ if (!contractTable.columns[columnName]) errorUnknownColumn(columnName, this.table.name);
683
+ const paramName = placeholder.name;
684
+ if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
685
+ const value = paramsMap[paramName];
686
+ const index = paramValues.push(value);
687
+ const columnMeta = contractTable.columns[columnName];
688
+ const codecId = columnMeta?.codecId;
689
+ if (paramName && codecId) paramCodecs[paramName] = codecId;
690
+ paramDescriptors.push({
691
+ name: paramName,
692
+ source: "dsl",
693
+ refs: {
694
+ table: this.table.name,
695
+ column: columnName
696
+ },
697
+ ...codecId ? { codecId } : {},
698
+ ...columnMeta?.nativeType ? { nativeType: columnMeta.nativeType } : {},
699
+ ...columnMeta?.nullable !== void 0 ? { nullable: columnMeta.nullable } : {}
700
+ });
701
+ set[columnName] = createParamRef(index, paramName);
702
+ }
703
+ const appliedDefaults = this.context.applyMutationDefaults({
704
+ op: "update",
705
+ table: this.table.name,
706
+ values: set
707
+ });
708
+ for (const defaultValue of appliedDefaults) {
709
+ const columnMeta = contractTable.columns[defaultValue.column];
710
+ if (!columnMeta) errorUnknownColumn(defaultValue.column, this.table.name);
711
+ const index = paramValues.push(defaultValue.value);
712
+ paramCodecs[defaultValue.column] = columnMeta.codecId;
713
+ paramDescriptors.push({
714
+ name: defaultValue.column,
715
+ source: "dsl",
716
+ refs: {
717
+ table: this.table.name,
718
+ column: defaultValue.column
719
+ },
720
+ codecId: columnMeta.codecId,
721
+ nativeType: columnMeta.nativeType,
722
+ nullable: columnMeta.nullable
723
+ });
724
+ set[defaultValue.column] = createParamRef(index, defaultValue.column);
725
+ }
726
+ const whereResult = buildWhereExpr(this.contract, this.wherePredicate, paramsMap, paramDescriptors, paramValues);
727
+ const whereExpr = whereResult.expr;
728
+ if (!whereExpr) errorFailedToBuildWhereClause();
729
+ if (whereResult.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
730
+ const returning = this.returningColumns.map((col) => {
731
+ const c = col;
732
+ return createColumnRef(c.table, c.column);
733
+ });
734
+ const ast = createUpdateAst({
735
+ table: createTableRef(this.table.name),
736
+ set,
737
+ where: whereExpr,
738
+ returning
739
+ });
740
+ const returningProjection = {
741
+ aliases: this.returningColumns.map((col) => {
742
+ return col.column;
743
+ }),
744
+ columns: this.returningColumns
745
+ };
746
+ const planMeta = buildMeta({
747
+ contract: this.contract,
748
+ table: this.table,
749
+ projection: returning.length > 0 ? returningProjection : {
750
+ aliases: [],
751
+ columns: []
752
+ },
753
+ paramDescriptors,
754
+ ...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {},
755
+ where: this.wherePredicate
756
+ });
757
+ return Object.freeze({
758
+ ast,
759
+ params: paramValues,
760
+ meta: {
761
+ ...planMeta,
762
+ lane: "dsl",
763
+ annotations: {
764
+ ...planMeta.annotations,
765
+ intent: "write",
766
+ isMutation: true,
767
+ hasWhere: true
768
+ }
769
+ }
770
+ });
771
+ }
772
+ };
773
+ var DeleteBuilderImpl = class DeleteBuilderImpl {
774
+ contract;
775
+ context;
776
+ table;
777
+ wherePredicate;
778
+ returningColumns = [];
779
+ constructor(options, table) {
780
+ this.context = options.context;
781
+ this.contract = options.context.contract;
782
+ this.table = table;
783
+ }
784
+ where(predicate) {
785
+ const builder = new DeleteBuilderImpl({ context: this.context }, this.table);
786
+ builder.wherePredicate = predicate;
787
+ builder.returningColumns = [...this.returningColumns];
788
+ return builder;
789
+ }
790
+ returning(...columns) {
791
+ checkReturningCapability(this.contract);
792
+ const builder = new DeleteBuilderImpl({ context: this.context }, this.table);
793
+ if (this.wherePredicate) builder.wherePredicate = this.wherePredicate;
794
+ builder.returningColumns = [...this.returningColumns, ...columns];
795
+ return builder;
796
+ }
797
+ build(options) {
798
+ if (!this.wherePredicate) errorWhereMustBeCalledForDelete();
799
+ const paramsMap = options?.params ?? {};
800
+ const paramDescriptors = [];
801
+ const paramValues = [];
802
+ const paramCodecs = {};
803
+ if (!this.contract.storage.tables[this.table.name]) errorUnknownTable(this.table.name);
804
+ const whereResult = buildWhereExpr(this.contract, this.wherePredicate, paramsMap, paramDescriptors, paramValues);
805
+ const whereExpr = whereResult.expr;
806
+ if (!whereExpr) errorFailedToBuildWhereClause();
807
+ if (whereResult.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
808
+ const returning = this.returningColumns.map((col) => {
809
+ const c = col;
810
+ return createColumnRef(c.table, c.column);
811
+ });
812
+ const ast = createDeleteAst({
813
+ table: createTableRef(this.table.name),
814
+ where: whereExpr,
815
+ returning
816
+ });
817
+ const returningProjection = {
818
+ aliases: this.returningColumns.map((col) => {
819
+ return col.column;
820
+ }),
821
+ columns: this.returningColumns
822
+ };
823
+ const planMeta = buildMeta({
824
+ contract: this.contract,
825
+ table: this.table,
826
+ projection: returning.length > 0 ? returningProjection : {
827
+ aliases: [],
828
+ columns: []
829
+ },
830
+ paramDescriptors,
831
+ ...Object.keys(paramCodecs).length > 0 ? { paramCodecs } : {},
832
+ where: this.wherePredicate
833
+ });
834
+ return Object.freeze({
835
+ ast,
836
+ params: paramValues,
837
+ meta: {
838
+ ...planMeta,
839
+ lane: "dsl",
840
+ annotations: {
841
+ ...planMeta.annotations,
842
+ intent: "write",
843
+ isMutation: true,
844
+ hasWhere: true
845
+ }
846
+ }
847
+ });
848
+ }
849
+ };
850
+
851
+ //#endregion
852
+ //#region src/sql/projection.ts
853
+ function generateAlias(path) {
854
+ if (path.length === 0) errorAliasPathEmpty();
855
+ return path.join("_");
856
+ }
857
+ var AliasTracker = class {
858
+ aliases = /* @__PURE__ */ new Set();
859
+ aliasToPath = /* @__PURE__ */ new Map();
860
+ register(path) {
861
+ const alias = generateAlias(path);
862
+ if (this.aliases.has(alias)) errorAliasCollision(path, alias, this.aliasToPath.get(alias));
863
+ this.aliases.add(alias);
864
+ this.aliasToPath.set(alias, path);
865
+ return alias;
866
+ }
867
+ getPath(alias) {
868
+ return this.aliasToPath.get(alias);
869
+ }
870
+ has(alias) {
871
+ return this.aliases.has(alias);
872
+ }
873
+ };
874
+ function flattenProjection(projection, tracker, currentPath = []) {
875
+ const aliases = [];
876
+ const columns = [];
877
+ for (const [key, value] of Object.entries(projection)) {
878
+ const path = [...currentPath, key];
879
+ if (isExpressionSource(value)) {
880
+ const alias = tracker.register(path);
881
+ aliases.push(alias);
882
+ columns.push(value);
883
+ } else if (typeof value === "object" && value !== null) {
884
+ const nested = flattenProjection(value, tracker, path);
885
+ aliases.push(...nested.aliases);
886
+ columns.push(...nested.columns);
887
+ } else errorInvalidProjectionValue(path);
888
+ }
889
+ return {
890
+ aliases,
891
+ columns
892
+ };
893
+ }
894
+ function buildProjectionState(_table, projection, includes) {
895
+ const tracker = new AliasTracker();
896
+ const aliases = [];
897
+ const columns = [];
898
+ for (const [key, value] of Object.entries(projection)) if (value === true) {
899
+ const matchingInclude = includes?.find((inc) => inc.alias === key);
900
+ if (!matchingInclude) errorIncludeAliasNotFound(key);
901
+ aliases.push(key);
902
+ columns.push({
903
+ kind: "column",
904
+ table: matchingInclude.table.name,
905
+ column: "",
906
+ columnMeta: {
907
+ nativeType: "jsonb",
908
+ codecId: "core/json@1",
909
+ nullable: true
910
+ },
911
+ toExpr: () => ({
912
+ kind: "col",
913
+ table: matchingInclude.table.name,
914
+ column: ""
915
+ })
916
+ });
917
+ } else if (isExpressionSource(value)) {
918
+ const alias = tracker.register([key]);
919
+ aliases.push(alias);
920
+ columns.push(value);
921
+ } else if (typeof value === "object" && value !== null) {
922
+ const nested = flattenProjection(value, tracker, [key]);
923
+ aliases.push(...nested.aliases);
924
+ columns.push(...nested.columns);
925
+ } else errorInvalidProjectionKey(key);
926
+ if (aliases.length === 0) errorProjectionEmpty();
927
+ return {
928
+ aliases,
929
+ columns
930
+ };
931
+ }
932
+
933
+ //#endregion
934
+ //#region src/sql/include-builder.ts
935
+ var IncludeChildBuilderImpl = class IncludeChildBuilderImpl {
936
+ contract;
937
+ codecTypes;
938
+ table;
939
+ childProjection;
940
+ childWhere;
941
+ childOrderBy;
942
+ childLimit;
943
+ constructor(contract, codecTypes, table) {
944
+ this.contract = contract;
945
+ this.codecTypes = codecTypes;
946
+ this.table = table;
947
+ }
948
+ select(projection) {
949
+ const projectionState = buildProjectionState(this.table, projection);
950
+ const builder = new IncludeChildBuilderImpl(this.contract, this.codecTypes, this.table);
951
+ builder.childProjection = projectionState;
952
+ if (this.childWhere !== void 0) builder.childWhere = this.childWhere;
953
+ if (this.childOrderBy !== void 0) builder.childOrderBy = this.childOrderBy;
954
+ if (this.childLimit !== void 0) builder.childLimit = this.childLimit;
955
+ return builder;
956
+ }
957
+ where(expr) {
958
+ const builder = new IncludeChildBuilderImpl(this.contract, this.codecTypes, this.table);
959
+ if (this.childProjection !== void 0) builder.childProjection = this.childProjection;
960
+ builder.childWhere = expr;
961
+ if (this.childOrderBy !== void 0) builder.childOrderBy = this.childOrderBy;
962
+ if (this.childLimit !== void 0) builder.childLimit = this.childLimit;
963
+ return builder;
964
+ }
965
+ orderBy(order) {
966
+ const builder = new IncludeChildBuilderImpl(this.contract, this.codecTypes, this.table);
967
+ if (this.childProjection !== void 0) builder.childProjection = this.childProjection;
968
+ if (this.childWhere !== void 0) builder.childWhere = this.childWhere;
969
+ builder.childOrderBy = order;
970
+ if (this.childLimit !== void 0) builder.childLimit = this.childLimit;
971
+ return builder;
972
+ }
973
+ limit(count) {
974
+ if (!Number.isInteger(count) || count < 0) errorLimitMustBeNonNegativeInteger();
975
+ const builder = new IncludeChildBuilderImpl(this.contract, this.codecTypes, this.table);
976
+ if (this.childProjection !== void 0) builder.childProjection = this.childProjection;
977
+ if (this.childWhere !== void 0) builder.childWhere = this.childWhere;
978
+ if (this.childOrderBy !== void 0) builder.childOrderBy = this.childOrderBy;
979
+ builder.childLimit = count;
980
+ return builder;
981
+ }
982
+ getState() {
983
+ if (!this.childProjection) errorChildProjectionMustBeSpecified();
984
+ const state = { childProjection: this.childProjection };
985
+ if (this.childWhere !== void 0) state.childWhere = this.childWhere;
986
+ if (this.childOrderBy !== void 0) state.childOrderBy = this.childOrderBy;
987
+ if (this.childLimit !== void 0) state.childLimit = this.childLimit;
988
+ return state;
989
+ }
990
+ };
991
+ function buildIncludeAst(include, contract, paramsMap, paramDescriptors, paramValues) {
992
+ const childOrderBy = include.childOrderBy ? (() => {
993
+ const orderBy = include.childOrderBy;
994
+ const orderExpr = orderBy.expr;
995
+ return [createOrderByItem((() => {
996
+ if (isOperationExpr(orderExpr)) {
997
+ const baseCol = extractBaseColumnRef(orderExpr);
998
+ return createColumnRef(baseCol.table, baseCol.column);
999
+ }
1000
+ const colBuilder = orderExpr;
1001
+ return createColumnRef(colBuilder.table, colBuilder.column);
1002
+ })(), orderBy.dir)];
1003
+ })() : void 0;
1004
+ let childWhere;
1005
+ if (include.childWhere) childWhere = buildWhereExpr(contract, include.childWhere, paramsMap, paramDescriptors, paramValues).expr;
1006
+ const onLeft = include.on.left;
1007
+ const onRight = include.on.right;
1008
+ const onExpr = createJoinOnExpr(createColumnRef(onLeft.table, onLeft.column), createColumnRef(onRight.table, onRight.column));
1009
+ return {
1010
+ kind: "includeMany",
1011
+ alias: include.alias,
1012
+ child: {
1013
+ table: createTableRef(include.table.name),
1014
+ on: onExpr,
1015
+ ...childWhere ? { where: childWhere } : {},
1016
+ ...childOrderBy ? { orderBy: childOrderBy } : {},
1017
+ ...typeof include.childLimit === "number" ? { limit: include.childLimit } : {},
1018
+ project: include.childProjection.aliases.map((alias, idx) => {
1019
+ const column = include.childProjection.columns[idx];
1020
+ if (!column || !alias) errorMissingColumnForAlias(alias ?? "unknown", idx);
1021
+ return {
1022
+ alias,
1023
+ expr: column.toExpr()
1024
+ };
1025
+ })
1026
+ }
1027
+ };
1028
+ }
1029
+
1030
+ //#endregion
1031
+ //#region src/sql/join-builder.ts
1032
+ function buildJoinAst(join) {
1033
+ const onLeft = join.on.left;
1034
+ const onRight = join.on.right;
1035
+ const onExpr = createJoinOnExpr(createColumnRef(onLeft.table, onLeft.column), createColumnRef(onRight.table, onRight.column));
1036
+ return createJoin(join.joinType, createTableRef(join.table.name), onExpr);
1037
+ }
1038
+
1039
+ //#endregion
1040
+ //#region src/sql/select-builder.ts
1041
+ var SelectBuilderImpl = class SelectBuilderImpl {
1042
+ contract;
1043
+ codecTypes;
1044
+ context;
1045
+ state = {};
1046
+ constructor(options, state) {
1047
+ this.context = options.context;
1048
+ this.contract = options.context.contract;
1049
+ this.codecTypes = options.context.contract.mappings.codecTypes;
1050
+ if (state) this.state = state;
1051
+ }
1052
+ from(table) {
1053
+ return new SelectBuilderImpl({ context: this.context }, {
1054
+ ...this.state,
1055
+ from: table
1056
+ });
1057
+ }
1058
+ innerJoin(table, on) {
1059
+ return this._addJoin("inner", table, on);
1060
+ }
1061
+ leftJoin(table, on) {
1062
+ return this._addJoin("left", table, on);
1063
+ }
1064
+ rightJoin(table, on) {
1065
+ return this._addJoin("right", table, on);
1066
+ }
1067
+ fullJoin(table, on) {
1068
+ return this._addJoin("full", table, on);
1069
+ }
1070
+ includeMany(childTable, on, childBuilder, options) {
1071
+ checkIncludeCapabilities(this.contract);
1072
+ if (!this.contract.storage.tables[childTable.name]) errorUnknownTable(childTable.name);
1073
+ const onPredicate = on(createJoinOnBuilder());
1074
+ const onLeft = onPredicate.left;
1075
+ const onRight = onPredicate.right;
1076
+ if (onLeft.table === onRight.table) errorSelfJoinNotSupported();
1077
+ const childState = childBuilder(new IncludeChildBuilderImpl(this.contract, this.codecTypes, childTable)).getState();
1078
+ if (childState.childProjection.aliases.length === 0) errorChildProjectionEmpty();
1079
+ const alias = options?.alias ?? childTable.name;
1080
+ if (this.state.projection) {
1081
+ if (this.state.projection.aliases.includes(alias)) errorIncludeAliasCollision(alias, "projection");
1082
+ }
1083
+ const existingIncludes = this.state.includes ?? [];
1084
+ if (existingIncludes.some((inc) => inc.alias === alias)) errorIncludeAliasCollision(alias, "include");
1085
+ const includeState = {
1086
+ alias,
1087
+ table: childTable,
1088
+ on: onPredicate,
1089
+ childProjection: childState.childProjection,
1090
+ ...childState.childWhere !== void 0 ? { childWhere: childState.childWhere } : {},
1091
+ ...childState.childOrderBy !== void 0 ? { childOrderBy: childState.childOrderBy } : {},
1092
+ ...childState.childLimit !== void 0 ? { childLimit: childState.childLimit } : {}
1093
+ };
1094
+ const newIncludes = [...existingIncludes, includeState];
1095
+ return new SelectBuilderImpl({ context: this.context }, {
1096
+ ...this.state,
1097
+ includes: newIncludes
1098
+ });
1099
+ }
1100
+ _addJoin(joinType, table, on) {
1101
+ const fromTable = this.ensureFrom();
1102
+ if (!this.contract.storage.tables[table.name]) errorUnknownTable(table.name);
1103
+ if (table.name === fromTable.name) errorSelfJoinNotSupported();
1104
+ const joinState = {
1105
+ joinType,
1106
+ table,
1107
+ on: on(createJoinOnBuilder())
1108
+ };
1109
+ const newJoins = [...this.state.joins ?? [], joinState];
1110
+ return new SelectBuilderImpl({ context: this.context }, {
1111
+ ...this.state,
1112
+ joins: newJoins
1113
+ });
1114
+ }
1115
+ where(expr) {
1116
+ return new SelectBuilderImpl({ context: this.context }, {
1117
+ ...this.state,
1118
+ where: expr
1119
+ });
1120
+ }
1121
+ select(projection) {
1122
+ const projectionState = buildProjectionState(this.ensureFrom(), projection, this.state.includes);
1123
+ return new SelectBuilderImpl({ context: this.context }, {
1124
+ ...this.state,
1125
+ projection: projectionState
1126
+ });
1127
+ }
1128
+ orderBy(order) {
1129
+ return new SelectBuilderImpl({ context: this.context }, {
1130
+ ...this.state,
1131
+ orderBy: order
1132
+ });
1133
+ }
1134
+ limit(count) {
1135
+ if (!Number.isInteger(count) || count < 0) errorLimitMustBeNonNegativeInteger();
1136
+ return new SelectBuilderImpl({ context: this.context }, {
1137
+ ...this.state,
1138
+ limit: count
1139
+ });
1140
+ }
1141
+ build(options) {
1142
+ const table = this.ensureFrom();
1143
+ const projection = this.ensureProjection();
1144
+ const paramsMap = options?.params ?? {};
1145
+ if (!this.contract.storage.tables[table.name]) errorUnknownTable(table.name);
1146
+ const paramDescriptors = [];
1147
+ const paramValues = [];
1148
+ const paramCodecs = {};
1149
+ const whereResult = this.state.where ? buildWhereExpr(this.contract, this.state.where, paramsMap, paramDescriptors, paramValues) : void 0;
1150
+ const whereExpr = whereResult?.expr;
1151
+ if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
1152
+ const orderByClause = this.state.orderBy ? (() => {
1153
+ const orderBy = this.state.orderBy;
1154
+ return [createOrderByItem(orderBy.expr, orderBy.dir)];
1155
+ })() : void 0;
1156
+ const joins = this.state.joins?.map((join) => buildJoinAst(join));
1157
+ const includes = this.state.includes?.map((include) => buildIncludeAst(include, this.contract, paramsMap, paramDescriptors, paramValues));
1158
+ const projectEntries = [];
1159
+ for (let i = 0; i < projection.aliases.length; i++) {
1160
+ const alias = projection.aliases[i];
1161
+ if (!alias) errorMissingAlias(i);
1162
+ const column = projection.columns[i];
1163
+ if (this.state.includes?.find((inc) => inc.alias === alias)) projectEntries.push({
1164
+ alias,
1165
+ expr: {
1166
+ kind: "includeRef",
1167
+ alias
1168
+ }
1169
+ });
1170
+ else if (column && isExpressionBuilder(column)) projectEntries.push({
1171
+ alias,
1172
+ expr: column.expr
1173
+ });
1174
+ else if (column) {
1175
+ const columnRef = column.toExpr();
1176
+ projectEntries.push({
1177
+ alias,
1178
+ expr: columnRef
1179
+ });
1180
+ }
1181
+ }
1182
+ const ast = createSelectAst({
1183
+ from: createTableRef(table.name),
1184
+ joins,
1185
+ includes,
1186
+ project: projectEntries,
1187
+ where: whereExpr,
1188
+ orderBy: orderByClause,
1189
+ limit: this.state.limit
1190
+ });
1191
+ const planMeta = buildMeta({
1192
+ contract: this.contract,
1193
+ table,
1194
+ projection,
1195
+ joins: this.state.joins,
1196
+ includes: this.state.includes,
1197
+ paramDescriptors,
1198
+ paramCodecs,
1199
+ where: this.state.where,
1200
+ orderBy: this.state.orderBy
1201
+ });
1202
+ return Object.freeze({
1203
+ ast,
1204
+ params: paramValues,
1205
+ meta: planMeta
1206
+ });
1207
+ }
1208
+ ensureFrom() {
1209
+ if (!this.state.from) errorFromMustBeCalled();
1210
+ return this.state.from;
1211
+ }
1212
+ ensureProjection() {
1213
+ if (!this.state.projection) errorSelectMustBeCalled();
1214
+ return this.state.projection;
1215
+ }
1216
+ };
1217
+
1218
+ //#endregion
1219
+ //#region src/sql/builder.ts
1220
+ function sql(options) {
1221
+ const builder = new SelectBuilderImpl(options);
1222
+ const rawFactory = createRawFactory(options.context.contract);
1223
+ Object.defineProperty(builder, "raw", {
1224
+ value: rawFactory,
1225
+ enumerable: true,
1226
+ configurable: false
1227
+ });
1228
+ Object.defineProperty(builder, "insert", {
1229
+ value: (table, values) => {
1230
+ return new InsertBuilderImpl(options, table, values);
1231
+ },
1232
+ enumerable: true,
1233
+ configurable: false
1234
+ });
1235
+ Object.defineProperty(builder, "update", {
1236
+ value: (table, set) => {
1237
+ return new UpdateBuilderImpl(options, table, set);
1238
+ },
1239
+ enumerable: true,
1240
+ configurable: false
1241
+ });
1242
+ Object.defineProperty(builder, "delete", {
1243
+ value: (table) => {
1244
+ return new DeleteBuilderImpl(options, table);
1245
+ },
1246
+ enumerable: true,
1247
+ configurable: false
1248
+ });
1249
+ return builder;
1250
+ }
1251
+
1252
+ //#endregion
1253
+ export { sql as n, rawOptions as r, createJoinOnBuilder$1 as t };
1254
+ //# sourceMappingURL=builder-DLGrrQ5F.mjs.map