@prisma-next/sql-orm-lane 0.3.0-pr.94.2 → 0.3.0-pr.95.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/chunk-C4EECZ4E.js +1723 -0
  2. package/dist/chunk-C4EECZ4E.js.map +1 -0
  3. package/dist/exports/orm.d.ts +3 -0
  4. package/dist/exports/orm.d.ts.map +1 -0
  5. package/dist/exports/orm.js +7 -0
  6. package/dist/exports/orm.js.map +1 -0
  7. package/dist/index.d.ts +4 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +9 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/mutations/delete-builder.d.ts +9 -0
  12. package/dist/mutations/delete-builder.d.ts.map +1 -0
  13. package/dist/mutations/insert-builder.d.ts +7 -0
  14. package/dist/mutations/insert-builder.d.ts.map +1 -0
  15. package/dist/mutations/update-builder.d.ts +9 -0
  16. package/dist/mutations/update-builder.d.ts.map +1 -0
  17. package/dist/orm/builder.d.ts +38 -0
  18. package/dist/orm/builder.d.ts.map +1 -0
  19. package/dist/orm/capabilities.d.ts +3 -0
  20. package/dist/orm/capabilities.d.ts.map +1 -0
  21. package/dist/orm/context.d.ts +5 -0
  22. package/dist/orm/context.d.ts.map +1 -0
  23. package/dist/orm/state.d.ts +45 -0
  24. package/dist/orm/state.d.ts.map +1 -0
  25. package/dist/orm-include-child.d.ts +35 -0
  26. package/dist/orm-include-child.d.ts.map +1 -0
  27. package/dist/orm-relation-filter.d.ts +19 -0
  28. package/dist/orm-relation-filter.d.ts.map +1 -0
  29. package/dist/orm-types.d.ts +86 -0
  30. package/dist/orm-types.d.ts.map +1 -0
  31. package/dist/orm.d.ts +5 -0
  32. package/dist/orm.d.ts.map +1 -0
  33. package/dist/plan/lowering.d.ts +2 -0
  34. package/dist/plan/lowering.d.ts.map +1 -0
  35. package/dist/plan/plan-assembly.d.ts +24 -0
  36. package/dist/plan/plan-assembly.d.ts.map +1 -0
  37. package/dist/plan/result-typing.d.ts +2 -0
  38. package/dist/plan/result-typing.d.ts.map +1 -0
  39. package/dist/relations/include-plan.d.ts +38 -0
  40. package/dist/relations/include-plan.d.ts.map +1 -0
  41. package/dist/selection/join.d.ts +3 -0
  42. package/dist/selection/join.d.ts.map +1 -0
  43. package/dist/selection/ordering.d.ts +11 -0
  44. package/dist/selection/ordering.d.ts.map +1 -0
  45. package/dist/selection/pagination.d.ts +6 -0
  46. package/dist/selection/pagination.d.ts.map +1 -0
  47. package/dist/selection/predicates.d.ts +10 -0
  48. package/dist/selection/predicates.d.ts.map +1 -0
  49. package/dist/selection/projection.d.ts +28 -0
  50. package/dist/selection/projection.d.ts.map +1 -0
  51. package/dist/selection/select-builder.d.ts +22 -0
  52. package/dist/selection/select-builder.d.ts.map +1 -0
  53. package/dist/types/internal.d.ts +4 -0
  54. package/dist/types/internal.d.ts.map +1 -0
  55. package/dist/utils/ast.d.ts +2 -0
  56. package/dist/utils/ast.d.ts.map +1 -0
  57. package/dist/utils/errors.d.ts +29 -0
  58. package/dist/utils/errors.d.ts.map +1 -0
  59. package/dist/utils/param-descriptor.d.ts +10 -0
  60. package/dist/utils/param-descriptor.d.ts.map +1 -0
  61. package/package.json +21 -23
  62. package/dist/exports/orm.d.mts +0 -2
  63. package/dist/exports/orm.mjs +0 -3
  64. package/dist/index.d.mts +0 -42
  65. package/dist/index.d.mts.map +0 -1
  66. package/dist/index.mjs +0 -3
  67. package/dist/orm-BYJaTDLm.mjs +0 -1286
  68. package/dist/orm-BYJaTDLm.mjs.map +0 -1
  69. package/dist/orm-DxyXF2Wh.d.mts +0 -89
  70. package/dist/orm-DxyXF2Wh.d.mts.map +0 -1
