@zenstackhq/runtime 3.0.0-alpha.9 → 3.0.0-beta.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.
@@ -16,15 +16,115 @@ var RejectedByPolicyError = class extends Error {
16
16
  // src/plugins/policy/policy-handler.ts
17
17
  import { invariant as invariant6 } from "@zenstackhq/common-helpers";
18
18
  import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode2, DeleteQueryNode, FromNode as FromNode2, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, TableNode as TableNode3, UpdateQueryNode, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
19
- import { match as match7 } from "ts-pattern";
19
+ import { match as match8 } from "ts-pattern";
20
20
 
21
21
  // src/client/crud/dialects/index.ts
22
- import { match as match4 } from "ts-pattern";
22
+ import { match as match5 } from "ts-pattern";
23
23
 
24
24
  // src/client/crud/dialects/postgresql.ts
25
25
  import { invariant as invariant2 } from "@zenstackhq/common-helpers";
26
26
  import { sql as sql2 } from "kysely";
27
- import { match as match2 } from "ts-pattern";
27
+ import { match as match3 } from "ts-pattern";
28
+
29
+ // src/client/constants.ts
30
+ var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
31
+ var LOGICAL_COMBINATORS = [
32
+ "AND",
33
+ "OR",
34
+ "NOT"
35
+ ];
36
+ var AGGREGATE_OPERATORS = [
37
+ "_count",
38
+ "_sum",
39
+ "_avg",
40
+ "_min",
41
+ "_max"
42
+ ];
43
+
44
+ // src/client/query-utils.ts
45
+ import { match } from "ts-pattern";
46
+
47
+ // src/schema/expression.ts
48
+ var ExpressionUtils = {
49
+ literal: /* @__PURE__ */ __name((value) => {
50
+ return {
51
+ kind: "literal",
52
+ value
53
+ };
54
+ }, "literal"),
55
+ array: /* @__PURE__ */ __name((items) => {
56
+ return {
57
+ kind: "array",
58
+ items
59
+ };
60
+ }, "array"),
61
+ call: /* @__PURE__ */ __name((functionName, args) => {
62
+ return {
63
+ kind: "call",
64
+ function: functionName,
65
+ args
66
+ };
67
+ }, "call"),
68
+ binary: /* @__PURE__ */ __name((left, op, right) => {
69
+ return {
70
+ kind: "binary",
71
+ op,
72
+ left,
73
+ right
74
+ };
75
+ }, "binary"),
76
+ unary: /* @__PURE__ */ __name((op, operand) => {
77
+ return {
78
+ kind: "unary",
79
+ op,
80
+ operand
81
+ };
82
+ }, "unary"),
83
+ field: /* @__PURE__ */ __name((field) => {
84
+ return {
85
+ kind: "field",
86
+ field
87
+ };
88
+ }, "field"),
89
+ member: /* @__PURE__ */ __name((receiver, members) => {
90
+ return {
91
+ kind: "member",
92
+ receiver,
93
+ members
94
+ };
95
+ }, "member"),
96
+ _this: /* @__PURE__ */ __name(() => {
97
+ return {
98
+ kind: "this"
99
+ };
100
+ }, "_this"),
101
+ _null: /* @__PURE__ */ __name(() => {
102
+ return {
103
+ kind: "null"
104
+ };
105
+ }, "_null"),
106
+ and: /* @__PURE__ */ __name((expr2, ...expressions) => {
107
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
108
+ }, "and"),
109
+ or: /* @__PURE__ */ __name((expr2, ...expressions) => {
110
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
111
+ }, "or"),
112
+ is: /* @__PURE__ */ __name((value, kind) => {
113
+ return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
114
+ }, "is"),
115
+ isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
116
+ isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
117
+ isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
118
+ isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
119
+ isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
120
+ isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
121
+ isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
122
+ isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
123
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
124
+ getLiteralValue: /* @__PURE__ */ __name((expr2) => {
125
+ return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
126
+ }, "getLiteralValue")
127
+ };
28
128
 
29
129
  // src/client/errors.ts
30
130
  var QueryError = class extends Error {
@@ -41,9 +141,6 @@ var InternalError = class extends Error {
41
141
  static {
42
142
  __name(this, "InternalError");
43
143
  }
44
- constructor(message) {
45
- super(message);
46
- }
47
144
  };
48
145
 
49
146
  // src/client/query-utils.ts
@@ -118,10 +215,15 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
118
215
  }
119
216
  __name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
120
217
  function isRelationField(schema, model, field) {
121
- const fieldDef = requireField(schema, model, field);
122
- return !!fieldDef.relation;
218
+ const fieldDef = getField(schema, model, field);
219
+ return !!fieldDef?.relation;
123
220
  }
124
221
  __name(isRelationField, "isRelationField");
222
+ function isInheritedField(schema, model, field) {
223
+ const fieldDef = getField(schema, model, field);
224
+ return !!fieldDef?.originModel;
225
+ }
226
+ __name(isInheritedField, "isInheritedField");
125
227
  function getUniqueFields(schema, model) {
126
228
  const modelDef = requireModel(schema, model);
127
229
  const result = [];
@@ -147,11 +249,14 @@ function getUniqueFields(schema, model) {
147
249
  return result;
148
250
  }
149
251
  __name(getUniqueFields, "getUniqueFields");
150
- function buildFieldRef(schema, model, field, options, eb, modelAlias) {
252
+ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComputedField = true) {
151
253
  const fieldDef = requireField(schema, model, field);
152
254
  if (!fieldDef.computed) {
153
255
  return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
154
256
  } else {
257
+ if (!inlineComputedField) {
258
+ return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
259
+ }
155
260
  let computer;
156
261
  if ("computedFields" in options) {
157
262
  const computedFields = options.computedFields;
@@ -160,7 +265,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
160
265
  if (!computer) {
161
266
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
162
267
  }
163
- return computer(eb);
268
+ return computer(eb, {
269
+ currentModel: modelAlias
270
+ });
164
271
  }
165
272
  }
166
273
  __name(buildFieldRef, "buildFieldRef");
@@ -203,11 +310,33 @@ function getManyToManyRelation(schema, model, field) {
203
310
  model,
204
311
  fieldDef.type
205
312
  ].sort();
313
+ let orderedFK;
314
+ if (model !== fieldDef.type) {
315
+ orderedFK = sortedModelNames[0] === model ? [
316
+ "A",
317
+ "B"
318
+ ] : [
319
+ "B",
320
+ "A"
321
+ ];
322
+ } else {
323
+ const sortedFieldNames = [
324
+ field,
325
+ oppositeFieldDef.name
326
+ ].sort();
327
+ orderedFK = sortedFieldNames[0] === field ? [
328
+ "A",
329
+ "B"
330
+ ] : [
331
+ "B",
332
+ "A"
333
+ ];
334
+ }
206
335
  return {
207
- parentFkName: sortedModelNames[0] === model ? "A" : "B",
336
+ parentFkName: orderedFK[0],
208
337
  otherModel: fieldDef.type,
209
338
  otherField: fieldDef.relation.opposite,
210
- otherFkName: sortedModelNames[0] === fieldDef.type ? "A" : "B",
339
+ otherFkName: orderedFK[1],
211
340
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
212
341
  };
213
342
  } else {
@@ -235,11 +364,38 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
235
364
  return result;
236
365
  }
237
366
  __name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
367
+ function ensureArray(value) {
368
+ if (Array.isArray(value)) {
369
+ return value;
370
+ } else {
371
+ return [
372
+ value
373
+ ];
374
+ }
375
+ }
376
+ __name(ensureArray, "ensureArray");
377
+ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
378
+ const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
379
+ subModels.forEach((def) => {
380
+ if (!collected.has(def)) {
381
+ collected.add(def);
382
+ getDelegateDescendantModels(schema, def.name, collected);
383
+ }
384
+ });
385
+ return [
386
+ ...collected
387
+ ];
388
+ }
389
+ __name(getDelegateDescendantModels, "getDelegateDescendantModels");
390
+ function aggregate(eb, expr2, op) {
391
+ return match(op).with("_count", () => eb.fn.count(expr2)).with("_sum", () => eb.fn.sum(expr2)).with("_avg", () => eb.fn.avg(expr2)).with("_min", () => eb.fn.min(expr2)).with("_max", () => eb.fn.max(expr2)).exhaustive();
392
+ }
393
+ __name(aggregate, "aggregate");
238
394
 
239
395
  // src/client/crud/dialects/base.ts
240
396
  import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
241
- import { sql } from "kysely";
242
- import { match, P } from "ts-pattern";
397
+ import { expressionBuilder, sql } from "kysely";
398
+ import { match as match2, P } from "ts-pattern";
243
399
 
244
400
  // src/utils/enumerate.ts
245
401
  function enumerate(x) {
@@ -269,6 +425,44 @@ var BaseCrudDialect = class {
269
425
  transformPrimitive(value, _type, _forArrayField) {
270
426
  return value;
271
427
  }
428
+ // #region common query builders
429
+ buildSelectModel(eb, model, modelAlias) {
430
+ const modelDef = requireModel(this.schema, model);
431
+ let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
432
+ let joinBase = modelDef.baseModel;
433
+ while (joinBase) {
434
+ result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
435
+ joinBase = requireModel(this.schema, joinBase).baseModel;
436
+ }
437
+ return result;
438
+ }
439
+ buildFilterSortTake(model, args, query, modelAlias) {
440
+ let result = query;
441
+ if (args.where) {
442
+ result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
443
+ }
444
+ let negateOrderBy = false;
445
+ const skip = args.skip;
446
+ let take = args.take;
447
+ if (take !== void 0 && take < 0) {
448
+ negateOrderBy = true;
449
+ take = -take;
450
+ }
451
+ result = this.buildSkipTake(result, skip, take);
452
+ result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
453
+ if ("distinct" in args && args.distinct) {
454
+ const distinct = ensureArray(args.distinct);
455
+ if (this.supportsDistinctOn) {
456
+ result = result.distinctOn(distinct.map((f) => sql.ref(`${modelAlias}.${f}`)));
457
+ } else {
458
+ throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
459
+ }
460
+ }
461
+ if (args.cursor) {
462
+ result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
463
+ }
464
+ return result;
465
+ }
272
466
  buildFilter(eb, model, modelAlias, where) {
273
467
  if (where === true || where === void 0) {
274
468
  return this.true(eb);
@@ -285,17 +479,20 @@ var BaseCrudDialect = class {
285
479
  if (key.startsWith("$")) {
286
480
  continue;
287
481
  }
288
- if (key === "AND" || key === "OR" || key === "NOT") {
482
+ if (this.isLogicalCombinator(key)) {
289
483
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
290
484
  continue;
291
485
  }
292
486
  const fieldDef = requireField(this.schema, model, key);
293
487
  if (fieldDef.relation) {
294
488
  result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
295
- } else if (fieldDef.array) {
296
- result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
297
489
  } else {
298
- result = this.and(eb, result, this.buildPrimitiveFilter(eb, model, modelAlias, key, fieldDef, payload));
490
+ const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
491
+ if (fieldDef.array) {
492
+ result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
493
+ } else {
494
+ result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
495
+ }
299
496
  }
300
497
  }
301
498
  if ("$expr" in _where && typeof _where["$expr"] === "function") {
@@ -303,8 +500,32 @@ var BaseCrudDialect = class {
303
500
  }
304
501
  return result;
305
502
  }
503
+ buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
504
+ const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
505
+ const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
506
+ const eb = expressionBuilder();
507
+ const subQueryAlias = `${model}$cursor$sub`;
508
+ const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
509
+ let result = query;
510
+ const filters = [];
511
+ for (let i = orderByItems.length - 1; i >= 0; i--) {
512
+ const andFilters = [];
513
+ for (let j = 0; j <= i; j++) {
514
+ const [field, order] = orderByItems[j];
515
+ const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
516
+ const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
517
+ andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
518
+ }
519
+ filters.push(eb.and(andFilters));
520
+ }
521
+ result = result.where((eb2) => eb2.or(filters));
522
+ return result;
523
+ }
524
+ isLogicalCombinator(key) {
525
+ return LOGICAL_COMBINATORS.includes(key);
526
+ }
306
527
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
307
- return match(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
528
+ return match2(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
308
529
  }
309
530
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
310
531
  if (!fieldDef.array) {
@@ -313,19 +534,26 @@ var BaseCrudDialect = class {
313
534
  return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
314
535
  }
315
536
  }
316
- buildToOneRelationFilter(eb, model, table, field, fieldDef, payload) {
537
+ buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
317
538
  if (payload === null) {
318
539
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
319
- if (ownedByModel) {
320
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(sql.ref(`${table}.${fk}`), "is", null)));
540
+ if (ownedByModel && !fieldDef.originModel) {
541
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(sql.ref(`${modelAlias}.${fk}`), "is", null)));
321
542
  } else {
322
- return this.buildToOneRelationFilter(eb, model, table, field, fieldDef, {
543
+ return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
323
544
  is: null
324
545
  });
325
546
  }
326
547
  }
327
- const joinAlias = `${table}$${field}`;
328
- const joinPairs = buildJoinPairs(this.schema, model, table, field, joinAlias);
548
+ const joinAlias = `${modelAlias}$${field}`;
549
+ const joinPairs = buildJoinPairs(
550
+ this.schema,
551
+ model,
552
+ // if field is from a base, use the base model to join
553
+ fieldDef.originModel ?? modelAlias,
554
+ field,
555
+ joinAlias
556
+ );
329
557
  const filterResultField = `${field}$filter`;
330
558
  const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
331
559
  const conditions = [];
@@ -355,25 +583,26 @@ var BaseCrudDialect = class {
355
583
  }
356
584
  return this.and(eb, ...conditions);
357
585
  }
358
- buildToManyRelationFilter(eb, model, table, field, fieldDef, payload) {
586
+ buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
359
587
  if (payload === null) {
360
- return eb(sql.ref(`${table}.${field}`), "is", null);
588
+ return eb(sql.ref(`${modelAlias}.${field}`), "is", null);
361
589
  }
362
590
  const relationModel = fieldDef.type;
591
+ const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
363
592
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
364
593
  const m2m = getManyToManyRelation(this.schema, model, field);
365
594
  if (m2m) {
366
595
  const modelIdField = getIdFields(this.schema, model)[0];
367
596
  const relationIdField = getIdFields(this.schema, relationModel)[0];
368
- return eb2(sql.ref(`${relationModel}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", sql.ref(`${table}.${modelIdField}`)));
597
+ return eb2(sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", sql.ref(`${modelAlias}.${modelIdField}`)));
369
598
  } else {
370
599
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
371
600
  let result2 = this.true(eb2);
372
601
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
373
602
  if (relationKeyPairs.ownedByModel) {
374
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${fk}`), "=", sql.ref(`${relationModel}.${pk}`)));
603
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${fk}`), "=", sql.ref(`${relationFilterSelectAlias}.${pk}`)));
375
604
  } else {
376
- result2 = this.and(eb2, result2, eb2(sql.ref(`${table}.${pk}`), "=", sql.ref(`${relationModel}.${fk}`)));
605
+ result2 = this.and(eb2, result2, eb2(sql.ref(`${modelAlias}.${pk}`), "=", sql.ref(`${relationFilterSelectAlias}.${fk}`)));
377
606
  }
378
607
  }
379
608
  return result2;
@@ -386,25 +615,24 @@ var BaseCrudDialect = class {
386
615
  }
387
616
  switch (key) {
388
617
  case "some": {
389
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
618
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), ">", 0));
390
619
  break;
391
620
  }
392
621
  case "every": {
393
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationModel, subPayload))), "=", 0));
622
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload))), "=", 0));
394
623
  break;
395
624
  }
396
625
  case "none": {
397
- result = this.and(eb, result, eb(eb.selectFrom(relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
626
+ result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), "=", 0));
398
627
  break;
399
628
  }
400
629
  }
401
630
  }
402
631
  return result;
403
632
  }
404
- buildArrayFilter(eb, model, modelAlias, field, fieldDef, payload) {
633
+ buildArrayFilter(eb, fieldRef, fieldDef, payload) {
405
634
  const clauses = [];
406
635
  const fieldType = fieldDef.type;
407
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
408
636
  for (const [key, _value] of Object.entries(payload)) {
409
637
  if (_value === void 0) {
410
638
  continue;
@@ -440,14 +668,14 @@ var BaseCrudDialect = class {
440
668
  }
441
669
  return this.and(eb, ...clauses);
442
670
  }
443
- buildPrimitiveFilter(eb, model, modelAlias, field, fieldDef, payload) {
671
+ buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
444
672
  if (payload === null) {
445
- return eb(sql.ref(`${modelAlias}.${field}`), "is", null);
673
+ return eb(fieldRef, "is", null);
446
674
  }
447
675
  if (isEnum(this.schema, fieldDef.type)) {
448
- return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
676
+ return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
449
677
  }
450
- return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).with("Json", () => {
678
+ return match2(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(eb, fieldRef, payload)).with("Json", () => {
451
679
  throw new InternalError("JSON filters are not supported yet");
452
680
  }).with("Unsupported", () => {
453
681
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -456,7 +684,7 @@ var BaseCrudDialect = class {
456
684
  buildLiteralFilter(eb, lhs, type, rhs) {
457
685
  return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
458
686
  }
459
- buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
687
+ buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
460
688
  if (payload === null || !isPlainObject(payload)) {
461
689
  return {
462
690
  conditions: [
@@ -471,8 +699,11 @@ var BaseCrudDialect = class {
471
699
  if (onlyForKeys && !onlyForKeys.includes(op)) {
472
700
  continue;
473
701
  }
702
+ if (excludeKeys.includes(op)) {
703
+ continue;
704
+ }
474
705
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
475
- const condition = match(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
706
+ const condition = match2(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
476
707
  invariant(Array.isArray(rhs), "right hand side must be an array");
477
708
  if (rhs.length === 0) {
478
709
  return this.false(eb);
@@ -486,7 +717,11 @@ var BaseCrudDialect = class {
486
717
  } else {
487
718
  return eb.not(eb(lhs, "in", rhs));
488
719
  }
489
- }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).otherwise(() => {
720
+ }).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).with(P.union(...AGGREGATE_OPERATORS), (op2) => {
721
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
722
+ consumedKeys.push(...innerResult.consumedKeys);
723
+ return this.and(eb, ...innerResult.conditions);
724
+ }).otherwise(() => {
490
725
  if (throwIfInvalid) {
491
726
  throw new QueryError(`Invalid filter key: ${op}`);
492
727
  } else {
@@ -503,24 +738,21 @@ var BaseCrudDialect = class {
503
738
  consumedKeys
504
739
  };
505
740
  }
506
- buildStringFilter(eb, table, field, payload) {
507
- const fieldDef = getField(this.schema, table, field);
508
- let fieldRef = fieldDef?.computed ? sql.ref(field) : sql.ref(`${table}.${field}`);
509
- let insensitive = false;
510
- if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
511
- insensitive = true;
512
- fieldRef = eb.fn("lower", [
513
- fieldRef
514
- ]);
741
+ buildStringFilter(eb, fieldRef, payload) {
742
+ let mode;
743
+ if (payload && typeof payload === "object" && "mode" in payload) {
744
+ mode = payload.mode;
515
745
  }
516
- const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, table, field, value));
746
+ const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
747
+ fieldRef
748
+ ]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
517
749
  if (payload && typeof payload === "object") {
518
750
  for (const [key, value] of Object.entries(payload)) {
519
751
  if (key === "mode" || consumedKeys.includes(key)) {
520
752
  continue;
521
753
  }
522
- const condition = match(key).with("contains", () => insensitive ? eb(fieldRef, "ilike", sql.lit(`%${value}%`)) : eb(fieldRef, "like", sql.lit(`%${value}%`))).with("startsWith", () => insensitive ? eb(fieldRef, "ilike", sql.lit(`${value}%`)) : eb(fieldRef, "like", sql.lit(`${value}%`))).with("endsWith", () => insensitive ? eb(fieldRef, "ilike", sql.lit(`%${value}`)) : eb(fieldRef, "like", sql.lit(`%${value}`))).otherwise(() => {
523
- throw new Error(`Invalid string filter key: ${key}`);
754
+ const condition = match2(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}%`)) : eb(fieldRef, "like", sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`${value}%`)) : eb(fieldRef, "like", sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", sql.val(`%${value}`)) : eb(fieldRef, "like", sql.val(`%${value}`))).otherwise(() => {
755
+ throw new QueryError(`Invalid string filter key: ${key}`);
524
756
  });
