@zenstackhq/runtime 3.0.0-alpha.9 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,15 +41,115 @@ var RejectedByPolicyError = class extends Error {
41
41
  // src/plugins/policy/policy-handler.ts
42
42
  var import_common_helpers6 = require("@zenstackhq/common-helpers");
43
43
  var import_kysely7 = require("kysely");
44
- var import_ts_pattern7 = require("ts-pattern");
44
+ var import_ts_pattern8 = require("ts-pattern");
45
45
 
46
46
  // src/client/crud/dialects/index.ts
47
- var import_ts_pattern4 = require("ts-pattern");
47
+ var import_ts_pattern5 = require("ts-pattern");
48
48
 
49
49
  // src/client/crud/dialects/postgresql.ts
50
50
  var import_common_helpers2 = require("@zenstackhq/common-helpers");
51
51
  var import_kysely2 = require("kysely");
52
- var import_ts_pattern2 = require("ts-pattern");
52
+ var import_ts_pattern3 = require("ts-pattern");
53
+
54
+ // src/client/constants.ts
55
+ var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
56
+ var LOGICAL_COMBINATORS = [
57
+ "AND",
58
+ "OR",
59
+ "NOT"
60
+ ];
61
+ var AGGREGATE_OPERATORS = [
62
+ "_count",
63
+ "_sum",
64
+ "_avg",
65
+ "_min",
66
+ "_max"
67
+ ];
68
+
69
+ // src/client/query-utils.ts
70
+ var import_ts_pattern = require("ts-pattern");
71
+
72
+ // src/schema/expression.ts
73
+ var ExpressionUtils = {
74
+ literal: /* @__PURE__ */ __name((value) => {
75
+ return {
76
+ kind: "literal",
77
+ value
78
+ };
79
+ }, "literal"),
80
+ array: /* @__PURE__ */ __name((items) => {
81
+ return {
82
+ kind: "array",
83
+ items
84
+ };
85
+ }, "array"),
86
+ call: /* @__PURE__ */ __name((functionName, args) => {
87
+ return {
88
+ kind: "call",
89
+ function: functionName,
90
+ args
91
+ };
92
+ }, "call"),
93
+ binary: /* @__PURE__ */ __name((left, op, right) => {
94
+ return {
95
+ kind: "binary",
96
+ op,
97
+ left,
98
+ right
99
+ };
100
+ }, "binary"),
101
+ unary: /* @__PURE__ */ __name((op, operand) => {
102
+ return {
103
+ kind: "unary",
104
+ op,
105
+ operand
106
+ };
107
+ }, "unary"),
108
+ field: /* @__PURE__ */ __name((field) => {
109
+ return {
110
+ kind: "field",
111
+ field
112
+ };
113
+ }, "field"),
114
+ member: /* @__PURE__ */ __name((receiver, members) => {
115
+ return {
116
+ kind: "member",
117
+ receiver,
118
+ members
119
+ };
120
+ }, "member"),
121
+ _this: /* @__PURE__ */ __name(() => {
122
+ return {
123
+ kind: "this"
124
+ };
125
+ }, "_this"),
126
+ _null: /* @__PURE__ */ __name(() => {
127
+ return {
128
+ kind: "null"
129
+ };
130
+ }, "_null"),
131
+ and: /* @__PURE__ */ __name((expr2, ...expressions) => {
132
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
133
+ }, "and"),
134
+ or: /* @__PURE__ */ __name((expr2, ...expressions) => {
135
+ return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
136
+ }, "or"),
137
+ is: /* @__PURE__ */ __name((value, kind) => {
138
+ return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
139
+ }, "is"),
140
+ isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
141
+ isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
142
+ isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
143
+ isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
144
+ isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
145
+ isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
146
+ isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
147
+ isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
148
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
149
+ getLiteralValue: /* @__PURE__ */ __name((expr2) => {
150
+ return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
151
+ }, "getLiteralValue")
152
+ };
53
153
 
54
154
  // src/client/errors.ts
55
155
  var QueryError = class extends Error {
@@ -66,9 +166,6 @@ var InternalError = class extends Error {
66
166
  static {
67
167
  __name(this, "InternalError");
68
168
  }
69
- constructor(message) {
70
- super(message);
71
- }
72
169
  };
73
170
 
74
171
  // src/client/query-utils.ts
@@ -143,10 +240,15 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
143
240
  }
144
241
  __name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
145
242
  function isRelationField(schema, model, field) {
146
- const fieldDef = requireField(schema, model, field);
147
- return !!fieldDef.relation;
243
+ const fieldDef = getField(schema, model, field);
244
+ return !!fieldDef?.relation;
148
245
  }
149
246
  __name(isRelationField, "isRelationField");
247
+ function isInheritedField(schema, model, field) {
248
+ const fieldDef = getField(schema, model, field);
249
+ return !!fieldDef?.originModel;
250
+ }
251
+ __name(isInheritedField, "isInheritedField");
150
252
  function getUniqueFields(schema, model) {
151
253
  const modelDef = requireModel(schema, model);
152
254
  const result = [];
@@ -172,11 +274,14 @@ function getUniqueFields(schema, model) {
172
274
  return result;
173
275
  }
174
276
  __name(getUniqueFields, "getUniqueFields");
175
- function buildFieldRef(schema, model, field, options, eb, modelAlias) {
277
+ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComputedField = true) {
176
278
  const fieldDef = requireField(schema, model, field);
177
279
  if (!fieldDef.computed) {
178
280
  return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
179
281
  } else {
282
+ if (!inlineComputedField) {
283
+ return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
284
+ }
180
285
  let computer;
181
286
  if ("computedFields" in options) {
182
287
  const computedFields = options.computedFields;
@@ -185,7 +290,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
185
290
  if (!computer) {
186
291
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
187
292
  }
188
- return computer(eb);
293
+ return computer(eb, {
294
+ currentModel: modelAlias
295
+ });
189
296
  }
190
297
  }
191
298
  __name(buildFieldRef, "buildFieldRef");
@@ -228,11 +335,33 @@ function getManyToManyRelation(schema, model, field) {
228
335
  model,
229
336
  fieldDef.type
230
337
  ].sort();
338
+ let orderedFK;
339
+ if (model !== fieldDef.type) {
340
+ orderedFK = sortedModelNames[0] === model ? [
341
+ "A",
342
+ "B"
343
+ ] : [
344
+ "B",
345
+ "A"
346
+ ];
347
+ } else {
348
+ const sortedFieldNames = [
349
+ field,
350
+ oppositeFieldDef.name
351
+ ].sort();
352
+ orderedFK = sortedFieldNames[0] === field ? [
353
+ "A",
354
+ "B"
355
+ ] : [
356
+ "B",
357
+ "A"
358
+ ];
359
+ }
231
360
  return {
232
- parentFkName: sortedModelNames[0] === model ? "A" : "B",
361
+ parentFkName: orderedFK[0],
233
362
  otherModel: fieldDef.type,
234
363
  otherField: fieldDef.relation.opposite,
235
- otherFkName: sortedModelNames[0] === fieldDef.type ? "A" : "B",
364
+ otherFkName: orderedFK[1],
236
365
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
237
366
  };
238
367
  } else {
@@ -260,11 +389,38 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
260
389
  return result;
261
390
  }
262
391
  __name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
392
+ function ensureArray(value) {
393
+ if (Array.isArray(value)) {
394
+ return value;
395
+ } else {
396
+ return [
397
+ value
398
+ ];
399
+ }
400
+ }
401
+ __name(ensureArray, "ensureArray");
402
+ function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
403
+ const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
404
+ subModels.forEach((def) => {
405
+ if (!collected.has(def)) {
406
+ collected.add(def);
407
+ getDelegateDescendantModels(schema, def.name, collected);
408
+ }
409
+ });
410
+ return [
411
+ ...collected
412
+ ];
413
+ }
414
+ __name(getDelegateDescendantModels, "getDelegateDescendantModels");
415
+ function aggregate(eb, expr2, op) {
416
+ return (0, import_ts_pattern.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();
417
+ }
418
+ __name(aggregate, "aggregate");
263
419
 
264
420
  // src/client/crud/dialects/base.ts
265
421
  var import_common_helpers = require("@zenstackhq/common-helpers");
266
422
  var import_kysely = require("kysely");
267
- var import_ts_pattern = require("ts-pattern");
423
+ var import_ts_pattern2 = require("ts-pattern");
268
424
 
269
425
  // src/utils/enumerate.ts
270
426
  function enumerate(x) {
@@ -294,6 +450,44 @@ var BaseCrudDialect = class {
294
450
  transformPrimitive(value, _type, _forArrayField) {
295
451
  return value;
296
452
  }
453
+ // #region common query builders
454
+ buildSelectModel(eb, model, modelAlias) {
455
+ const modelDef = requireModel(this.schema, model);
456
+ let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
457
+ let joinBase = modelDef.baseModel;
458
+ while (joinBase) {
459
+ result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
460
+ joinBase = requireModel(this.schema, joinBase).baseModel;
461
+ }
462
+ return result;
463
+ }
464
+ buildFilterSortTake(model, args, query, modelAlias) {
465
+ let result = query;
466
+ if (args.where) {
467
+ result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
468
+ }
469
+ let negateOrderBy = false;
470
+ const skip = args.skip;
471
+ let take = args.take;
472
+ if (take !== void 0 && take < 0) {
473
+ negateOrderBy = true;
474
+ take = -take;
475
+ }
476
+ result = this.buildSkipTake(result, skip, take);
477
+ result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
478
+ if ("distinct" in args && args.distinct) {
479
+ const distinct = ensureArray(args.distinct);
480
+ if (this.supportsDistinctOn) {
481
+ result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
482
+ } else {
483
+ throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
484
+ }
485
+ }
486
+ if (args.cursor) {
487
+ result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
488
+ }
489
+ return result;
490
+ }
297
491
  buildFilter(eb, model, modelAlias, where) {
298
492
  if (where === true || where === void 0) {
299
493
  return this.true(eb);
@@ -310,17 +504,20 @@ var BaseCrudDialect = class {
310
504
  if (key.startsWith("$")) {
311
505
  continue;
312
506
  }
313
- if (key === "AND" || key === "OR" || key === "NOT") {
507
+ if (this.isLogicalCombinator(key)) {
314
508
  result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
315
509
  continue;
316
510
  }
317
511
  const fieldDef = requireField(this.schema, model, key);
318
512
  if (fieldDef.relation) {
319
513
  result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
320
- } else if (fieldDef.array) {
321
- result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
322
514
  } else {
323
- result = this.and(eb, result, this.buildPrimitiveFilter(eb, model, modelAlias, key, fieldDef, payload));
515
+ const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
516
+ if (fieldDef.array) {
517
+ result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
518
+ } else {
519
+ result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
520
+ }
324
521
  }
325
522
  }
326
523
  if ("$expr" in _where && typeof _where["$expr"] === "function") {
@@ -328,8 +525,32 @@ var BaseCrudDialect = class {
328
525
  }
329
526
  return result;
330
527
  }
528
+ buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
529
+ const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
530
+ const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
531
+ const eb = (0, import_kysely.expressionBuilder)();
532
+ const subQueryAlias = `${model}$cursor$sub`;
533
+ const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
534
+ let result = query;
535
+ const filters = [];
536
+ for (let i = orderByItems.length - 1; i >= 0; i--) {
537
+ const andFilters = [];
538
+ for (let j = 0; j <= i; j++) {
539
+ const [field, order] = orderByItems[j];
540
+ const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
541
+ const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
542
+ andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
543
+ }
544
+ filters.push(eb.and(andFilters));
545
+ }
546
+ result = result.where((eb2) => eb2.or(filters));
547
+ return result;
548
+ }
549
+ isLogicalCombinator(key) {
550
+ return LOGICAL_COMBINATORS.includes(key);
551
+ }
331
552
  buildCompositeFilter(eb, model, modelAlias, key, payload) {
332
- return (0, import_ts_pattern.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();
553
+ return (0, import_ts_pattern2.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();
333
554
  }
334
555
  buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
335
556
  if (!fieldDef.array) {
@@ -338,19 +559,26 @@ var BaseCrudDialect = class {
338
559
  return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
339
560
  }
340
561
  }
341
- buildToOneRelationFilter(eb, model, table, field, fieldDef, payload) {
562
+ buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
342
563
  if (payload === null) {
343
564
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
344
- if (ownedByModel) {
345
- return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${table}.${fk}`), "is", null)));
565
+ if (ownedByModel && !fieldDef.originModel) {
566
+ return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
346
567
  } else {
347
- return this.buildToOneRelationFilter(eb, model, table, field, fieldDef, {
568
+ return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
348
569
  is: null
349
570
  });
350
571
  }
351
572
  }
352
- const joinAlias = `${table}$${field}`;
353
- const joinPairs = buildJoinPairs(this.schema, model, table, field, joinAlias);
573
+ const joinAlias = `${modelAlias}$${field}`;
574
+ const joinPairs = buildJoinPairs(
575
+ this.schema,
576
+ model,
577
+ // if field is from a base, use the base model to join
578
+ fieldDef.originModel ?? modelAlias,
579
+ field,
580
+ joinAlias
581
+ );
354
582
  const filterResultField = `${field}$filter`;
355
583
  const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
356
584
  const conditions = [];
@@ -380,25 +608,26 @@ var BaseCrudDialect = class {
380
608
  }
381
609
  return this.and(eb, ...conditions);
382
610
  }
383
- buildToManyRelationFilter(eb, model, table, field, fieldDef, payload) {
611
+ buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
384
612
  if (payload === null) {
385
- return eb(import_kysely.sql.ref(`${table}.${field}`), "is", null);
613
+ return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
386
614
  }
387
615
  const relationModel = fieldDef.type;
616
+ const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
388
617
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
389
618
  const m2m = getManyToManyRelation(this.schema, model, field);
390
619
  if (m2m) {
391
620
  const modelIdField = getIdFields(this.schema, model)[0];
392
621
  const relationIdField = getIdFields(this.schema, relationModel)[0];
393
- return eb2(import_kysely.sql.ref(`${relationModel}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${table}.${modelIdField}`)));
622
+ return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdField}`)));
394
623
  } else {
395
624
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
396
625
  let result2 = this.true(eb2);
397
626
  for (const { fk, pk } of relationKeyPairs.keyPairs) {
398
627
  if (relationKeyPairs.ownedByModel) {
399
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${table}.${fk}`), "=", import_kysely.sql.ref(`${relationModel}.${pk}`)));
628
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
400
629
  } else {
401
- result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${table}.${pk}`), "=", import_kysely.sql.ref(`${relationModel}.${fk}`)));
630
+ result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
402
631
  }
403
632
  }
404
633
  return result2;
@@ -411,25 +640,24 @@ var BaseCrudDialect = class {
411
640
  }
412
641
  switch (key) {
413
642
  case "some": {
414
- 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));
643
+ 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));
415
644
  break;
416
645
  }
417
646
  case "every": {
418
- 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));
647
+ 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));
419
648
  break;