@@ -1,1286 +0,0 @@
1
- import { planInvalid } from "@prisma-next/plan";
2
- import { schema } from "@prisma-next/sql-relational-core/schema";
3
- import { augmentDescriptorWithColumnMeta } from "@prisma-next/sql-relational-core/plan";
4
- import { collectColumnRefs, extractBaseColumnRef, getColumnMeta, isColumnBuilder, isExpressionBuilder, isOperationExpr, isParamPlaceholder } from "@prisma-next/sql-relational-core/utils/guards";
5
- import { compact, createBinaryExpr, createColumnRef, createDeleteAst, createInsertAst, createJoinOnExpr, createOrderByItem, createParamRef, createSelectAst, createTableRef, createUpdateAst } from "@prisma-next/sql-relational-core/ast";
6
- import { param } from "@prisma-next/sql-relational-core/param";
7
-
8
- //#region src/utils/errors.ts
9
- function errorModelNotFound(modelName) {
10
- throw planInvalid(`Model ${modelName} not found in mappings`);
11
- }
12
- function errorTableNotFound(tableName) {
13
- throw planInvalid(`Table ${tableName} not found in schema`);
14
- }
15
- function errorUnknownTable(tableName) {
16
- throw planInvalid(`Unknown table ${tableName}`);
17
- }
18
- function errorUnknownColumn(columnName, tableName) {
19
- throw planInvalid(`Unknown column ${columnName} in table ${tableName}`);
20
- }
21
- function errorMissingParameter(paramName) {
22
- throw planInvalid(`Missing value for parameter ${paramName}`);
23
- }
24
- function errorAliasPathEmpty() {
25
- throw planInvalid("Alias path cannot be empty");
26
- }
27
- function errorAliasCollision(path, alias, existingPath) {
28
- throw planInvalid(`Alias collision: path ${path.join(".")} would generate alias "${alias}" which conflicts with path ${existingPath?.join(".") ?? "unknown"}`);
29
- }
30
- function errorInvalidProjectionValue(path) {
31
- throw planInvalid(`Invalid projection value at path ${path.join(".")}: expected ColumnBuilder or nested object`);
32
- }
33
- function errorIncludeAliasNotFound(alias) {
34
- throw planInvalid(`Include alias "${alias}" not found. Did you call includeMany() with alias "${alias}"?`);
35
- }
36
- function errorInvalidProjectionKey(key) {
37
- throw planInvalid(`Invalid projection value at key "${key}": expected ColumnBuilder, boolean true (for includes), or nested object`);
38
- }
39
- function errorProjectionEmpty() {
40
- throw planInvalid("select() requires at least one column or include");
41
- }
42
- function errorCreateRequiresFields() {
43
- throw planInvalid("create() requires at least one field");
44
- }
45
- function errorUpdateRequiresFields() {
46
- throw planInvalid("update() requires at least one field");
47
- }
48
- function errorIncludeRequiresCapabilities() {
49
- throw planInvalid("includeMany requires lateral and jsonAgg capabilities");
50
- }
51
- function errorIncludeCapabilitiesNotTrue() {
52
- throw planInvalid("includeMany requires lateral and jsonAgg capabilities to be true");
53
- }
54
- function errorMultiColumnJoinsNotSupported() {
55
- throw planInvalid("Multi-column joins in includes are not yet supported");
56
- }
57
- function errorJoinColumnsMustBeDefined() {
58
- throw planInvalid("Join columns must be defined");
59
- }
60
- function errorColumnNotFound(columnName, tableName) {
61
- throw planInvalid(`Column ${columnName} not found in table ${tableName}`);
62
- }
63
- function errorChildProjectionMustBeSpecified() {
64
- throw planInvalid("Child projection must be specified");
65
- }
66
- function errorChildProjectionEmpty() {
67
- throw planInvalid("Child projection must not be empty after filtering boolean values");
68
- }
69
- function errorMissingAlias(index) {
70
- throw planInvalid(`Missing alias at index ${index}`);
71
- }
72
- function errorMissingColumn(alias, index) {
73
- throw planInvalid(`Missing column for alias "${alias}" at index ${index}`);
74
- }
75
- function errorInvalidColumn(alias, index) {
76
- throw planInvalid(`Invalid column for alias "${alias}" at index ${index}`);
77
- }
78
- function errorFailedToBuildWhereClause() {
79
- throw planInvalid("Failed to build WHERE clause");
80
- }
81
- function assertColumnExists(columnMeta, columnName, tableName) {
82
- if (!columnMeta) errorUnknownColumn(columnName, tableName);
83
- }
84
- function assertParameterExists(paramsMap, paramName) {
85
- if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
86
- return paramsMap[paramName];
87
- }
88
-
89
- //#endregion
90
- //#region src/selection/predicates.ts
91
- function buildWhereExpr(where, contract, paramsMap, descriptors, values) {
92
- let leftExpr;
93
- let codecId;
94
- let rightExpr;
95
- let paramName;
96
- leftExpr = where.left;
97
- if (leftExpr.kind === "col") {
98
- const { table, column } = leftExpr;
99
- const contractTable = contract.storage.tables[table];
100
- if (!contractTable) errorUnknownTable(table);
101
- const columnMeta = contractTable.columns[column];
102
- if (columnMeta) codecId = columnMeta.codecId;
103
- }
104
- if (isParamPlaceholder(where.right)) {
105
- paramName = where.right.name;
106
- if (!Object.hasOwn(paramsMap, paramName)) errorMissingParameter(paramName);
107
- const value = paramsMap[paramName];
108
- const index = values.push(value);
109
- if (leftExpr.kind === "col") {
110
- const { table, column } = leftExpr;
111
- const columnMeta = contract.storage.tables[table]?.columns[column];
112
- descriptors.push({
113
- name: paramName,
114
- source: "dsl",
115
- refs: {
116
- table,
117
- column
118
- },
119
- ...columnMeta && typeof columnMeta.nullable === "boolean" ? { nullable: columnMeta.nullable } : {}
120
- });
121
- augmentDescriptorWithColumnMeta(descriptors, columnMeta);
122
- }
123
- rightExpr = createParamRef(index, paramName);
124
- } else if (isColumnBuilder(where.right) || isExpressionBuilder(where.right)) {
125
- rightExpr = where.right.toExpr();
126
- paramName = "";
127
- } else errorFailedToBuildWhereClause();
128
- return {
129
- expr: createBinaryExpr(where.op, leftExpr, rightExpr),
130
- ...codecId ? { codecId } : {},
131
- paramName
132
- };
133
- }
134
-
135
- //#endregion
136
- //#region src/mutations/delete-builder.ts
137
- function buildDeletePlan(context, modelName, where, getModelAccessor, options) {
138
- const wherePredicate = where(getModelAccessor());
139
- const tableName = context.contract.mappings.modelToTable?.[modelName];
140
- if (!tableName) errorModelNotFound(modelName);
141
- const table = createTableRef(tableName);
142
- const paramsMap = options?.params ?? {};
143
- const paramDescriptors = [];
144
- const paramValues = [];
145
- const paramCodecs = {};
146
- const whereResult = buildWhereExpr(wherePredicate, context.contract, paramsMap, paramDescriptors, paramValues);
147
- const whereExpr = whereResult.expr;
148
- if (!whereExpr) errorFailedToBuildWhereClause();
149
- if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
150
- const ast = createDeleteAst({
151
- table,
152
- where: whereExpr
153
- });
154
- return Object.freeze({
155
- ast,
156
- params: paramValues,
157
- meta: {
158
- target: context.contract.target,
159
- targetFamily: context.contract.targetFamily,
160
- coreHash: context.contract.coreHash,
161
- lane: "orm",
162
- refs: {
163
- tables: [tableName],
164
- columns: []
165
- },
166
- projection: {},
167
- paramDescriptors,
168
- ...Object.keys(paramCodecs).length > 0 ? { annotations: {
169
- codecs: paramCodecs,
170
- intent: "write",
171
- isMutation: true
172
- } } : { annotations: {
173
- intent: "write",
174
- isMutation: true
175
- } }
176
- }
177
- });
178
- }
179
-
180
- //#endregion
181
- //#region src/utils/param-descriptor.ts
182
- function createParamDescriptor(args) {
183
- return {
184
- name: args.name,
185
- source: "dsl",
186
- refs: {
187
- table: args.table,
188
- column: args.column
189
- },
190
- ...args.codecId ? { codecId: args.codecId } : {},
191
- ...args.nativeType ? { nativeType: args.nativeType } : {},
192
- nullable: args.nullable
193
- };
194
- }
195
-
196
- //#endregion
197
- //#region src/mutations/insert-builder.ts
198
- function convertModelFieldsToColumns(contract, modelName, fields) {
199
- const model = contract.models[modelName];
200
- if (!model || typeof model !== "object" || !("fields" in model)) throw new Error(`Model ${modelName} does not have fields`);
201
- const modelFields = model.fields;
202
- const result = {};
203
- for (const fieldName in fields) {
204
- if (!Object.hasOwn(fields, fieldName)) continue;
205
- if (!Object.hasOwn(modelFields, fieldName)) throw new Error(`Field ${fieldName} does not exist on model ${modelName}`);
206
- const field = modelFields[fieldName];
207
- if (!field) continue;
208
- const columnName = contract.mappings.fieldToColumn?.[modelName]?.[fieldName] ?? field.column ?? fieldName;
209
- result[columnName] = param(fieldName);
210
- }
211
- return result;
212
- }
213
- function buildInsertPlan(context, modelName, data, options) {
214
- if (!data || Object.keys(data).length === 0) errorCreateRequiresFields();
215
- const values = convertModelFieldsToColumns(context.contract, modelName, data);
216
- const tableName = context.contract.mappings.modelToTable?.[modelName];
217
- if (!tableName) errorModelNotFound(modelName);
218
- const table = createTableRef(tableName);
219
- const paramsMap = {
220
- ...options?.params ?? {},
221
- ...data
222
- };
223
- const paramDescriptors = [];
224
- const paramValues = [];
225
- const paramCodecs = {};
226
- const contractTable = context.contract.storage.tables[tableName];
227
- if (!contractTable) errorUnknownTable(tableName);
228
- const insertValues = {};
229
- for (const [columnName, placeholder] of Object.entries(values)) {
230
- const columnMeta = contractTable.columns[columnName];
231
- assertColumnExists(columnMeta, columnName, tableName);
232
- const paramName = placeholder.name;
233
- const value = assertParameterExists(paramsMap, paramName);
234
- const index = paramValues.push(value);
235
- const codecId = columnMeta.codecId;
236
- if (paramName) paramCodecs[paramName] = codecId;
237
- paramDescriptors.push(createParamDescriptor({
238
- name: paramName,
239
- table: tableName,
240
- column: columnName,
241
- codecId,
242
- nativeType: columnMeta.nativeType,
243
- nullable: columnMeta.nullable
244
- }));
245
- insertValues[columnName] = createParamRef(index, paramName);
246
- }
247
- const ast = createInsertAst({
248
- table,
249
- values: insertValues
250
- });
251
- return Object.freeze({
252
- ast,
253
- params: paramValues,
254
- meta: {
255
- target: context.contract.target,
256
- targetFamily: context.contract.targetFamily,
257
- coreHash: context.contract.coreHash,
258
- lane: "orm",
259
- refs: {
260
- tables: [tableName],
261
- columns: []
262
- },
263
- projection: {},
264
- paramDescriptors,
265
- ...Object.keys(paramCodecs).length > 0 ? { annotations: {
266
- codecs: paramCodecs,
267
- intent: "write",
268
- isMutation: true
269
- } } : { annotations: {
270
- intent: "write",
271
- isMutation: true
272
- } }
273
- }
274
- });
275
- }
276
-
277
- //#endregion
278
- //#region src/mutations/update-builder.ts
279
- function buildUpdatePlan(context, modelName, where, getModelAccessor, data, options) {
280
- if (!data || Object.keys(data).length === 0) errorUpdateRequiresFields();
281
- const set = convertModelFieldsToColumns(context.contract, modelName, data);
282
- const wherePredicate = where(getModelAccessor());
283
- const tableName = context.contract.mappings.modelToTable?.[modelName];
284
- if (!tableName) errorModelNotFound(modelName);
285
- const table = createTableRef(tableName);
286
- const paramsMap = {
287
- ...options?.params ?? {},
288
- ...data
289
- };
290
- const paramDescriptors = [];
291
- const paramValues = [];
292
- const paramCodecs = {};
293
- const contractTable = context.contract.storage.tables[tableName];
294
- if (!contractTable) errorUnknownTable(tableName);
295
- const updateSet = {};
296
- for (const [columnName, placeholder] of Object.entries(set)) {
297
- const columnMeta = contractTable.columns[columnName];
298
- assertColumnExists(columnMeta, columnName, tableName);
299
- const paramName = placeholder.name;
300
- const value = assertParameterExists(paramsMap, paramName);
301
- const index = paramValues.push(value);
302
- const codecId = columnMeta.codecId;
303
- if (paramName) paramCodecs[paramName] = codecId;
304
- paramDescriptors.push(createParamDescriptor({
305
- name: paramName,
306
- table: tableName,
307
- column: columnName,
308
- codecId,
309
- nativeType: columnMeta.nativeType,
310
- nullable: columnMeta.nullable
311
- }));
312
- updateSet[columnName] = createParamRef(index, paramName);
313
- }
314
- const whereResult = buildWhereExpr(wherePredicate, context.contract, paramsMap, paramDescriptors, paramValues);
315
- const whereExpr = whereResult.expr;
316
- if (!whereExpr) errorFailedToBuildWhereClause();
317
- if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
318
- const ast = createUpdateAst({
319
- table,
320
- set: updateSet,
321
- where: whereExpr
322
- });
323
- return Object.freeze({
324
- ast,
325
- params: paramValues,
326
- meta: {
327
- target: context.contract.target,
328
- targetFamily: context.contract.targetFamily,
329
- coreHash: context.contract.coreHash,
330
- lane: "orm",
331
- refs: {
332
- tables: [tableName],
333
- columns: []
334
- },
335
- projection: {},
336
- paramDescriptors,
337
- ...Object.keys(paramCodecs).length > 0 ? { annotations: {
338
- codecs: paramCodecs,
339
- intent: "write",
340
- isMutation: true
341
- } } : { annotations: {
342
- intent: "write",
343
- isMutation: true
344
- } }
345
- }
346
- });
347
- }
348
-
349
- //#endregion
350
- //#region src/orm-include-child.ts
351
- var OrmIncludeChildBuilderImpl = class OrmIncludeChildBuilderImpl {
352
- context;
353
- contract;
354
- childModelName;
355
- childWhere;
356
- childOrderBy;
357
- childLimit;
358
- childProjection = void 0;
359
- constructor(options, childModelName) {
360
- this.context = options.context;
361
- this.contract = options.context.contract;
362
- this.childModelName = childModelName;
363
- }
364
- where(fn) {
365
- const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
366
- builder.childWhere = fn(this._getModelAccessor());
367
- builder.childOrderBy = this.childOrderBy;
368
- builder.childLimit = this.childLimit;
369
- builder.childProjection = this.childProjection;
370
- return builder;
371
- }
372
- orderBy(fn) {
373
- const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
374
- builder.childWhere = this.childWhere;
375
- builder.childOrderBy = fn(this._getModelAccessor());
376
- builder.childLimit = this.childLimit;
377
- builder.childProjection = this.childProjection;
378
- return builder;
379
- }
380
- take(n) {
381
- const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
382
- builder.childWhere = this.childWhere;
383
- builder.childOrderBy = this.childOrderBy;
384
- builder.childLimit = n;
385
- builder.childProjection = this.childProjection;
386
- return builder;
387
- }
388
- select(fn) {
389
- const builder = new OrmIncludeChildBuilderImpl({ context: this.context }, this.childModelName);
390
- builder.childWhere = this.childWhere;
391
- builder.childOrderBy = this.childOrderBy;
392
- builder.childLimit = this.childLimit;
393
- builder.childProjection = fn(this._getModelAccessor());
394
- return builder;
395
- }
396
- getState() {
397
- return {
398
- ...this.childWhere !== void 0 ? { childWhere: this.childWhere } : {},
399
- ...this.childOrderBy !== void 0 ? { childOrderBy: this.childOrderBy } : {},
400
- ...this.childLimit !== void 0 ? { childLimit: this.childLimit } : {},
401
- ...this.childProjection !== void 0 ? { childProjection: this.childProjection } : {}
402
- };
403
- }
404
- _getModelAccessor() {
405
- const tableName = this.contract.mappings.modelToTable?.[this.childModelName];
406
- if (!tableName) throw planInvalid(`Model ${this.childModelName} not found in mappings`);
407
- const table = schema(this.context).tables[tableName];
408
- if (!table) throw planInvalid(`Table ${tableName} not found in schema`);
409
- const accessor = {};
410
- const model = this.contract.models[this.childModelName];
411
- if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.childModelName} does not have fields`);
412
- const modelFields = model.fields;
413
- for (const fieldName in modelFields) {
414
- const field = modelFields[fieldName];
415
- if (!field) continue;
416
- const columnName = this.contract.mappings.fieldToColumn?.[this.childModelName]?.[fieldName] ?? field.column ?? fieldName;
417
- const column = table.columns[columnName];
418
- if (column) accessor[fieldName] = column;
419
- }
420
- return accessor;
421
- }
422
- };
423
-
424
- //#endregion
425
- //#region src/orm-relation-filter.ts
426
- var OrmRelationFilterBuilderImpl = class OrmRelationFilterBuilderImpl {
427
- context;
428
- contract;
429
- childModelName;
430
- wherePredicate = void 0;
431
- modelAccessor = void 0;
432
- constructor(options, childModelName) {
433
- this.context = options.context;
434
- this.contract = options.context.contract;
435
- this.childModelName = childModelName;
436
- this.modelAccessor = this._getModelAccessor();
437
- }
438
- where(fn) {
439
- const builder = new OrmRelationFilterBuilderImpl({ context: this.context }, this.childModelName);
440
- builder.modelAccessor = this.modelAccessor;
441
- if (this.modelAccessor) builder.wherePredicate = fn(this.modelAccessor);
442
- return builder;
443
- }
444
- getWherePredicate() {
445
- return this.wherePredicate;
446
- }
447
- getChildModelName() {
448
- return this.childModelName;
449
- }
450
- getModelAccessor() {
451
- if (!this.modelAccessor) this.modelAccessor = this._getModelAccessor();
452
- if (!this.modelAccessor) throw planInvalid(`Failed to get model accessor for ${this.childModelName}`);
453
- return this.modelAccessor;
454
- }
455
- _getModelAccessor() {
456
- const tableName = this.contract.mappings.modelToTable?.[this.childModelName];
457
- if (!tableName) throw planInvalid(`Model ${this.childModelName} not found in mappings`);
458
- const table = schema(this.context).tables[tableName];
459
- if (!table) throw planInvalid(`Table ${tableName} not found in schema`);
460
- const accessor = {};
461
- const model = this.contract.models[this.childModelName];
462
- if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.childModelName} does not have fields`);
463
- const modelFields = model.fields;
464
- for (const fieldName in modelFields) {
465
- const field = modelFields[fieldName];
466
- if (!field) continue;
467
- const columnName = this.contract.mappings.fieldToColumn?.[this.childModelName]?.[fieldName] ?? field.column ?? fieldName;
468
- const column = table.columns[columnName];
469
- if (column) accessor[fieldName] = column;
470
- }
471
- return accessor;
472
- }
473
- };
474
-
475
- //#endregion
476
- //#region src/plan/plan-assembly.ts
477
- /**
478
- * Extracts column references from an ExpressionSource (ColumnBuilder or ExpressionBuilder).
479
- * Skips entries with empty table or column names (e.g., placeholder columns for includes).
480
- */
481
- function collectRefsFromExpressionSource(source, refsColumns) {
482
- if (isExpressionBuilder(source)) {
483
- const allRefs = collectColumnRefs(source.expr);
484
- for (const ref of allRefs) if (ref.table && ref.column) refsColumns.set(`${ref.table}.${ref.column}`, {
485
- table: ref.table,
486
- column: ref.column
487
- });
488
- } else if (isColumnBuilder(source)) {
489
- const col = source;
490
- if (col.table && col.column) refsColumns.set(`${col.table}.${col.column}`, {
491
- table: col.table,
492
- column: col.column
493
- });
494
- }
495
- }
496
- /**
497
- * Extracts column references from an Expression (AST node).
498
- */
499
- function collectRefsFromExpression(expr, refsColumns) {
500
- if (isOperationExpr(expr)) {
501
- const allRefs = collectColumnRefs(expr);
502
- for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
503
- table: ref.table,
504
- column: ref.column
505
- });
506
- } else if (expr.kind === "col") refsColumns.set(`${expr.table}.${expr.column}`, {
507
- table: expr.table,
508
- column: expr.column
509
- });
510
- }
511
- function buildMeta(args) {
512
- const refsColumns = /* @__PURE__ */ new Map();
513
- const refsTables = new Set([args.table.name]);
514
- for (const column of args.projection.columns) collectRefsFromExpressionSource(column, refsColumns);
515
- if (args.includes) for (const include of args.includes) {
516
- refsTables.add(include.table.name);
517
- const onLeft = include.on.left;
518
- const onRight = include.on.right;
519
- if (onLeft.table && onLeft.column && onRight.table && onRight.column) {
520
- refsColumns.set(`${onLeft.table}.${onLeft.column}`, {
521
- table: onLeft.table,
522
- column: onLeft.column
523
- });
524
- refsColumns.set(`${onRight.table}.${onRight.column}`, {
525
- table: onRight.table,
526
- column: onRight.column
527
- });
528
- }
529
- for (const column of include.childProjection.columns) {
530
- const col = column;
531
- if (col.table && col.column) refsColumns.set(`${col.table}.${col.column}`, {
532
- table: col.table,
533
- column: col.column
534
- });
535
- }
536
- if (include.childWhere) collectRefsFromExpression(include.childWhere.left, refsColumns);
537
- if (include.childOrderBy) collectRefsFromExpression(include.childOrderBy.expr, refsColumns);
538
- }
539
- if (args.where) {
540
- const leftExpr = args.where.left;
541
- if (isOperationExpr(leftExpr)) {
542
- const allRefs = collectColumnRefs(leftExpr);
543
- for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
544
- table: ref.table,
545
- column: ref.column
546
- });
547
- } else refsColumns.set(`${leftExpr.table}.${leftExpr.column}`, {
548
- table: leftExpr.table,
549
- column: leftExpr.column
550
- });
551
- }
552
- if (args.orderBy) {
553
- const orderByExpr = args.orderBy.expr;
554
- if (isOperationExpr(orderByExpr)) {
555
- const allRefs = collectColumnRefs(orderByExpr);
556
- for (const ref of allRefs) refsColumns.set(`${ref.table}.${ref.column}`, {
557
- table: ref.table,
558
- column: ref.column
559
- });
560
- } else refsColumns.set(`${orderByExpr.table}.${orderByExpr.column}`, {
561
- table: orderByExpr.table,
562
- column: orderByExpr.column
563
- });
564
- }
565
- const includeAliases = new Set(args.includes?.map((inc) => inc.alias) ?? []);
566
- const projectionMap = Object.fromEntries(args.projection.aliases.map((alias, index) => {
567
- if (includeAliases.has(alias)) return [alias, `include:${alias}`];
568
- const column = args.projection.columns[index];
569
- if (!column) throw planInvalid(`Missing column for alias ${alias} at index ${index}`);
570
- if (isExpressionBuilder(column)) return [alias, `operation:${column.expr.method}`];
571
- const col = column;
572
- if (!col.table || !col.column) return [alias, `include:${alias}`];
573
- return [alias, `${col.table}.${col.column}`];
574
- }));
575
- const projectionTypes = {};
576
- for (let i = 0; i < args.projection.aliases.length; i++) {
577
- const alias = args.projection.aliases[i];
578
- if (!alias || includeAliases.has(alias)) continue;
579
- const col = args.projection.columns[i];
580
- if (!col) continue;
581
- if (isExpressionBuilder(col)) {
582
- const operationExpr = col.expr;
583
- if (operationExpr.returns.kind === "typeId") projectionTypes[alias] = operationExpr.returns.type;
584
- else if (operationExpr.returns.kind === "builtin") projectionTypes[alias] = operationExpr.returns.type;
585
- } else {
586
- const codecId = getColumnMeta(col)?.codecId;
587
- if (codecId) projectionTypes[alias] = codecId;
588
- }
589
- }
590
- const projectionCodecs = {};
591
- for (let i = 0; i < args.projection.aliases.length; i++) {
592
- const alias = args.projection.aliases[i];
593
- if (!alias || includeAliases.has(alias)) continue;
594
- const column = args.projection.columns[i];
595
- if (!column) continue;
596
- if (isExpressionBuilder(column)) {
597
- const operationExpr = column.expr;
598
- if (operationExpr.returns.kind === "typeId") projectionCodecs[alias] = operationExpr.returns.type;
599
- } else {
600
- const codecId = getColumnMeta(column)?.codecId;
601
- if (codecId) projectionCodecs[alias] = codecId;
602
- }
603
- }
604
- const allCodecs = {
605
- ...projectionCodecs,
606
- ...args.paramCodecs ? args.paramCodecs : {}
607
- };
608
- return Object.freeze(compact({
609
- target: args.contract.target,
610
- targetFamily: args.contract.targetFamily,
611
- coreHash: args.contract.coreHash,
612
- lane: "dsl",
613
- refs: {
614
- tables: Array.from(refsTables),
615
- columns: Array.from(refsColumns.values())
616
- },
617
- projection: projectionMap,
618
- projectionTypes: Object.keys(projectionTypes).length > 0 ? projectionTypes : void 0,
619
- annotations: Object.keys(allCodecs).length > 0 ? Object.freeze({ codecs: Object.freeze(allCodecs) }) : void 0,
620
- paramDescriptors: args.paramDescriptors,
621
- profileHash: args.contract.profileHash
622
- }));
623
- }
624
-
625
- //#endregion
626
- //#region src/orm/capabilities.ts
627
- function checkIncludeCapabilities(contract) {
628
- const target = contract.target;
629
- const capabilities = contract.capabilities;
630
- if (!capabilities || !capabilities[target]) errorIncludeRequiresCapabilities();
631
- const targetCapabilities = capabilities[target];
632
- if (capabilities[target]["lateral"] !== true || targetCapabilities["jsonAgg"] !== true) errorIncludeCapabilitiesNotTrue();
633
- }
634
-
635
- //#endregion
636
- //#region src/selection/join.ts
637
- function buildJoinOnExpr(parentTableName, parentColName, childTableName, childColName) {
638
- return createJoinOnExpr(createColumnRef(parentTableName, parentColName), createColumnRef(childTableName, childColName));
639
- }
640
-
641
- //#endregion
642
- //#region src/selection/ordering.ts
643
- function buildOrderByClause(orderBy) {
644
- if (!orderBy) return;
645
- const orderByBuilder = orderBy;
646
- const orderExpr = orderByBuilder.expr;
647
- return [createOrderByItem(isOperationExpr(orderExpr) ? orderExpr : (() => {
648
- const colBuilder = orderExpr;
649
- return createColumnRef(colBuilder.table, colBuilder.column);
650
- })(), orderByBuilder.dir)];
651
- }
652
- function buildChildOrderByClause(orderBy) {
653
- if (!orderBy) return;
654
- const orderByBuilder = orderBy;
655
- const orderExpr = orderByBuilder.expr;
656
- return [createOrderByItem((() => {
657
- if (isOperationExpr(orderExpr)) {
658
- const baseCol = extractBaseColumnRef(orderExpr);
659
- return createColumnRef(baseCol.table, baseCol.column);
660
- }
661
- const colBuilder = orderExpr;
662
- return createColumnRef(colBuilder.table, colBuilder.column);
663
- })(), orderByBuilder.dir)];
664
- }
665
-
666
- //#endregion
667
- //#region src/selection/projection.ts
668
- function generateAlias(path) {
669
- if (path.length === 0) errorAliasPathEmpty();
670
- return path.join("_");
671
- }
672
- var AliasTracker = class {
673
- aliases = /* @__PURE__ */ new Set();
674
- aliasToPath = /* @__PURE__ */ new Map();
675
- register(path) {
676
- const alias = generateAlias(path);
677
- if (this.aliases.has(alias)) errorAliasCollision(path, alias, this.aliasToPath.get(alias));
678
- this.aliases.add(alias);
679
- this.aliasToPath.set(alias, path);
680
- return alias;
681
- }
682
- getPath(alias) {
683
- return this.aliasToPath.get(alias);
684
- }
685
- has(alias) {
686
- return this.aliases.has(alias);
687
- }
688
- };
689
- function flattenProjection(projection, tracker, currentPath = []) {
690
- const aliases = [];
691
- const columns = [];
692
- for (const [key, value] of Object.entries(projection)) {
693
- const path = [...currentPath, key];
694
- if (isColumnBuilder(value) || isExpressionBuilder(value)) {
695
- const alias = tracker.register(path);
696
- aliases.push(alias);
697
- columns.push(value);
698
- } else if (typeof value === "object" && value !== null) {
699
- const nested = flattenProjection(value, tracker, path);
700
- aliases.push(...nested.aliases);
701
- columns.push(...nested.columns);
702
- } else errorInvalidProjectionValue(path);
703
- }
704
- return {
705
- aliases,
706
- columns
707
- };
708
- }
709
- function buildProjectionState(_table, projection, includes) {
710
- const tracker = new AliasTracker();
711
- const aliases = [];
712
- const columns = [];
713
- for (const [key, value] of Object.entries(projection)) if (value === true) {
714
- const matchingInclude = includes?.find((inc) => inc.alias === key);
715
- if (!matchingInclude) errorIncludeAliasNotFound(key);
716
- aliases.push(key);
717
- columns.push({
718
- kind: "column",
719
- table: matchingInclude.table.name,
720
- column: "",
721
- columnMeta: {
722
- nativeType: "jsonb",
723
- codecId: "core/json@1",
724
- nullable: true
725
- },
726
- toExpr() {
727
- return {
728
- kind: "col",
729
- table: matchingInclude.table.name,
730
- column: ""
731
- };
732
- }
733
- });
734
- } else if (isColumnBuilder(value) || isExpressionBuilder(value)) {
735
- const alias = tracker.register([key]);
736
- aliases.push(alias);
737
- columns.push(value);
738
- } else if (typeof value === "object" && value !== null) {
739
- const nested = flattenProjection(value, tracker, [key]);
740
- aliases.push(...nested.aliases);
741
- columns.push(...nested.columns);
742
- } else errorInvalidProjectionKey(key);
743
- if (aliases.length === 0) errorProjectionEmpty();
744
- return {
745
- aliases,
746
- columns
747
- };
748
- }
749
-
750
- //#endregion
751
- //#region src/relations/include-plan.ts
752
- function buildIncludeAsts(input) {
753
- const { includes, contract, context, modelName, paramsMap, paramDescriptors, paramValues, paramCodecs } = input;
754
- const includesAst = [];
755
- const includesForMeta = [];
756
- for (const includeState of includes) {
757
- checkIncludeCapabilities(contract);
758
- const parentTableName = contract.mappings.modelToTable?.[modelName];
759
- if (!parentTableName) errorModelNotFound(modelName);
760
- const parentSchemaTable = schema(context).tables[parentTableName];
761
- if (!parentSchemaTable) errorTableNotFound(parentTableName);
762
- const childSchemaTable = schema(context).tables[includeState.childTable.name];
763
- if (!childSchemaTable) errorTableNotFound(includeState.childTable.name);
764
- if (includeState.relation.on.parentCols.length !== 1 || includeState.relation.on.childCols.length !== 1) errorMultiColumnJoinsNotSupported();
765
- const parentColName = includeState.relation.on.parentCols[0];
766
- const childColName = includeState.relation.on.childCols[0];
767
- if (!parentColName || !childColName) errorJoinColumnsMustBeDefined();
768
- const parentCol = parentSchemaTable.columns[parentColName];
769
- const childCol = childSchemaTable.columns[childColName];
770
- if (!parentCol) errorColumnNotFound(parentColName, parentTableName);
771
- if (!childCol) errorColumnNotFound(childColName, includeState.childTable.name);
772
- const onExpr = buildJoinOnExpr(parentTableName, parentColName, includeState.childTable.name, childColName);
773
- if (!includeState.childProjection) errorChildProjectionMustBeSpecified();
774
- const filteredProjection = {};
775
- for (const [key, value] of Object.entries(includeState.childProjection)) if (value !== true && value !== false) filteredProjection[key] = value;
776
- if (Object.keys(filteredProjection).length === 0) errorChildProjectionEmpty();
777
- const childProjectionState = buildProjectionState(includeState.childTable, filteredProjection);
778
- let childWhere;
779
- if (includeState.childWhere) {
780
- const whereResult = buildWhereExpr(includeState.childWhere, contract, paramsMap, paramDescriptors, paramValues);
781
- childWhere = whereResult.expr;
782
- if (whereResult.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
783
- }
784
- const childOrderBy = buildChildOrderByClause(includeState.childOrderBy);
785
- const childProjectionItems = [];
786
- for (let i = 0; i < childProjectionState.aliases.length; i++) {
787
- const alias = childProjectionState.aliases[i];
788
- if (!alias) errorMissingAlias(i);
789
- const column = childProjectionState.columns[i];
790
- if (!column) errorMissingColumn(alias, i);
791
- if (isExpressionBuilder(column)) childProjectionItems.push({
792
- alias,
793
- expr: column.expr
794
- });
795
- else childProjectionItems.push({
796
- alias,
797
- expr: column.toExpr()
798
- });
799
- }
800
- const includeAst = compact({
801
- kind: "includeMany",
802
- alias: includeState.alias,
803
- child: compact({
804
- table: includeState.childTable,
805
- on: onExpr,
806
- project: childProjectionItems,
807
- where: childWhere,
808
- orderBy: childOrderBy,
809
- limit: includeState.childLimit
810
- })
811
- });
812
- includesAst.push(includeAst);
813
- const includeForMeta = compact({
814
- alias: includeState.alias,
815
- table: includeState.childTable,
816
- on: {
817
- kind: "join-on",
818
- left: parentCol,
819
- right: childCol
820
- },
821
- childProjection: childProjectionState,
822
- childWhere: includeState.childWhere,
823
- childOrderBy: includeState.childOrderBy,
824
- childLimit: includeState.childLimit
825
- });
826
- includesForMeta.push(includeForMeta);
827
- }
828
- return {
829
- includesAst,
830
- includesForMeta
831
- };
832
- }
833
- function buildExistsSubqueries(relationFilters, contract, modelName, options) {
834
- const existsExprs = [];
835
- for (const filter of relationFilters) {
836
- const childTableName = contract.mappings.modelToTable?.[filter.childModelName];
837
- if (!childTableName) errorModelNotFound(filter.childModelName);
838
- const childTable = {
839
- kind: "table",
840
- name: childTableName
841
- };
842
- const parentTableName = contract.mappings.modelToTable?.[modelName];
843
- if (!parentTableName) errorModelNotFound(modelName);
844
- const joinConditions = [];
845
- for (let i = 0; i < filter.relation.on.parentCols.length; i++) {
846
- const parentCol = filter.relation.on.parentCols[i];
847
- const childCol = filter.relation.on.childCols[i];
848
- if (!parentCol || !childCol) continue;
849
- joinConditions.push({
850
- left: {
851
- kind: "col",
852
- table: parentTableName,
853
- column: parentCol
854
- },
855
- right: {
856
- kind: "col",
857
- table: childTableName,
858
- column: childCol
859
- }
860
- });
861
- }
862
- let childWhere;
863
- if (filter.childWhere) {
864
- const paramsMap = options?.params ?? {};
865
- childWhere = buildWhereExpr(filter.childWhere, contract, paramsMap, [], []).expr;
866
- }
867
- let subqueryWhere = childWhere;
868
- if (joinConditions.length > 0) {
869
- const firstJoinCondition = joinConditions[0];
870
- if (firstJoinCondition) {
871
- const joinWhere = {
872
- kind: "bin",
873
- op: "eq",
874
- left: firstJoinCondition.left,
875
- right: firstJoinCondition.right
876
- };
877
- if (childWhere) subqueryWhere = joinWhere;
878
- else subqueryWhere = joinWhere;
879
- }
880
- }
881
- const existsExpr = {
882
- kind: "exists",
883
- subquery: createSelectAst({
884
- from: childTable,
885
- project: [{
886
- alias: "_exists",
887
- expr: joinConditions[0]?.right ?? createColumnRef(childTableName, "id")
888
- }],
889
- where: subqueryWhere
890
- }),
891
- not: filter.filterType === "none" || filter.filterType === "every"
892
- };
893
- existsExprs.push(existsExpr);
894
- }
895
- return existsExprs;
896
- }
897
- function combineWhereClauses(mainWhere, existsExprs) {
898
- if (existsExprs.length === 1) return existsExprs[0];
899
- if (mainWhere) return mainWhere;
900
- if (existsExprs.length > 0) return existsExprs[0];
901
- }
902
-
903
- //#endregion
904
- //#region src/selection/select-builder.ts
905
- function buildProjectionItems(projectionState, includesForMeta) {
906
- const projectEntries = [];
907
- for (let i = 0; i < projectionState.aliases.length; i++) {
908
- const alias = projectionState.aliases[i];
909
- if (!alias) errorMissingAlias(i);
910
- const column = projectionState.columns[i];
911
- if (!column) errorMissingColumn(alias, i);
912
- if (includesForMeta.find((inc) => inc.alias === alias)) projectEntries.push({
913
- alias,
914
- expr: {
915
- kind: "includeRef",
916
- alias
917
- }
918
- });
919
- else if (isExpressionBuilder(column)) projectEntries.push({
920
- alias,
921
- expr: column.expr
922
- });
923
- else {
924
- const expr = column.toExpr();
925
- if (expr.kind === "col" && (!expr.table || !expr.column)) errorInvalidColumn(alias, i);
926
- projectEntries.push({
927
- alias,
928
- expr
929
- });
930
- }
931
- }
932
- return projectEntries;
933
- }
934
- function buildSelectAst(params) {
935
- const { table, projectEntries, includesAst, whereExpr, orderByClause, limit } = params;
936
- return createSelectAst({
937
- from: createTableRef(table.name),
938
- project: projectEntries,
939
- ...includesAst ? { includes: includesAst } : {},
940
- ...whereExpr ? { where: whereExpr } : {},
941
- ...orderByClause ? { orderBy: orderByClause } : {},
942
- ...limit !== void 0 ? { limit } : {}
943
- });
944
- }
945
-
946
- //#endregion
947
- //#region src/orm/context.ts
948
- function createOrmContext(context) {
949
- return context;
950
- }
951
-
952
- //#endregion
953
- //#region src/orm/builder.ts
954
- var OrmModelBuilderImpl = class OrmModelBuilderImpl {
955
- context;
956
- contract;
957
- modelName;
958
- table;
959
- wherePredicate = void 0;
960
- relationFilters = [];
961
- includes = [];
962
- orderByExpr = void 0;
963
- limitValue = void 0;
964
- offsetValue = void 0;
965
- projection = void 0;
966
- constructor(options, modelName) {
967
- this.context = options.context;
968
- this.contract = options.context.contract;
969
- this.modelName = modelName;
970
- const tableName = this.contract.mappings.modelToTable?.[modelName];
971
- if (!tableName) errorModelNotFound(modelName);
972
- const table = schema(options.context).tables[tableName];
973
- if (!table) errorTableNotFound(tableName);
974
- this.table = table;
975
- }
976
- get where() {
977
- const whereFn = (fn) => {
978
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
979
- builder["table"] = this.table;
980
- builder.wherePredicate = fn(this._getModelAccessor());
981
- builder.relationFilters = this.relationFilters;
982
- builder.includes = this.includes;
983
- builder.orderByExpr = this.orderByExpr;
984
- builder.limitValue = this.limitValue;
985
- builder.offsetValue = this.offsetValue;
986
- builder.projection = this.projection;
987
- return builder;
988
- };
989
- const related = this._createRelatedProxy();
990
- return Object.assign(whereFn, { related });
991
- }
992
- get include() {
993
- return this._createIncludeProxy();
994
- }
995
- _createIncludeProxy() {
996
- const self = this;
997
- const tableName = this.contract.mappings.modelToTable?.[this.modelName];
998
- if (!tableName) return {};
999
- const modelRelations = this.contract.relations?.[tableName];
1000
- if (!modelRelations || typeof modelRelations !== "object") return {};
1001
- return new Proxy({}, { get(_target, prop) {
1002
- if (typeof prop !== "string") return;
1003
- const relation = modelRelations[prop];
1004
- if (!relation || typeof relation !== "object" || !("to" in relation)) throw planInvalid(`Relation ${prop} not found on model ${self.modelName}`);
1005
- const childModelName = relation.to;
1006
- const relationDef = relation;
1007
- const relationName = prop;
1008
- const includeFn = ((child) => {
1009
- return self._applyInclude(relationName, childModelName, child, relationDef);
1010
- });
1011
- return includeFn;
1012
- } });
1013
- }
1014
- _applyInclude(relationName, childModelName, childBuilderFn, relationDef) {
1015
- const childTableName = this.contract.mappings.modelToTable?.[childModelName];
1016
- if (!childTableName) errorModelNotFound(childModelName);
1017
- const childTable = {
1018
- kind: "table",
1019
- name: childTableName
1020
- };
1021
- const childState = childBuilderFn(new OrmIncludeChildBuilderImpl({ context: this.context }, childModelName)).getState();
1022
- const includeState = {
1023
- relationName,
1024
- childModelName,
1025
- childTable,
1026
- childWhere: childState.childWhere,
1027
- childOrderBy: childState.childOrderBy,
1028
- childLimit: childState.childLimit,
1029
- childProjection: childState.childProjection,
1030
- alias: relationName,
1031
- relation: relationDef
1032
- };
1033
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1034
- builder["table"] = this.table;
1035
- builder.wherePredicate = this.wherePredicate;
1036
- builder.relationFilters = this.relationFilters;
1037
- builder.includes = [...this.includes, includeState];
1038
- builder.orderByExpr = this.orderByExpr;
1039
- builder.limitValue = this.limitValue;
1040
- builder.offsetValue = this.offsetValue;
1041
- builder.projection = this.projection;
1042
- return builder;
1043
- }
1044
- _createRelatedProxy() {
1045
- const self = this;
1046
- const tableName = this.contract.mappings.modelToTable?.[this.modelName];
1047
- if (!tableName) return {};
1048
- const modelRelations = this.contract.relations?.[tableName];
1049
- if (!modelRelations || typeof modelRelations !== "object") return {};
1050
- return new Proxy({}, { get(_target, prop) {
1051
- if (typeof prop !== "string") return;
1052
- const relation = modelRelations[prop];
1053
- if (!relation || typeof relation !== "object" || !("to" in relation)) throw planInvalid(`Relation ${prop} not found on model ${self.modelName}`);
1054
- const childModelName = relation.to;
1055
- const relationDef = relation;
1056
- const filterBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
1057
- const modelAccessor = filterBuilder.getModelAccessor();
1058
- const builderWithAccessor = Object.assign(filterBuilder, modelAccessor);
1059
- return {
1060
- some: (fn) => {
1061
- const result = fn(builderWithAccessor);
1062
- if (result && "kind" in result && result.kind === "binary") {
1063
- const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
1064
- wrappedBuilder["wherePredicate"] = result;
1065
- return self._applyRelationFilter(prop, childModelName, "some", () => wrappedBuilder, relationDef);
1066
- }
1067
- return self._applyRelationFilter(prop, childModelName, "some", () => result, relationDef);
1068
- },
1069
- none: (fn) => {
1070
- const result = fn(builderWithAccessor);
1071
- if (result && "kind" in result && result.kind === "binary") {
1072
- const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
1073
- wrappedBuilder["wherePredicate"] = result;
1074
- return self._applyRelationFilter(prop, childModelName, "none", () => wrappedBuilder, relationDef);
1075
- }
1076
- return self._applyRelationFilter(prop, childModelName, "none", () => result, relationDef);
1077
- },
1078
- every: (fn) => {
1079
- const result = fn(builderWithAccessor);
1080
- if (result && "kind" in result && result.kind === "binary") {
1081
- const wrappedBuilder = new OrmRelationFilterBuilderImpl({ context: self.context }, childModelName);
1082
- wrappedBuilder["wherePredicate"] = result;
1083
- return self._applyRelationFilter(prop, childModelName, "every", () => wrappedBuilder, relationDef);
1084
- }
1085
- return self._applyRelationFilter(prop, childModelName, "every", () => result, relationDef);
1086
- }
1087
- };
1088
- } });
1089
- }
1090
- _applyRelationFilter(relationName, childModelName, filterType, fn, relationDef) {
1091
- const relationFilter = {
1092
- relationName,
1093
- childModelName,
1094
- filterType,
1095
- childWhere: fn(new OrmRelationFilterBuilderImpl({ context: this.context }, childModelName)).getWherePredicate(),
1096
- relation: relationDef
1097
- };
1098
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1099
- builder["table"] = this.table;
1100
- builder.wherePredicate = this.wherePredicate;
1101
- builder.relationFilters = [...this.relationFilters, relationFilter];
1102
- builder.includes = this.includes;
1103
- builder.orderByExpr = this.orderByExpr;
1104
- builder.limitValue = this.limitValue;
1105
- builder.offsetValue = this.offsetValue;
1106
- builder.projection = this.projection;
1107
- return builder;
1108
- }
1109
- orderBy(fn) {
1110
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1111
- builder["table"] = this.table;
1112
- builder.wherePredicate = this.wherePredicate;
1113
- builder.relationFilters = this.relationFilters;
1114
- builder.includes = this.includes;
1115
- builder.orderByExpr = fn(this._getModelAccessor());
1116
- builder.limitValue = this.limitValue;
1117
- builder.offsetValue = this.offsetValue;
1118
- builder.projection = this.projection;
1119
- return builder;
1120
- }
1121
- take(n) {
1122
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1123
- builder["table"] = this.table;
1124
- builder.wherePredicate = this.wherePredicate;
1125
- builder.relationFilters = this.relationFilters;
1126
- builder.includes = this.includes;
1127
- builder.orderByExpr = this.orderByExpr;
1128
- builder.limitValue = n;
1129
- builder.offsetValue = this.offsetValue;
1130
- builder.projection = this.projection;
1131
- return builder;
1132
- }
1133
- skip(n) {
1134
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1135
- builder["table"] = this.table;
1136
- builder.wherePredicate = this.wherePredicate;
1137
- builder.relationFilters = this.relationFilters;
1138
- builder.includes = this.includes;
1139
- builder.orderByExpr = this.orderByExpr;
1140
- builder.limitValue = this.limitValue;
1141
- builder.offsetValue = n;
1142
- builder.projection = this.projection;
1143
- return builder;
1144
- }
1145
- select(fn) {
1146
- const builder = new OrmModelBuilderImpl({ context: this.context }, this.modelName);
1147
- builder["table"] = this.table;
1148
- builder.wherePredicate = this.wherePredicate;
1149
- builder.relationFilters = this.relationFilters;
1150
- builder.includes = this.includes;
1151
- builder.orderByExpr = this.orderByExpr;
1152
- builder.limitValue = this.limitValue;
1153
- builder.offsetValue = this.offsetValue;
1154
- builder.projection = fn(this._getModelAccessor());
1155
- return builder;
1156
- }
1157
- findMany(options) {
1158
- const paramsMap = options?.params ?? {};
1159
- if (!this.contract.storage.tables[this.table.name]) errorUnknownTable(this.table.name);
1160
- const paramDescriptors = [];
1161
- const paramValues = [];
1162
- const paramCodecs = {};
1163
- const projectionInput = this.projection ?? (() => {
1164
- const modelAccessor = this._getModelAccessor();
1165
- const defaultProjection = {};
1166
- for (const fieldName in modelAccessor) defaultProjection[fieldName] = modelAccessor[fieldName];
1167
- return defaultProjection;
1168
- })();
1169
- const { includesAst, includesForMeta } = buildIncludeAsts({
1170
- includes: this.includes,
1171
- contract: this.contract,
1172
- context: this.context,
1173
- modelName: this.modelName,
1174
- paramsMap,
1175
- paramDescriptors,
1176
- paramValues,
1177
- paramCodecs
1178
- });
1179
- const projectionState = buildProjectionState(this.table, projectionInput, includesForMeta.length > 0 ? includesForMeta : void 0);
1180
- const whereResult = this.wherePredicate ? buildWhereExpr(this.wherePredicate, this.contract, paramsMap, paramDescriptors, paramValues) : void 0;
1181
- const whereExpr = whereResult?.expr;
1182
- if (whereResult?.codecId && whereResult.paramName) paramCodecs[whereResult.paramName] = whereResult.codecId;
1183
- const orderByClause = buildOrderByClause(this.orderByExpr);
1184
- const projectEntries = buildProjectionItems(projectionState, includesForMeta);
1185
- const ast = buildSelectAst({
1186
- table: this.table,
1187
- projectEntries,
1188
- ...includesAst.length > 0 ? { includesAst } : {},
1189
- ...whereExpr ? { whereExpr } : {},
1190
- ...orderByClause ? { orderByClause } : {},
1191
- ...this.limitValue !== void 0 ? { limit: this.limitValue } : {}
1192
- });
1193
- const planMeta = buildMeta({
1194
- contract: this.contract,
1195
- table: createTableRef(this.table.name),
1196
- projection: projectionState,
1197
- includes: includesForMeta.length > 0 ? includesForMeta : void 0,
1198
- paramDescriptors,
1199
- paramCodecs: Object.keys(paramCodecs).length > 0 ? paramCodecs : void 0,
1200
- where: this.wherePredicate,
1201
- orderBy: this.orderByExpr
1202
- });
1203
- if (this.relationFilters.length > 0) {
1204
- const existsExprs = buildExistsSubqueries(this.relationFilters, this.contract, this.modelName, options);
1205
- if (existsExprs.length > 0) {
1206
- const combinedWhere = combineWhereClauses(ast.where, existsExprs);
1207
- const modifiedAst = {
1208
- ...ast,
1209
- ...combinedWhere !== void 0 ? { where: combinedWhere } : {}
1210
- };
1211
- return Object.freeze({
1212
- ast: modifiedAst,
1213
- params: paramValues,
1214
- meta: {
1215
- ...planMeta,
1216
- lane: "orm"
1217
- }
1218
- });
1219
- }
1220
- }
1221
- return Object.freeze({
1222
- ast,
1223
- params: paramValues,
1224
- meta: {
1225
- ...planMeta,
1226
- lane: "orm"
1227
- }
1228
- });
1229
- }
1230
- findFirst(options) {
1231
- return this.take(1).findMany(options);
1232
- }
1233
- findUnique(where, options) {
1234
- return this.where(where).take(1).findMany(options);
1235
- }
1236
- create(data, options) {
1237
- return buildInsertPlan(createOrmContext(this.context), this.modelName, data, options);
1238
- }
1239
- update(where, data, options) {
1240
- return buildUpdatePlan(createOrmContext(this.context), this.modelName, where, () => this._getModelAccessor(), data, options);
1241
- }
1242
- delete(where, options) {
1243
- return buildDeletePlan(createOrmContext(this.context), this.modelName, where, () => this._getModelAccessor(), options);
1244
- }
1245
- _getModelAccessor() {
1246
- const tableName = this.contract.mappings.modelToTable?.[this.modelName];
1247
- if (!tableName) errorModelNotFound(this.modelName);
1248
- const table = schema(this.context).tables[tableName];
1249
- if (!table) errorTableNotFound(tableName);
1250
- const accessor = {};
1251
- const model = this.contract.models[this.modelName];
1252
- if (!model || typeof model !== "object" || !("fields" in model)) throw planInvalid(`Model ${this.modelName} does not have fields`);
1253
- const modelFields = model.fields;
1254
- for (const fieldName in modelFields) {
1255
- const field = modelFields[fieldName];
1256
- if (!field) continue;
1257
- const columnName = this.contract.mappings.fieldToColumn?.[this.modelName]?.[fieldName] ?? field.column ?? fieldName;
1258
- const column = table.columns[columnName];
1259
- if (column) accessor[fieldName] = column;
1260
- }
1261
- return accessor;
1262
- }
1263
- };
1264
-
1265
- //#endregion
1266
- //#region src/orm.ts
1267
- function orm(options) {
1268
- const contract = options.context.contract;
1269
- return new Proxy({}, {
1270
- get(_target, prop) {
1271
- if (typeof prop !== "string") return;
1272
- const modelName = prop.charAt(0).toUpperCase() + prop.slice(1);
1273
- if (!contract.models || typeof contract.models !== "object" || !(modelName in contract.models)) throw planInvalid(`Model ${prop} (resolved to ${modelName}) not found in contract`);
1274
- return () => new OrmModelBuilderImpl(options, modelName);
1275
- },
1276
- has(_target, prop) {
1277
- if (typeof prop !== "string") return false;
1278
- const modelName = prop.charAt(0).toUpperCase() + prop.slice(1);
1279
- return contract.models && typeof contract.models === "object" && modelName in contract.models;
1280
- }
1281
- });
1282
- }
1283
-
1284
- //#endregion
1285
- export { OrmModelBuilderImpl as n, orm as t };
1286
- //# sourceMappingURL=orm-BYJaTDLm.mjs.map