525
757
  if (condition) {
526
758
  conditions.push(condition);
@@ -529,34 +761,37 @@ var BaseCrudDialect = class {
529
761
  }
530
762
  return this.and(eb, ...conditions);
531
763
  }
532
- prepStringCasing(eb, value, toLower = true) {
764
+ prepStringCasing(eb, value, mode) {
765
+ if (!mode || mode === "default") {
766
+ return value === null ? value : sql.val(value);
767
+ }
533
768
  if (typeof value === "string") {
534
- return toLower ? eb.fn("lower", [
535
- sql.lit(value)
536
- ]) : sql.lit(value);
769
+ return eb.fn("lower", [
770
+ sql.val(value)
771
+ ]);
537
772
  } else if (Array.isArray(value)) {
538
- return value.map((v) => this.prepStringCasing(eb, v, toLower));
773
+ return value.map((v) => this.prepStringCasing(eb, v, mode));
539
774
  } else {
540
- return value === null ? null : sql.lit(value);
775
+ return value === null ? null : sql.val(value);
541
776
  }
542
777
  }
543
- buildNumberFilter(eb, model, table, field, type, payload) {
544
- const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
778
+ buildNumberFilter(eb, fieldRef, type, payload) {
779
+ const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
545
780
  return this.and(eb, ...conditions);
546
781
  }
547
- buildBooleanFilter(eb, table, field, payload) {
548
- const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
782
+ buildBooleanFilter(eb, fieldRef, payload) {
783
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
549
784
  "equals",
550
785
  "not"
551
786
  ]);
552
787
  return this.and(eb, ...conditions);
553
788
  }
554
- buildDateTimeFilter(eb, table, field, payload) {
555
- const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
789
+ buildDateTimeFilter(eb, fieldRef, payload) {
790
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
556
791
  return this.and(eb, ...conditions);
557
792
  }
558
- buildBytesFilter(eb, table, field, payload) {
559
- const conditions = this.buildStandardFilter(eb, "Bytes", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
793
+ buildBytesFilter(eb, fieldRef, payload) {
794
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
560
795
  "equals",
561
796
  "in",
562
797
  "notIn",
@@ -564,8 +799,8 @@ var BaseCrudDialect = class {
564
799
  ]);
565
800
  return this.and(eb, ...conditions.conditions);
566
801
  }
567
- buildEnumFilter(eb, table, field, fieldDef, payload) {
568
- const conditions = this.buildStandardFilter(eb, "String", payload, sql.ref(`${table}.${field}`), (value) => value, (value) => this.buildEnumFilter(eb, table, field, fieldDef, value), true, [
802
+ buildEnumFilter(eb, fieldRef, fieldDef, payload) {
803
+ const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
569
804
  "equals",
570
805
  "in",
571
806
  "notIn",
@@ -597,9 +832,7 @@ var BaseCrudDialect = class {
597
832
  invariant(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
598
833
  for (const [k, v] of Object.entries(value)) {
599
834
  invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
600
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
601
- sql.ref(k)
602
- ]), sql.raw(this.negateSort(v, negated)));
835
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), sql.raw(this.negateSort(v, negated)));
603
836
  }
604
837
  continue;
605
838
  }
@@ -608,7 +841,7 @@ var BaseCrudDialect = class {
608
841
  invariant(value && typeof value === "object", 'invalid orderBy value for field "_count"');
609
842
  for (const [k, v] of Object.entries(value)) {
610
843
  invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
611
- result = result.orderBy((eb) => eb.fn.count(sql.ref(k)), sql.raw(this.negateSort(v, negated)));
844
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), sql.raw(this.negateSort(v, negated)));
612
845
  }
613
846
  continue;
614
847
  }
@@ -617,10 +850,11 @@ var BaseCrudDialect = class {
617
850
  }
618
851
  const fieldDef = requireField(this.schema, model, field);
619
852
  if (!fieldDef.relation) {
853
+ const fieldRef = this.fieldRef(model, field, expressionBuilder(), modelAlias);
620
854
  if (value === "asc" || value === "desc") {
621
- result = result.orderBy(sql.ref(`${modelAlias}.${field}`), this.negateSort(value, negated));
855
+ result = result.orderBy(fieldRef, this.negateSort(value, negated));
622
856
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
623
- result = result.orderBy(sql.ref(`${modelAlias}.${field}`), sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
857
+ result = result.orderBy(fieldRef, sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
624
858
  }
625
859
  } else {
626
860
  const relationModel = fieldDef.type;
@@ -632,8 +866,9 @@ var BaseCrudDialect = class {
632
866
  invariant(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
633
867
  const sort = this.negateSort(value._count, negated);
634
868
  result = result.orderBy((eb) => {
635
- let subQuery = eb.selectFrom(relationModel);
636
- const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
869
+ const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
870
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
871
+ const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
637
872
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right)))));
638
873
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
639
874
  return subQuery;
@@ -651,6 +886,92 @@ var BaseCrudDialect = class {
651
886
  });
652
887
  return result;
653
888
  }
889
+ buildSelectAllFields(model, query, omit, modelAlias) {
890
+ const modelDef = requireModel(this.schema, model);
891
+ let result = query;
892
+ for (const field of Object.keys(modelDef.fields)) {
893
+ if (isRelationField(this.schema, model, field)) {
894
+ continue;
895
+ }
896
+ if (omit?.[field] === true) {
897
+ continue;
898
+ }
899
+ result = this.buildSelectField(result, model, modelAlias, field);
900
+ }
901
+ const descendants = getDelegateDescendantModels(this.schema, model);
902
+ for (const subModel of descendants) {
903
+ result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
904
+ result = result.select((eb) => {
905
+ const jsonObject = {};
906
+ for (const field of Object.keys(subModel.fields)) {
907
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
908
+ continue;
909
+ }
910
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
911
+ }
912
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
913
+ });
914
+ }
915
+ return result;
916
+ }
917
+ buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
918
+ let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
919
+ if (selectAllFields) {
920
+ subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
921
+ }
922
+ if (payload && typeof payload === "object") {
923
+ subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
924
+ }
925
+ return subQuery;
926
+ }
927
+ buildSelectField(query, model, modelAlias, field) {
928
+ const fieldDef = requireField(this.schema, model, field);
929
+ if (fieldDef.computed) {
930
+ return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
931
+ } else if (!fieldDef.originModel) {
932
+ return query.select(sql.ref(`${modelAlias}.${field}`).as(field));
933
+ } else {
934
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
935
+ }
936
+ }
937
+ buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
938
+ const idFields = getIdFields(this.schema, thisModel);
939
+ query = query.leftJoin(otherModelAlias, (qb) => {
940
+ for (const idField of idFields) {
941
+ qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
942
+ }
943
+ return qb;
944
+ });
945
+ return query;
946
+ }
947
+ buildCountJson(model, eb, parentAlias, payload) {
948
+ const modelDef = requireModel(this.schema, model);
949
+ const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
950
+ const selections = payload === true ? {
951
+ select: toManyRelations.reduce((acc, [field]) => {
952
+ acc[field] = true;
953
+ return acc;
954
+ }, {})
955
+ } : payload;
956
+ const jsonObject = {};
957
+ for (const [field, value] of Object.entries(selections.select)) {
958
+ const fieldDef = requireField(this.schema, model, field);
959
+ const fieldModel = fieldDef.type;
960
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
961
+ let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
962
+ for (const [left, right] of joinPairs) {
963
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
964
+ }
965
+ if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
966
+ const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
967
+ fieldCountQuery = fieldCountQuery.where(filter);
968
+ }
969
+ jsonObject[field] = fieldCountQuery;
970
+ }
971
+ return this.buildJsonObject(eb, jsonObject);
972
+ }
973
+ // #endregion
974
+ // #region utils
654
975
  negateSort(sort, negated) {
655
976
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
656
977
  }