420
649
  }
421
650
  case "none": {
422
- 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));
651
+ 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));
423
652
  break;
424
653
  }
425
654
  }
426
655
  }
427
656
  return result;
428
657
  }
429
- buildArrayFilter(eb, model, modelAlias, field, fieldDef, payload) {
658
+ buildArrayFilter(eb, fieldRef, fieldDef, payload) {
430
659
  const clauses = [];
431
660
  const fieldType = fieldDef.type;
432
- const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
433
661
  for (const [key, _value] of Object.entries(payload)) {
434
662
  if (_value === void 0) {
435
663
  continue;
@@ -465,14 +693,14 @@ var BaseCrudDialect = class {
465
693
  }
466
694
  return this.and(eb, ...clauses);
467
695
  }
468
- buildPrimitiveFilter(eb, model, modelAlias, field, fieldDef, payload) {
696
+ buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
469
697
  if (payload === null) {
470
- return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
698
+ return eb(fieldRef, "is", null);
471
699
  }
472
700
  if (isEnum(this.schema, fieldDef.type)) {
473
- return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
701
+ return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
474
702
  }
475
- return (0, import_ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(import_ts_pattern.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", () => {
703
+ return (0, import_ts_pattern2.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern2.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", () => {
476
704
  throw new InternalError("JSON filters are not supported yet");
477
705
  }).with("Unsupported", () => {
478
706
  throw new QueryError(`Unsupported field cannot be used in filters`);
@@ -481,7 +709,7 @@ var BaseCrudDialect = class {
481
709
  buildLiteralFilter(eb, lhs, type, rhs) {
482
710
  return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
483
711
  }
484
- buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
712
+ buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
485
713
  if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
486
714
  return {
487
715
  conditions: [
@@ -496,8 +724,11 @@ var BaseCrudDialect = class {
496
724
  if (onlyForKeys && !onlyForKeys.includes(op)) {
497
725
  continue;
498
726
  }
727
+ if (excludeKeys.includes(op)) {
728
+ continue;
729
+ }
499
730
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
500
- const condition = (0, import_ts_pattern.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
731
+ const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
501
732
  (0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
502
733
  if (rhs.length === 0) {
503
734
  return this.false(eb);
@@ -511,7 +742,11 @@ var BaseCrudDialect = class {
511
742
  } else {
512
743
  return eb.not(eb(lhs, "in", rhs));
513
744
  }
514
- }).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(() => {
745
+ }).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(import_ts_pattern2.P.union(...AGGREGATE_OPERATORS), (op2) => {
746
+ const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
747
+ consumedKeys.push(...innerResult.consumedKeys);
748
+ return this.and(eb, ...innerResult.conditions);
749
+ }).otherwise(() => {
515
750
  if (throwIfInvalid) {
516
751
  throw new QueryError(`Invalid filter key: ${op}`);
517
752
  } else {
@@ -528,24 +763,21 @@ var BaseCrudDialect = class {
528
763
  consumedKeys
529
764
  };
530
765
  }
531
- buildStringFilter(eb, table, field, payload) {
532
- const fieldDef = getField(this.schema, table, field);
533
- let fieldRef = fieldDef?.computed ? import_kysely.sql.ref(field) : import_kysely.sql.ref(`${table}.${field}`);
534
- let insensitive = false;
535
- if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
536
- insensitive = true;
537
- fieldRef = eb.fn("lower", [
538
- fieldRef
539
- ]);
766
+ buildStringFilter(eb, fieldRef, payload) {
767
+ let mode;
768
+ if (payload && typeof payload === "object" && "mode" in payload) {
769
+ mode = payload.mode;
540
770
  }
541
- const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, table, field, value));
771
+ const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
772
+ fieldRef
773
+ ]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
542
774
  if (payload && typeof payload === "object") {
543
775
  for (const [key, value] of Object.entries(payload)) {
544
776
  if (key === "mode" || consumedKeys.includes(key)) {
545
777
  continue;
546
778
  }
547
- const condition = (0, import_ts_pattern.match)(key).with("contains", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.lit(`%${value}%`))).with("startsWith", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.lit(`${value}%`))).with("endsWith", () => insensitive ? eb(fieldRef, "ilike", import_kysely.sql.lit(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.lit(`%${value}`))).otherwise(() => {
548
- throw new Error(`Invalid string filter key: ${key}`);
779
+ const condition = (0, import_ts_pattern2.match)(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}`))).otherwise(() => {
780
+ throw new QueryError(`Invalid string filter key: ${key}`);
549
781
  });
550
782
  if (condition) {
551
783
  conditions.push(condition);
@@ -554,34 +786,37 @@ var BaseCrudDialect = class {
554
786
  }
555
787
  return this.and(eb, ...conditions);
556
788
  }
557
- prepStringCasing(eb, value, toLower = true) {
789
+ prepStringCasing(eb, value, mode) {
790
+ if (!mode || mode === "default") {
791
+ return value === null ? value : import_kysely.sql.val(value);
792
+ }
558
793
  if (typeof value === "string") {
559
- return toLower ? eb.fn("lower", [
560
- import_kysely.sql.lit(value)
561
- ]) : import_kysely.sql.lit(value);
794
+ return eb.fn("lower", [
795
+ import_kysely.sql.val(value)
796
+ ]);
562
797
  } else if (Array.isArray(value)) {
563
- return value.map((v) => this.prepStringCasing(eb, v, toLower));
798
+ return value.map((v) => this.prepStringCasing(eb, v, mode));
564
799
  } else {
565
- return value === null ? null : import_kysely.sql.lit(value);
800
+ return value === null ? null : import_kysely.sql.val(value);
566
801
  }
567
802
  }
568
- buildNumberFilter(eb, model, table, field, type, payload) {
569
- 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));
803
+ buildNumberFilter(eb, fieldRef, type, payload) {
804
+ const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
570
805
  return this.and(eb, ...conditions);
571
806
  }
572
- buildBooleanFilter(eb, table, field, payload) {
573
- const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
807
+ buildBooleanFilter(eb, fieldRef, payload) {
808
+ const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
574
809
  "equals",
575
810
  "not"
576
811
  ]);
577
812
  return this.and(eb, ...conditions);
578
813
  }
579
- buildDateTimeFilter(eb, table, field, payload) {
580
- const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
814
+ buildDateTimeFilter(eb, fieldRef, payload) {
815
+ const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
581
816
  return this.and(eb, ...conditions);
582
817
  }
583
- buildBytesFilter(eb, table, field, payload) {
584
- const conditions = this.buildStandardFilter(eb, "Bytes", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
818
+ buildBytesFilter(eb, fieldRef, payload) {
819
+ const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
585
820
  "equals",
586
821
  "in",
587
822
  "notIn",
@@ -589,8 +824,8 @@ var BaseCrudDialect = class {
589
824
  ]);
590
825
  return this.and(eb, ...conditions.conditions);
591
826
  }
592
- buildEnumFilter(eb, table, field, fieldDef, payload) {
593
- const conditions = this.buildStandardFilter(eb, "String", payload, import_kysely.sql.ref(`${table}.${field}`), (value) => value, (value) => this.buildEnumFilter(eb, table, field, fieldDef, value), true, [
827
+ buildEnumFilter(eb, fieldRef, fieldDef, payload) {
828
+ const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
594
829
  "equals",
595
830
  "in",
596
831
  "notIn",
@@ -622,9 +857,7 @@ var BaseCrudDialect = class {
622
857
  (0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
623
858
  for (const [k, v] of Object.entries(value)) {
624
859
  (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
625
- result = result.orderBy((eb) => eb.fn(field.slice(1), [
626
- import_kysely.sql.ref(k)
627
- ]), import_kysely.sql.raw(this.negateSort(v, negated)));
860
+ result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
628
861
  }
629
862
  continue;
630
863
  }
@@ -633,7 +866,7 @@ var BaseCrudDialect = class {
633
866
  (0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
634
867
  for (const [k, v] of Object.entries(value)) {
635
868
  (0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
636
- result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
869
+ result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
637
870
  }
638
871
  continue;
639
872
  }
@@ -642,10 +875,11 @@ var BaseCrudDialect = class {
642
875
  }
643
876
  const fieldDef = requireField(this.schema, model, field);
644
877
  if (!fieldDef.relation) {
878
+ const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
645
879
  if (value === "asc" || value === "desc") {
646
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), this.negateSort(value, negated));
880
+ result = result.orderBy(fieldRef, this.negateSort(value, negated));
647
881
  } else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
648
- result = result.orderBy(import_kysely.sql.ref(`${modelAlias}.${field}`), import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
882
+ result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
649
883
  }
650
884
  } else {
651
885
  const relationModel = fieldDef.type;
@@ -657,8 +891,9 @@ var BaseCrudDialect = class {
657
891
  (0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
658
892
  const sort = this.negateSort(value._count, negated);
659
893
  result = result.orderBy((eb) => {
660
- let subQuery = eb.selectFrom(relationModel);
661
- const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
894
+ const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
895
+ let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
896
+ const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
662
897
  subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
663
898
  subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
664
899
  return subQuery;
@@ -676,6 +911,92 @@ var BaseCrudDialect = class {
676
911
  });
677
912
  return result;
678
913
  }
914
+ buildSelectAllFields(model, query, omit, modelAlias) {
915
+ const modelDef = requireModel(this.schema, model);
916
+ let result = query;
917
+ for (const field of Object.keys(modelDef.fields)) {
918
+ if (isRelationField(this.schema, model, field)) {
919
+ continue;
920
+ }
921
+ if (omit?.[field] === true) {
922
+ continue;
923
+ }
924
+ result = this.buildSelectField(result, model, modelAlias, field);
925
+ }
926
+ const descendants = getDelegateDescendantModels(this.schema, model);
927
+ for (const subModel of descendants) {
928
+ result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
929
+ result = result.select((eb) => {
930
+ const jsonObject = {};
931
+ for (const field of Object.keys(subModel.fields)) {
932
+ if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
933
+ continue;
934
+ }
935
+ jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
936
+ }
937
+ return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
938
+ });
939
+ }
940
+ return result;
941
+ }
942
+ buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
943
+ let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
944
+ if (selectAllFields) {
945
+ subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
946
+ }
947
+ if (payload && typeof payload === "object") {
948
+ subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
949
+ }
950
+ return subQuery;
951
+ }
952
+ buildSelectField(query, model, modelAlias, field) {
953
+ const fieldDef = requireField(this.schema, model, field);
954
+ if (fieldDef.computed) {
955
+ return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
956
+ } else if (!fieldDef.originModel) {
957
+ return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
958
+ } else {
959
+ return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
960
+ }
961
+ }
962
+ buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
963
+ const idFields = getIdFields(this.schema, thisModel);
964
+ query = query.leftJoin(otherModelAlias, (qb) => {
965
+ for (const idField of idFields) {
966
+ qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
967
+ }
968
+ return qb;
969
+ });
970
+ return query;
971
+ }
972
+ buildCountJson(model, eb, parentAlias, payload) {
973
+ const modelDef = requireModel(this.schema, model);
974
+ const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
975
+ const selections = payload === true ? {
976
+ select: toManyRelations.reduce((acc, [field]) => {
977
+ acc[field] = true;
978
+ return acc;
979
+ }, {})
980
+ } : payload;
981
+ const jsonObject = {};
982
+ for (const [field, value] of Object.entries(selections.select)) {
983
+ const fieldDef = requireField(this.schema, model, field);
984
+ const fieldModel = fieldDef.type;
985
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
986
+ let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
987
+ for (const [left, right] of joinPairs) {
988
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
989
+ }
990
+ if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
991
+ const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
992
+ fieldCountQuery = fieldCountQuery.where(filter);
993
+ }
994
+ jsonObject[field] = fieldCountQuery;
995
+ }
996
+ return this.buildJsonObject(eb, jsonObject);
997
+ }
998
+ // #endregion
999
+ // #region utils
679
1000
  negateSort(sort, negated) {
680
1001
  return negated ? sort === "asc" ? "desc" : "asc" : sort;
681
1002
  }
@@ -722,6 +1043,21 @@ var BaseCrudDialect = class {
722
1043
  not(eb, ...args) {
723
1044
  return eb.not(this.and(eb, ...args));
724
1045
  }
1046
+ fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
1047
+ return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
1048
+ }
1049
+ canJoinWithoutNestedSelect(modelDef, payload) {
1050
+ if (modelDef.computedFields) {
1051
+ return false;
1052
+ }
1053
+ if (modelDef.baseModel || modelDef.isDelegate) {
1054
+ return false;
1055
+ }
1056
+ if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
1057
+ return false;
1058
+ }
1059
+ return true;
1060
+ }
725
1061
  };
726
1062
 
727
1063
  // src/client/crud/dialects/postgresql.ts
@@ -743,98 +1079,110 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
743
1079
  return value.map((v) => this.transformPrimitive(v, type, false));
744
1080
  }
745
1081
  } else {
746
- return (0, import_ts_pattern2.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1082
+ return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
747
1083
  }
748
1084
  }
749
1085
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
750
- const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload);
751
- return joinedQuery.select(`${parentAlias}$${relationField}.$j as ${relationField}`);
1086
+ const relationResultName = `${parentAlias}$${relationField}`;
1087
+ const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
1088
+ return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
752
1089
  }
753
- buildRelationJSON(model, qb, relationField, parentName, payload) {
1090
+ buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
754
1091
  const relationFieldDef = requireField(this.schema, model, relationField);
755
1092
  const relationModel = relationFieldDef.type;
756
1093
  return qb.leftJoinLateral((eb) => {
757
- const joinTableName = `${parentName}$${relationField}`;
758
- let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
759
- result = eb.selectFrom(() => {
760
- let subQuery = eb.selectFrom(`${relationModel}`).selectAll();
761
- if (payload && typeof payload === "object") {
762
- if (payload.where) {
763
- subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
764
- }
765
- const skip = payload.skip;
766
- let take = payload.take;
767
- let negateOrderBy = false;
768
- if (take !== void 0 && take < 0) {
769
- negateOrderBy = true;
770
- take = -take;
771
- }
772
- subQuery = this.buildSkipTake(subQuery, skip, take);
773
- subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
774
- }
775
- const m2m = getManyToManyRelation(this.schema, model, relationField);
776
- if (m2m) {
777
- const parentIds = getIdFields(this.schema, model);
778
- const relationIds = getIdFields(this.schema, relationModel);
779
- (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
780
- (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
781
- 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}`)));
782
- } else {
783
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
784
- subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
785
- }
786
- return subQuery.as(joinTableName);
787
- });
788
- result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
789
- result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
790
- return result.as(joinTableName);
1094
+ const relationSelectName = `${resultName}$sub`;
1095
+ const relationModelDef = requireModel(this.schema, relationModel);
1096
+ let tbl;
1097
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1098
+ tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
1099
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
1100
+ } else {
1101
+ tbl = eb.selectFrom(() => {
1102
+ let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
1103
+ subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
1104
+ return subQuery.as(relationSelectName);
1105
+ });
1106
+ }
1107
+ tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
1108
+ tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
1109
+ return tbl.as(resultName);
791
1110
  }, (join) => join.onTrue());
792
1111
  }
793
- buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
1112
+ buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1113
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1114
+ if (m2m) {
1115
+ const parentIds = getIdFields(this.schema, model);
1116
+ const relationIds = getIdFields(this.schema, relationModel);
1117
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1118
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1119
+ 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}`)));
1120
+ } else {
1121
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1122
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1123
+ }
1124
+ return query;
1125
+ }
1126
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
794
1127
  qb = qb.select((eb) => {
795
- const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
1128
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
796
1129
  if (relationFieldDef.array) {
797
- return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$j");
1130
+ return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
798
1131
  } else {
799
- return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$j");
1132
+ return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
800
1133
  }
801
1134
  });
802
1135
  return qb;
803
1136
  }
804
- buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
1137
+ buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
805
1138
  const relationModelDef = requireModel(this.schema, relationModel);
806
1139
  const objArgs = [];
1140
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1141
+ if (descendantModels.length > 0) {
1142
+ objArgs.push(...descendantModels.map((subModel) => [
1143
+ import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1144
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1145
+ ]).flatMap((v) => v));
1146
+ }
807
1147
  if (payload === true || !payload.select) {
808
1148
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
809
1149
  import_kysely2.sql.lit(field),
810
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1150
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false)
811
1151
  ]).flatMap((v) => v));
812
1152
  } else if (payload.select) {
813
- objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => {
814
- const fieldDef = requireField(this.schema, relationModel, field);
815
- const fieldValue = fieldDef.relation ? eb.ref(`${parentName}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
816
- return [
817
- import_kysely2.sql.lit(field),
818
- fieldValue
819
- ];
1153
+ objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1154
+ if (field === "_count") {
1155
+ const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1156
+ return [
1157
+ import_kysely2.sql.lit(field),
1158
+ subJson
1159
+ ];
1160
+ } else {
1161
+ const fieldDef = requireField(this.schema, relationModel, field);
1162
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1163
+ return [
1164
+ import_kysely2.sql.lit(field),
1165
+ fieldValue
1166
+ ];
1167
+ }
820
1168
  }).flatMap((v) => v));
821
1169
  }
822
1170
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
823
1171
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
824
1172
  import_kysely2.sql.lit(field),
825
1173
  // reference the synthesized JSON field
826
- eb.ref(`${parentName}$${relationField}$${field}.$j`)
1174
+ eb.ref(`${parentResultName}$${field}.$data`)
827
1175
  ]).flatMap((v) => v));
