@prisma-next/sql-lane 0.0.1

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