@@ -697,6 +1018,21 @@ var BaseCrudDialect = class {
697
1018
  not(eb, ...args) {
698
1019
  return eb.not(this.and(eb, ...args));
699
1020
  }
1021
+ fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
1022
+ return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
1023
+ }
1024
+ canJoinWithoutNestedSelect(modelDef, payload) {
1025
+ if (modelDef.computedFields) {
1026
+ return false;
1027
+ }
1028
+ if (modelDef.baseModel || modelDef.isDelegate) {
1029
+ return false;
1030
+ }
1031
+ if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
1032
+ return false;
1033
+ }
1034
+ return true;
1035
+ }
700
1036
  };
701
1037
 
702
1038
  // src/client/crud/dialects/postgresql.ts
@@ -718,98 +1054,110 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
718
1054
  return value.map((v) => this.transformPrimitive(v, type, false));
719
1055
  }
720
1056
  } else {
721
- return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1057
+ return match3(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
722
1058
  }
723
1059
  }
724
1060
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
725
- const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload);
726
- return joinedQuery.select(`${parentAlias}$${relationField}.$j as ${relationField}`);
1061
+ const relationResultName = `${parentAlias}$${relationField}`;
1062
+ const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
1063
+ return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
727
1064
  }
728
- buildRelationJSON(model, qb, relationField, parentName, payload) {
1065
+ buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
729
1066
  const relationFieldDef = requireField(this.schema, model, relationField);
730
1067
  const relationModel = relationFieldDef.type;
731
1068
  return qb.leftJoinLateral((eb) => {
732
- const joinTableName = `${parentName}$${relationField}`;
733
- let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
734
- result = eb.selectFrom(() => {
735
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
736
- if (payload && typeof payload === "object") {
737
- if (payload.where) {
738
- subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
739
- }
740
- const skip = payload.skip;
741
- let take = payload.take;
742
- let negateOrderBy = false;
743
- if (take !== void 0 && take < 0) {
744
- negateOrderBy = true;
745
- take = -take;
746
- }
747
- subQuery = this.buildSkipTake(subQuery, skip, take);
748
- subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
749
- }
750
- const m2m = getManyToManyRelation(this.schema, model, relationField);
751
- if (m2m) {
752
- const parentIds = getIdFields(this.schema, model);
753
- const relationIds = getIdFields(this.schema, relationModel);
754
- invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
755
- invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
756
- subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
757
- } else {
758
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
759
- subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(sql2.ref(left), "=", sql2.ref(right)))));
760
- }
761
- return subQuery.as(joinTableName);
762
- });
763
- result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
764
- result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
765
- return result.as(joinTableName);
1069
+ const relationSelectName = `${resultName}$sub`;
1070
+ const relationModelDef = requireModel(this.schema, relationModel);
1071
+ let tbl;
1072
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1073
+ tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
1074
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
1075
+ } else {
1076
+ tbl = eb.selectFrom(() => {
1077
+ let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
1078
+ subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
1079
+ return subQuery.as(relationSelectName);
1080
+ });
1081
+ }
1082
+ tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
1083
+ tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
1084
+ return tbl.as(resultName);
766
1085
  }, (join) => join.onTrue());