828
1176
  }
829
1177
  return objArgs;
830
1178
  }
831
- buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
832
- let result = qb;
1179
+ buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
1180
+ let result = query;
833
1181
  if (typeof payload === "object") {
834
1182
  const selectInclude = payload.include ?? payload.select;
835
1183
  if (selectInclude && typeof selectInclude === "object") {
836
1184
  Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
837
- result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1185
+ result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
838
1186
  });
839
1187
  }
840
1188
  }
@@ -876,12 +1224,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
876
1224
  return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
877
1225
  }
878
1226
  }
1227
+ get supportInsertWithDefault() {
1228
+ return true;
1229
+ }
879
1230
  };
880
1231
 
881
1232
  // src/client/crud/dialects/sqlite.ts
882
1233
  var import_common_helpers3 = require("@zenstackhq/common-helpers");
883
1234
  var import_kysely3 = require("kysely");
884
- var import_ts_pattern3 = require("ts-pattern");
1235
+ var import_ts_pattern4 = require("ts-pattern");
885
1236
  var SqliteCrudDialect = class extends BaseCrudDialect {
886
1237
  static {
887
1238
  __name(this, "SqliteCrudDialect");
@@ -896,79 +1247,75 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
896
1247
  if (Array.isArray(value)) {
897
1248
  return value.map((v) => this.transformPrimitive(v, type, false));
898
1249
  } else {
899
- return (0, import_ts_pattern3.match)(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);
1250
+ if (this.schema.typeDefs && type in this.schema.typeDefs) {
1251
+ return JSON.stringify(value);
1252
+ } else {
1253
+ return (0, import_ts_pattern4.match)(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);
1254
+ }
900
1255
  }
901
1256
  }
902
1257
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
903
1258
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
904
1259
  }
