@zenstackhq/runtime 3.0.0-beta.4 → 3.0.0-beta.5

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.
package/dist/index.js CHANGED
@@ -6,14 +6,15 @@ var __export = (target, all) => {
6
6
  };
7
7
 
8
8
  // src/client/client-impl.ts
9
- import { invariant as invariant14 } from "@zenstackhq/common-helpers";
10
- import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as DefaultQueryExecutor2, Kysely, Log, sql as sql9, Transaction } from "kysely";
9
+ import { invariant as invariant15 } from "@zenstackhq/common-helpers";
10
+ import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as DefaultQueryExecutor2, Kysely, Log, sql as sql10, Transaction } from "kysely";
11
11
 
12
12
  // src/client/crud/operations/aggregate.ts
13
- import { sql as sql5 } from "kysely";
13
+ import { sql as sql6 } from "kysely";
14
14
  import { match as match10 } from "ts-pattern";
15
15
 
16
16
  // src/client/query-utils.ts
17
+ import { invariant } from "@zenstackhq/common-helpers";
17
18
  import { match } from "ts-pattern";
18
19
 
19
20
  // src/schema/expression.ts
@@ -192,10 +193,19 @@ function requireField(schema, modelOrType, field) {
192
193
  }
193
194
  __name(requireField, "requireField");
194
195
  function getIdFields(schema, model) {
195
- const modelDef = requireModel(schema, model);
196
+ const modelDef = getModel(schema, model);
196
197
  return modelDef?.idFields;
197
198
  }
198
199
  __name(getIdFields, "getIdFields");
200
+ function requireIdFields(schema, model) {
201
+ const modelDef = requireModel(schema, model);
202
+ const result = modelDef?.idFields;
203
+ if (!result) {
204
+ throw new InternalError(`Model "${model}" does not have ID field(s)`);
205
+ }
206
+ return result;
207
+ }
208
+ __name(requireIdFields, "requireIdFields");
199
209
  function getRelationForeignKeyFieldPairs(schema, model, relationField) {
200
210
  const fieldDef = requireField(schema, model, relationField);
201
211
  if (!fieldDef?.relation) {
@@ -309,7 +319,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
309
319
  throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
310
320
  }
311
321
  return computer(eb, {
312
- currentModel: modelAlias
322
+ modelAlias
313
323
  });
314
324
  }
315
325
  }
@@ -344,7 +354,7 @@ function buildJoinPairs(schema, model, modelAlias, relationField, relationModelA
344
354
  }
345
355
  __name(buildJoinPairs, "buildJoinPairs");
346
356
  function makeDefaultOrderBy(schema, model) {
347
- const idFields = getIdFields(schema, model);
357
+ const idFields = requireIdFields(schema, model);
348
358
  return idFields.map((f) => ({
349
359
  [f]: "asc"
350
360
  }));
@@ -383,11 +393,17 @@ function getManyToManyRelation(schema, model, field) {
383
393
  "A"
384
394
  ];
385
395
  }