767
1086
  }
768
- buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
1087
+ buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1088
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1089
+ if (m2m) {
1090
+ const parentIds = getIdFields(this.schema, model);
1091
+ const relationIds = getIdFields(this.schema, relationModel);
1092
+ invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1093
+ invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1094
+ query = query.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1095
+ } else {
1096
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1097
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql2.ref(left), "=", sql2.ref(right)))));
1098
+ }
1099
+ return query;
1100
+ }
1101
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
769
1102
  qb = qb.select((eb) => {
770
- const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
1103
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
771
1104
  if (relationFieldDef.array) {
772
- return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$j");
1105
+ return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$data");
773
1106
  } else {
774
- return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$j");
1107
+ return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$data");
775
1108
  }
776
1109
  });
777
1110
  return qb;
778
1111
  }
779
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
1112
+ buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
780
1113
  const relationModelDef = requireModel(this.schema, relationModel);
781
1114
  const objArgs = [];
1115
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1116
+ if (descendantModels.length > 0) {
1117
+ objArgs.push(...descendantModels.map((subModel) => [
1118
+ sql2.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1119
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1120
+ ]).flatMap((v) => v));
1121
+ }
782
1122
  if (payload === true || !payload.select) {
783
1123
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
784
1124
  sql2.lit(field),
785
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1125
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false)
786
1126
  ]).flatMap((v) => v));