905
- buildRelationJSON(model, eb, relationField, parentName, payload) {
1260
+ buildRelationJSON(model, eb, relationField, parentAlias, payload) {
906
1261
  const relationFieldDef = requireField(this.schema, model, relationField);
907
1262
  const relationModel = relationFieldDef.type;
908
1263
  const relationModelDef = requireModel(this.schema, relationModel);
909
- const subQueryName = `${parentName}$${relationField}`;
910
- let tbl = eb.selectFrom(() => {
911
- let subQuery = eb.selectFrom(relationModel).selectAll();
912
- if (payload && typeof payload === "object") {
913
- if (payload.where) {
914
- subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
915
- }
916
- const skip = payload.skip;
917
- let take = payload.take;
918
- let negateOrderBy = false;
919
- if (take !== void 0 && take < 0) {
920
- negateOrderBy = true;
921
- take = -take;
922
- }
923
- subQuery = this.buildSkipTake(subQuery, skip, take);
924
- subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
925
- }
926
- const m2m = getManyToManyRelation(this.schema, model, relationField);
927
- if (m2m) {
928
- const parentIds = getIdFields(this.schema, model);
929
- const relationIds = getIdFields(this.schema, relationModel);
930
- (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
931
- (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
932
- 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}`)));
933
- } else {
934
- const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
935
- keyPairs.forEach(({ fk, pk }) => {
936
- if (ownedByModel) {
937
- subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
938
- } else {
939
- subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
940
- }
941
- });
942
- }
943
- return subQuery.as(subQueryName);
944
- });
1264
+ const subQueryName = `${parentAlias}$${relationField}`;
1265
+ let tbl;
1266
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1267
+ tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
1268
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
1269
+ } else {
1270
+ tbl = eb.selectFrom(() => {
1271
+ const selectModelAlias = `${parentAlias}$${relationField}$sub`;
1272
+ let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
1273
+ selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
1274
+ return selectModelQuery.as(subQueryName);
1275
+ });
1276
+ }
945
1277
  tbl = tbl.select(() => {
946
1278
  const objArgs = [];
1279
+ const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
1280
+ if (descendantModels.length > 0) {
1281
+ objArgs.push(...descendantModels.map((subModel) => [
1282
+ import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
1283
+ eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
1284
+ ]).flatMap((v) => v));
1285
+ }
947
1286
  if (payload === true || !payload.select) {
948
1287
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
949
1288
  import_kysely3.sql.lit(field),
950
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
1289
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
951
1290
  ]).flatMap((v) => v));
952
1291
  } else if (payload.select) {
953
1292
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
954
- const fieldDef = requireField(this.schema, relationModel, field);
955
- if (fieldDef.relation) {
956
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1293
+ if (field === "_count") {
1294
+ const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
957
1295
  return [
958
1296
  import_kysely3.sql.lit(field),
959
1297
  subJson
960
1298
  ];
961
1299
  } else {
962
- return [
963
- import_kysely3.sql.lit(field),
964
- buildFieldRef(this.schema, relationModel, field, this.options, eb)
965
- ];
1300
+ const fieldDef = requireField(this.schema, relationModel, field);
1301
+ if (fieldDef.relation) {
1302
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
1303
+ return [
1304
+ import_kysely3.sql.lit(field),
1305
+ subJson
1306
+ ];
1307
+ } else {
1308
+ return [
1309
+ import_kysely3.sql.lit(field),
1310
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1311
+ ];
1312
+ }
966
1313
  }
967
1314
  }).flatMap((v) => v));
968
1315
  }
969
1316
  if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
970
1317
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
971
- const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
1318
+ const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
972
1319
  return [
973
1320
  import_kysely3.sql.lit(field),
974
1321
  subJson
@@ -976,13 +1323,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
976
1323
  }).flatMap((v) => v));
977
1324
  }
978
1325
  if (relationFieldDef.array) {
979
- return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
1326
+ return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
980
1327
  } else {
981
- return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
1328
+ return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
982
1329
  }
983
1330
  });
984
1331
  return tbl;
985
1332
  }
1333
+ buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
1334
+ const fieldDef = requireField(this.schema, model, relationField);
1335
+ const relationModel = fieldDef.type;
1336
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1337
+ if (m2m) {
1338
+ const parentIds = getIdFields(this.schema, model);
1339
+ const relationIds = getIdFields(this.schema, relationModel);
1340
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1341
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1342
+ 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}`)));
1343
+ } else {
1344
+ const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1345
+ keyPairs.forEach(({ fk, pk }) => {
1346
+ if (ownedByModel) {
1347
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1348
+ } else {
1349
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1350
+ }
1351
+ });
1352
+ }
1353
+ return selectModelQuery;
1354
+ }
986
1355
  buildSkipTake(query, skip, take) {
987
1356
  if (take !== void 0) {
988
1357
  query = query.limit(take);
@@ -1018,93 +1387,17 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1018
1387
  buildArrayLiteralSQL(_values) {
1019
1388
  throw new Error("SQLite does not support array literals");
1020
1389
  }
1390
+ get supportInsertWithDefault() {
1391
+ return false;
1392
+ }
1021
1393
  };
1022
1394
 
1023
1395
  // src/client/crud/dialects/index.ts
1024
1396
  function getCrudDialect(schema, options) {
1025
- return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1397
+ return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
1026
1398
  }
1027
1399
  __name(getCrudDialect, "getCrudDialect");
1028
1400
 
1029
- // src/schema/expression.ts
1030
- var ExpressionUtils = {
1031
- literal: /* @__PURE__ */ __name((value) => {
1032
- return {
1033
- kind: "literal",
1034
- value
1035
- };
1036
- }, "literal"),
1037
- array: /* @__PURE__ */ __name((items) => {
1038
- return {
1039
- kind: "array",
1040
- items
1041
- };
1042
- }, "array"),
1043
- call: /* @__PURE__ */ __name((functionName, args) => {
1044
- return {
1045
- kind: "call",
1046
- function: functionName,
1047
- args
1048
- };
1049
- }, "call"),
1050
- binary: /* @__PURE__ */ __name((left, op, right) => {
1051
- return {
1052
- kind: "binary",
1053
- op,
1054
- left,
1055
- right
1056
- };
1057
- }, "binary"),
1058
- unary: /* @__PURE__ */ __name((op, operand) => {
1059
- return {
1060
- kind: "unary",
1061
- op,
1062
- operand
1063
- };
1064
- }, "unary"),
1065
- field: /* @__PURE__ */ __name((field) => {
1066
- return {
1067
- kind: "field",
1068
- field
1069
- };
1070
- }, "field"),
1071
- member: /* @__PURE__ */ __name((receiver, members) => {
1072
- return {
1073
- kind: "member",
1074
- receiver,
1075
- members
1076
- };
1077
- }, "member"),
1078
- _this: /* @__PURE__ */ __name(() => {
1079
- return {
1080
- kind: "this"
1081
- };
1082
- }, "_this"),
1083
- _null: /* @__PURE__ */ __name(() => {
1084
- return {
1085
- kind: "null"
1086
- };
1087
- }, "_null"),
1088
- and: /* @__PURE__ */ __name((expr2, ...expressions) => {
1089
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
1090
- }, "and"),
1091
- or: /* @__PURE__ */ __name((expr2, ...expressions) => {
1092
- return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
1093
- }, "or"),
1094
- is: /* @__PURE__ */ __name((value, kind) => {
1095
- return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
1096
- }, "is"),
1097
- isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
1098
- isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
1099
- isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
1100
- isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
1101
- isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
1102
- isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
1103
- isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
1104
- isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
1105
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
1106
- };
1107
-
1108
1401
  // src/utils/default-operation-node-visitor.ts
1109
1402
  var import_kysely4 = require("kysely");
1110
1403
  var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
@@ -1426,17 +1719,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1426
1719
  // src/plugins/policy/expression-transformer.ts
1427
1720
  var import_common_helpers5 = require("@zenstackhq/common-helpers");
1428
1721
  var import_kysely6 = require("kysely");
1429
- var import_ts_pattern6 = require("ts-pattern");
1722
+ var import_ts_pattern7 = require("ts-pattern");
1430
1723
 
1431
1724
  // src/plugins/policy/expression-evaluator.ts
1432
1725
  var import_common_helpers4 = require("@zenstackhq/common-helpers");
1433
- var import_ts_pattern5 = require("ts-pattern");
1726
+ var import_ts_pattern6 = require("ts-pattern");
1434
1727
  var ExpressionEvaluator = class {
1435
1728
  static {
1436
1729
  __name(this, "ExpressionEvaluator");
1437
1730
  }
1438
1731
  evaluate(expression, context) {
1439
- const result = (0, import_ts_pattern5.match)(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();
1732
+ const result = (0, import_ts_pattern6.match)(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();
1440
1733
  return result ?? null;
1441
1734
  }
1442
1735
  evaluateCall(expr2, context) {
@@ -1447,7 +1740,7 @@ var ExpressionEvaluator = class {
1447
1740
  }
1448
1741
  }
1449
1742
  evaluateUnary(expr2, context) {
1450
- return (0, import_ts_pattern5.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1743
+ return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
1451
1744
  }
1452
1745
  evaluateMember(expr2, context) {
1453
1746
  let val = this.evaluate(expr2.receiver, context);
@@ -1471,7 +1764,7 @@ var ExpressionEvaluator = class {
1471
1764
  }
1472
1765
  const left = this.evaluate(expr2.left, context);
1473
1766
  const right = this.evaluate(expr2.right, context);
1474
- return (0, import_ts_pattern5.match)(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", () => {
1767
+ return (0, import_ts_pattern6.match)(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", () => {
1475
1768
  const _right = right ?? [];
1476
1769
  (0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
1477
1770
  return _right.includes(left);
@@ -1485,7 +1778,7 @@ var ExpressionEvaluator = class {
1485
1778
  return false;
1486
1779
  }
1487
1780
  (0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
1488
- return (0, import_ts_pattern5.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1781
+ return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1489
1782
  ...context,
1490
1783
  thisValue: item
1491
1784
  }))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
@@ -1739,7 +2032,7 @@ var ExpressionTransformer = class {
1739
2032
  const count = import_kysely6.FunctionNode.create("count", [
1740
2033
  import_kysely6.ValueNode.createImmediate(1)
1741
2034
  ]);
1742
- const predicateResult = (0, import_ts_pattern6.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
2035
+ const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
1743
2036
  return this.transform(expr2.left, {
1744
2037
  ...context,
1745
2038
  memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
@@ -1770,7 +2063,7 @@ var ExpressionTransformer = class {
1770
2063
  return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
1771
2064
  }
1772
2065
  transformOperator(op) {
1773
- const mappedOp = (0, import_ts_pattern6.match)(op).with("==", () => "=").otherwise(() => op);
2066
+ const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
1774
2067
  return import_kysely6.OperatorNode.create(mappedOp);
1775
2068
  }
1776
2069
  _call(expr2, context) {
@@ -2173,7 +2466,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
2173
2466
  return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely7.BinaryOperationNode.create(import_kysely7.ColumnNode.create(field), import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.create(row[field]))))));
2174
2467
  }
2175
2468
  getMutationModel(node) {
2176
- const r = (0, import_ts_pattern7.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2469
+ const r = (0, import_ts_pattern8.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
2177
2470
  if (node2.from.froms.length !== 1) {
2178
2471
  throw new InternalError("Only one from table is supported for delete");
2179
2472
  }
@@ -2354,4 +2647,4 @@ var PolicyPlugin = class {
2354
2647
  PolicyPlugin,
2355
2648
  RejectedByPolicyError
2356
2649
  });
2357
- //# sourceMappingURL=policy.cjs.map
2650
+ //# sourceMappingURL=index.cjs.map