396
+ const modelIdFields = requireIdFields(schema, model);
397
+ invariant(modelIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
398
+ const otherIdFields = requireIdFields(schema, fieldDef.type);
399
+ invariant(otherIdFields.length === 1, "Only single-field ID is supported for many-to-many relation");
386
400
  return {
387
401
  parentFkName: orderedFK[0],
402
+ parentPKName: modelIdFields[0],
388
403
  otherModel: fieldDef.type,
389
404
  otherField: fieldDef.relation.opposite,
390
405
  otherFkName: orderedFK[1],
406
+ otherPKName: otherIdFields[0],
391
407
  joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
392
408
  };
393
409
  } else {
@@ -426,7 +442,7 @@ function ensureArray(value) {
426
442
  }
427
443
  __name(ensureArray, "ensureArray");
428
444
  function extractIdFields(entity, schema, model) {
429
- const idFields = getIdFields(schema, model);
445
+ const idFields = requireIdFields(schema, model);
430
446
  return extractFields(entity, idFields);
431
447
  }
432
448
  __name(extractIdFields, "extractIdFields");
@@ -463,35 +479,94 @@ __name(aggregate, "aggregate");
463
479
 
464
480
  // src/client/crud/operations/base.ts
465
481
  import { createId } from "@paralleldrive/cuid2";
466
- import { invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
467
- import { expressionBuilder as expressionBuilder3, sql as sql4 } from "kysely";
482
+ import { invariant as invariant9, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
483
+ import { expressionBuilder as expressionBuilder4, sql as sql5 } from "kysely";
468
484
  import { nanoid } from "nanoid";
469
485
  import { match as match9 } from "ts-pattern";
470
486
  import { ulid } from "ulid";
471
487
  import * as uuid from "uuid";
472
488
 
473
489
  // src/plugins/policy/errors.ts
490
+ var RejectedByPolicyReason = /* @__PURE__ */ function(RejectedByPolicyReason2) {
491
+ RejectedByPolicyReason2["NO_ACCESS"] = "no-access";
492
+ RejectedByPolicyReason2["CANNOT_READ_BACK"] = "cannot-read-back";
493
+ RejectedByPolicyReason2["OTHER"] = "other";
494
+ return RejectedByPolicyReason2;
495
+ }({});
474
496
  var RejectedByPolicyError = class extends Error {
475
497
  static {
476
498
  __name(this, "RejectedByPolicyError");
477
499
  }
478
500
  model;
479
501
  reason;
480
- constructor(model, reason) {
481
- super(reason ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
502
+ constructor(model, reason = "no-access", message) {
503
+ super(message ?? `Operation rejected by policy${model ? ": " + model : ""}`), this.model = model, this.reason = reason;
482
504
  }
483
505
  };
484
506
 
507
+ // src/plugins/policy/functions.ts
508
+ import { invariant as invariant8 } from "@zenstackhq/common-helpers";
509
+ import { ExpressionWrapper as ExpressionWrapper2, ValueNode as ValueNode4 } from "kysely";
510
+
511
+ // src/client/contract.ts
512
+ var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
513
+ TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
514
+ TransactionIsolationLevel2["ReadCommitted"] = "read committed";
515
+ TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
516
+ TransactionIsolationLevel2["Serializable"] = "serializable";
517
+ TransactionIsolationLevel2["Snapshot"] = "snapshot";
518
+ return TransactionIsolationLevel2;
519
+ }({});
520
+ var CRUD = [
521
+ "create",
522
+ "read",
523
+ "update",
524
+ "delete"
525
+ ];
526
+
527
+ // src/client/kysely-utils.ts
528
+ import { AliasNode, ColumnNode, ReferenceNode, TableNode } from "kysely";
529
+ function stripAlias(node) {
530
+ if (AliasNode.is(node)) {
531
+ return {
532
+ alias: node.alias,
533
+ node: node.node
534
+ };
535
+ } else {
536
+ return {
537
+ alias: void 0,
538
+ node
539
+ };
540
+ }
541
+ }
542
+ __name(stripAlias, "stripAlias");
543
+ function extractModelName(node) {
544
+ const { node: innerNode } = stripAlias(node);
545
+ return TableNode.is(innerNode) ? innerNode.table.identifier.name : void 0;
546
+ }
547
+ __name(extractModelName, "extractModelName");
548
+ function extractFieldName(node) {
549
+ if (ReferenceNode.is(node) && ColumnNode.is(node.column)) {
550
+ return node.column.column.name;
551
+ } else if (ColumnNode.is(node)) {
552
+ return node.column.name;
553
+ } else {
554
+ return void 0;
555
+ }
556
+ }
557
+ __name(extractFieldName, "extractFieldName");
558
+
485
559
  // src/plugins/policy/policy-handler.ts
486
- import { invariant as invariant6 } from "@zenstackhq/common-helpers";
487
- import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode2, DeleteQueryNode, FromNode as FromNode2, FunctionNode as FunctionNode3, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, ParensNode as ParensNode2, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, TableNode as TableNode3, UpdateQueryNode, ValueListNode as ValueListNode2, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
560
+ import { invariant as invariant7 } from "@zenstackhq/common-helpers";
561
+ import { AliasNode as AliasNode4, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode3, DeleteQueryNode, expressionBuilder as expressionBuilder3, ExpressionWrapper, FromNode as FromNode2, FunctionNode as FunctionNode3, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, ParensNode as ParensNode2, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, sql as sql4, TableNode as TableNode4, UpdateQueryNode, ValueListNode as ValueListNode2, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
488
562
  import { match as match8 } from "ts-pattern";
489
563
 
490
564
  // src/client/crud/dialects/index.ts
491
565
  import { match as match5 } from "ts-pattern";
492
566
 
493
567
  // src/client/crud/dialects/postgresql.ts
494
- import { invariant as invariant2 } from "@zenstackhq/common-helpers";
568
+ import { invariant as invariant3 } from "@zenstackhq/common-helpers";
569
+ import Decimal from "decimal.js";
495
570
  import { sql as sql2 } from "kysely";
496
571
  import { match as match3 } from "ts-pattern";
497
572
 
@@ -517,7 +592,7 @@ var AGGREGATE_OPERATORS = [
517
592
  ];
518
593
 
519
594
  // src/client/crud/dialects/base-dialect.ts
520
- import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
595
+ import { invariant as invariant2, isPlainObject } from "@zenstackhq/common-helpers";
521
596
  import { expressionBuilder, sql } from "kysely";
522
597
  import { match as match2, P } from "ts-pattern";
523
598
 
@@ -549,6 +624,9 @@ var BaseCrudDialect = class {
549
624
  transformPrimitive(value, _type, _forArrayField) {
550
625
  return value;
551
626
  }
627
+ transformOutput(value, _type) {
628
+ return value;
629
+ }
552
630
  // #region common query builders
553
631
  buildSelectModel(eb, model, modelAlias) {
554
632
  const modelDef = requireModel(this.schema, model);
@@ -716,9 +794,11 @@ var BaseCrudDialect = class {
716
794
  const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
717
795
  const m2m = getManyToManyRelation(this.schema, model, field);
718
796
  if (m2m) {
719
- const modelIdField = getIdFields(this.schema, model)[0];
720
- const relationIdField = getIdFields(this.schema, relationModel)[0];
721
- 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}`)));
797
+ const modelIdFields = requireIdFields(this.schema, model);
798
+ invariant2(modelIdFields.length === 1, "many-to-many relation must have exactly one id field");
799
+ const relationIdFields = requireIdFields(this.schema, relationModel);
800
+ invariant2(relationIdFields.length === 1, "many-to-many relation must have exactly one id field");
801
+ return eb2(sql.ref(`${relationFilterSelectAlias}.${relationIdFields[0]}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", sql.ref(`${modelAlias}.${modelIdFields[0]}`)));
722
802
  } else {
723
803
  const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
724
804
  let result2 = this.true(eb2);
@@ -828,14 +908,14 @@ var BaseCrudDialect = class {
828
908
  }
829
909
  const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
830
910
  const condition = match2(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
831
- invariant(Array.isArray(rhs), "right hand side must be an array");
911
+ invariant2(Array.isArray(rhs), "right hand side must be an array");
832
912
  if (rhs.length === 0) {
833
913
  return this.false(eb);
834
914
  } else {
835
915
  return eb(lhs, "in", rhs);
836
916
  }
837
917
  }).with("notIn", () => {
838
- invariant(Array.isArray(rhs), "right hand side must be an array");
918
+ invariant2(Array.isArray(rhs), "right hand side must be an array");
839
919
  if (rhs.length === 0) {
840
920
  return this.true(eb);
841
921
  } else {
@@ -953,18 +1033,18 @@ var BaseCrudDialect = class {
953
1033
  "_min",
954
1034
  "_max"
955
1035
  ].includes(field)) {
956
- invariant(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
1036
+ invariant2(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
957
1037
  for (const [k, v] of Object.entries(value)) {
958
- invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
1038
+ invariant2(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
959
1039
  result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), sql.raw(this.negateSort(v, negated)));
960
1040
  }
961
1041
  continue;
962
1042
  }
963
1043
  switch (field) {
964
1044
  case "_count": {
965
- invariant(value && typeof value === "object", 'invalid orderBy value for field "_count"');
1045
+ invariant2(value && typeof value === "object", 'invalid orderBy value for field "_count"');
966
1046
  for (const [k, v] of Object.entries(value)) {
967
- invariant(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
1047
+ invariant2(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
968
1048
  result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), sql.raw(this.negateSort(v, negated)));
969
1049
  }
970
1050
  continue;
@@ -987,7 +1067,7 @@ var BaseCrudDialect = class {
987
1067
  throw new QueryError(`invalid orderBy value for field "${field}"`);
988
1068
  }
989
1069
  if ("_count" in value) {
990
- invariant(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
1070
+ invariant2(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
991
1071
  const sort = this.negateSort(value._count, negated);
992
1072
  result = result.orderBy((eb) => {
993
1073
  const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
@@ -1059,7 +1139,7 @@ var BaseCrudDialect = class {
1059
1139
  }
1060
1140
  }
1061
1141
  buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
1062
- const idFields = getIdFields(this.schema, thisModel);
1142
+ const idFields = requireIdFields(this.schema, thisModel);
1063
1143
  query = query.leftJoin(otherModelAlias, (qb) => {
1064
1144
  for (const idField of idFields) {
1065
1145
  qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
@@ -1081,10 +1161,16 @@ var BaseCrudDialect = class {
1081
1161
  for (const [field, value] of Object.entries(selections.select)) {
1082
1162
  const fieldDef = requireField(this.schema, model, field);
1083
1163
  const fieldModel = fieldDef.type;
1084
- const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
1085
- let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
1086
- for (const [left, right] of joinPairs) {
1087
- fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
1164
+ let fieldCountQuery;
1165
+ const m2m = getManyToManyRelation(this.schema, model, field);
1166
+ if (m2m) {
1167
+ fieldCountQuery = eb.selectFrom(fieldModel).innerJoin(m2m.joinTable, (join) => join.onRef(`${m2m.joinTable}.${m2m.otherFkName}`, "=", `${fieldModel}.${m2m.otherPKName}`).onRef(`${m2m.joinTable}.${m2m.parentFkName}`, "=", `${parentAlias}.${m2m.parentPKName}`)).select(eb.fn.countAll().as(`_count$${field}`));
1168
+ } else {
1169
+ fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
1170
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
1171
+ for (const [left, right] of joinPairs) {
1172
+ fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
1173
+ }
1088
1174
  }
1089
1175
  if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
1090
1176
  const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
@@ -1164,6 +1250,9 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1164
1250
  static {
1165
1251
  __name(this, "PostgresCrudDialect");
1166
1252
  }
1253
+ constructor(schema, options) {
1254
+ super(schema, options);
1255
+ }
1167
1256
  get provider() {
1168
1257
  return "postgresql";
1169
1258
  }
@@ -1178,9 +1267,41 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1178
1267
  return value.map((v) => this.transformPrimitive(v, type, false));
1179
1268
  }
1180
1269
  } else {
1181
- 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);
1270
+ return match3(type).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
1271
+ }
1272
+ }
1273
+ transformOutput(value, type) {
1274
+ if (value === null || value === void 0) {
1275
+ return value;
1276
+ }
1277
+ return match3(type).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Decimal", () => this.transformDecimal(value)).otherwise(() => super.transformOutput(value, type));
1278
+ }
1279
+ transformOutputBigInt(value) {
1280
+ if (typeof value === "bigint") {
1281
+ return value;
1282
+ }
1283
+ invariant3(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1284
+ return BigInt(value);
1285
+ }
1286
+ transformDecimal(value) {
1287
+ if (value instanceof Decimal) {
1288
+ return value;
1289
+ }
1290
+ invariant3(typeof value === "string" || typeof value === "number" || value instanceof Decimal, `Expected string, number or Decimal, got ${typeof value}`);
1291
+ return new Decimal(value);
1292
+ }
1293
+ transformOutputDate(value) {
1294
+ if (typeof value === "string") {
1295
+ return new Date(value);
1296
+ } else if (value instanceof Date && this.options.fixPostgresTimezone !== false) {
1297
+ return new Date(value.getTime() - value.getTimezoneOffset() * 60 * 1e3);
1298
+ } else {
1299
+ return value;
1182
1300
  }
1183
1301
  }
1302
+ transformOutputBytes(value) {
1303
+ return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
1304
+ }
1184
1305
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1185
1306
  const relationResultName = `${parentAlias}$${relationField}`;
1186
1307
  const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
@@ -1211,10 +1332,10 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1211
1332
  buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1212
1333
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1213
1334
  if (m2m) {
1214
- const parentIds = getIdFields(this.schema, model);
1215
- const relationIds = getIdFields(this.schema, relationModel);
1216
- invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1217
- invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1335
+ const parentIds = requireIdFields(this.schema, model);
1336
+ const relationIds = requireIdFields(this.schema, relationModel);
1337
+ invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1338
+ invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1218
1339
  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}`)));
1219
1340
  } else {
1220
1341
  const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
@@ -1326,10 +1447,32 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1326
1447
  get supportInsertWithDefault() {
1327
1448
  return true;
1328
1449
  }
1450
+ getFieldSqlType(fieldDef) {
1451
+ if (fieldDef.relation) {
1452
+ throw new QueryError("Cannot get SQL type of a relation field");
1453
+ }
1454
+ let result;
1455
+ if (this.schema.enums?.[fieldDef.type]) {
1456
+ result = "text";
1457
+ } else {
1458
+ result = match3(fieldDef.type).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("BigInt", () => "bigint").with("Float", () => "double precision").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => "bytea").with("Json", () => "jsonb").otherwise(() => "text");
1459
+ }
1460
+ if (fieldDef.array) {
1461
+ result += "[]";
1462
+ }
1463
+ return result;
1464
+ }
1465
+ getStringCasingBehavior() {
1466
+ return {
1467
+ supportsILike: true,
1468
+ likeCaseSensitive: true
1469
+ };
1470
+ }
1329
1471
  };
1330
1472
 
1331
1473
  // src/client/crud/dialects/sqlite.ts
1332
- import { invariant as invariant3 } from "@zenstackhq/common-helpers";
1474
+ import { invariant as invariant4 } from "@zenstackhq/common-helpers";
1475
+ import Decimal2 from "decimal.js";
1333
1476
  import { sql as sql3 } from "kysely";
1334
1477
  import { match as match4 } from "ts-pattern";
1335
1478
  var SqliteCrudDialect = class extends BaseCrudDialect {
@@ -1349,10 +1492,58 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1349
1492
  if (this.schema.typeDefs && type in this.schema.typeDefs) {
1350
1493
  return JSON.stringify(value);
1351
1494
  } else {
1352
- 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);
1495
+ return match4(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
1353
1496
  }
1354
1497
  }
1355
1498
  }
1499
+ transformOutput(value, type) {
1500
+ if (value === null || value === void 0) {
1501
+ return value;
1502
+ } else if (this.schema.typeDefs && type in this.schema.typeDefs) {
1503
+ return this.transformOutputJson(value);
1504
+ } else {
1505
+ return match4(type).with("Boolean", () => this.transformOutputBoolean(value)).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("Decimal", () => this.transformOutputDecimal(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Json", () => this.transformOutputJson(value)).otherwise(() => super.transformOutput(value, type));
1506
+ }
1507
+ }
1508
+ transformOutputDecimal(value) {
1509
+ if (value instanceof Decimal2) {
1510
+ return value;
1511
+ }
1512
+ invariant4(typeof value === "string" || typeof value === "number" || value instanceof Decimal2, `Expected string, number or Decimal, got ${typeof value}`);
1513
+ return new Decimal2(value);
1514
+ }
1515
+ transformOutputBigInt(value) {
1516
+ if (typeof value === "bigint") {
1517
+ return value;
1518
+ }
1519
+ invariant4(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
1520
+ return BigInt(value);
1521
+ }
1522
+ transformOutputBoolean(value) {
1523
+ return !!value;
1524
+ }
1525
+ transformOutputDate(value) {
1526
+ if (typeof value === "number") {
1527
+ return new Date(value);
1528
+ } else if (typeof value === "string") {
1529
+ return new Date(value);
1530
+ } else {
1531
+ return value;
1532
+ }
1533
+ }
1534
+ transformOutputBytes(value) {
1535
+ return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
1536
+ }
1537
+ transformOutputJson(value) {
1538
+ if (typeof value === "string") {
1539
+ try {
1540
+ return JSON.parse(value);
1541
+ } catch (e) {
1542
+ throw new QueryError("Invalid JSON returned", e);
1543
+ }
1544
+ }
1545
+ return value;
1546
+ }
1356
1547
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1357
1548
  return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
1358
1549
  }
@@ -1434,10 +1625,10 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1434
1625
  const relationModel = fieldDef.type;
1435
1626
  const m2m = getManyToManyRelation(this.schema, model, relationField);
1436
1627
  if (m2m) {
1437
- const parentIds = getIdFields(this.schema, model);
1438
- const relationIds = getIdFields(this.schema, relationModel);
1439
- invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1440
- invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1628
+ const parentIds = requireIdFields(this.schema, model);
1629
+ const relationIds = requireIdFields(this.schema, relationModel);
1630
+ invariant4(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1631
+ invariant4(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1441
1632
  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}`)));
1442
1633
  } else {
1443
1634
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
@@ -1489,6 +1680,24 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1489
1680
  get supportInsertWithDefault() {
1490
1681
  return false;
1491
1682
  }
1683
+ getFieldSqlType(fieldDef) {
1684
+ if (fieldDef.relation) {
1685
+ throw new QueryError("Cannot get SQL type of a relation field");
1686
+ }
1687
+ if (fieldDef.array) {
1688
+ throw new QueryError("SQLite does not support scalar list type");
1689
+ }
1690
+ if (this.schema.enums?.[fieldDef.type]) {
1691
+ return "text";
1692
+ }
1693
+ return match4(fieldDef.type).with("String", () => "text").with("Boolean", () => "integer").with("Int", () => "integer").with("BigInt", () => "integer").with("Float", () => "real").with("Decimal", () => "decimal").with("DateTime", () => "numeric").with("Bytes", () => "blob").with("Json", () => "jsonb").otherwise(() => "text");
1694
+ }
1695
+ getStringCasingBehavior() {
1696
+ return {
1697
+ supportsILike: false,
1698
+ likeCaseSensitive: false
1699
+ };
1700
+ }
1492
1701
  };
1493
1702
 
1494
1703
  // src/client/crud/dialects/index.ts
@@ -1816,12 +2025,12 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
1816
2025
  };
1817
2026
 
1818
2027
  // src/plugins/policy/expression-transformer.ts
1819
- import { invariant as invariant5 } from "@zenstackhq/common-helpers";
1820
- 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";
2028
+ import { invariant as invariant6 } from "@zenstackhq/common-helpers";
2029
+ import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode2, ColumnNode as ColumnNode2, expressionBuilder as expressionBuilder2, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode3, SelectionNode, SelectQueryNode, TableNode as TableNode3, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
1821
2030
  import { match as match7 } from "ts-pattern";
1822
2031
 
1823
2032
  // src/plugins/policy/expression-evaluator.ts
1824
- import { invariant as invariant4 } from "@zenstackhq/common-helpers";
2033
+ import { invariant as invariant5 } from "@zenstackhq/common-helpers";
1825
2034
  import { match as match6 } from "ts-pattern";
1826
2035
  var ExpressionEvaluator = class {
1827
2036
  static {
@@ -1865,18 +2074,18 @@ var ExpressionEvaluator = class {
1865
2074
  const right = this.evaluate(expr2.right, context);
1866
2075
  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", () => {
1867
2076
  const _right = right ?? [];
1868
- invariant4(Array.isArray(_right), 'expected array for "in" operator');
2077
+ invariant5(Array.isArray(_right), 'expected array for "in" operator');
1869
2078
  return _right.includes(left);
1870
2079
  }).exhaustive();
1871
2080
  }
1872
2081
  evaluateCollectionPredicate(expr2, context) {
1873
2082
  const op = expr2.op;
1874
- invariant4(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
2083
+ invariant5(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
1875
2084
  const left = this.evaluate(expr2.left, context);
1876
2085
  if (!left) {
1877
2086
  return false;
1878
2087
  }
1879
- invariant4(Array.isArray(left), "expected array");
2088
+ invariant5(Array.isArray(left), "expected array");
1880
2089
  return match6(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
1881
2090
  ...context,
1882
2091
  thisValue: item
@@ -1891,7 +2100,7 @@ var ExpressionEvaluator = class {
1891
2100
  };
1892
2101
 
1893
2102
  // src/plugins/policy/utils.ts
1894
- import { AliasNode, AndNode, BinaryOperationNode, FunctionNode, OperatorNode, OrNode, ParensNode, ReferenceNode, TableNode, UnaryOperationNode, ValueNode } from "kysely";
2103
+ import { AliasNode as AliasNode2, AndNode, BinaryOperationNode, FunctionNode, OperatorNode, OrNode, ParensNode, ReferenceNode as ReferenceNode2, TableNode as TableNode2, UnaryOperationNode, ValueNode } from "kysely";
1895
2104
  function trueNode(dialect) {
1896
2105
  return ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
1897
2106
  }
@@ -1977,11 +2186,11 @@ function getTableName(node) {
1977
2186
  if (!node) {
1978
2187
  return node;
1979
2188
  }
1980
- if (TableNode.is(node)) {
2189
+ if (TableNode2.is(node)) {
1981
2190
  return node.table.identifier.name;
1982
- } else if (AliasNode.is(node)) {
2191
+ } else if (AliasNode2.is(node)) {
1983
2192
  return getTableName(node.node);
1984
- } else if (ReferenceNode.is(node) && node.table) {
2193
+ } else if (ReferenceNode2.is(node) && node.table) {
1985
2194
  return getTableName(node.table);
1986
2195
  }
1987
2196
  return void 0;
@@ -2014,16 +2223,21 @@ var ExpressionTransformer = class {
2014
2223
  static {
2015
2224
  __name(this, "ExpressionTransformer");
2016
2225
  }
2017
- schema;
2018
- clientOptions;
2019
- auth;
2226
+ client;
2020
2227
  dialect;
2021
- constructor(schema, clientOptions, auth) {
2022
- this.schema = schema;
2023
- this.clientOptions = clientOptions;
2024
- this.auth = auth;
2228
+ constructor(client) {
2229
+ this.client = client;
2025
2230
  this.dialect = getCrudDialect(this.schema, this.clientOptions);
2026
2231
  }
2232
+ get schema() {
2233
+ return this.client.$schema;
2234
+ }
2235
+ get clientOptions() {
2236
+ return this.client.$options;
2237
+ }
2238
+ get auth() {
2239
+ return this.client.$auth;
2240
+ }
2027
2241
  get authType() {
2028
2242
  if (!this.schema.authType) {
2029
2243
  throw new InternalError('Schema does not have an "authType" specified');
@@ -2093,8 +2307,9 @@ var ExpressionTransformer = class {
2093
2307
  if (op === "?" || op === "!" || op === "^") {
2094
2308
  return this.transformCollectionPredicate(expr2, context);
2095
2309
  }
2096
- const left = this.transform(expr2.left, context);
2097
- const right = this.transform(expr2.right, context);
2310
+ const { normalizedLeft, normalizedRight } = this.normalizeBinaryOperationOperands(expr2, context);
2311
+ const left = this.transform(normalizedLeft, context);
2312
+ const right = this.transform(normalizedRight, context);
2098
2313
  if (op === "in") {
2099
2314
  if (this.isNullNode(left)) {
2100
2315
  return this.transformValue(false, "Boolean");
@@ -2109,29 +2324,65 @@ var ExpressionTransformer = class {
2109
2324
  }
2110
2325
  }
2111
2326
  if (this.isNullNode(right)) {
2112
- return expr2.op === "==" ? BinaryOperationNode2.create(left, OperatorNode2.create("is"), right) : BinaryOperationNode2.create(left, OperatorNode2.create("is not"), right);
2327
+ return this.transformNullCheck(left, expr2.op);
2113
2328
  } else if (this.isNullNode(left)) {
2114
- return expr2.op === "==" ? BinaryOperationNode2.create(right, OperatorNode2.create("is"), ValueNode2.createImmediate(null)) : BinaryOperationNode2.create(right, OperatorNode2.create("is not"), ValueNode2.createImmediate(null));
2329
+ return this.transformNullCheck(right, expr2.op);
2330
+ } else {
2331
+ return BinaryOperationNode2.create(left, this.transformOperator(op), right);
2115
2332
  }
2116
- return BinaryOperationNode2.create(left, this.transformOperator(op), right);
2333
+ }
2334
+ transformNullCheck(expr2, operator) {
2335
+ invariant6(operator === "==" || operator === "!=", 'operator must be "==" or "!=" for null comparison');
2336
+ if (ValueNode2.is(expr2)) {
2337
+ if (expr2.value === null) {
2338
+ return operator === "==" ? trueNode(this.dialect) : falseNode(this.dialect);
2339
+ } else {
2340
+ return operator === "==" ? falseNode(this.dialect) : trueNode(this.dialect);
2341
+ }
2342
+ } else {
2343
+ return operator === "==" ? BinaryOperationNode2.create(expr2, OperatorNode2.create("is"), ValueNode2.createImmediate(null)) : BinaryOperationNode2.create(expr2, OperatorNode2.create("is not"), ValueNode2.createImmediate(null));
2344
+ }
2345
+ }
2346
+ normalizeBinaryOperationOperands(expr2, context) {
2347
+ let normalizedLeft = expr2.left;
2348
+ if (this.isRelationField(expr2.left, context.model)) {
2349
+ invariant6(ExpressionUtils.isNull(expr2.right), "only null comparison is supported for relation field");
2350
+ const leftRelDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2351
+ invariant6(leftRelDef, "failed to get relation field definition");
2352
+ const idFields = requireIdFields(this.schema, leftRelDef.type);
2353
+ normalizedLeft = this.makeOrAppendMember(normalizedLeft, idFields[0]);
2354
+ }
2355
+ let normalizedRight = expr2.right;
2356
+ if (this.isRelationField(expr2.right, context.model)) {
2357
+ invariant6(ExpressionUtils.isNull(expr2.left), "only null comparison is supported for relation field");
2358
+ const rightRelDef = this.getFieldDefFromFieldRef(expr2.right, context.model);
2359
+ invariant6(rightRelDef, "failed to get relation field definition");
2360
+ const idFields = requireIdFields(this.schema, rightRelDef.type);
2361
+ normalizedRight = this.makeOrAppendMember(normalizedRight, idFields[0]);
2362
+ }
2363
+ return {
2364
+ normalizedLeft,
2365
+ normalizedRight
2366
+ };
2117
2367
  }
2118
2368
  transformCollectionPredicate(expr2, context) {
2119
- invariant5(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2369
+ invariant6(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
2120
2370
  if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
2121
2371
  const value = new ExpressionEvaluator().evaluate(expr2, {
2122
2372
  auth: this.auth
2123
2373
  });
2124
2374
  return this.transformValue(value, "Boolean");
2125
2375
  }
2126
- invariant5(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2376
+ invariant6(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
2127
2377
  let newContextModel;
2128
- if (ExpressionUtils.isField(expr2.left)) {
2129
- const fieldDef = requireField(this.schema, context.model, expr2.left.field);
2378
+ const fieldDef = this.getFieldDefFromFieldRef(expr2.left, context.model);
2379
+ if (fieldDef) {
2380
+ invariant6(fieldDef.relation, `field is not a relation: ${JSON.stringify(expr2.left)}`);
2130
2381
  newContextModel = fieldDef.type;
2131
2382
  } else {
2132
- invariant5(ExpressionUtils.isField(expr2.left.receiver));
2133
- const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
2134
- newContextModel = fieldDef.type;
2383
+ invariant6(ExpressionUtils.isMember(expr2.left) && ExpressionUtils.isField(expr2.left.receiver), "left operand must be member access with field receiver");
2384
+ const fieldDef2 = requireField(this.schema, context.model, expr2.left.receiver.field);
2385
+ newContextModel = fieldDef2.type;
2135
2386
  for (const member of expr2.left.members) {
2136
2387
  const memberDef = requireField(this.schema, newContextModel, member);
2137
2388
  newContextModel = memberDef.type;
@@ -2151,7 +2402,7 @@ var ExpressionTransformer = class {
2151
2402
  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();
2152
2403
  return this.transform(expr2.left, {
2153
2404
  ...context,
2154
- memberSelect: SelectionNode.create(AliasNode2.create(predicateResult, IdentifierNode.create("$t"))),
2405
+ memberSelect: SelectionNode.create(AliasNode3.create(predicateResult, IdentifierNode.create("$t"))),
2155
2406
  memberFilter: predicateFilter
2156
2407
  });
2157
2408
  }
@@ -2176,12 +2427,10 @@ var ExpressionTransformer = class {
2176
2427
  throw new QueryError(`Unsupported use of \`auth()\` in policy of model "${context.model}", comparing with \`auth()\` is only possible when auth type is a model`);
2177
2428
  }
2178
2429
  const idFields = Object.values(authModel.fields).filter((f) => f.id).map((f) => f.name);
2179
- invariant5(idFields.length > 0, "auth type model must have at least one id field");
2430
+ invariant6(idFields.length > 0, "auth type model must have at least one id field");
2180
2431
  const conditions = idFields.map((fieldName) => ExpressionUtils.binary(ExpressionUtils.member(authExpr, [
2181
2432
  fieldName
2182
- ]), "==", ExpressionUtils.member(other, [
2183
- fieldName
2184
- ])));
2433
+ ]), "==", this.makeOrAppendMember(other, fieldName)));
2185
2434
  let result = this.buildAnd(conditions);
2186
2435
  if (expr2.op === "!=") {
2187
2436
  result = this.buildLogicalNot(result);
@@ -2189,11 +2438,29 @@ var ExpressionTransformer = class {
2189
2438
  return this.transform(result, context);
2190
2439
  }
2191
2440
  }
2441
+ makeOrAppendMember(other, fieldName) {
2442
+ if (ExpressionUtils.isMember(other)) {
2443
+ return ExpressionUtils.member(other.receiver, [
2444
+ ...other.members,
2445
+ fieldName
2446
+ ]);
2447
+ } else {
2448
+ return ExpressionUtils.member(other, [
2449
+ fieldName
2450
+ ]);
2451
+ }
2452
+ }
2192
2453
  transformValue(value, type) {
2193
- return ValueNode2.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2454
+ if (value === true) {
2455
+ return trueNode(this.dialect);
2456
+ } else if (value === false) {
2457
+ return falseNode(this.dialect);
2458
+ } else {
2459
+ return ValueNode2.create(this.dialect.transformPrimitive(value, type, false) ?? null);
2460
+ }
2194
2461
  }
2195
2462
  _unary(expr2, context) {
2196
- invariant5(expr2.op === "!", 'only "!" operator is supported');
2463
+ invariant6(expr2.op === "!", 'only "!" operator is supported');
2197
2464
  return logicalNot(this.dialect, this.transform(expr2.operand, context));
2198
2465
  }
2199
2466
  transformOperator(op) {
@@ -2205,17 +2472,31 @@ var ExpressionTransformer = class {
2205
2472
  return result.toOperationNode();
2206
2473
  }
2207
2474
  transformCall(expr2, context) {
2208
- const func = this.clientOptions.functions?.[expr2.function];
2475
+ const func = this.getFunctionImpl(expr2.function);
2209
2476
  if (!func) {
2210
2477
  throw new QueryError(`Function not implemented: ${expr2.function}`);
2211
2478
  }
2212
2479
  const eb = expressionBuilder2();
2213
2480
  return func(eb, (expr2.args ?? []).map((arg) => this.transformCallArg(eb, arg, context)), {
2481
+ client: this.client,
2214
2482
  dialect: this.dialect,
2215
2483
  model: context.model,
2484
+ modelAlias: context.alias ?? context.model,
2216
2485
  operation: context.operation
2217
2486
  });
2218
2487
  }
2488
+ getFunctionImpl(functionName) {
2489
+ let func = this.clientOptions.functions?.[functionName];
2490
+ if (!func) {
2491
+ for (const plugin of this.clientOptions.plugins ?? []) {
2492
+ if (plugin.functions?.[functionName]) {
2493
+ func = plugin.functions[functionName];
2494
+ break;
2495
+ }
2496
+ }
2497
+ }
2498
+ return func;
2499
+ }
2219
2500
  transformCallArg(eb, arg, context) {
2220
2501
  if (ExpressionUtils.isLiteral(arg)) {
2221
2502
  return eb.val(arg.value);
@@ -2236,23 +2517,22 @@ var ExpressionTransformer = class {
2236
2517
  if (this.isAuthCall(expr2.receiver)) {
2237
2518
  return this.valueMemberAccess(this.auth, expr2, this.authType);
2238
2519
  }
2239
- invariant5(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
2520
+ invariant6(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
2240
2521
  let members = expr2.members;
2241
2522
  let receiver;
2242
2523
  const { memberFilter, memberSelect, ...restContext } = context;
2243
2524
  if (ExpressionUtils.isThis(expr2.receiver)) {
2244
2525
  if (expr2.members.length === 1) {
2245
- const fieldDef = requireField(this.schema, context.model, expr2.members[0]);
2246
- invariant5(!fieldDef.relation, "this.relation access should have been transformed into relation access");
2247
- return this.createColumnRef(expr2.members[0], restContext);
2526
+ return this._field(ExpressionUtils.field(expr2.members[0]), context);
2527
+ } else {
2528
+ const firstMemberFieldDef = requireField(this.schema, context.model, expr2.members[0]);
2529
+ receiver = this.transformRelationAccess(expr2.members[0], firstMemberFieldDef.type, restContext);
2530
+ members = expr2.members.slice(1);
2248
2531
  }
2249
- const firstMemberFieldDef = requireField(this.schema, context.model, expr2.members[0]);
2250
- receiver = this.transformRelationAccess(expr2.members[0], firstMemberFieldDef.type, restContext);
2251
- members = expr2.members.slice(1);
2252
2532
  } else {
2253
2533
  receiver = this.transform(expr2.receiver, restContext);
2254
2534
  }
2255
- invariant5(SelectQueryNode.is(receiver), "expected receiver to be select query");
2535
+ invariant6(SelectQueryNode.is(receiver), "expected receiver to be select query");
2256
2536
  let startType;
2257
2537
  if (ExpressionUtils.isField(expr2.receiver)) {
2258
2538
  const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
@@ -2281,11 +2561,11 @@ var ExpressionTransformer = class {
2281
2561
  alias: void 0
2282
2562
  });
2283
2563
  if (currNode) {
2284
- invariant5(SelectQueryNode.is(currNode), "expected select query node");
2564
+ invariant6(SelectQueryNode.is(currNode), "expected select query node");
2285
2565
  currNode = {
2286
2566
  ...relation,
2287
2567
  selections: [
2288
- SelectionNode.create(AliasNode2.create(currNode, IdentifierNode.create(members[i + 1])))
2568
+ SelectionNode.create(AliasNode3.create(currNode, IdentifierNode.create(members[i + 1])))
2289
2569
  ]
2290
2570
  };
2291
2571
  } else {
@@ -2298,15 +2578,15 @@ var ExpressionTransformer = class {
2298
2578
  };
2299
2579
  }
2300
2580
  } else {
2301
- invariant5(i === members.length - 1, "plain field access must be the last segment");
2302
- invariant5(!currNode, "plain field access must be the last segment");
2303
- currNode = ColumnNode.create(member);
2581
+ invariant6(i === members.length - 1, "plain field access must be the last segment");
2582
+ invariant6(!currNode, "plain field access must be the last segment");
2583
+ currNode = ColumnNode2.create(member);
2304
2584
  }
2305
2585
  }
2306
2586
  return {
2307
2587
  ...receiver,
2308
2588
  selections: [
2309
- SelectionNode.create(AliasNode2.create(currNode, IdentifierNode.create("$t")))
2589
+ SelectionNode.create(AliasNode3.create(currNode, IdentifierNode.create("$t")))
2310
2590
  ]
2311
2591
  };
2312
2592
  }
@@ -2323,24 +2603,33 @@ var ExpressionTransformer = class {
2323
2603
  return this.transformValue(fieldValue, fieldDef.type);
2324
2604
  }
2325
2605
  transformRelationAccess(field, relationModel, context) {
2606
+ const m2m = getManyToManyRelation(this.schema, context.model, field);
2607
+ if (m2m) {
2608
+ return this.transformManyToManyRelationAccess(m2m, context);
2609
+ }
2326
2610
  const fromModel = context.model;
2327
2611
  const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, fromModel, field);
2328
2612
  let condition;
2329
2613
  if (ownedByModel) {
2330
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => BinaryOperationNode2.create(ReferenceNode2.create(ColumnNode.create(fk), TableNode2.create(context.alias ?? fromModel)), OperatorNode2.create("="), ReferenceNode2.create(ColumnNode.create(pk), TableNode2.create(relationModel)))));
2614
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => BinaryOperationNode2.create(ReferenceNode3.create(ColumnNode2.create(fk), TableNode3.create(context.alias ?? fromModel)), OperatorNode2.create("="), ReferenceNode3.create(ColumnNode2.create(pk), TableNode3.create(relationModel)))));
2331
2615
  } else {
2332
- condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => BinaryOperationNode2.create(ReferenceNode2.create(ColumnNode.create(pk), TableNode2.create(context.alias ?? fromModel)), OperatorNode2.create("="), ReferenceNode2.create(ColumnNode.create(fk), TableNode2.create(relationModel)))));
2616
+ condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => BinaryOperationNode2.create(ReferenceNode3.create(ColumnNode2.create(pk), TableNode3.create(context.alias ?? fromModel)), OperatorNode2.create("="), ReferenceNode3.create(ColumnNode2.create(fk), TableNode3.create(relationModel)))));
2333
2617
  }
2334
2618
  return {
2335
2619
  kind: "SelectQueryNode",
2336
2620
  from: FromNode.create([
2337
- TableNode2.create(relationModel)
2621
+ TableNode3.create(relationModel)
2338
2622
  ]),
2339
2623
  where: WhereNode.create(condition)
2340
2624
  };
2341
2625
  }
2626
+ transformManyToManyRelationAccess(m2m, context) {
2627
+ const eb = expressionBuilder2();
2628
+ const relationQuery = eb.selectFrom(m2m.otherModel).innerJoin(m2m.joinTable, (join) => join.onRef(`${m2m.otherModel}.${m2m.otherPKName}`, "=", `${m2m.joinTable}.${m2m.otherFkName}`).onRef(`${m2m.joinTable}.${m2m.parentFkName}`, "=", `${context.alias ?? context.model}.${m2m.parentPKName}`));
2629
+ return relationQuery.toOperationNode();
2630
+ }
2342
2631
  createColumnRef(column, context) {
2343
- return ReferenceNode2.create(ColumnNode.create(column), TableNode2.create(context.alias ?? context.model));
2632
+ return ReferenceNode3.create(ColumnNode2.create(column), TableNode3.create(context.alias ?? context.model));
2344
2633
  }
2345
2634
  isAuthCall(value) {
2346
2635
  return ExpressionUtils.isCall(value) && value.function === "auth";
@@ -2363,6 +2652,19 @@ var ExpressionTransformer = class {
2363
2652
  return conditions.reduce((acc, condition) => ExpressionUtils.binary(acc, "&&", condition));
2364
2653
  }
2365
2654
  }
2655
+ isRelationField(expr2, model) {
2656
+ const fieldDef = this.getFieldDefFromFieldRef(expr2, model);
2657
+ return !!fieldDef?.relation;
2658
+ }
2659
+ getFieldDefFromFieldRef(expr2, model) {
2660
+ if (ExpressionUtils.isField(expr2)) {
2661
+ return requireField(this.schema, model, expr2.field);
2662
+ } else if (ExpressionUtils.isMember(expr2) && expr2.members.length === 1 && ExpressionUtils.isThis(expr2.receiver)) {
2663
+ return requireField(this.schema, model, expr2.members[0]);
2664
+ } else {
2665
+ return void 0;
2666
+ }
2667
+ }
2366
2668
  };
2367
2669
  _ts_decorate([
2368
2670
  expr("literal"),
@@ -2449,86 +2751,249 @@ var PolicyHandler = class extends OperationNodeTransformer {
2449
2751
  }
2450
2752
  async handle(node, proceed) {
2451
2753
  if (!this.isCrudQueryNode(node)) {
2452
- throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
2754
+ throw new RejectedByPolicyError(void 0, RejectedByPolicyReason.OTHER, "non-CRUD queries are not allowed");
2453
2755
  }
2454
2756
  if (!this.isMutationQueryNode(node)) {
2455
2757
  return proceed(this.transformNode(node));
2456
2758
  }
2457
- let mutationRequiresTransaction = false;
2458
- const mutationModel = this.getMutationModel(node);
2759
+ const { mutationModel } = this.getMutationModel(node);
2459
2760
  if (InsertQueryNode.is(node)) {
2460
- const constCondition = this.tryGetConstantPolicy(mutationModel, "create");
2461
- if (constCondition === false) {
2462
- throw new RejectedByPolicyError(mutationModel);
2463
- } else if (constCondition === void 0) {
2464
- mutationRequiresTransaction = true;
2761
+ const isManyToManyJoinTable = this.isManyToManyJoinTable(mutationModel);
2762
+ let needCheckPreCreate = true;
2763
+ if (!isManyToManyJoinTable) {
2764
+ const constCondition = this.tryGetConstantPolicy(mutationModel, "create");
2765
+ if (constCondition === true) {
2766
+ needCheckPreCreate = false;
2767
+ } else if (constCondition === false) {
2768
+ throw new RejectedByPolicyError(mutationModel);
2769
+ }
2770
+ }
2771
+ if (needCheckPreCreate) {
2772
+ await this.enforcePreCreatePolicy(node, mutationModel, isManyToManyJoinTable, proceed);
2465
2773
  }
2466
2774
  }
2467
- if (!mutationRequiresTransaction && !node.returning) {
2468
- return proceed(this.transformNode(node));
2469
- }
2470
- if (InsertQueryNode.is(node)) {
2471
- await this.enforcePreCreatePolicy(node, proceed);
2472
- }
2473
- const transformedNode = this.transformNode(node);
2474
- const result = await proceed(transformedNode);
2475
- if (!this.onlyReturningId(node)) {
2775
+ const result = await proceed(this.transformNode(node));
2776
+ if (!node.returning || this.onlyReturningId(node)) {
2777
+ return result;
2778
+ } else {
2476
2779
  const readBackResult = await this.processReadBack(node, result, proceed);
2477
2780
  if (readBackResult.rows.length !== result.rows.length) {
2478
- throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
2781
+ throw new RejectedByPolicyError(mutationModel, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
2479
2782
  }
2480
2783
  return readBackResult;
2481
- } else {
2784
+ }
2785
+ }
2786
+ // #region overrides
2787
+ transformSelectQuery(node) {
2788
+ let whereNode = this.transformNode(node.where);
2789
+ const policyFilter = this.createPolicyFilterForFrom(node.from);
2790
+ if (policyFilter) {
2791
+ whereNode = WhereNode2.create(whereNode?.where ? conjunction(this.dialect, [
2792
+ whereNode.where,
2793
+ policyFilter
2794
+ ]) : policyFilter);
2795
+ }
2796
+ const baseResult = super.transformSelectQuery({
2797
+ ...node,
2798
+ where: void 0
2799
+ });
2800
+ return {
2801
+ ...baseResult,
2802
+ where: whereNode
2803
+ };
2804
+ }
2805
+ transformJoin(node) {
2806
+ const table = this.extractTableName(node.table);
2807
+ if (!table) {
2808
+ return super.transformJoin(node);
2809
+ }
2810
+ const filter = this.buildPolicyFilter(table.model, table.alias, "read");
2811
+ const nestedSelect = {
2812
+ kind: "SelectQueryNode",
2813
+ from: FromNode2.create([
2814
+ node.table
2815
+ ]),
2816
+ selections: [
2817
+ SelectionNode2.createSelectAll()
2818
+ ],
2819
+ where: WhereNode2.create(filter)
2820
+ };
2821
+ return {
2822
+ ...node,
2823
+ table: AliasNode4.create(ParensNode2.create(nestedSelect), IdentifierNode2.create(table.alias ?? table.model))
2824
+ };
2825
+ }
2826
+ transformInsertQuery(node) {
2827
+ let onConflict = node.onConflict;
2828
+ if (onConflict?.updates) {
2829
+ const { mutationModel, alias } = this.getMutationModel(node);
2830
+ const filter = this.buildPolicyFilter(mutationModel, alias, "update");
2831
+ if (onConflict.updateWhere) {
2832
+ onConflict = {
2833
+ ...onConflict,
2834
+ updateWhere: WhereNode2.create(conjunction(this.dialect, [
2835
+ onConflict.updateWhere.where,
2836
+ filter
2837
+ ]))
2838
+ };
2839
+ } else {
2840
+ onConflict = {
2841
+ ...onConflict,
2842
+ updateWhere: WhereNode2.create(filter)
2843
+ };
2844
+ }
2845
+ }
2846
+ const processedNode = onConflict ? {
2847
+ ...node,
2848
+ onConflict
2849
+ } : node;
2850
+ const result = super.transformInsertQuery(processedNode);
2851
+ if (!node.returning) {
2482
2852
  return result;
2483
2853
  }
2854
+ if (this.onlyReturningId(node)) {
2855
+ return result;
2856
+ } else {
2857
+ const { mutationModel } = this.getMutationModel(node);
2858
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
2859
+ return {
2860
+ ...result,
2861
+ returning: ReturningNode.create(idFields.map((field) => SelectionNode2.create(ColumnNode3.create(field))))
2862
+ };
2863
+ }
2484
2864
  }
2865
+ transformUpdateQuery(node) {
2866
+ const result = super.transformUpdateQuery(node);
2867
+ const { mutationModel, alias } = this.getMutationModel(node);
2868
+ let filter = this.buildPolicyFilter(mutationModel, alias, "update");
2869
+ if (node.from) {
2870
+ const joinFilter = this.createPolicyFilterForFrom(node.from);
2871
+ if (joinFilter) {
2872
+ filter = conjunction(this.dialect, [
2873
+ filter,
2874
+ joinFilter
2875
+ ]);
2876
+ }
2877
+ }
2878
+ return {
2879
+ ...result,
2880
+ where: WhereNode2.create(result.where ? conjunction(this.dialect, [
2881
+ result.where.where,
2882
+ filter
2883
+ ]) : filter)
2884
+ };
2885
+ }
2886
+ transformDeleteQuery(node) {
2887
+ const result = super.transformDeleteQuery(node);
2888
+ const { mutationModel, alias } = this.getMutationModel(node);
2889
+ let filter = this.buildPolicyFilter(mutationModel, alias, "delete");
2890
+ if (node.using) {
2891
+ const joinFilter = this.createPolicyFilterForTables(node.using.tables);
2892
+ if (joinFilter) {
2893
+ filter = conjunction(this.dialect, [
2894
+ filter,
2895
+ joinFilter
2896
+ ]);
2897
+ }
2898
+ }
2899
+ return {
2900
+ ...result,
2901
+ where: WhereNode2.create(result.where ? conjunction(this.dialect, [
2902
+ result.where.where,
2903
+ filter
2904
+ ]) : filter)
2905
+ };
2906
+ }
2907
+ // #endregion
2908
+ // #region helpers
2485
2909
  onlyReturningId(node) {
2486
2910
  if (!node.returning) {
2487
2911
  return true;
2488
2912
  }
2489
- const idFields = getIdFields(this.client.$schema, this.getMutationModel(node));
2913
+ const { mutationModel } = this.getMutationModel(node);
2914
+ const idFields = requireIdFields(this.client.$schema, mutationModel);
2490
2915
  const collector = new ColumnCollector();
2491
2916
  const selectedColumns = collector.collect(node.returning);
2492
2917
  return selectedColumns.every((c) => idFields.includes(c));
2493
2918
  }
2494
- async enforcePreCreatePolicy(node, proceed) {
2495
- const model = this.getMutationModel(node);
2919
+ async enforcePreCreatePolicy(node, mutationModel, isManyToManyJoinTable, proceed) {
2496
2920
  const fields = node.columns?.map((c) => c.column.name) ?? [];
2497
- const valueRows = node.values ? this.unwrapCreateValueRows(node.values, model, fields) : [
2921
+ const valueRows = node.values ? this.unwrapCreateValueRows(node.values, mutationModel, fields, isManyToManyJoinTable) : [
2498
2922
  []
2499
2923
  ];
2500
2924
  for (const values of valueRows) {
2501
- await this.enforcePreCreatePolicyForOne(model, fields, values.map((v) => v.node), proceed);
2925
+ if (isManyToManyJoinTable) {
2926
+ await this.enforcePreCreatePolicyForManyToManyJoinTable(mutationModel, fields, values.map((v) => v.node), proceed);
2927
+ } else {
2928
+ await this.enforcePreCreatePolicyForOne(mutationModel, fields, values.map((v) => v.node), proceed);
2929
+ }
2930
+ }
2931
+ }
2932
+ async enforcePreCreatePolicyForManyToManyJoinTable(tableName, fields, values, proceed) {
2933
+ const m2m = this.resolveManyToManyJoinTable(tableName);
2934
+ invariant7(m2m);
2935
+ invariant7(fields.includes("A") && fields.includes("B"), "many-to-many join table must have A and B fk fields");
2936
+ const aIndex = fields.indexOf("A");
2937
+ const aNode = values[aIndex];
2938
+ const bIndex = fields.indexOf("B");
2939
+ const bNode = values[bIndex];
2940
+ invariant7(ValueNode3.is(aNode) && ValueNode3.is(bNode), "A and B values must be ValueNode");
2941
+ const aValue = aNode.value;
2942
+ const bValue = bNode.value;
2943
+ invariant7(aValue !== null && aValue !== void 0, "A value cannot be null or undefined");
2944
+ invariant7(bValue !== null && bValue !== void 0, "B value cannot be null or undefined");
2945
+ const eb = expressionBuilder3();
2946
+ const filterA = this.buildPolicyFilter(m2m.firstModel, void 0, "update");
2947
+ const queryA = eb.selectFrom(m2m.firstModel).where(eb(eb.ref(`${m2m.firstModel}.${m2m.firstIdField}`), "=", aValue)).select(() => new ExpressionWrapper(filterA).as("$t"));
2948
+ const filterB = this.buildPolicyFilter(m2m.secondModel, void 0, "update");
2949
+ const queryB = eb.selectFrom(m2m.secondModel).where(eb(eb.ref(`${m2m.secondModel}.${m2m.secondIdField}`), "=", bValue)).select(() => new ExpressionWrapper(filterB).as("$t"));
2950
+ const queryNode = {
2951
+ kind: "SelectQueryNode",
2952
+ selections: [
2953
+ SelectionNode2.create(AliasNode4.create(queryA.toOperationNode(), IdentifierNode2.create("$conditionA"))),
2954
+ SelectionNode2.create(AliasNode4.create(queryB.toOperationNode(), IdentifierNode2.create("$conditionB")))
2955
+ ]
2956
+ };
2957
+ const result = await proceed(queryNode);
2958
+ if (!result.rows[0]?.$conditionA) {
2959
+ throw new RejectedByPolicyError(m2m.firstModel, RejectedByPolicyReason.CANNOT_READ_BACK, `many-to-many relation participant model "${m2m.firstModel}" not updatable`);
2960
+ }
2961
+ if (!result.rows[0]?.$conditionB) {
2962
+ throw new RejectedByPolicyError(m2m.secondModel, RejectedByPolicyReason.NO_ACCESS, `many-to-many relation participant model "${m2m.secondModel}" not updatable`);
2502
2963
  }
2503
2964
  }
2504
2965
  async enforcePreCreatePolicyForOne(model, fields, values, proceed) {
2505
- const allFields = Object.keys(requireModel(this.client.$schema, model).fields);
2966
+ const allFields = Object.entries(requireModel(this.client.$schema, model).fields).filter(([, def]) => !def.relation);
2506
2967
  const allValues = [];
2507
- for (const fieldName of allFields) {
2508
- const index = fields.indexOf(fieldName);
2968
+ for (const [name, _def] of allFields) {
2969
+ const index = fields.indexOf(name);
2509
2970
  if (index >= 0) {
2510
2971
  allValues.push(values[index]);
2511
2972
  } else {
2512
2973
  allValues.push(ValueNode3.createImmediate(null));
2513
2974
  }
2514
2975
  }
2976
+ const eb = expressionBuilder3();
2515
2977
  const constTable = {
2516
2978
  kind: "SelectQueryNode",
2517
2979
  from: FromNode2.create([
2518
- AliasNode3.create(ParensNode2.create(ValuesNode.create([
2980
+ AliasNode4.create(ParensNode2.create(ValuesNode.create([
2519
2981
  ValueListNode2.create(allValues)
2520
2982
  ])), IdentifierNode2.create("$t"))
2521
2983
  ]),
2522
- selections: allFields.map((field, index) => SelectionNode2.create(AliasNode3.create(ColumnNode2.create(`column${index + 1}`), IdentifierNode2.create(field))))
2984
+ selections: allFields.map(([name, def], index) => {
2985
+ const castedColumnRef = sql4`CAST(${eb.ref(`column${index + 1}`)} as ${sql4.raw(this.dialect.getFieldSqlType(def))})`.as(name);
2986
+ return SelectionNode2.create(castedColumnRef.toOperationNode());
2987
+ })
2523
2988
  };
2524
2989
  const filter = this.buildPolicyFilter(model, void 0, "create");
2525
2990
  const preCreateCheck = {
2526
2991
  kind: "SelectQueryNode",
2527
2992
  from: FromNode2.create([
2528
- AliasNode3.create(constTable, IdentifierNode2.create(model))
2993
+ AliasNode4.create(constTable, IdentifierNode2.create(model))
2529
2994
  ]),
2530
2995
  selections: [
2531
- SelectionNode2.create(AliasNode3.create(BinaryOperationNode3.create(FunctionNode3.create("COUNT", [
2996
+ SelectionNode2.create(AliasNode4.create(BinaryOperationNode3.create(FunctionNode3.create("COUNT", [
2532
2997
  ValueNode3.createImmediate(1)
2533
2998
  ]), OperatorNode3.create(">"), ValueNode3.createImmediate(0)), IdentifierNode2.create("$condition")))
2534
2999
  ],
@@ -2539,31 +3004,35 @@ var PolicyHandler = class extends OperationNodeTransformer {
2539
3004
  throw new RejectedByPolicyError(model);
2540
3005
  }
2541
3006
  }
2542
- unwrapCreateValueRows(node, model, fields) {
3007
+ unwrapCreateValueRows(node, model, fields, isManyToManyJoinTable) {
2543
3008
  if (ValuesNode.is(node)) {
2544
- return node.values.map((v) => this.unwrapCreateValueRow(v.values, model, fields));
3009
+ return node.values.map((v) => this.unwrapCreateValueRow(v.values, model, fields, isManyToManyJoinTable));
2545
3010
  } else if (PrimitiveValueListNode.is(node)) {
2546
3011
  return [
2547
- this.unwrapCreateValueRow(node.values, model, fields)
3012
+ this.unwrapCreateValueRow(node.values, model, fields, isManyToManyJoinTable)
2548
3013
  ];
2549
3014
  } else {
2550
3015
  throw new InternalError(`Unexpected node kind: ${node.kind} for unwrapping create values`);
2551
3016
  }
2552
3017
  }
2553
- unwrapCreateValueRow(data, model, fields) {
2554
- invariant6(data.length === fields.length, "data length must match fields length");
3018
+ unwrapCreateValueRow(data, model, fields, isImplicitManyToManyJoinTable) {
3019
+ invariant7(data.length === fields.length, "data length must match fields length");
2555
3020
  const result = [];
2556
3021
  for (let i = 0; i < data.length; i++) {
2557
3022
  const item = data[i];
2558
- const fieldDef = requireField(this.client.$schema, model, fields[i]);
2559
3023
  if (typeof item === "object" && item && "kind" in item) {
2560
- invariant6(item.kind === "ValueNode", "expecting a ValueNode");
3024
+ const fieldDef = requireField(this.client.$schema, model, fields[i]);
3025
+ invariant7(item.kind === "ValueNode", "expecting a ValueNode");
2561
3026
  result.push({
2562
3027
  node: ValueNode3.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
2563
3028
  raw: item.value
2564
3029
  });
2565
3030
  } else {
2566
- const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
3031
+ let value = item;
3032
+ if (!isImplicitManyToManyJoinTable) {
3033
+ const fieldDef = requireField(this.client.$schema, model, fields[i]);
3034
+ value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
3035
+ }
2567
3036
  if (Array.isArray(value)) {
2568
3037
  result.push({
2569
3038
  node: RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
@@ -2607,16 +3076,13 @@ var PolicyHandler = class extends OperationNodeTransformer {
2607
3076
  if (!this.isMutationQueryNode(node) || !node.returning) {
2608
3077
  return result;
2609
3078
  }
2610
- const table = this.getMutationModel(node);
2611
- if (!table) {
2612
- throw new InternalError(`Unable to get table name for query node: ${node}`);
2613
- }
2614
- const idConditions = this.buildIdConditions(table, result.rows);
2615
- const policyFilter = this.buildPolicyFilter(table, void 0, "read");
3079
+ const { mutationModel } = this.getMutationModel(node);
3080
+ const idConditions = this.buildIdConditions(mutationModel, result.rows);
3081
+ const policyFilter = this.buildPolicyFilter(mutationModel, void 0, "read");
2616
3082
  const select = {
2617
3083
  kind: "SelectQueryNode",
2618
3084
  from: FromNode2.create([
2619
- TableNode3.create(table)
3085
+ TableNode4.create(mutationModel)
2620
3086
  ]),
2621
3087
  where: WhereNode2.create(conjunction(this.dialect, [
2622
3088
  idConditions,
@@ -2628,15 +3094,31 @@ var PolicyHandler = class extends OperationNodeTransformer {
2628
3094
  return selectResult;
2629
3095
  }
2630
3096
  buildIdConditions(table, rows) {
2631
- const idFields = getIdFields(this.client.$schema, table);
2632
- return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => BinaryOperationNode3.create(ColumnNode2.create(field), OperatorNode3.create("="), ValueNode3.create(row[field]))))));
3097
+ const idFields = requireIdFields(this.client.$schema, table);
3098
+ return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => BinaryOperationNode3.create(ColumnNode3.create(field), OperatorNode3.create("="), ValueNode3.create(row[field]))))));
2633
3099
  }
2634
3100
  getMutationModel(node) {
2635
- const r = match8(node).when(InsertQueryNode.is, (node2) => getTableName(node2.into)).when(UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(DeleteQueryNode.is, (node2) => {
3101
+ const r = match8(node).when(InsertQueryNode.is, (node2) => ({
3102
+ mutationModel: getTableName(node2.into),
3103
+ alias: void 0
3104
+ })).when(UpdateQueryNode.is, (node2) => {
3105
+ if (!node2.table) {
3106
+ throw new QueryError("Update query must have a table");
3107
+ }
3108
+ const r2 = this.extractTableName(node2.table);
3109
+ return r2 ? {
3110
+ mutationModel: r2.model,
3111
+ alias: r2.alias
3112
+ } : void 0;
3113
+ }).when(DeleteQueryNode.is, (node2) => {
2636
3114
  if (node2.from.froms.length !== 1) {
2637
- throw new InternalError("Only one from table is supported for delete");
3115
+ throw new QueryError("Only one from table is supported for delete");
2638
3116
  }
2639
- return getTableName(node2.from.froms[0]);
3117
+ const r2 = this.extractTableName(node2.from.froms[0]);
3118
+ return r2 ? {
3119
+ mutationModel: r2.model,
3120
+ alias: r2.alias
3121
+ } : void 0;
2640
3122
  }).exhaustive();
2641
3123
  if (!r) {
2642
3124
  throw new InternalError(`Unable to get table name for query node: ${node}`);
@@ -2650,12 +3132,16 @@ var PolicyHandler = class extends OperationNodeTransformer {
2650
3132
  return InsertQueryNode.is(node) || UpdateQueryNode.is(node) || DeleteQueryNode.is(node);
2651
3133
  }
2652
3134
  buildPolicyFilter(model, alias, operation) {
3135
+ const m2mFilter = this.getModelPolicyFilterForManyToManyJoinTable(model, alias, operation);
3136
+ if (m2mFilter) {
3137
+ return m2mFilter;
3138
+ }
2653
3139
  const policies = this.getModelPolicies(model, operation);
2654
3140
  if (policies.length === 0) {
2655
3141
  return falseNode(this.dialect);
2656
3142
  }
2657
- const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.transformPolicyCondition(model, alias, operation, policy));
2658
- const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.transformPolicyCondition(model, alias, operation, policy));
3143
+ const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
3144
+ const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.compilePolicyCondition(model, alias, operation, policy));
2659
3145
  let combinedPolicy;
2660
3146
  if (allows.length === 0) {
2661
3147
  combinedPolicy = falseNode(this.dialect);
@@ -2671,100 +3157,59 @@ var PolicyHandler = class extends OperationNodeTransformer {
2671
3157
  }
2672
3158
  return combinedPolicy;
2673
3159
  }
2674
- transformSelectQuery(node) {
2675
- let whereNode = node.where;
2676
- node.from?.froms.forEach((from) => {
2677
- const extractResult = this.extractTableName(from);
2678
- if (extractResult) {
2679
- const { model, alias } = extractResult;
2680
- const filter = this.buildPolicyFilter(model, alias, "read");
2681
- whereNode = WhereNode2.create(whereNode?.where ? conjunction(this.dialect, [
2682
- whereNode.where,
2683
- filter
2684
- ]) : filter);
2685
- }
2686
- });
2687
- const baseResult = super.transformSelectQuery({
2688
- ...node,
2689
- where: void 0
2690
- });
2691
- return {
2692
- ...baseResult,
2693
- where: whereNode
2694
- };
2695
- }
2696
- transformInsertQuery(node) {
2697
- const result = super.transformInsertQuery(node);
2698
- if (!node.returning) {
2699
- return result;
2700
- }
2701
- if (this.onlyReturningId(node)) {
2702
- return result;
2703
- } else {
2704
- const idFields = getIdFields(this.client.$schema, this.getMutationModel(node));
2705
- return {
2706
- ...result,
2707
- returning: ReturningNode.create(idFields.map((field) => SelectionNode2.create(ColumnNode2.create(field))))
2708
- };
2709
- }
2710
- }
2711
- transformUpdateQuery(node) {
2712
- const result = super.transformUpdateQuery(node);
2713
- const mutationModel = this.getMutationModel(node);
2714
- const filter = this.buildPolicyFilter(mutationModel, void 0, "update");
2715
- return {
2716
- ...result,
2717
- where: WhereNode2.create(result.where ? conjunction(this.dialect, [
2718
- result.where.where,
2719
- filter
2720
- ]) : filter)
2721
- };
2722
- }
2723
- transformDeleteQuery(node) {
2724
- const result = super.transformDeleteQuery(node);
2725
- const mutationModel = this.getMutationModel(node);
2726
- const filter = this.buildPolicyFilter(mutationModel, void 0, "delete");
2727
- return {
2728
- ...result,
2729
- where: WhereNode2.create(result.where ? conjunction(this.dialect, [
2730
- result.where.where,
2731
- filter
2732
- ]) : filter)
2733
- };
2734
- }
2735
- extractTableName(from) {
2736
- if (TableNode3.is(from)) {
3160
+ extractTableName(node) {
3161
+ if (TableNode4.is(node)) {
2737
3162
  return {
2738
- model: from.table.identifier.name
3163
+ model: node.table.identifier.name
2739
3164
  };
2740
3165
  }
2741
- if (AliasNode3.is(from)) {
2742
- const inner = this.extractTableName(from.node);
3166
+ if (AliasNode4.is(node)) {
3167
+ const inner = this.extractTableName(node.node);
2743
3168
  if (!inner) {
2744
3169
  return void 0;
2745
3170
  }
2746
3171
  return {
2747
3172
  model: inner.model,
2748
- alias: IdentifierNode2.is(from.alias) ? from.alias.name : void 0
3173
+ alias: IdentifierNode2.is(node.alias) ? node.alias.name : void 0
2749
3174
  };
2750
3175
  } else {
2751
3176
  return void 0;
2752
3177
  }
2753
3178
  }
2754
- transformPolicyCondition(model, alias, operation, policy) {
2755
- return new ExpressionTransformer(this.client.$schema, this.client.$options, this.client.$auth).transform(policy.condition, {
3179
+ createPolicyFilterForFrom(node) {
3180
+ if (!node) {
3181
+ return void 0;
3182
+ }
3183
+ return this.createPolicyFilterForTables(node.froms);
3184
+ }
3185
+ createPolicyFilterForTables(tables) {
3186
+ return tables.reduce((acc, table) => {
3187
+ const extractResult = this.extractTableName(table);
3188
+ if (extractResult) {
3189
+ const { model, alias } = extractResult;
3190
+ const filter = this.buildPolicyFilter(model, alias, "read");
3191
+ return acc ? conjunction(this.dialect, [
3192
+ acc,
3193
+ filter
3194
+ ]) : filter;
3195
+ }
3196
+ return acc;
3197
+ }, void 0);
3198
+ }
3199
+ compilePolicyCondition(model, alias, operation, policy) {
3200
+ return new ExpressionTransformer(this.client).transform(policy.condition, {
2756
3201
  model,
2757
3202
  alias,
2758
3203
  operation,
2759
3204
  auth: this.client.$auth
2760
3205
  });
2761
3206
  }
2762
- getModelPolicies(modelName, operation) {
2763
- const modelDef = requireModel(this.client.$schema, modelName);
3207
+ getModelPolicies(model, operation) {
3208
+ const modelDef = requireModel(this.client.$schema, model);
2764
3209
  const result = [];
2765
3210
  const extractOperations = /* @__PURE__ */ __name((expr2) => {
2766
- invariant6(ExpressionUtils.isLiteral(expr2), "expecting a literal");
2767
- invariant6(typeof expr2.value === "string", "expecting a string literal");
3211
+ invariant7(ExpressionUtils.isLiteral(expr2), "expecting a literal");
3212
+ invariant7(typeof expr2.value === "string", "expecting a string literal");
2768
3213
  return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
2769
3214
  }, "extractOperations");
2770
3215
  if (modelDef.attributes) {
@@ -2776,8 +3221,84 @@ var PolicyHandler = class extends OperationNodeTransformer {
2776
3221
  }
2777
3222
  return result;
2778
3223
  }
3224
+ resolveManyToManyJoinTable(tableName) {
3225
+ for (const model of Object.values(this.client.$schema.models)) {
3226
+ for (const field of Object.values(model.fields)) {
3227
+ const m2m = getManyToManyRelation(this.client.$schema, model.name, field.name);
3228
+ if (m2m?.joinTable === tableName) {
3229
+ const sortedRecord = [
3230
+ {
3231
+ model: model.name,
3232
+ field: field.name
3233
+ },
3234
+ {
3235
+ model: m2m.otherModel,
3236
+ field: m2m.otherField
3237
+ }
3238
+ ].sort(this.manyToManySorter);
3239
+ const firstIdFields = requireIdFields(this.client.$schema, sortedRecord[0].model);
3240
+ const secondIdFields = requireIdFields(this.client.$schema, sortedRecord[1].model);
3241
+ invariant7(firstIdFields.length === 1 && secondIdFields.length === 1, "only single-field id is supported for implicit many-to-many join table");
3242
+ return {
3243
+ firstModel: sortedRecord[0].model,
3244
+ firstField: sortedRecord[0].field,
3245
+ firstIdField: firstIdFields[0],
3246
+ secondModel: sortedRecord[1].model,
3247
+ secondField: sortedRecord[1].field,
3248
+ secondIdField: secondIdFields[0]
3249
+ };
3250
+ }
3251
+ }
3252
+ }
3253
+ return void 0;
3254
+ }
3255
+ manyToManySorter(a, b) {
3256
+ return a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field);
3257
+ }
3258
+ isManyToManyJoinTable(tableName) {
3259
+ return !!this.resolveManyToManyJoinTable(tableName);
3260
+ }
3261
+ getModelPolicyFilterForManyToManyJoinTable(tableName, alias, operation) {
3262
+ const m2m = this.resolveManyToManyJoinTable(tableName);
3263
+ if (!m2m) {
3264
+ return void 0;
3265
+ }
3266
+ const checkForOperation = operation === "read" ? "read" : "update";
3267
+ const eb = expressionBuilder3();
3268
+ const joinTable = alias ?? tableName;
3269
+ const aQuery = eb.selectFrom(m2m.firstModel).whereRef(`${m2m.firstModel}.${m2m.firstIdField}`, "=", `${joinTable}.A`).select(() => new ExpressionWrapper(this.buildPolicyFilter(m2m.firstModel, void 0, checkForOperation)).as("$conditionA"));
3270
+ const bQuery = eb.selectFrom(m2m.secondModel).whereRef(`${m2m.secondModel}.${m2m.secondIdField}`, "=", `${joinTable}.B`).select(() => new ExpressionWrapper(this.buildPolicyFilter(m2m.secondModel, void 0, checkForOperation)).as("$conditionB"));
3271
+ return eb.and([
3272
+ aQuery,
3273
+ bQuery
3274
+ ]).toOperationNode();
3275
+ }
2779
3276
  };
2780
3277
 
3278
+ // src/plugins/policy/functions.ts
3279
+ var check = /* @__PURE__ */ __name((eb, args, { client, model, modelAlias, operation }) => {
3280
+ invariant8(args.length === 1 || args.length === 2, '"check" function requires 1 or 2 arguments');
3281
+ const arg1Node = args[0].toOperationNode();
3282
+ const arg2Node = args.length === 2 ? args[1].toOperationNode() : void 0;
3283
+ if (arg2Node) {
3284
+ invariant8(ValueNode4.is(arg2Node) && typeof arg2Node.value === "string", '"operation" parameter must be a string literal when provided');
3285
+ invariant8(CRUD.includes(arg2Node.value), '"operation" parameter must be one of "create", "read", "update", "delete"');
3286
+ }
3287
+ const fieldName = extractFieldName(arg1Node);
3288
+ invariant8(fieldName, 'Failed to extract field name from the first argument of "check" function');
3289
+ const fieldDef = requireField(client.$schema, model, fieldName);
3290
+ invariant8(fieldDef.relation, `Field "${fieldName}" is not a relation field in model "${model}"`);
3291
+ invariant8(!fieldDef.array, `Field "${fieldName}" is a to-many relation, which is not supported by "check"`);
3292
+ const relationModel = fieldDef.type;
3293
+ const op = arg2Node ? arg2Node.value : operation;
3294
+ const policyHandler = new PolicyHandler(client);
3295
+ const joinPairs = buildJoinPairs(client.$schema, model, modelAlias, fieldName, relationModel);
3296
+ const joinCondition = joinPairs.length === 1 ? eb(eb.ref(joinPairs[0][0]), "=", eb.ref(joinPairs[0][1])) : eb.and(joinPairs.map(([left, right]) => eb(eb.ref(left), "=", eb.ref(right))));
3297
+ const policyCondition = policyHandler.buildPolicyFilter(relationModel, void 0, op);
3298
+ const result = eb.selectFrom(relationModel).where(joinCondition).select(new ExpressionWrapper2(policyCondition).as("$condition"));
3299
+ return result;
3300
+ }, "check");
3301
+
2781
3302
  // src/plugins/policy/plugin.ts
2782
3303
  var PolicyPlugin = class {
2783
3304
  static {
@@ -2792,6 +3313,11 @@ var PolicyPlugin = class {
2792
3313
  get description() {
2793
3314
  return "Enforces access policies defined in the schema.";
2794
3315
  }
3316
+ get functions() {
3317
+ return {
3318
+ check
3319
+ };
3320
+ }
2795
3321
  onKyselyQuery({
2796
3322
  query,
2797
3323
  client,
@@ -2827,16 +3353,6 @@ function clone(value) {
2827
3353
  }
2828
3354
  __name(clone, "clone");
2829
3355
 
2830
- // src/client/contract.ts
2831
- var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
2832
- TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
2833
- TransactionIsolationLevel2["ReadCommitted"] = "read committed";
2834
- TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
2835
- TransactionIsolationLevel2["Serializable"] = "serializable";
2836
- TransactionIsolationLevel2["Snapshot"] = "snapshot";
2837
- return TransactionIsolationLevel2;
2838
- }({});
2839
-
2840
3356
  // src/client/crud/operations/base.ts
2841
3357
  var BaseOperationHandler = class {
2842
3358
  static {
@@ -2881,7 +3397,7 @@ var BaseOperationHandler = class {
2881
3397
  return getField(this.schema, model, field);
2882
3398
  }
2883
3399
  async exists(kysely, model, filter) {
2884
- const idFields = getIdFields(this.schema, model);
3400
+ const idFields = requireIdFields(this.schema, model);
2885
3401
  const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
2886
3402
  const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
2887
3403
  model,
@@ -2890,7 +3406,7 @@ var BaseOperationHandler = class {
2890
3406
  return this.executeQueryTakeFirst(kysely, query, "exists");
2891
3407
  }
2892
3408
  async read(kysely, model, args) {
2893
- let query = this.dialect.buildSelectModel(expressionBuilder3(), model, model);
3409
+ let query = this.dialect.buildSelectModel(expressionBuilder4(), model, model);
2894
3410
  if (args) {
2895
3411
  query = this.dialect.buildFilterSortTake(model, args, query, model);
2896
3412
  }
@@ -2969,7 +3485,7 @@ var BaseOperationHandler = class {
2969
3485
  if (!m2m) {
2970
3486
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation?.model ?? "", fromRelation?.field ?? "");
2971
3487
  if (!ownedByModel) {
2972
- const parentFkFields = this.buildFkAssignments(fromRelation.model, fromRelation.field, fromRelation.ids);
3488
+ const parentFkFields = await this.buildFkAssignments(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
2973
3489
  Object.assign(createFields, parentFkFields);
2974
3490
  } else {
2975
3491
  updateParent = /* @__PURE__ */ __name((entity) => {
@@ -3009,17 +3525,16 @@ var BaseOperationHandler = class {
3009
3525
  createFields = baseCreateResult.remainingFields;
3010
3526
  }
3011
3527
  const updatedData = this.fillGeneratedAndDefaultValues(modelDef, createFields);
3012
- const idFields = getIdFields(this.schema, model);
3528
+ const idFields = requireIdFields(this.schema, model);
3013
3529
  const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(idFields).modifyEnd(this.makeContextComment({
3014
3530
  model,
3015
3531
  operation: "create"
3016
3532
  }));
3017
3533
  const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
3018
3534
  if (Object.keys(postCreateRelations).length > 0) {
3019
- const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
3020
- return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
3021
- });
3022
- await Promise.all(relationPromises);
3535
+ for (const [field, subPayload] of Object.entries(postCreateRelations)) {
3536
+ await this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
3537
+ }
3023
3538
  }
3024
3539
  if (fromRelation && m2m) {
3025
3540
  await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, createdEntity, m2m.joinTable);
@@ -3041,7 +3556,7 @@ var BaseOperationHandler = class {
3041
3556
  }
3042
3557
  });
3043
3558
  const discriminatorField = getDiscriminatorField(this.schema, model);
3044
- invariant7(discriminatorField, `Base model "${model}" must have a discriminator field`);
3559
+ invariant9(discriminatorField, `Base model "${model}" must have a discriminator field`);
3045
3560
  thisCreateFields[discriminatorField] = forModel;
3046
3561
  const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
3047
3562
  const idValues = extractIdFields(baseEntity, this.schema, model);
@@ -3051,14 +3566,24 @@ var BaseOperationHandler = class {
3051
3566
  remainingFields
3052
3567
  };
3053
3568
  }
3054
- buildFkAssignments(model, relationField, entity) {
3569
+ async buildFkAssignments(kysely, model, relationField, entity) {
3055
3570
  const parentFkFields = {};
3056
- invariant7(relationField, "parentField must be defined if parentModel is defined");
3057
- invariant7(entity, "parentEntity must be defined if parentModel is defined");
3571
+ invariant9(relationField, "parentField must be defined if parentModel is defined");
3572
+ invariant9(entity, "parentEntity must be defined if parentModel is defined");
3058
3573
  const { keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
3059
3574
  for (const pair of keyPairs) {
3060
3575
  if (!(pair.pk in entity)) {
3061
- throw new QueryError(`Field "${pair.pk}" not found in parent created data`);
3576
+ const extraRead = await this.readUnique(kysely, model, {
3577
+ where: entity,
3578
+ select: {
3579
+ [pair.pk]: true
3580
+ }
3581
+ });
3582
+ if (!extraRead) {
3583
+ throw new QueryError(`Field "${pair.pk}" not found in parent created data`);
3584
+ } else {
3585
+ Object.assign(entity, extraRead);
3586
+ }
3062
3587
  }
3063
3588
  Object.assign(parentFkFields, {
3064
3589
  [pair.fk]: entity[pair.pk]
@@ -3079,15 +3604,15 @@ var BaseOperationHandler = class {
3079
3604
  entity: rightEntity
3080
3605
  }
3081
3606
  ].sort((a, b) => (
3082
- // the implement m2m join table's "A", "B" fk fields' order is determined
3607
+ // the implicit m2m join table's "A", "B" fk fields' order is determined
3083
3608
  // by model name's sort order, and when identical (for self-relations),
3084
3609
  // field name's sort order
3085
3610
  a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
3086
3611
  ));
3087
- const firstIds = getIdFields(this.schema, sortedRecords[0].model);
3088
- const secondIds = getIdFields(this.schema, sortedRecords[1].model);
3089
- invariant7(firstIds.length === 1, "many-to-many relation must have exactly one id field");
3090
- invariant7(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3612
+ const firstIds = requireIdFields(this.schema, sortedRecords[0].model);
3613
+ const secondIds = requireIdFields(this.schema, sortedRecords[1].model);
3614
+ invariant9(firstIds.length === 1, "many-to-many relation must have exactly one id field");
3615
+ invariant9(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3091
3616
  if (action === "connect") {
3092
3617
  const result = await kysely.insertInto(joinTable).values({
3093
3618
  A: sortedRecords[0].entity[firstIds[0]],
@@ -3098,17 +3623,17 @@ var BaseOperationHandler = class {
3098
3623
  ]).doNothing()).execute();
3099
3624
  return result[0];
3100
3625
  } else {
3101
- const eb = expressionBuilder3();
3626
+ const eb = expressionBuilder4();
3102
3627
  const result = await kysely.deleteFrom(joinTable).where(eb(`${joinTable}.A`, "=", sortedRecords[0].entity[firstIds[0]])).where(eb(`${joinTable}.B`, "=", sortedRecords[1].entity[secondIds[0]])).execute();
3103
3628
  return result[0];
3104
3629
  }
3105
3630
  }
3106
3631
  resetManyToManyRelation(kysely, model, field, parentIds) {
3107
- invariant7(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
3632
+ invariant9(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
3108
3633
  const parentId = Object.values(parentIds)[0];
3109
3634
  const m2m = getManyToManyRelation(this.schema, model, field);
3110
- invariant7(m2m, "not a many-to-many relation");
3111
- const eb = expressionBuilder3();
3635
+ invariant9(m2m, "not a many-to-many relation");
3636
+ const eb = expressionBuilder4();
3112
3637
  return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
3113
3638
  }
3114
3639
  async processOwnedRelationForCreate(kysely, relationField, payload) {
@@ -3129,7 +3654,7 @@ var BaseOperationHandler = class {
3129
3654
  }
3130
3655
  case "connect": {
3131
3656
  const referencedPkFields = relationField.relation.references;
3132
- invariant7(referencedPkFields, "relation must have fields info");
3657
+ invariant9(referencedPkFields, "relation must have fields info");
3133
3658
  const extractedFks = extractFields(subPayload, referencedPkFields);
3134
3659
  if (Object.keys(extractedFks).length === referencedPkFields.length) {
3135
3660
  result = extractedFks;
@@ -3161,10 +3686,9 @@ var BaseOperationHandler = class {
3161
3686
  }
3162
3687
  return result;
3163
3688
  }
3164
- processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
3689
+ async processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
3165
3690
  const relationFieldDef = this.requireField(contextModel, relationFieldName);
3166
3691
  const relationModel = relationFieldDef.type;
3167
- const tasks = [];
3168
3692
  const fromRelationContext = {
3169
3693
  model: contextModel,
3170
3694
  field: relationFieldName,
@@ -3177,27 +3701,35 @@ var BaseOperationHandler = class {
3177
3701
  }
3178
3702
  switch (action) {
3179
3703
  case "create": {
3180
- tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, fromRelationContext)));
3704
+ for (const item of enumerate(subPayload)) {
3705
+ await this.create(kysely, relationModel, item, fromRelationContext);
3706
+ }
3181
3707
  break;
3182
3708
  }
3183
3709
  case "createMany": {
3184
- invariant7(relationFieldDef.array, "relation must be an array for createMany");
3185
- tasks.push(this.createMany(kysely, relationModel, subPayload, false, fromRelationContext));
3710
+ invariant9(relationFieldDef.array, "relation must be an array for createMany");
3711
+ await this.createMany(kysely, relationModel, subPayload, false, fromRelationContext);
3186
3712
  break;
3187
3713
  }
3188
3714
  case "connect": {
3189
- tasks.push(this.connectRelation(kysely, relationModel, subPayload, fromRelationContext));
3715
+ await this.connectRelation(kysely, relationModel, subPayload, fromRelationContext);
3190
3716
  break;
3191
3717
  }
3192
3718
  case "connectOrCreate": {
3193
- tasks.push(...enumerate(subPayload).map((item) => this.exists(kysely, relationModel, item.where).then((found) => !found ? this.create(kysely, relationModel, item.create, fromRelationContext) : this.connectRelation(kysely, relationModel, found, fromRelationContext))));
3719
+ for (const item of enumerate(subPayload)) {
3720
+ const found = await this.exists(kysely, relationModel, item.where);
3721
+ if (!found) {
3722
+ await this.create(kysely, relationModel, item.create, fromRelationContext);
3723
+ } else {
3724
+ await this.connectRelation(kysely, relationModel, found, fromRelationContext);
3725
+ }
3726
+ }
3194
3727
  break;
3195
3728
  }
3196
3729
  default:
3197
3730
  throw new QueryError(`Invalid relation action: ${action}`);
3198
3731
  }
3199
3732
  }
3200
- return Promise.all(tasks);
3201
3733
  }
3202
3734
  async createMany(kysely, model, input, returnData, fromRelation) {
3203
3735
  if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
@@ -3218,7 +3750,7 @@ var BaseOperationHandler = class {
3218
3750
  const newItem = {};
3219
3751
  for (const [name, value] of Object.entries(item)) {
3220
3752
  const fieldDef = this.requireField(model, name);
3221
- invariant7(!fieldDef.relation, "createMany does not support relations");
3753
+ invariant9(!fieldDef.relation, "createMany does not support relations");
3222
3754
  newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
3223
3755
  }
3224
3756
  if (fromRelation) {
@@ -3268,7 +3800,7 @@ var BaseOperationHandler = class {
3268
3800
  count: Number(result.numAffectedRows)
3269
3801
  };
3270
3802
  } else {
3271
- const idFields = getIdFields(this.schema, model);
3803
+ const idFields = requireIdFields(this.schema, model);
3272
3804
  const result = await query.returning(idFields).execute();
3273
3805
  return result;
3274
3806
  }
@@ -3277,7 +3809,7 @@ var BaseOperationHandler = class {
3277
3809
  const thisCreateRows = [];
3278
3810
  const remainingFieldRows = [];
3279
3811
  const discriminatorField = getDiscriminatorField(this.schema, model);
3280
- invariant7(discriminatorField, `Base model "${model}" must have a discriminator field`);
3812
+ invariant9(discriminatorField, `Base model "${model}" must have a discriminator field`);
3281
3813
  for (const createFields of createRows) {
3282
3814
  const thisCreateFields = {};
3283
3815
  const remainingFields = {};
@@ -3373,7 +3905,7 @@ var BaseOperationHandler = class {
3373
3905
  }
3374
3906
  } else {
3375
3907
  const fromRelationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3376
- invariant7(fromRelationFieldDef.relation?.opposite);
3908
+ invariant9(fromRelationFieldDef.relation?.opposite);
3377
3909
  parentWhere[fromRelationFieldDef.relation.opposite] = {
3378
3910
  some: fromRelation.ids
3379
3911
  };
@@ -3431,10 +3963,7 @@ var BaseOperationHandler = class {
3431
3963
  throw new QueryError(`Relation update not allowed for field "${field}"`);
3432
3964
  }
3433
3965
  if (!thisEntity) {
3434
- thisEntity = await this.readUnique(kysely, model, {
3435
- where: combinedWhere,
3436
- select: this.makeIdSelect(model)
3437
- });
3966
+ thisEntity = await this.getEntityIds(kysely, model, combinedWhere);
3438
3967
  if (!thisEntity) {
3439
3968
  if (throwIfNotFound) {
3440
3969
  throw new NotFoundError(model);
@@ -3452,7 +3981,7 @@ var BaseOperationHandler = class {
3452
3981
  if (Object.keys(updateFields).length === 0) {
3453
3982
  return combinedWhere;
3454
3983
  } else {
3455
- const idFields = getIdFields(this.schema, model);
3984
+ const idFields = requireIdFields(this.schema, model);
3456
3985
  const query = kysely.updateTable(model).where((eb) => this.dialect.buildFilter(eb, model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
3457
3986
  model,
3458
3987
  operation: "update"
@@ -3497,7 +4026,7 @@ var BaseOperationHandler = class {
3497
4026
  if (!filter || typeof filter !== "object") {
3498
4027
  return false;
3499
4028
  }
3500
- const idFields = getIdFields(this.schema, model);
4029
+ const idFields = requireIdFields(this.schema, model);
3501
4030
  return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3502
4031
  }
3503
4032
  async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
@@ -3518,20 +4047,20 @@ var BaseOperationHandler = class {
3518
4047
  };
3519
4048
  }
3520
4049
  transformIncrementalUpdate(model, field, fieldDef, payload) {
3521
- invariant7(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
4050
+ invariant9(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
3522
4051
  const key = Object.keys(payload)[0];
3523
4052
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
3524
- const eb = expressionBuilder3();
4053
+ const eb = expressionBuilder4();
3525
4054
  const fieldRef = this.dialect.fieldRef(model, field, eb);
3526
4055
  return match9(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3527
4056
  throw new InternalError(`Invalid incremental update operation: ${key}`);
3528
4057
  });
3529
4058
  }
3530
4059
  transformScalarListUpdate(model, field, fieldDef, payload) {
3531
- invariant7(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
4060
+ invariant9(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
3532
4061
  const key = Object.keys(payload)[0];
3533
4062
  const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
3534
- const eb = expressionBuilder3();
4063
+ const eb = expressionBuilder4();
3535
4064
  const fieldRef = this.dialect.fieldRef(model, field, eb);
3536
4065
  return match9(key).with("set", () => value).with("push", () => {
3537
4066
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
@@ -3543,7 +4072,7 @@ var BaseOperationHandler = class {
3543
4072
  return NUMERIC_FIELD_TYPES.includes(fieldDef.type) && !fieldDef.array;
3544
4073
  }
3545
4074
  makeContextComment(_context) {
3546
- return sql4``;
4075
+ return sql5``;
3547
4076
  }
3548
4077
  async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
3549
4078
  if (typeof data !== "object") {
@@ -3602,7 +4131,7 @@ var BaseOperationHandler = class {
3602
4131
  count: Number(result.numAffectedRows)
3603
4132
  };
3604
4133
  } else {
3605
- const idFields = getIdFields(this.schema, model);
4134
+ const idFields = requireIdFields(this.schema, model);
3606
4135
  const result = await query.returning(idFields).execute();
3607
4136
  return result;
3608
4137
  }
@@ -3625,11 +4154,10 @@ var BaseOperationHandler = class {
3625
4154
  };
3626
4155
  }
3627
4156
  buildIdFieldRefs(kysely, model) {
3628
- const idFields = getIdFields(this.schema, model);
4157
+ const idFields = requireIdFields(this.schema, model);
3629
4158
  return idFields.map((f) => kysely.dynamic.ref(`${model}.${f}`));
3630
4159
  }
3631
4160
  async processRelationUpdates(kysely, model, field, fieldDef, parentIds, args, throwIfNotFound) {
3632
- const tasks = [];
3633
4161
  const fieldModel = fieldDef.type;
3634
4162
  const fromRelationContext = {
3635
4163
  model,
@@ -3640,68 +4168,73 @@ var BaseOperationHandler = class {
3640
4168
  for (const [key, value] of Object.entries(args)) {
3641
4169
  switch (key) {
3642
4170
  case "create": {
3643
- invariant7(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
3644
- tasks.push(...enumerate(value).map((item) => this.create(kysely, fieldModel, item, fromRelationContext)));
4171
+ invariant9(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
4172
+ for (const item of enumerate(value)) {
4173
+ await this.create(kysely, fieldModel, item, fromRelationContext);
4174
+ }
3645
4175
  break;
3646
4176
  }
3647
4177
  case "createMany": {
3648
- invariant7(fieldDef.array, "relation must be an array for createMany");
3649
- tasks.push(this.createMany(kysely, fieldModel, value, false, fromRelationContext));
4178
+ invariant9(fieldDef.array, "relation must be an array for createMany");
4179
+ await this.createMany(kysely, fieldModel, value, false, fromRelationContext);
3650
4180
  break;
3651
4181
  }
3652
4182
  case "connect": {
3653
- tasks.push(this.connectRelation(kysely, fieldModel, value, fromRelationContext));
4183
+ await this.connectRelation(kysely, fieldModel, value, fromRelationContext);
3654
4184
  break;
3655
4185
  }
3656
4186
  case "connectOrCreate": {
3657
- tasks.push(this.connectOrCreateRelation(kysely, fieldModel, value, fromRelationContext));
4187
+ await this.connectOrCreateRelation(kysely, fieldModel, value, fromRelationContext);
3658
4188
  break;
3659
4189
  }
3660
4190
  case "disconnect": {
3661
- tasks.push(this.disconnectRelation(kysely, fieldModel, value, fromRelationContext));
4191
+ await this.disconnectRelation(kysely, fieldModel, value, fromRelationContext);
3662
4192
  break;
3663
4193
  }
3664
4194
  case "set": {
3665
- invariant7(fieldDef.array, "relation must be an array");
3666
- tasks.push(this.setRelation(kysely, fieldModel, value, fromRelationContext));
4195
+ invariant9(fieldDef.array, "relation must be an array");
4196
+ await this.setRelation(kysely, fieldModel, value, fromRelationContext);
3667
4197
  break;
3668
4198
  }
3669
4199
  case "update": {
3670
- tasks.push(...enumerate(value).map((item) => {
4200
+ for (const _item of enumerate(value)) {
4201
+ const item = _item;
3671
4202
  let where;
3672
4203
  let data;
3673
- if ("where" in item) {
4204
+ if ("data" in item && typeof item.data === "object") {
3674
4205
  where = item.where;
3675
4206
  data = item.data;
3676
4207
  } else {
3677
4208
  where = void 0;
3678
4209
  data = item;
3679
4210
  }
3680
- return this.update(kysely, fieldModel, where, data, fromRelationContext, true, throwIfNotFound);
3681
- }));
4211
+ await this.update(kysely, fieldModel, where, data, fromRelationContext, true, throwIfNotFound);
4212
+ }
3682
4213
  break;
3683
4214
  }
3684
4215
  case "upsert": {
3685
- tasks.push(...enumerate(value).map(async (item) => {
4216
+ for (const _item of enumerate(value)) {
4217
+ const item = _item;
3686
4218
  const updated = await this.update(kysely, fieldModel, item.where, item.update, fromRelationContext, true, false);
3687
- if (updated) {
3688
- return updated;
3689
- } else {
3690
- return this.create(kysely, fieldModel, item.create, fromRelationContext);
4219
+ if (!updated) {
4220
+ await this.create(kysely, fieldModel, item.create, fromRelationContext);
3691
4221
  }
3692
- }));
4222
+ }
3693
4223
  break;
3694
4224
  }
3695
4225
  case "updateMany": {
3696
- tasks.push(...enumerate(value).map((item) => this.update(kysely, fieldModel, item.where, item.data, fromRelationContext, false, false)));
4226
+ for (const _item of enumerate(value)) {
4227
+ const item = _item;
4228
+ await this.update(kysely, fieldModel, item.where, item.data, fromRelationContext, false, false);
4229
+ }
3697
4230
  break;
3698
4231
  }
3699
4232
  case "delete": {
3700
- tasks.push(this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true));
4233
+ await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, true);
3701
4234
  break;
3702
4235
  }
3703
4236
  case "deleteMany": {
3704
- tasks.push(this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false));
4237
+ await this.deleteRelation(kysely, fieldModel, value, fromRelationContext, false);
3705
4238
  break;
3706
4239
  }
3707
4240
  default: {
@@ -3709,7 +4242,6 @@ var BaseOperationHandler = class {
3709
4242
  }
3710
4243
  }
3711
4244
  }
3712
- await Promise.all(tasks);
3713
4245
  return fromRelationContext.parentUpdates;
3714
4246
  }
3715
4247
  // #region relation manipulation
@@ -3720,18 +4252,22 @@ var BaseOperationHandler = class {
3720
4252
  }
3721
4253
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3722
4254
  if (m2m) {
3723
- const actions = _data.map(async (d) => {
4255
+ const results = [];
4256
+ for (const d of _data) {
3724
4257
  const ids = await this.getEntityIds(kysely, model, d);
3725
- return this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3726
- });
3727
- const results = await Promise.all(actions);
4258
+ if (!ids) {
4259
+ throw new NotFoundError(model);
4260
+ }
4261
+ const r = await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
4262
+ results.push(r);
4263
+ }
3728
4264
  if (_data.length > results.filter((r) => !!r).length) {
3729
4265
  throw new NotFoundError(model);
3730
4266
  }
3731
4267
  } else {
3732
4268
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3733
4269
  if (ownedByModel) {
3734
- invariant7(_data.length === 1, "only one entity can be connected");
4270
+ invariant9(_data.length === 1, "only one entity can be connected");
3735
4271
  const target = await this.readUnique(kysely, model, {
3736
4272
  where: _data[0]
3737
4273
  });
@@ -3744,7 +4280,7 @@ var BaseOperationHandler = class {
3744
4280
  } else {
3745
4281
  const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
3746
4282
  if (!relationFieldDef.array) {
3747
- const query2 = kysely.updateTable(model).where((eb) => eb.and(keyPairs.map(({ fk, pk }) => eb(sql4.ref(fk), "=", fromRelation.ids[pk])))).set(keyPairs.reduce((acc, { fk }) => ({
4283
+ const query2 = kysely.updateTable(model).where((eb) => eb.and(keyPairs.map(({ fk, pk }) => eb(sql5.ref(fk), "=", fromRelation.ids[pk])))).set(keyPairs.reduce((acc, { fk }) => ({
3748
4284
  ...acc,
3749
4285
  [fk]: null
3750
4286
  }), {})).modifyEnd(this.makeContextComment({
@@ -3772,16 +4308,16 @@ var BaseOperationHandler = class {
3772
4308
  if (_data.length === 0) {
3773
4309
  return;
3774
4310
  }
3775
- return Promise.all(_data.map(async ({ where, create }) => {
4311
+ for (const { where, create } of _data) {
3776
4312
  const existing = await this.exists(kysely, model, where);
3777
4313
  if (existing) {
3778
- return this.connectRelation(kysely, model, [
4314
+ await this.connectRelation(kysely, model, [
3779
4315
  where
3780
4316
  ], fromRelation);
3781
4317
  } else {
3782
- return this.create(kysely, model, create, fromRelation);
4318
+ await this.create(kysely, model, create, fromRelation);
3783
4319
  }
3784
- }));
4320
+ }
3785
4321
  }
3786
4322
  async disconnectRelation(kysely, model, data, fromRelation) {
3787
4323
  let disconnectConditions = [];
@@ -3804,19 +4340,18 @@ var BaseOperationHandler = class {
3804
4340
  }
3805
4341
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3806
4342
  if (m2m) {
3807
- const actions = disconnectConditions.map(async (d) => {
4343
+ for (const d of disconnectConditions) {
3808
4344
  const ids = await this.getEntityIds(kysely, model, d);
3809
4345
  if (!ids) {
3810
4346
  return;
3811
4347
  }
3812
- return this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3813
- });
3814
- await Promise.all(actions);
4348
+ await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
4349
+ }
3815
4350
  } else {
3816
4351
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3817
- const eb = expressionBuilder3();
4352
+ const eb = expressionBuilder4();
3818
4353
  if (ownedByModel) {
3819
- invariant7(disconnectConditions.length === 1, "only one entity can be disconnected");
4354
+ invariant9(disconnectConditions.length === 1, "only one entity can be disconnected");
3820
4355
  const condition = disconnectConditions[0];
3821
4356
  if (condition === true) {
3822
4357
  for (const { fk } of keyPairs) {
@@ -3875,11 +4410,14 @@ var BaseOperationHandler = class {
3875
4410
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3876
4411
  if (m2m) {
3877
4412
  await this.resetManyToManyRelation(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
3878
- const actions = _data.map(async (d) => {
4413
+ const results = [];
4414
+ for (const d of _data) {
3879
4415
  const ids = await this.getEntityIds(kysely, model, d);
3880
- return this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3881
- });
3882
- const results = await Promise.all(actions);
4416
+ if (!ids) {
4417
+ throw new NotFoundError(model);
4418
+ }
4419
+ results.push(await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable));
4420
+ }
3883
4421
  if (_data.length > results.filter((r) => !!r).length) {
3884
4422
  throw new NotFoundError(model);
3885
4423
  }
@@ -3945,7 +4483,7 @@ var BaseOperationHandler = class {
3945
4483
  if (m2m) {
3946
4484
  deleteFromModel = model;
3947
4485
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3948
- invariant7(fieldDef.relation?.opposite);
4486
+ invariant9(fieldDef.relation?.opposite);
3949
4487
  deleteResult = await this.delete(kysely, model, {
3950
4488
  AND: [
3951
4489
  {
@@ -3969,7 +4507,7 @@ var BaseOperationHandler = class {
3969
4507
  throw new NotFoundError(fromRelation.model);
3970
4508
  }
3971
4509
  const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
3972
- invariant7(fieldDef.relation?.opposite);
4510
+ invariant9(fieldDef.relation?.opposite);
3973
4511
  deleteResult = await this.delete(kysely, model, {
3974
4512
  AND: [
3975
4513
  // filter for parent
@@ -4099,7 +4637,7 @@ var BaseOperationHandler = class {
4099
4637
  // reused the filter if it's a complete id filter (without extra fields)
4100
4638
  // otherwise, read the entity by the filter
4101
4639
  getEntityIds(kysely, model, uniqueFilter) {
4102
- const idFields = getIdFields(this.schema, model);
4640
+ const idFields = requireIdFields(this.schema, model);
4103
4641
  if (
4104
4642
  // all id fields are provided
4105
4643
  idFields.every((f) => f in uniqueFilter && uniqueFilter[f] !== void 0) && // no non-id filter exists
@@ -4201,7 +4739,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4201
4739
  if (field === "_all") {
4202
4740
  query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as(`_count._all`));
4203
4741
  } else {
4204
- query = query.select((eb) => eb.cast(eb.fn.count(sql5.ref(`$sub.${field}`)), "integer").as(`${key}.${field}`));
4742
+ query = query.select((eb) => eb.cast(eb.fn.count(sql6.ref(`$sub.${field}`)), "integer").as(`${key}.${field}`));
4205
4743
  }
4206
4744
  }
4207
4745
  });
@@ -4216,7 +4754,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4216
4754
  if (val === true) {
4217
4755
  query = query.select((eb) => {
4218
4756
  const fn = match10(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4219
- return fn(sql5.ref(`$sub.${field}`)).as(`${key}.${field}`);
4757
+ return fn(sql6.ref(`$sub.${field}`)).as(`${key}.${field}`);
4220
4758
  });
4221
4759
  }
4222
4760
  });
@@ -4263,7 +4801,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4263
4801
  };
4264
4802
 
4265
4803
  // src/client/crud/operations/count.ts
4266
- import { sql as sql6 } from "kysely";
4804
+ import { sql as sql7 } from "kysely";
4267
4805
  var CountOperationHandler = class extends BaseOperationHandler {
4268
4806
  static {
4269
4807
  __name(this, "CountOperationHandler");
@@ -4287,7 +4825,7 @@ var CountOperationHandler = class extends BaseOperationHandler {
4287
4825
  return subQuery.as(subQueryName);
4288
4826
  });
4289
4827
  if (parsedArgs?.select && typeof parsedArgs.select === "object") {
4290
- query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(sql6.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4828
+ query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(sql7.ref(`${subQueryName}.${key}`)), "integer").as(key)));
4291
4829
  const result = await this.executeQuery(this.kysely, query, "count");
4292
4830
  return result.rows[0];
4293
4831
  } else {
@@ -4323,7 +4861,7 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4323
4861
  });
4324
4862
  });
4325
4863
  if (!result && this.hasPolicyEnabled) {
4326
- throw new RejectedByPolicyError(this.model, `result is not allowed to be read back`);
4864
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, `result is not allowed to be read back`);
4327
4865
  }
4328
4866
  return result;
4329
4867
  }
@@ -4369,15 +4907,15 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
4369
4907
  omit: args.omit,
4370
4908
  where: args.where
4371
4909
  });
4372
- if (!existing) {
4373
- throw new NotFoundError(this.model);
4374
- }
4375
4910
  await this.safeTransaction(async (tx) => {
4376
4911
  const result = await this.delete(tx, this.model, args.where);
4377
4912
  if (result.count === 0) {
4378
4913
  throw new NotFoundError(this.model);
4379
4914
  }
4380
4915
  });
4916
+ if (!existing && this.hasPolicyEnabled) {
4917
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4918
+ }
4381
4919
  return existing;
4382
4920
  }
4383
4921
  async runDeleteMany(args) {
@@ -4411,7 +4949,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4411
4949
  };
4412
4950
 
4413
4951
  // src/client/crud/operations/group-by.ts
4414
- import { expressionBuilder as expressionBuilder4 } from "kysely";
4952
+ import { expressionBuilder as expressionBuilder5 } from "kysely";
4415
4953
  import { match as match13 } from "ts-pattern";
4416
4954
  var GroupByOperationHandler = class extends BaseOperationHandler {
4417
4955
  static {
@@ -4433,7 +4971,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4433
4971
  subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
4434
4972
  return subQuery.as("$sub");
4435
4973
  });
4436
- const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, expressionBuilder4(), "$sub"), "fieldRef");
4974
+ const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, expressionBuilder5(), "$sub"), "fieldRef");
4437
4975
  const bys = typeof parsedArgs.by === "string" ? [
4438
4976
  parsedArgs.by
4439
4977
  ] : parsedArgs.by;
@@ -4548,7 +5086,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4548
5086
  });
4549
5087
  if (!readBackResult) {
4550
5088
  if (this.hasPolicyEnabled) {
4551
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
5089
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4552
5090
  } else {
4553
5091
  return null;
4554
5092
  }
@@ -4565,16 +5103,24 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4565
5103
  if (!args) {
4566
5104
  return [];
4567
5105
  }
4568
- return this.safeTransaction(async (tx) => {
4569
- const updateResult = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true);
4570
- return this.read(tx, this.model, {
5106
+ const { readBackResult, updateResult } = await this.safeTransaction(async (tx) => {
5107
+ const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true);
5108
+ const readBackResult2 = await this.read(tx, this.model, {
4571
5109
  select: args.select,
4572
5110
  omit: args.omit,
4573
5111
  where: {
4574
- OR: updateResult.map((item) => getIdValues(this.schema, this.model, item))
5112
+ OR: updateResult2.map((item) => getIdValues(this.schema, this.model, item))
4575
5113
  }
4576
5114
  });
5115
+ return {
5116
+ readBackResult: readBackResult2,
5117
+ updateResult: updateResult2
5118
+ };
4577
5119
  });
5120
+ if (readBackResult.length < updateResult.length && this.hasPolicyEnabled) {
5121
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
5122
+ }
5123
+ return readBackResult;
4578
5124
  }
4579
5125
  async runUpsert(args) {
4580
5126
  const result = await this.safeTransaction(async (tx) => {
@@ -4590,18 +5136,32 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4590
5136
  });
4591
5137
  });
4592
5138
  if (!result && this.hasPolicyEnabled) {
4593
- throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
5139
+ throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
4594
5140
  }
4595
5141
  return result;
4596
5142
  }
4597
5143
  };
4598
5144
 
4599
5145
  // src/client/crud/validator.ts
4600
- import { invariant as invariant8 } from "@zenstackhq/common-helpers";
4601
- import Decimal from "decimal.js";
5146
+ import { invariant as invariant10 } from "@zenstackhq/common-helpers";
5147
+ import Decimal3 from "decimal.js";
4602
5148
  import stableStringify from "json-stable-stringify";
4603
5149
  import { match as match15, P as P2 } from "ts-pattern";
4604
5150
  import { z } from "zod";
5151
+
5152
+ // src/utils/zod-utils.ts
5153
+ import { fromError as fromError3 } from "zod-validation-error/v3";
5154
+ import { fromError as fromError4 } from "zod-validation-error/v4";
5155
+ function formatError(error) {
5156
+ if ("_zod" in error) {
5157
+ return fromError4(error).toString();
5158
+ } else {
5159
+ return fromError3(error).toString();
5160
+ }
5161
+ }
5162
+ __name(formatError, "formatError");
5163
+
5164
+ // src/client/crud/validator.ts
4605
5165
  var InputValidator = class {
4606
5166
  static {
4607
5167
  __name(this, "InputValidator");
@@ -4663,7 +5223,7 @@ var InputValidator = class {
4663
5223
  }
4664
5224
  const { error } = schema.safeParse(args);
4665
5225
  if (error) {
4666
- throw new InputValidationError(`Invalid ${operation} args: ${error.message}`, error);
5226
+ throw new InputValidationError(`Invalid ${operation} args: ${formatError(error)}`, error);
4667
5227
  }
4668
5228
  return args;
4669
5229
  }
@@ -4707,7 +5267,7 @@ var InputValidator = class {
4707
5267
  z.bigint()
4708
5268
  ])).with("Decimal", () => z.union([
4709
5269
  z.number(),
4710
- z.instanceof(Decimal),
5270
+ z.instanceof(Decimal3),
4711
5271
  z.string()
4712
5272
  ])).with("DateTime", () => z.union([
4713
5273
  z.date(),
@@ -4722,7 +5282,7 @@ var InputValidator = class {
4722
5282
  return schema;
4723
5283
  }
4724
5284
  const typeDef = this.schema.typeDefs?.[type];
4725
- invariant8(typeDef, `Type definition "${type}" not found in schema`);
5285
+ invariant10(typeDef, `Type definition "${type}" not found in schema`);
4726
5286
  schema = z.object(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
4727
5287
  let fieldSchema = this.makePrimitiveSchema(def.type);
4728
5288
  if (def.array) {
@@ -4790,7 +5350,7 @@ var InputValidator = class {
4790
5350
  for (const uniqueField of uniqueFields) {
4791
5351
  if ("defs" in uniqueField) {
4792
5352
  fields[uniqueField.name] = z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
4793
- invariant8(!def.relation, "unique field cannot be a relation");
5353
+ invariant10(!def.relation, "unique field cannot be a relation");
4794
5354
  let fieldSchema;
4795
5355
  const enumDef = getEnum(this.schema, def.type);
4796
5356
  if (enumDef) {
@@ -4996,9 +5556,16 @@ var InputValidator = class {
4996
5556
  fields[field] = z.boolean().optional();
4997
5557
  }
4998
5558
  }
5559
+ const _countSchema = this.makeCountSelectionSchema(modelDef);
5560
+ if (_countSchema) {
5561
+ fields["_count"] = _countSchema;
5562
+ }
5563
+ return z.strictObject(fields);
5564
+ }
5565
+ makeCountSelectionSchema(modelDef) {
4999
5566
  const toManyRelations = Object.values(modelDef.fields).filter((def) => def.relation && def.array);
5000
5567
  if (toManyRelations.length > 0) {
5001
- fields["_count"] = z.union([
5568
+ return z.union([
5002
5569
  z.literal(true),
5003
5570
  z.strictObject({
5004
5571
  select: z.strictObject(toManyRelations.reduce((acc, fieldDef) => ({
@@ -5012,8 +5579,9 @@ var InputValidator = class {
5012
5579
  }), {}))
5013
5580
  })
5014
5581
  ]).optional();
5582
+ } else {
5583
+ return void 0;
5015
5584
  }
5016
- return z.strictObject(fields);
5017
5585
  }
5018
5586
  makeRelationSelectIncludeSchema(fieldDef) {
5019
5587
  let objSchema = z.strictObject({
@@ -5060,6 +5628,10 @@ var InputValidator = class {
5060
5628
  fields[field] = this.makeRelationSelectIncludeSchema(fieldDef).optional();
5061
5629
  }
5062
5630
  }
5631
+ const _countSchema = this.makeCountSelectionSchema(modelDef);
5632
+ if (_countSchema) {
5633
+ fields["_count"] = _countSchema;
5634
+ }
5063
5635
  return z.strictObject(fields);
5064
5636
  }
5065
5637
  makeOrderBySchema(model, withRelation, WithAggregation) {
@@ -5126,13 +5698,15 @@ var InputValidator = class {
5126
5698
  // #region Create
5127
5699
  makeCreateSchema(model) {
5128
5700
  const dataSchema = this.makeCreateDataSchema(model, false);
5129
- const schema = z.strictObject({
5701
+ let schema = z.strictObject({
5130
5702
  data: dataSchema,
5131
5703
  select: this.makeSelectSchema(model).optional(),
5132
5704
  include: this.makeIncludeSchema(model).optional(),
5133
5705
  omit: this.makeOmitSchema(model).optional()
5134
5706
  });
5135
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5707
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5708
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5709
+ return schema;
5136
5710
  }
5137
5711
  makeCreateManySchema(model) {
5138
5712
  return this.makeCreateManyDataSchema(model, []).optional();
@@ -5257,11 +5831,11 @@ var InputValidator = class {
5257
5831
  fields["delete"] = this.makeDeleteRelationDataSchema(fieldType, array, true).optional();
5258
5832
  }
5259
5833
  fields["update"] = array ? this.orArray(z.strictObject({
5260
- where: this.makeWhereSchema(fieldType, true),
5834
+ where: this.makeWhereSchema(fieldType, true).optional(),
5261
5835
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
5262
5836
  }), true).optional() : z.union([
5263
5837
  z.strictObject({
5264
- where: this.makeWhereSchema(fieldType, true),
5838
+ where: this.makeWhereSchema(fieldType, true).optional(),
5265
5839
  data: this.makeUpdateDataSchema(fieldType, withoutFields)
5266
5840
  }),
5267
5841
  this.makeUpdateDataSchema(fieldType, withoutFields)
@@ -5321,14 +5895,16 @@ var InputValidator = class {
5321
5895
  // #endregion
5322
5896
  // #region Update
5323
5897
  makeUpdateSchema(model) {
5324
- const schema = z.strictObject({
5898
+ let schema = z.strictObject({
5325
5899
  where: this.makeWhereSchema(model, true),
5326
5900
  data: this.makeUpdateDataSchema(model),
5327
5901
  select: this.makeSelectSchema(model).optional(),
5328
5902
  include: this.makeIncludeSchema(model).optional(),
5329
5903
  omit: this.makeOmitSchema(model).optional()
5330
5904
  });
5331
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5905
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5906
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5907
+ return schema;
5332
5908
  }
5333
5909
  makeUpdateManySchema(model) {
5334
5910
  return z.strictObject({
@@ -5339,14 +5915,15 @@ var InputValidator = class {
5339
5915
  }
5340
5916
  makeUpdateManyAndReturnSchema(model) {
5341
5917
  const base = this.makeUpdateManySchema(model);
5342
- const result = base.extend({
5918
+ let schema = base.extend({
5343
5919
  select: this.makeSelectSchema(model).optional(),
5344
5920
  omit: this.makeOmitSchema(model).optional()
5345
5921
  });
5346
- return this.refineForSelectOmitMutuallyExclusive(result);
5922
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5923
+ return schema;
5347
5924
  }
5348
5925
  makeUpsertSchema(model) {
5349
- const schema = z.strictObject({
5926
+ let schema = z.strictObject({
5350
5927
  where: this.makeWhereSchema(model, true),
5351
5928
  create: this.makeCreateDataSchema(model, false),
5352
5929
  update: this.makeUpdateDataSchema(model),
@@ -5354,7 +5931,9 @@ var InputValidator = class {
5354
5931
  include: this.makeIncludeSchema(model).optional(),
5355
5932
  omit: this.makeOmitSchema(model).optional()
5356
5933
  });
5357
- return this.refineForSelectIncludeMutuallyExclusive(schema);
5934
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
5935
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
5936
+ return schema;
5358
5937
  }
5359
5938
  makeUpdateDataSchema(model, withoutFields = [], withoutRelationFields = false) {
5360
5939
  const uncheckedVariantFields = {};
@@ -5431,12 +6010,14 @@ var InputValidator = class {
5431
6010
  // #endregion
5432
6011
  // #region Delete
5433
6012
  makeDeleteSchema(model) {
5434
- const schema = z.strictObject({
6013
+ let schema = z.strictObject({
5435
6014
  where: this.makeWhereSchema(model, true),
5436
6015
  select: this.makeSelectSchema(model).optional(),
5437
6016
  include: this.makeIncludeSchema(model).optional()
5438
6017
  });
5439
- return this.refineForSelectIncludeMutuallyExclusive(schema);
6018
+ schema = this.refineForSelectIncludeMutuallyExclusive(schema);
6019
+ schema = this.refineForSelectOmitMutuallyExclusive(schema);
6020
+ return schema;
5440
6021
  }
5441
6022
  makeDeleteManySchema(model) {
5442
6023
  return z.object({
@@ -5786,30 +6367,13 @@ function performanceNow() {
5786
6367
  __name(performanceNow, "performanceNow");
5787
6368
 
5788
6369
  // src/client/executor/zenstack-query-executor.ts
5789
- import { invariant as invariant10 } from "@zenstackhq/common-helpers";
5790
- import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode2, SelectionNode as SelectionNode4, SingleConnectionProvider, TableNode as TableNode5, UpdateQueryNode as UpdateQueryNode2, WhereNode as WhereNode3 } from "kysely";
6370
+ import { invariant as invariant12 } from "@zenstackhq/common-helpers";
6371
+ import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode2, SelectionNode as SelectionNode4, SingleConnectionProvider, TableNode as TableNode6, UpdateQueryNode as UpdateQueryNode2, WhereNode as WhereNode3 } from "kysely";
5791
6372
  import { match as match16 } from "ts-pattern";
5792
6373
 
5793
- // src/client/executor/kysely-utils.ts
5794
- import { AliasNode as AliasNode4 } from "kysely";
5795
- function stripAlias(node) {
5796
- if (AliasNode4.is(node)) {
5797
- return {
5798
- alias: node.alias,
5799
- node: node.node
5800
- };
5801
- } else {
5802
- return {
5803
- alias: void 0,
5804
- node
5805
- };
5806
- }
5807
- }
5808
- __name(stripAlias, "stripAlias");
5809
-
5810
6374
  // src/client/executor/name-mapper.ts
5811
- import { invariant as invariant9 } from "@zenstackhq/common-helpers";
5812
- import { AliasNode as AliasNode5, ColumnNode as ColumnNode3, FromNode as FromNode3, IdentifierNode as IdentifierNode3, OperationNodeTransformer as OperationNodeTransformer2, ReferenceNode as ReferenceNode3, SelectAllNode, SelectionNode as SelectionNode3, TableNode as TableNode4 } from "kysely";
6375
+ import { invariant as invariant11 } from "@zenstackhq/common-helpers";
6376
+ import { AliasNode as AliasNode5, ColumnNode as ColumnNode4, FromNode as FromNode3, IdentifierNode as IdentifierNode3, OperationNodeTransformer as OperationNodeTransformer2, ReferenceNode as ReferenceNode4, SelectAllNode, SelectionNode as SelectionNode3, TableNode as TableNode5 } from "kysely";
5813
6377
  var QueryNameMapper = class extends OperationNodeTransformer2 {
5814
6378
  static {
5815
6379
  __name(this, "QueryNameMapper");
@@ -5878,7 +6442,7 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5878
6442
  };
5879
6443
  }
5880
6444
  transformReference(node) {
5881
- if (!ColumnNode3.is(node.column)) {
6445
+ if (!ColumnNode4.is(node.column)) {
5882
6446
  return super.transformReference(node);
5883
6447
  }
5884
6448
  const scope = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
@@ -5891,7 +6455,7 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5891
6455
  mappedTableName = this.mapTableName(scope.model);
5892
6456
  }
5893
6457
  }
5894
- return ReferenceNode3.create(ColumnNode3.create(mappedFieldName), mappedTableName ? TableNode4.create(mappedTableName) : void 0);
6458
+ return ReferenceNode4.create(ColumnNode4.create(mappedFieldName), mappedTableName ? TableNode5.create(mappedTableName) : void 0);
5895
6459
  } else {
5896
6460
  return super.transformReference(node);
5897
6461
  }
@@ -5902,14 +6466,14 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5902
6466
  return super.transformColumn(node);
5903
6467
  }
5904
6468
  const mappedName = this.mapFieldName(scope.model, node.column.name);
5905
- return ColumnNode3.create(mappedName);
6469
+ return ColumnNode4.create(mappedName);
5906
6470
  }
5907
6471
  transformUpdateQuery(node) {
5908
6472
  if (!node.table) {
5909
6473
  return super.transformUpdateQuery(node);
5910
6474
  }
5911
6475
  const { alias, node: innerTable } = stripAlias(node.table);
5912
- if (!innerTable || !TableNode4.is(innerTable)) {
6476
+ if (!innerTable || !TableNode5.is(innerTable)) {
5913
6477
  return super.transformUpdateQuery(node);
5914
6478
  }
5915
6479
  return this.withScope({
@@ -5927,14 +6491,14 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5927
6491
  const scopes = node.from.froms.map((node2) => {
5928
6492
  const { alias, node: innerNode } = stripAlias(node2);
5929
6493
  return {
5930
- model: this.extractModelName(innerNode),
6494
+ model: extractModelName(innerNode),
5931
6495
  alias,
5932
6496
  namesMapped: false
5933
6497
  };
5934
6498
  });
5935
6499
  const froms = node.from.froms.map((from) => {
5936
6500
  const { alias, node: innerNode } = stripAlias(from);
5937
- if (TableNode4.is(innerNode)) {
6501
+ if (TableNode5.is(innerNode)) {
5938
6502
  return this.wrapAlias(this.processTableRef(innerNode), alias);
5939
6503
  } else {
5940
6504
  return super.transformNode(from);
@@ -5959,13 +6523,13 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5959
6523
  } else {
5960
6524
  selections.push(super.transformSelection(selection));
5961
6525
  }
5962
- } else if (ReferenceNode3.is(selection.selection) || ColumnNode3.is(selection.selection)) {
6526
+ } else if (ReferenceNode4.is(selection.selection) || ColumnNode4.is(selection.selection)) {
5963
6527
  const transformed = this.transformNode(selection.selection);
5964
6528
  if (AliasNode5.is(transformed)) {
5965
6529
  selections.push(SelectionNode3.create(transformed));
5966
6530
  } else {
5967
- const origFieldName = this.extractFieldName(selection.selection);
5968
- const fieldName = this.extractFieldName(transformed);
6531
+ const origFieldName = extractFieldName(selection.selection);
6532
+ const fieldName = extractFieldName(transformed);
5969
6533
  if (fieldName !== origFieldName) {
5970
6534
  selections.push(SelectionNode3.create(this.wrapAlias(transformed, origFieldName ? IdentifierNode3.create(origFieldName) : void 0)));
5971
6535
  } else {
@@ -6035,10 +6599,10 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
6035
6599
  if (!node) {
6036
6600
  return node;
6037
6601
  }
6038
- if (!TableNode4.is(node)) {
6602
+ if (!TableNode5.is(node)) {
6039
6603
  return super.transformNode(node);
6040
6604
  }
6041
- return TableNode4.create(this.mapTableName(node.table.identifier.name));
6605
+ return TableNode5.create(this.mapTableName(node.table.identifier.name));
6042
6606
  }
6043
6607
  getMappedName(def) {
6044
6608
  const mapAttr = def.attributes?.find((attr) => attr.name === "@@map" || attr.name === "@map");
@@ -6074,12 +6638,12 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
6074
6638
  // convert a "from" node to a nested query if there are columns with name mapping
6075
6639
  processSelectTable(node) {
6076
6640
  const { alias, node: innerNode } = stripAlias(node);
6077
- if (innerNode && TableNode4.is(innerNode)) {
6641
+ if (innerNode && TableNode5.is(innerNode)) {
6078
6642
  const modelName = innerNode.table.identifier.name;
6079
6643
  const mappedName = this.mapTableName(modelName);
6080
6644
  const finalAlias = alias ?? (mappedName !== modelName ? IdentifierNode3.create(modelName) : void 0);
6081
6645
  return {
6082
- node: this.wrapAlias(TableNode4.create(mappedName), finalAlias),
6646
+ node: this.wrapAlias(TableNode5.create(mappedName), finalAlias),
6083
6647
  scope: {
6084
6648
  alias: alias ?? IdentifierNode3.create(modelName),
6085
6649
  model: modelName,
@@ -6101,7 +6665,7 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
6101
6665
  const modelDef = requireModel(this.schema, model);
6102
6666
  return this.getModelFields(modelDef).map((fieldDef) => {
6103
6667
  const columnName = this.mapFieldName(model, fieldDef.name);
6104
- const columnRef = ReferenceNode3.create(ColumnNode3.create(columnName), alias && IdentifierNode3.is(alias) ? TableNode4.create(alias.name) : void 0);
6668
+ const columnRef = ReferenceNode4.create(ColumnNode4.create(columnName), alias && IdentifierNode3.is(alias) ? TableNode5.create(alias.name) : void 0);
6105
6669
  if (columnName !== fieldDef.name) {
6106
6670
  const aliased = AliasNode5.create(columnRef, IdentifierNode3.create(fieldDef.name));
6107
6671
  return SelectionNode3.create(aliased);
@@ -6132,37 +6696,24 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
6132
6696
  processSelection(node) {
6133
6697
  let alias;
6134
6698
  if (!AliasNode5.is(node)) {
6135
- alias = this.extractFieldName(node);
6699
+ alias = extractFieldName(node);
6136
6700
  }
6137
6701
  const result = super.transformNode(node);
6138
6702
  return this.wrapAlias(result, alias ? IdentifierNode3.create(alias) : void 0);
6139
6703
  }
6140
6704
  processSelectAll(node) {
6141
6705
  const scope = this.scopes[this.scopes.length - 1];
6142
- invariant9(scope);
6706
+ invariant11(scope);
6143
6707
  if (!scope.model || !this.hasMappedColumns(scope.model)) {
6144
6708
  return super.transformSelectAll(node);
6145
6709
  }
6146
6710
  const modelDef = requireModel(this.schema, scope.model);
6147
6711
  return this.getModelFields(modelDef).map((fieldDef) => {
6148
6712
  const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
6149
- const columnRef = ReferenceNode3.create(ColumnNode3.create(columnName));
6713
+ const columnRef = ReferenceNode4.create(ColumnNode4.create(columnName));
6150
6714
  return columnName !== fieldDef.name ? this.wrapAlias(columnRef, IdentifierNode3.create(fieldDef.name)) : columnRef;
6151
6715
  });
6152
6716
  }
6153
- extractModelName(node) {
6154
- const { node: innerNode } = stripAlias(node);
6155
- return TableNode4.is(innerNode) ? innerNode.table.identifier.name : void 0;
6156
- }
6157
- extractFieldName(node) {
6158
- if (ReferenceNode3.is(node) && ColumnNode3.is(node.column)) {
6159
- return node.column.column.name;
6160
- } else if (ColumnNode3.is(node)) {
6161
- return node.column.name;
6162
- } else {
6163
- return void 0;
6164
- }
6165
- }
6166
6717
  };
6167
6718
 
6168
6719
  // src/client/executor/zenstack-query-executor.ts
@@ -6367,17 +6918,17 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
6367
6918
  }
6368
6919
  getMutationModel(queryNode) {
6369
6920
  return match16(queryNode).when(InsertQueryNode2.is, (node) => {
6370
- invariant10(node.into, "InsertQueryNode must have an into clause");
6921
+ invariant12(node.into, "InsertQueryNode must have an into clause");
6371
6922
  return node.into.table.identifier.name;
6372
6923
  }).when(UpdateQueryNode2.is, (node) => {
6373
- invariant10(node.table, "UpdateQueryNode must have a table");
6924
+ invariant12(node.table, "UpdateQueryNode must have a table");
6374
6925
  const { node: tableNode } = stripAlias(node.table);
6375
- invariant10(TableNode5.is(tableNode), "UpdateQueryNode must use a TableNode");
6926
+ invariant12(TableNode6.is(tableNode), "UpdateQueryNode must use a TableNode");
6376
6927
  return tableNode.table.identifier.name;
6377
6928
  }).when(DeleteQueryNode2.is, (node) => {
6378
- invariant10(node.from.froms.length === 1, "Delete query must have exactly one from table");
6929
+ invariant12(node.from.froms.length === 1, "Delete query must have exactly one from table");
6379
6930
  const { node: tableNode } = stripAlias(node.from.froms[0]);
6380
- invariant10(TableNode5.is(tableNode), "DeleteQueryNode must use a TableNode");
6931
+ invariant12(TableNode6.is(tableNode), "DeleteQueryNode must use a TableNode");
6381
6932
  return tableNode.table.identifier.name;
6382
6933
  }).otherwise((node) => {
6383
6934
  throw new InternalError(`Invalid query node: ${node}`);
@@ -6475,53 +7026,58 @@ __export(functions_exports, {
6475
7026
  search: () => search,
6476
7027
  startsWith: () => startsWith
6477
7028
  });
6478
- import { invariant as invariant11, lowerCaseFirst, upperCaseFirst } from "@zenstackhq/common-helpers";
6479
- import { sql as sql7, ValueNode as ValueNode4 } from "kysely";
7029
+ import { invariant as invariant13, lowerCaseFirst, upperCaseFirst } from "@zenstackhq/common-helpers";
7030
+ import { sql as sql8, ValueNode as ValueNode5 } from "kysely";
6480
7031
  import { match as match17 } from "ts-pattern";
6481
- var contains = /* @__PURE__ */ __name((eb, args) => {
6482
- const [field, search2, caseInsensitive = false] = args;
6483
- if (!field) {
6484
- throw new Error('"field" parameter is required');
6485
- }
6486
- if (!search2) {
6487
- throw new Error('"search" parameter is required');
6488
- }
6489
- const searchExpr = eb.fn("CONCAT", [
6490
- sql7.lit("%"),
6491
- search2,
6492
- sql7.lit("%")
6493
- ]);
6494
- return eb(field, caseInsensitive ? "ilike" : "like", searchExpr);
6495
- }, "contains");
7032
+ var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
6496
7033
  var search = /* @__PURE__ */ __name((_eb, _args) => {
6497
7034
  throw new Error(`"search" function is not implemented yet`);
6498
7035
  }, "search");
6499
- var startsWith = /* @__PURE__ */ __name((eb, args) => {
6500
- const [field, search2] = args;
6501
- if (!field) {
6502
- throw new Error('"field" parameter is required');
6503
- }
6504
- if (!search2) {
6505
- throw new Error('"search" parameter is required');
6506
- }
6507
- return eb(field, "like", eb.fn("CONCAT", [
6508
- search2,
6509
- sql7.lit("%")
6510
- ]));
6511
- }, "startsWith");
6512
- var endsWith = /* @__PURE__ */ __name((eb, args) => {
6513
- const [field, search2] = args;
7036
+ var startsWith = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "startsWith"), "startsWith");
7037
+ var endsWith = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "endsWith"), "endsWith");
7038
+ var textMatch = /* @__PURE__ */ __name((eb, args, { dialect }, method) => {
7039
+ const [field, search2, caseInsensitive = void 0] = args;
6514
7040
  if (!field) {
6515
7041
  throw new Error('"field" parameter is required');
6516
7042
  }
6517
7043
  if (!search2) {
6518
7044
  throw new Error('"search" parameter is required');
6519
7045
  }
6520
- return eb(field, "like", eb.fn("CONCAT", [
6521
- sql7.lit("%"),
6522
- search2
6523
- ]));
6524
- }, "endsWith");
7046
+ const casingBehavior = dialect.getStringCasingBehavior();
7047
+ const caseInsensitiveValue = readBoolean(caseInsensitive, false);
7048
+ let op;
7049
+ let fieldExpr = field;
7050
+ let searchExpr = search2;
7051
+ if (caseInsensitiveValue) {
7052
+ if (casingBehavior.supportsILike) {
7053
+ op = "ilike";
7054
+ } else {
7055
+ op = "like";
7056
+ if (casingBehavior.likeCaseSensitive === true) {
7057
+ fieldExpr = eb.fn("LOWER", [
7058
+ fieldExpr
7059
+ ]);
7060
+ searchExpr = eb.fn("LOWER", [
7061
+ searchExpr
7062
+ ]);
7063
+ }
7064
+ }
7065
+ } else {
7066
+ op = "like";
7067
+ }
7068
+ searchExpr = match17(method).with("contains", () => eb.fn("CONCAT", [
7069
+ sql8.lit("%"),
7070
+ sql8`CAST(${searchExpr} as text)`,
7071
+ sql8.lit("%")
7072
+ ])).with("startsWith", () => eb.fn("CONCAT", [
7073
+ sql8`CAST(${searchExpr} as text)`,
7074
+ sql8.lit("%")
7075
+ ])).with("endsWith", () => eb.fn("CONCAT", [
7076
+ sql8.lit("%"),
7077
+ sql8`CAST(${searchExpr} as text)`
7078
+ ])).exhaustive();
7079
+ return eb(fieldExpr, op, searchExpr);
7080
+ }, "textMatch");
6525
7081
  var has = /* @__PURE__ */ __name((eb, args) => {
6526
7082
  const [field, search2] = args;
6527
7083
  if (!field) {
@@ -6559,18 +7115,16 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6559
7115
  if (!field) {
6560
7116
  throw new Error('"field" parameter is required');
6561
7117
  }
6562
- return eb(dialect.buildArrayLength(eb, field), "=", sql7.lit(0));
7118
+ return eb(dialect.buildArrayLength(eb, field), "=", sql8.lit(0));
6563
7119
  }, "isEmpty");
6564
- var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6565
- return match17(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => sql7.raw("CURRENT_TIMESTAMP")).exhaustive();
6566
- }, "now");
7120
+ var now = /* @__PURE__ */ __name(() => sql8.raw("CURRENT_TIMESTAMP"), "now");
6567
7121
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6568
7122
  let result = model;
6569
7123
  const [casing] = args;
6570
7124
  if (casing) {
6571
7125
  result = processCasing(casing, result, model);
6572
7126
  }
6573
- return sql7.lit(result);
7127
+ return sql8.lit(result);
6574
7128
  }, "currentModel");
6575
7129
  var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6576
7130
  let result = operation;
@@ -6578,21 +7132,30 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6578
7132
  if (casing) {
6579
7133
  result = processCasing(casing, result, operation);
6580
7134
  }
6581
- return sql7.lit(result);
7135
+ return sql8.lit(result);
6582
7136
  }, "currentOperation");
6583
7137
  function processCasing(casing, result, model) {
6584
7138
  const opNode = casing.toOperationNode();
6585
- invariant11(ValueNode4.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
7139
+ invariant13(ValueNode5.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6586
7140
  result = match17(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst(result)).otherwise(() => {
6587
7141
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6588
7142
  });
6589
7143
  return result;
6590
7144
  }
6591
7145
  __name(processCasing, "processCasing");
7146
+ function readBoolean(expr2, defaultValue) {
7147
+ if (expr2 === void 0) {
7148
+ return defaultValue;
7149
+ }
7150
+ const opNode = expr2.toOperationNode();
7151
+ invariant13(ValueNode5.is(opNode), "expression must be a literal value");
7152
+ return !!opNode.value;
7153
+ }
7154
+ __name(readBoolean, "readBoolean");
6592
7155
 
6593
7156
  // src/client/helpers/schema-db-pusher.ts
6594
- import { invariant as invariant12 } from "@zenstackhq/common-helpers";
6595
- import { sql as sql8 } from "kysely";
7157
+ import { invariant as invariant14 } from "@zenstackhq/common-helpers";
7158
+ import { sql as sql9 } from "kysely";
6596
7159
  import toposort from "toposort";
6597
7160
  import { match as match18 } from "ts-pattern";
6598
7161
  var SchemaDbPusher = class {
@@ -6613,7 +7176,8 @@ var SchemaDbPusher = class {
6613
7176
  await createEnum.execute();
6614
7177
  }
6615
7178
  }
6616
- const sortedModels = this.sortModels(this.schema.models);
7179
+ const models = Object.values(this.schema.models).filter((m) => !m.isView);
7180
+ const sortedModels = this.sortModels(models);
6617
7181
  for (const modelDef of sortedModels) {
6618
7182
  const createTable = this.createModelTable(tx, modelDef);
6619
7183
  await createTable.execute();
@@ -6622,7 +7186,7 @@ var SchemaDbPusher = class {
6622
7186
  }
6623
7187
  sortModels(models) {
6624
7188
  const graph = [];
6625
- for (const model of Object.values(models)) {
7189
+ for (const model of models) {
6626
7190
  let added = false;
6627
7191
  if (model.baseModel) {
6628
7192
  const baseDef = requireModel(this.schema, model.baseModel);
@@ -6707,7 +7271,7 @@ var SchemaDbPusher = class {
6707
7271
  }
6708
7272
  addUniqueConstraint(table, modelDef) {
6709
7273
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
6710
- invariant12(typeof value === "object", "expecting an object");
7274
+ invariant14(typeof value === "object", "expecting an object");
6711
7275
  if ("type" in value) {
6712
7276
  const fieldDef = modelDef.fields[key];
6713
7277
  if (fieldDef.unique) {
@@ -6730,7 +7294,7 @@ var SchemaDbPusher = class {
6730
7294
  if (fieldDef.default !== void 0) {
6731
7295
  if (typeof fieldDef.default === "object" && "kind" in fieldDef.default) {
6732
7296
  if (ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "now") {
6733
- col = col.defaultTo(sql8`CURRENT_TIMESTAMP`);
7297
+ col = col.defaultTo(sql9`CURRENT_TIMESTAMP`);
6734
7298
  }
6735
7299
  } else {
6736
7300
  col = col.defaultTo(fieldDef.default);
@@ -6750,7 +7314,7 @@ var SchemaDbPusher = class {
6750
7314
  }
6751
7315
  mapFieldType(fieldDef) {
6752
7316
  if (this.schema.enums?.[fieldDef.type]) {
6753
- return this.schema.provider.type === "postgresql" ? sql8.ref(fieldDef.type) : "text";
7317
+ return this.schema.provider.type === "postgresql" ? sql9.ref(fieldDef.type) : "text";
6754
7318
  }
6755
7319
  if (this.isAutoIncrement(fieldDef) && this.schema.provider.type === "postgresql") {
6756
7320
  return "serial";
@@ -6763,7 +7327,7 @@ var SchemaDbPusher = class {
6763
7327
  throw new Error(`Unsupported field type: ${type}`);
6764
7328
  });
6765
7329
  if (fieldDef.array) {
6766
- return sql8.raw(`${result}[]`);
7330
+ return sql9.raw(`${result}[]`);
6767
7331
  } else {
6768
7332
  return result;
6769
7333
  }
@@ -6775,7 +7339,7 @@ var SchemaDbPusher = class {
6775
7339
  return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
6776
7340
  }
6777
7341
  addForeignKeyConstraint(table, model, fieldName, fieldDef) {
6778
- invariant12(fieldDef.relation, "field must be a relation");
7342
+ invariant14(fieldDef.relation, "field must be a relation");
6779
7343
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
6780
7344
  return table;
6781
7345
  }
@@ -6832,16 +7396,15 @@ function valueToPromise(thing) {
6832
7396
  __name(valueToPromise, "valueToPromise");
6833
7397
 
6834
7398
  // src/client/result-processor.ts
6835
- import { invariant as invariant13 } from "@zenstackhq/common-helpers";
6836
- import Decimal2 from "decimal.js";
6837
- import { match as match19 } from "ts-pattern";
6838
7399
  var ResultProcessor = class {
6839
7400
  static {
6840
7401
  __name(this, "ResultProcessor");
6841
7402
  }
6842
7403
  schema;
6843
- constructor(schema) {
7404
+ dialect;
7405
+ constructor(schema, options) {
6844
7406
  this.schema = schema;
7407
+ this.dialect = getCrudDialect(schema, options);
6845
7408
  }
6846
7409
  processResult(data, model, args) {
6847
7410
  const result = this.doProcessResult(data, model);
@@ -6870,7 +7433,7 @@ var ResultProcessor = class {
6870
7433
  }
6871
7434
  if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
6872
7435
  if (value) {
6873
- const subRow = this.transformJson(value);
7436
+ const subRow = this.dialect.transformOutput(value, "Json");
6874
7437
  const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
6875
7438
  const idValues = getIdValues(this.schema, subModel, subRow);
6876
7439
  if (Object.values(idValues).some((v) => v === null || v === void 0)) {
@@ -6904,10 +7467,10 @@ var ResultProcessor = class {
6904
7467
  processFieldValue(value, fieldDef) {
6905
7468
  const type = fieldDef.type;
6906
7469
  if (Array.isArray(value)) {
6907
- value.forEach((v, i) => value[i] = this.transformScalar(v, type));
7470
+ value.forEach((v, i) => value[i] = this.dialect.transformOutput(v, type));
6908
7471
  return value;
6909
7472
  } else {
6910
- return this.transformScalar(value, type);
7473
+ return this.dialect.transformOutput(value, type);
6911
7474
  }
6912
7475
  }
6913
7476
  processRelation(value, fieldDef) {
@@ -6921,42 +7484,6 @@ var ResultProcessor = class {
6921
7484
  }
6922
7485
  return this.doProcessResult(relationData, fieldDef.type);
6923
7486
  }
6924
- transformScalar(value, type) {
6925
- if (this.schema.typeDefs && type in this.schema.typeDefs) {
6926
- return this.transformJson(value);
6927
- } else {
6928
- return match19(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).with("Json", () => this.transformJson(value)).otherwise(() => value);
6929
- }
6930
- }
6931
- transformDecimal(value) {
6932
- if (value instanceof Decimal2) {
6933
- return value;
6934
- }
6935
- invariant13(typeof value === "string" || typeof value === "number" || value instanceof Decimal2, `Expected string, number or Decimal, got ${typeof value}`);
6936
- return new Decimal2(value);
6937
- }
6938
- transformBigInt(value) {
6939
- if (typeof value === "bigint") {
6940
- return value;
6941
- }
6942
- invariant13(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6943
- return BigInt(value);
6944
- }
6945
- transformBoolean(value) {
6946
- return !!value;
6947
- }
6948
- transformDate(value) {
6949
- if (typeof value === "number") {
6950
- return new Date(value);
6951
- } else if (typeof value === "string") {
6952
- return new Date(Date.parse(value));
6953
- } else {
6954
- return value;
6955
- }
6956
- }
6957
- transformBytes(value) {
6958
- return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
6959
- }
6960
7487
  fixReversedResult(data, model, args) {
6961
7488
  if (!data) {
6962
7489
  return;
@@ -6981,12 +7508,6 @@ var ResultProcessor = class {
6981
7508
  }
6982
7509
  }
6983
7510
  }
6984
- transformJson(value) {
6985
- return match19(this.schema.provider.type).with("sqlite", () => {
6986
- invariant13(typeof value === "string", "Expected string, got " + typeof value);
6987
- return JSON.parse(value);
6988
- }).otherwise(() => value);
6989
- }
6990
7511
  };
6991
7512
 
6992
7513
  // src/client/client-impl.ts
@@ -7009,7 +7530,7 @@ var ClientImpl = class _ClientImpl {
7009
7530
  this.schema = schema;
7010
7531
  this.options = options;
7011
7532
  this.$schema = schema;
7012
- this.$options = options ?? {};
7533
+ this.$options = options;
7013
7534
  this.$options.functions = {
7014
7535
  ...functions_exports,
7015
7536
  ...this.$options.functions
@@ -7060,7 +7581,7 @@ var ClientImpl = class _ClientImpl {
7060
7581
  }
7061
7582
  // implementation
7062
7583
  async $transaction(input, options) {
7063
- invariant14(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
7584
+ invariant15(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
7064
7585
  if (typeof input === "function") {
7065
7586
  return this.interactiveTransaction(input, options);
7066
7587
  } else {
@@ -7176,7 +7697,7 @@ var ClientImpl = class _ClientImpl {
7176
7697
  }
7177
7698
  $executeRaw(query, ...values) {
7178
7699
  return createZenStackPromise(async () => {
7179
- const result = await sql9(query, ...values).execute(this.kysely);
7700
+ const result = await sql10(query, ...values).execute(this.kysely);
7180
7701
  return Number(result.numAffectedRows ?? 0);
7181
7702
  });
7182
7703
  }
@@ -7189,7 +7710,7 @@ var ClientImpl = class _ClientImpl {
7189
7710
  }
7190
7711
  $queryRaw(query, ...values) {
7191
7712
  return createZenStackPromise(async () => {
7192
- const result = await sql9(query, ...values).execute(this.kysely);
7713
+ const result = await sql10(query, ...values).execute(this.kysely);
7193
7714
  return result.rows;
7194
7715
  });
7195
7716
  }
@@ -7210,7 +7731,7 @@ var ClientImpl = class _ClientImpl {
7210
7731
  };
7211
7732
  function createClientProxy(client) {
7212
7733
  const inputValidator = new InputValidator(client.$schema);
7213
- const resultProcessor = new ResultProcessor(client.$schema);
7734
+ const resultProcessor = new ResultProcessor(client.$schema, client.$options);
7214
7735
  return new Proxy(client, {
7215
7736
  get: /* @__PURE__ */ __name((target, prop, receiver) => {
7216
7737
  if (typeof prop === "string" && prop.startsWith("$")) {
@@ -7328,7 +7849,7 @@ function definePlugin(plugin) {
7328
7849
  __name(definePlugin, "definePlugin");
7329
7850
 
7330
7851
  // src/client/index.ts
7331
- import { sql as sql10 } from "kysely";
7852
+ import { sql as sql11 } from "kysely";
7332
7853
  export {
7333
7854
  InputValidationError,
7334
7855
  InternalError,
@@ -7336,6 +7857,6 @@ export {
7336
7857
  QueryError,
7337
7858
  ZenStackClient,
7338
7859
  definePlugin,
7339
- sql10 as sql
7860
+ sql11 as sql
7340
7861
  };
7341
7862
  //# sourceMappingURL=index.js.map