787
1127
  } else if (payload.select) {
788
- objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => {
789
- const fieldDef = requireField(this.schema, relationModel, field);
790
- const fieldValue = fieldDef.relation ? eb.ref(`${parentName}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
791
- return [
792
- sql2.lit(field),
793
- fieldValue
794
- ];
1128
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1129
+ if (field === "_count") {
1130
+ const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1131
+ return [
1132
+ sql2.lit(field),
1133
+ subJson
1134
+ ];
1135
+ } else {
1136
+ const fieldDef = requireField(this.schema, relationModel, field);
1137
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1138
+ return [
1139
+ sql2.lit(field),
1140
+ fieldValue
1141
+ ];
1142
+ }
795
1143
  }).flatMap((v) => v));
796
1144
  }
797
1145
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
798
1146
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
799
1147
  sql2.lit(field),
800
1148
  // reference the synthesized JSON field
801
- eb.ref(`${parentName}$${relationField}$${field}.$j`)
1149
+ eb.ref(`${parentResultName}$${field}.$data`)
802
1150
  ]).flatMap((v) => v));
803
1151
  }
804
1152
  return objArgs;
805
1153
  }
806
- buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
807
- let result = qb;
1154
+ buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
1155
+ let result = query;
808
1156
  if (typeof payload === "object") {
809
1157
  const selectInclude = payload.include ?? payload.select;
810
1158
  if (selectInclude && typeof selectInclude === "object") {
811
1159
  Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
812
- result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1160
+ result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
813
1161
  });
814
1162
  }
815
1163
  }
@@ -851,12 +1199,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
851
1199
  return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
852
1200
  }
853
1201
  }
1202
+ get supportInsertWithDefault() {
1203
+ return true;
1204
+ }
854
1205
  };
855
1206
 
856
1207
  // src/client/crud/dialects/sqlite.ts
857
1208
  import { invariant as invariant3 } from "@zenstackhq/common-helpers";
858
1209
  import { sql as sql3 } from "kysely";
859
- import { match as match3 } from "ts-pattern";
1210
+ import { match as match4 } from "ts-pattern";
860
1211
  var SqliteCrudDialect = class extends BaseCrudDialect {
861
1212
  static {
862
1213
  __name(this, "SqliteCrudDialect");
@@ -871,79 +1222,75 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
871
1222
  if (Array.isArray(value)) {
872
1223
  return value.map((v) => this.transformPrimitive(v, type, false));
873
1224
  } else {
874
- return match3(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1225
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1226
+ return JSON.stringify(value);
1227
+ } else {
1228
+ return match4(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1229
+ }
875
1230
  }
876
1231
  }
877
1232
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
878
1233
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
879
1234
  }
880
- buildRelationJSON(model, eb, relationField, parentName, payload) {
1235
+ buildRelationJSON(model, eb, relationField, parentAlias, payload) {
881
1236
  const relationFieldDef = requireField(this.schema, model, relationField);
882
1237
  const relationModel = relationFieldDef.type;
883
1238
  const relationModelDef = requireModel(this.schema, relationModel);
884
- const subQueryName = `${parentName}$${relationField}`;
885
- let tbl = eb.selectFrom(() => {
886
- let subQuery = eb.selectFrom(relationModel).selectAll();
887
- if (payload && typeof payload === "object") {
888
- if (payload.where) {
889
- subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
890
- }
891
- const skip = payload.skip;
892
- let take = payload.take;
893
- let negateOrderBy = false;
894
- if (take !== void 0 && take < 0) {
895
- negateOrderBy = true;
896
- take = -take;
897
- }
898
- subQuery = this.buildSkipTake(subQuery, skip, take);
899
- subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
900
- }
901
- const m2m = getManyToManyRelation(this.schema, model, relationField);
902
- if (m2m) {
903
- const parentIds = getIdFields(this.schema, model);
904
- const relationIds = getIdFields(this.schema, relationModel);
905
- invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
906
- invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
907
- subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
908
- } else {
909
- const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
910
- keyPairs.forEach(({ fk, pk }) => {
911
- if (ownedByModel) {
912
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
913
- } else {
914
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
915
- }
916
- });
917
- }
918
- return subQuery.as(subQueryName);
919
- });
1239
+ const subQueryName = `${parentAlias}$${relationField}`;
1240
+ let tbl;
1241
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1242
+ tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
1243
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
1244
+ } else {
1245
+ tbl = eb.selectFrom(() => {
1246
+ const selectModelAlias = `${parentAlias}$${relationField}$sub`;
1247
+ let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
1248
+ selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
1249
+ return selectModelQuery.as(subQueryName);
1250
+ });
1251
+ }
920
1252
  tbl = tbl.select(() => {
921
1253
  const objArgs = [];
1254
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1255
+ if (descendantModels.length > 0) {
1256
+ objArgs.push(...descendantModels.map((subModel) => [
1257
+ sql3.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1258
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1259
+ ]).flatMap((v) => v));
1260
+ }
922
1261
  if (payload === true || !payload.select) {
923
1262
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
924
1263
  sql3.lit(field),
925
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1264
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
926
1265
  ]).flatMap((v) => v));
927
1266
  } else if (payload.select) {
928
1267
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
929
- const fieldDef = requireField(this.schema, relationModel, field);
930
- if (fieldDef.relation) {
931
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1268
+ if (field === "_count") {
1269
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
932
1270
  return [
933
1271
  sql3.lit(field),
934
1272
  subJson
935
1273
  ];
936
1274
  } else {
937
- return [
938
- sql3.lit(field),
939
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
940
- ];
1275
+ const fieldDef = requireField(this.schema, relationModel, field);
1276
+ if (fieldDef.relation) {
1277
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1278
+ return [
1279
+ sql3.lit(field),
1280
+ subJson
1281
+ ];
1282
+ } else {
1283
+ return [
1284
+ sql3.lit(field),
1285
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1286
+ ];
1287
+ }
941
1288
  }
942
1289
  }).flatMap((v) => v));
943
1290
  }
944
1291
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
945
1292
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
946
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1293
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
947
1294
  return [
948
1295
  sql3.lit(field),
949
1296
  subJson
@@ -951,13 +1298,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
951
1298
  }).flatMap((v) => v));
952
1299
  }
953
1300
  if (relationFieldDef.array) {
954
- return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$j");
1301
+ return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$data");
955
1302
  } else {
956
- return sql3`json_object(${sql3.join(objArgs)})`.as("data");
1303
+ return sql3`json_object(${sql3.join(objArgs)})`.as("$data");
957
1304
  }
958
1305
  });
959
1306
  return tbl;
960
1307
  }
1308
+ buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
1309
+ const fieldDef = requireField(this.schema, model, relationField);
1310
+ const relationModel = fieldDef.type;
1311
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1312
+ if (m2m) {
1313
+ const parentIds = getIdFields(this.schema, model);
1314
+ const relationIds = getIdFields(this.schema, relationModel);
1315
+ invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1316
+ invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1317
+ selectModelQuery = selectModelQuery.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1318
+ } else {
1319
+ const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1320
+ keyPairs.forEach(({ fk, pk }) => {
1321
+ if (ownedByModel) {
1322
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1323
+ } else {
1324
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1325
+ }
1326
+ });
1327
+ }
1328
+ return selectModelQuery;
1329
+ }
961
1330
  buildSkipTake(query, skip, take) {
962
1331
  if (take !== void 0) {
963
1332
  query = query.limit(take);
@@ -993,93 +1362,17 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
993
1362
  buildArrayLiteralSQL(_values) {
994
1363
  throw new Error("SQLite does not support array literals");
995
1364
  }
1365
+ get supportInsertWithDefault() {
1366
+ return false;
1367
+ }
996
1368
  };
997
1369
 
998
1370
  // src/client/crud/dialects/index.ts
999
1371
  function getCrudDialect(schema, options) {
1000
- return match4(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1372
+ return match5(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1001
1373
  }
1002
1374
  __name(getCrudDialect, "getCrudDialect");
1003
1375
 
1004
- // src/schema/expression.ts
1005
- var ExpressionUtils = {
1006
- literal: /* @__PURE__ */ __name((value) => {
1007
- return {
1008
- kind: "literal",
1009
- value
1010
- };
1011
- }, "literal"),
1012
- array: /* @__PURE__ */ __name((items) => {
1013
- return {
1014
- kind: "array",
1015
- items
1016
- };
1017
- }, "array"),
1018
- call: /* @__PURE__ */ __name((functionName, args) => {
1019
- return {
1020
- kind: "call",
1021
- function: functionName,
1022
- args
1023
- };
1024
- }, "call"),
1025
- binary: /* @__PURE__ */ __name((left, op, right) => {
1026
- return {
1027
- kind: "binary",
1028
- op,
1029
- left,
1030
- right
1031
- };
1032
- }, "binary"),
1033
- unary: /* @__PURE__ */ __name((op, operand) => {
1034
- return {
1035
- kind: "unary",
1036
- op,
1037
- operand
1038
- };
1039
- }, "unary"),
1040
- field: /* @__PURE__ */ __name((field) => {
1041
- return {
1042
- kind: "field",
1043
- field
1044
- };
1045
- }, "field"),
1046
- member: /* @__PURE__ */ __name((receiver, members) => {
1047
- return {
1048
- kind: "member",
1049
- receiver,
1050
- members
1051
- };
1052
- }, "member"),
1053
- _this: /* @__PURE__ */ __name(() => {
1054
- return {
1055
- kind: "this"
1056
- };
1057
- }, "_this"),
1058
- _null: /* @__PURE__ */ __name(() => {
1059
- return {
1060
- kind: "null"
1061
- };
1062
- }, "_null"),
1063
- and: /* @__PURE__ */ __name((expr2, ...expressions) => {
1064
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
1065
- }, "and"),
1066
- or: /* @__PURE__ */ __name((expr2, ...expressions) => {
1067
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
1068
- }, "or"),
1069
- is: /* @__PURE__ */ __name((value, kind) => {
1070
- return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
1071
- }, "is"),
1072
- isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
1073
- isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
1074
- isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
1075
- isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
1076
- isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
1077
- isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
1078
- isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
1079
- isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
1080
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
1081
- };
1082
-
1083
1376
  // src/utils/default-operation-node-visitor.ts
1084
1377
  import { OperationNodeVisitor } from "kysely";
1085
1378
  var DefaultOperationNodeVisitor = class extends OperationNodeVisitor {
@@ -1400,18 +1693,18 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1400
1693
 
1401
1694
  // src/plugins/policy/expression-transformer.ts
1402
1695
  import { invariant as invariant5 } from "@zenstackhq/common-helpers";
1403
- import { AliasNode as AliasNode2, BinaryOperationNode as BinaryOperationNode2, ColumnNode, expressionBuilder, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode2, SelectionNode, SelectQueryNode, TableNode as TableNode2, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
1404
- import { match as match6 } from "ts-pattern";
1696
+ import { AliasNode as AliasNode2, BinaryOperationNode as BinaryOperationNode2, ColumnNode, expressionBuilder as expressionBuilder2, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode2, SelectionNode, SelectQueryNode, TableNode as TableNode2, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
1697
+ import { match as match7 } from "ts-pattern";
1405
1698
 
1406
1699
  // src/plugins/policy/expression-evaluator.ts
1407
1700
  import { invariant as invariant4 } from "@zenstackhq/common-helpers";
1408
- import { match as match5 } from "ts-pattern";
1701
+ import { match as match6 } from "ts-pattern";
1409
1702
  var ExpressionEvaluator = class {
1410
1703
  static {
1411
1704
  __name(this, "ExpressionEvaluator");
1412
1705
  }
1413
1706
  evaluate(expression, context) {
1414
- const result = match5(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
1707
+ const result = match6(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
1415
1708
  return result ?? null;
1416
1709
  }
1417
1710
  evaluateCall(expr2, context) {
@@ -1422,7 +1715,7 @@ var ExpressionEvaluator = class {
1422
1715
  }
1423
1716
  }
1424
1717
  evaluateUnary(expr2, context) {
1425
- return match5(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1718
+ return match6(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1426
1719
  }
1427
1720
  evaluateMember(expr2, context) {
1428
1721
  let val = this.evaluate(expr2.receiver, context);
@@ -1446,7 +1739,7 @@ var ExpressionEvaluator = class {
1446
1739
  }
1447
1740
  const left = this.evaluate(expr2.left, context);
1448
1741
  const right = this.evaluate(expr2.right, context);
1449
- return match5(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
1742
+ return match6(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
1450
1743
  const _right = right ?? [];
1451
1744
  invariant4(Array.isArray(_right), 'expected array for "in" operator');
1452
1745
  return _right.includes(left);
@@ -1460,7 +1753,7 @@ var ExpressionEvaluator = class {
1460
1753
  return false;
1461
1754
  }
1462
1755
  invariant4(Array.isArray(left), "expected array");
1463
- return match5(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1756
+ return match6(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1464
1757
  ...context,
1465
1758
  thisValue: item
1466
1759
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1714,7 +2007,7 @@ var ExpressionTransformer = class {
1714
2007
  const count = FunctionNode2.create("count", [
1715
2008
  ValueNode2.createImmediate(1)
1716
2009
  ]);
1717
- const predicateResult = match6(expr2.op).with("?", () => BinaryOperationNode2.create(count, OperatorNode2.create(">"), ValueNode2.createImmediate(0))).with("!", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).with("^", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).exhaustive();
2010
+ const predicateResult = match7(expr2.op).with("?", () => BinaryOperationNode2.create(count, OperatorNode2.create(">"), ValueNode2.createImmediate(0))).with("!", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).with("^", () => BinaryOperationNode2.create(count, OperatorNode2.create("="), ValueNode2.createImmediate(0))).exhaustive();
1718
2011
  return this.transform(expr2.left, {
1719
2012
  ...context,
1720
2013
  memberSelect: SelectionNode.create(AliasNode2.create(predicateResult, IdentifierNode.create("$t"))),
@@ -1745,7 +2038,7 @@ var ExpressionTransformer = class {
1745
2038
  return BinaryOperationNode2.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1746
2039
  }
1747
2040
  transformOperator(op) {
1748
- const mappedOp = match6(op).with("==", () => "=").otherwise(() => op);
2041
+ const mappedOp = match7(op).with("==", () => "=").otherwise(() => op);
1749
2042
  return OperatorNode2.create(mappedOp);
1750
2043
  }
1751
2044
  _call(expr2, context) {
@@ -1757,7 +2050,7 @@ var ExpressionTransformer = class {
1757
2050
  if (!func) {
1758
2051
  throw new QueryError(`Function not implemented: ${expr2.function}`);
1759
2052
  }
1760
- const eb = expressionBuilder();
2053
+ const eb = expressionBuilder2();
1761
2054
  return func(eb, (expr2.args ?? []).map((arg) => this.transformCallArg(eb, arg, context)), {
1762
2055
  dialect: this.dialect,
1763
2056
  model: context.model,
@@ -2148,7 +2441,7 @@ var PolicyHandler = class extends OperationNodeTransformer {
2148
2441
  return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => BinaryOperationNode3.create(ColumnNode2.create(field), OperatorNode3.create("="), ValueNode3.create(row[field]))))));
2149
2442
  }
2150
2443
  getMutationModel(node) {
2151
- const r = match7(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
2444
+ const r = match8(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
2152
2445
  if (node2.from.froms.length !== 1) {
2153
2446
  throw new InternalError("Only one from table is supported for delete");
2154
2447
  }
@@ -2328,4 +2621,4 @@ export {
2328
2621
  PolicyPlugin,
2329
2622
  RejectedByPolicyError
2330
2623
  };
2331
- //# sourceMappingURL=policy.js.map
2624
+ //# sourceMappingURL=index.js.map