@zenstackhq/runtime 3.0.0-alpha.31 → 3.0.0-alpha.33

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.cjs CHANGED
@@ -37,13 +37,13 @@ __export(src_exports, {
37
37
  QueryError: () => QueryError,
38
38
  ZenStackClient: () => ZenStackClient,
39
39
  definePlugin: () => definePlugin,
40
- sql: () => import_kysely17.sql
40
+ sql: () => import_kysely18.sql
41
41
  });
42
42
  module.exports = __toCommonJS(src_exports);
43
43
 
44
44
  // src/client/client-impl.ts
45
- var import_common_helpers14 = require("@zenstackhq/common-helpers");
46
- var import_kysely16 = require("kysely");
45
+ var import_common_helpers16 = require("@zenstackhq/common-helpers");
46
+ var import_kysely17 = require("kysely");
47
47
 
48
48
  // src/client/crud/operations/aggregate.ts
49
49
  var import_kysely9 = require("kysely");
@@ -128,7 +128,10 @@ var ExpressionUtils = {
128
128
  isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
129
129
  isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
130
130
  isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
131
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
131
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
132
+ getLiteralValue: /* @__PURE__ */ __name((expr2) => {
133
+ return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
134
+ }, "getLiteralValue")
132
135
  };
133
136
 
134
137
  // src/utils/object-utils.ts
@@ -1052,6 +1055,16 @@ var BaseCrudDialect = class {
1052
1055
  }
1053
1056
  return result;
1054
1057
  }
1058
+ buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
1059
+ let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
1060
+ if (selectAllFields) {
1061
+ subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1062
+ }
1063
+ if (payload && typeof payload === "object") {
1064
+ subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
1065
+ }
1066
+ return subQuery;
1067
+ }
1055
1068
  buildSelectField(query, model, modelAlias, field) {
1056
1069
  const fieldDef = requireField(this.schema, model, field);
1057
1070
  if (fieldDef.computed) {
@@ -1149,6 +1162,18 @@ var BaseCrudDialect = class {
1149
1162
  fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
1150
1163
  return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
1151
1164
  }
1165
+ canJoinWithoutNestedSelect(modelDef, payload) {
1166
+ if (modelDef.computedFields) {
1167
+ return false;
1168
+ }
1169
+ if (modelDef.baseModel || modelDef.isDelegate) {
1170
+ return false;
1171
+ }
1172
+ if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
1173
+ return false;
1174
+ }
1175
+ return true;
1176
+ }
1152
1177
  };
1153
1178
 
1154
1179
  // src/client/crud/dialects/postgresql.ts
@@ -1174,52 +1199,58 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1174
1199
  }
1175
1200
  }
1176
1201
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1177
- const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload);
1178
- return joinedQuery.select(`${parentAlias}$${relationField}.$j as ${relationField}`);
1202
+ const relationResultName = `${parentAlias}$${relationField}`;
1203
+ const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
1204
+ return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
1179
1205
  }
1180
- buildRelationJSON(model, qb, relationField, parentName, payload) {
1206
+ buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
1181
1207
  const relationFieldDef = requireField(this.schema, model, relationField);
1182
1208
  const relationModel = relationFieldDef.type;
1183
1209
  return qb.leftJoinLateral((eb) => {
1184
- const joinTableName = `${parentName}$${relationField}`;
1185
- let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
1186
- const subQueryAlias = `${relationModel}$${relationField}$sub`;
1187
- result = eb.selectFrom(() => {
1188
- let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1189
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1190
- if (payload && typeof payload === "object") {
1191
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1192
- }
1193
- const m2m = getManyToManyRelation(this.schema, model, relationField);
1194
- if (m2m) {
1195
- const parentIds = getIdFields(this.schema, model);
1196
- const relationIds = getIdFields(this.schema, relationModel);
1197
- (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1198
- (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1199
- subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1200
- } else {
1201
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
1202
- subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1203
- }
1204
- return subQuery.as(joinTableName);
1205
- });
1206
- result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
1207
- result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
1208
- return result.as(joinTableName);
1210
+ const relationSelectName = `${resultName}$sub`;
1211
+ const relationModelDef = requireModel(this.schema, relationModel);
1212
+ let tbl;
1213
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1214
+ tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
1215
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
1216
+ } else {
1217
+ tbl = eb.selectFrom(() => {
1218
+ let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
1219
+ subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
1220
+ return subQuery.as(relationSelectName);
1221
+ });
1222
+ }
1223
+ tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
1224
+ tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
1225
+ return tbl.as(resultName);
1209
1226
  }, (join) => join.onTrue());
1210
1227
  }
1211
- buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
1228
+ buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1229
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1230
+ if (m2m) {
1231
+ const parentIds = getIdFields(this.schema, model);
1232
+ const relationIds = getIdFields(this.schema, relationModel);
1233
+ (0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1234
+ (0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1235
+ 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}`)));
1236
+ } else {
1237
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1238
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
1239
+ }
1240
+ return query;
1241
+ }
1242
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
1212
1243
  qb = qb.select((eb) => {
1213
- const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
1244
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
1214
1245
  if (relationFieldDef.array) {
1215
- return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$j");
1246
+ return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
1216
1247
  } else {
1217
- return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$j");
1248
+ return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
1218
1249
  }
1219
1250
  });
1220
1251
  return qb;
1221
1252
  }
1222
- buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
1253
+ buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
1223
1254
  const relationModelDef = requireModel(this.schema, relationModel);
1224
1255
  const objArgs = [];
1225
1256
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1237,14 +1268,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1237
1268
  } else if (payload.select) {
1238
1269
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1239
1270
  if (field === "_count") {
1240
- const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1271
+ const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1241
1272
  return [
1242
1273
  import_kysely2.sql.lit(field),
1243
1274
  subJson
1244
1275
  ];
1245
1276
  } else {
1246
1277
  const fieldDef = requireField(this.schema, relationModel, field);
1247
- const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : this.fieldRef(relationModel, field, eb, void 0, false);
1278
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1248
1279
  return [
1249
1280
  import_kysely2.sql.lit(field),
1250
1281
  fieldValue
@@ -1256,18 +1287,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1256
1287
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
1257
1288
  import_kysely2.sql.lit(field),
1258
1289
  // reference the synthesized JSON field
1259
- eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
1290
+ eb.ref(`${parentResultName}$${field}.$data`)
1260
1291
  ]).flatMap((v) => v));
1261
1292
  }
1262
1293
  return objArgs;
1263
1294
  }
1264
- buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
1265
- let result = qb;
1295
+ buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
1296
+ let result = query;
1266
1297
  if (typeof payload === "object") {
1267
1298
  const selectInclude = payload.include ?? payload.select;
1268
1299
  if (selectInclude && typeof selectInclude === "object") {
1269
1300
  Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
1270
- result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1301
+ result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
1271
1302
  });
1272
1303
  }
1273
1304
  }
@@ -1347,32 +1378,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1347
1378
  const relationModel = relationFieldDef.type;
1348
1379
  const relationModelDef = requireModel(this.schema, relationModel);
1349
1380
  const subQueryName = `${parentAlias}$${relationField}`;
1350
- let tbl = eb.selectFrom(() => {
1351
- const subQueryAlias = `${parentAlias}$${relationField}$sub`;
1352
- let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1353
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1354
- if (payload && typeof payload === "object") {
1355
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1356
- }
1357
- const m2m = getManyToManyRelation(this.schema, model, relationField);
1358
- if (m2m) {
1359
- const parentIds = getIdFields(this.schema, model);
1360
- const relationIds = getIdFields(this.schema, relationModel);
1361
- (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1362
- (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1363
- subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
1364
- } else {
1365
- const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1366
- keyPairs.forEach(({ fk, pk }) => {
1367
- if (ownedByModel) {
1368
- subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1369
- } else {
1370
- subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1371
- }
1372
- });
1373
- }
1374
- return subQuery.as(subQueryName);
1375
- });
1381
+ let tbl;
1382
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1383
+ tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
1384
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
1385
+ } else {
1386
+ tbl = eb.selectFrom(() => {
1387
+ const selectModelAlias = `${parentAlias}$${relationField}$sub`;
1388
+ let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
1389
+ selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
1390
+ return selectModelQuery.as(subQueryName);
1391
+ });
1392
+ }
1376
1393
  tbl = tbl.select(() => {
1377
1394
  const objArgs = [];
1378
1395
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1385,7 +1402,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1385
1402
  if (payload === true || !payload.select) {
1386
1403
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1387
1404
  import_kysely3.sql.lit(field),
1388
- this.fieldRef(relationModel, field, eb, void 0, false)
1405
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1389
1406
  ]).flatMap((v) => v));
1390
1407
  } else if (payload.select) {
1391
1408
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
@@ -1406,7 +1423,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1406
1423
  } else {
1407
1424
  return [
1408
1425
  import_kysely3.sql.lit(field),
1409
- this.fieldRef(relationModel, field, eb, void 0, false)
1426
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1410
1427
  ];
1411
1428
  }
1412
1429
  }
@@ -1422,13 +1439,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1422
1439
  }).flatMap((v) => v));
1423
1440
  }
1424
1441
  if (relationFieldDef.array) {
1425
- return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
1442
+ return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
1426
1443
  } else {
1427
- return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
1444
+ return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
1428
1445
  }
1429
1446
  });
1430
1447
  return tbl;
1431
1448
  }
1449
+ buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
1450
+ const fieldDef = requireField(this.schema, model, relationField);
1451
+ const relationModel = fieldDef.type;
1452
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1453
+ if (m2m) {
1454
+ const parentIds = getIdFields(this.schema, model);
1455
+ const relationIds = getIdFields(this.schema, relationModel);
1456
+ (0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1457
+ (0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1458
+ 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}`)));
1459
+ } else {
1460
+ const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1461
+ keyPairs.forEach(({ fk, pk }) => {
1462
+ if (ownedByModel) {
1463
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1464
+ } else {
1465
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1466
+ }
1467
+ });
1468
+ }
1469
+ return selectModelQuery;
1470
+ }
1432
1471
  buildSkipTake(query, skip, take) {
1433
1472
  if (take !== void 0) {
1434
1473
  query = query.limit(take);
@@ -2740,6 +2779,16 @@ function clone(value) {
2740
2779
  }
2741
2780
  __name(clone, "clone");
2742
2781
 
2782
+ // src/client/contract.ts
2783
+ var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
2784
+ TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
2785
+ TransactionIsolationLevel2["ReadCommitted"] = "read committed";
2786
+ TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
2787
+ TransactionIsolationLevel2["Serializable"] = "serializable";
2788
+ TransactionIsolationLevel2["Snapshot"] = "snapshot";
2789
+ return TransactionIsolationLevel2;
2790
+ }({});
2791
+
2743
2792
  // src/client/crud/operations/base.ts
2744
2793
  var BaseOperationHandler = class {
2745
2794
  static {
@@ -3978,7 +4027,7 @@ var BaseOperationHandler = class {
3978
4027
  return callback(this.kysely);
3979
4028
  } else {
3980
4029
  let txBuilder = this.kysely.transaction();
3981
- txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? "repeatable read");
4030
+ txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? TransactionIsolationLevel.RepeatableRead);
3982
4031
  return txBuilder.execute(callback);
3983
4032
  }
3984
4033
  }
@@ -5544,7 +5593,11 @@ var ZenStackDriver = class {
5544
5593
  this.#txConnections.delete(connection);
5545
5594
  if (callbacks) {
5546
5595
  for (const callback of callbacks) {
5547
- await callback();
5596
+ try {
5597
+ await callback();
5598
+ } catch (err) {
5599
+ console.error(`Error executing transaction commit callback: ${err}`);
5600
+ }
5548
5601
  }
5549
5602
  }
5550
5603
  return result;
@@ -5662,21 +5715,40 @@ function performanceNow() {
5662
5715
  __name(performanceNow, "performanceNow");
5663
5716
 
5664
5717
  // src/client/executor/zenstack-query-executor.ts
5665
- var import_kysely13 = require("kysely");
5666
- var import_nanoid2 = require("nanoid");
5718
+ var import_common_helpers12 = require("@zenstackhq/common-helpers");
5719
+ var import_kysely14 = require("kysely");
5667
5720
  var import_ts_pattern16 = require("ts-pattern");
5668
5721
 
5669
- // src/client/executor/name-mapper.ts
5722
+ // src/client/executor/kysely-utils.ts
5670
5723
  var import_common_helpers10 = require("@zenstackhq/common-helpers");
5671
5724
  var import_kysely12 = require("kysely");
5672
- var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5725
+ function stripAlias(node) {
5726
+ if (import_kysely12.AliasNode.is(node)) {
5727
+ (0, import_common_helpers10.invariant)(import_kysely12.IdentifierNode.is(node.alias), "Expected identifier as alias");
5728
+ return {
5729
+ alias: node.alias.name,
5730
+ node: node.node
5731
+ };
5732
+ } else {
5733
+ return {
5734
+ alias: void 0,
5735
+ node
5736
+ };
5737
+ }
5738
+ }
5739
+ __name(stripAlias, "stripAlias");
5740
+
5741
+ // src/client/executor/name-mapper.ts
5742
+ var import_common_helpers11 = require("@zenstackhq/common-helpers");
5743
+ var import_kysely13 = require("kysely");
5744
+ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5673
5745
  static {
5674
5746
  __name(this, "QueryNameMapper");
5675
5747
  }
5676
5748
  schema;
5677
5749
  modelToTableMap = /* @__PURE__ */ new Map();
5678
5750
  fieldToColumnMap = /* @__PURE__ */ new Map();
5679
- modelScopes = [];
5751
+ scopes = [];
5680
5752
  constructor(schema) {
5681
5753
  super(), this.schema = schema;
5682
5754
  for (const [modelName, modelDef] of Object.entries(schema.models)) {
@@ -5697,12 +5769,23 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5697
5769
  if (!node.from?.froms) {
5698
5770
  return super.transformSelectQuery(node);
5699
5771
  }
5700
- const scopes = this.createScopesFromFroms(node.from, true);
5772
+ const processedFroms = node.from.froms.map((from) => this.processSelectTable(from));
5773
+ const processedJoins = (node.joins ?? []).map((join) => this.processSelectTable(join.table));
5774
+ const scopes = [
5775
+ ...processedFroms.map(({ scope }) => scope),
5776
+ ...processedJoins.map(({ scope }) => scope)
5777
+ ];
5701
5778
  return this.withScopes(scopes, () => {
5779
+ const joins = node.joins ? node.joins.map((join, i) => ({
5780
+ ...join,
5781
+ table: processedJoins[i].node,
5782
+ on: this.transformNode(join.on)
5783
+ })) : void 0;
5702
5784
  return {
5703
5785
  ...super.transformSelectQuery(node),
5704
- // convert "from" to nested query as needed
5705
- from: this.processFrom(node.from)
5786
+ from: import_kysely13.FromNode.create(processedFroms.map((f) => f.node)),
5787
+ joins,
5788
+ selections: this.processSelectQuerySelections(node)
5706
5789
  };
5707
5790
  });
5708
5791
  }
@@ -5725,27 +5808,13 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5725
5808
  selections: this.processSelections(node.selections)
5726
5809
  };
5727
5810
  }
5728
- transformJoin(node) {
5729
- const { alias, node: innerNode } = this.stripAlias(node.table);
5730
- if (import_kysely12.TableNode.is(innerNode)) {
5731
- const modelName = innerNode.table.identifier.name;
5732
- if (this.hasMappedColumns(modelName)) {
5733
- const select = this.createSelectAll(modelName);
5734
- return {
5735
- ...super.transformJoin(node),
5736
- table: this.wrapAlias(select, alias ?? modelName)
5737
- };
5738
- }
5739
- }
5740
- return super.transformJoin(node);
5741
- }
5742
5811
  transformReference(node) {
5743
- if (!import_kysely12.ColumnNode.is(node.column)) {
5812
+ if (!import_kysely13.ColumnNode.is(node.column)) {
5744
5813
  return super.transformReference(node);
5745
5814
  }
5746
- const { fieldDef, modelDef, scope } = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
5747
- if (fieldDef && !scope.namesMapped) {
5748
- const mappedFieldName = this.mapFieldName(modelDef.name, fieldDef.name);
5815
+ const scope = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
5816
+ if (scope && !scope.namesMapped && scope.model) {
5817
+ const mappedFieldName = this.mapFieldName(scope.model, node.column.column.name);
5749
5818
  let mappedTableName = node.table?.table.identifier.name;
5750
5819
  if (mappedTableName) {
5751
5820
  if (scope.alias === mappedTableName) {
@@ -5753,22 +5822,25 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5753
5822
  mappedTableName = this.mapTableName(scope.model);
5754
5823
  }
5755
5824
  }
5756
- return import_kysely12.ReferenceNode.create(import_kysely12.ColumnNode.create(mappedFieldName), mappedTableName ? import_kysely12.TableNode.create(mappedTableName) : void 0);
5825
+ return import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(mappedFieldName), mappedTableName ? import_kysely13.TableNode.create(mappedTableName) : void 0);
5757
5826
  } else {
5758
5827
  return super.transformReference(node);
5759
5828
  }
5760
5829
  }
5761
5830
  transformColumn(node) {
5762
- const { modelDef, fieldDef, scope } = this.resolveFieldFromScopes(node.column.name);
5763
- if (!fieldDef || scope.namesMapped) {
5831
+ const scope = this.resolveFieldFromScopes(node.column.name);
5832
+ if (!scope || scope.namesMapped || !scope.model) {
5764
5833
  return super.transformColumn(node);
5765
5834
  }
5766
- const mappedName = this.mapFieldName(modelDef.name, fieldDef.name);
5767
- return import_kysely12.ColumnNode.create(mappedName);
5835
+ const mappedName = this.mapFieldName(scope.model, node.column.name);
5836
+ return import_kysely13.ColumnNode.create(mappedName);
5768
5837
  }
5769
5838
  transformUpdateQuery(node) {
5770
- const { alias, node: innerTable } = this.stripAlias(node.table);
5771
- if (!innerTable || !import_kysely12.TableNode.is(innerTable)) {
5839
+ if (!node.table) {
5840
+ return super.transformUpdateQuery(node);
5841
+ }
5842
+ const { alias, node: innerTable } = stripAlias(node.table);
5843
+ if (!innerTable || !import_kysely13.TableNode.is(innerTable)) {
5772
5844
  return super.transformUpdateQuery(node);
5773
5845
  }
5774
5846
  return this.withScope({
@@ -5783,10 +5855,17 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5783
5855
  });
5784
5856
  }
5785
5857
  transformDeleteQuery(node) {
5786
- const scopes = this.createScopesFromFroms(node.from, false);
5858
+ const scopes = node.from.froms.map((node2) => {
5859
+ const { alias, node: innerNode } = stripAlias(node2);
5860
+ return {
5861
+ model: this.extractModelName(innerNode),
5862
+ alias,
5863
+ namesMapped: false
5864
+ };
5865
+ });
5787
5866
  const froms = node.from.froms.map((from) => {
5788
- const { alias, node: innerNode } = this.stripAlias(from);
5789
- if (import_kysely12.TableNode.is(innerNode)) {
5867
+ const { alias, node: innerNode } = stripAlias(from);
5868
+ if (import_kysely13.TableNode.is(innerNode)) {
5790
5869
  return this.wrapAlias(this.processTableRef(innerNode), alias);
5791
5870
  } else {
5792
5871
  return super.transformNode(from);
@@ -5795,52 +5874,81 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5795
5874
  return this.withScopes(scopes, () => {
5796
5875
  return {
5797
5876
  ...super.transformDeleteQuery(node),
5798
- from: import_kysely12.FromNode.create(froms)
5877
+ from: import_kysely13.FromNode.create(froms)
5799
5878
  };
5800
5879
  });
5801
5880
  }
5802
5881
  // #endregion
5803
5882
  // #region utils
5883
+ processSelectQuerySelections(node) {
5884
+ const selections = [];
5885
+ for (const selection of node.selections ?? []) {
5886
+ if (import_kysely13.SelectAllNode.is(selection.selection)) {
5887
+ const scope = this.scopes[this.scopes.length - 1];
5888
+ if (scope?.model && !scope.namesMapped) {
5889
+ selections.push(...this.createSelectAllFields(scope.model, scope.alias));
5890
+ } else {
5891
+ selections.push(super.transformSelection(selection));
5892
+ }
5893
+ } else if (import_kysely13.ReferenceNode.is(selection.selection) || import_kysely13.ColumnNode.is(selection.selection)) {
5894
+ const transformed = this.transformNode(selection.selection);
5895
+ if (import_kysely13.AliasNode.is(transformed)) {
5896
+ selections.push(import_kysely13.SelectionNode.create(transformed));
5897
+ } else {
5898
+ const origFieldName = this.extractFieldName(selection.selection);
5899
+ const fieldName = this.extractFieldName(transformed);
5900
+ if (fieldName !== origFieldName) {
5901
+ selections.push(import_kysely13.SelectionNode.create(this.wrapAlias(transformed, origFieldName)));
5902
+ } else {
5903
+ selections.push(import_kysely13.SelectionNode.create(transformed));
5904
+ }
5905
+ }
5906
+ } else {
5907
+ selections.push(super.transformSelection(selection));
5908
+ }
5909
+ }
5910
+ return selections;
5911
+ }
5804
5912
  resolveFieldFromScopes(name, qualifier) {
5805
- for (const scope of this.modelScopes.toReversed()) {
5913
+ for (let i = this.scopes.length - 1; i >= 0; i--) {
5914
+ const scope = this.scopes[i];
5806
5915
  if (qualifier) {
5807
5916
  if (scope.alias) {
5808
- if (qualifier !== scope.alias) {
5917
+ if (scope.alias === qualifier) {
5918
+ return scope;
5919
+ } else {
5809
5920
  continue;
5810
5921
  }
5811
- } else {
5812
- if (qualifier !== scope.model) {
5922
+ } else if (scope.model) {
5923
+ if (scope.model === qualifier) {
5924
+ return scope;
5925
+ } else {
5813
5926
  continue;
5814
5927
  }
5815
5928
  }
5816
- }
5817
- const modelDef = getModel(this.schema, scope.model);
5818
- if (!modelDef) {
5819
- continue;
5820
- }
5821
- if (modelDef.fields[name]) {
5822
- return {
5823
- modelDef,
5824
- fieldDef: modelDef.fields[name],
5825
- scope
5826
- };
5929
+ } else {
5930
+ if (scope.model) {
5931
+ const modelDef = getModel(this.schema, scope.model);
5932
+ if (!modelDef) {
5933
+ continue;
5934
+ }
5935
+ if (modelDef.fields[name]) {
5936
+ return scope;
5937
+ }
5938
+ }
5827
5939
  }
5828
5940
  }
5829
- return {
5830
- modelDef: void 0,
5831
- fieldDef: void 0,
5832
- scope: void 0
5833
- };
5941
+ return void 0;
5834
5942
  }
5835
5943
  pushScope(scope) {
5836
- this.modelScopes.push(scope);
5944
+ this.scopes.push(scope);
5837
5945
  }
5838
5946
  withScope(scope, fn) {
5839
5947
  this.pushScope(scope);
5840
5948
  try {
5841
5949
  return fn();
5842
5950
  } finally {
5843
- this.modelScopes.pop();
5951
+ this.scopes.pop();
5844
5952
  }
5845
5953
  }
5846
5954
  withScopes(scopes, fn) {
@@ -5848,26 +5956,20 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5848
5956
  try {
5849
5957
  return fn();
5850
5958
  } finally {
5851
- scopes.forEach(() => this.modelScopes.pop());
5959
+ scopes.forEach(() => this.scopes.pop());
5852
5960
  }
5853
5961
  }
5854
5962
  wrapAlias(node, alias) {
5855
- return alias ? import_kysely12.AliasNode.create(node, import_kysely12.IdentifierNode.create(alias)) : node;
5856
- }
5857
- ensureAlias(node, alias, fallbackName) {
5858
- if (!node) {
5859
- return node;
5860
- }
5861
- return alias ? import_kysely12.AliasNode.create(node, import_kysely12.IdentifierNode.create(alias)) : import_kysely12.AliasNode.create(node, import_kysely12.IdentifierNode.create(fallbackName));
5963
+ return alias ? import_kysely13.AliasNode.create(node, import_kysely13.IdentifierNode.create(alias)) : node;
5862
5964
  }
5863
5965
  processTableRef(node) {
5864
5966
  if (!node) {
5865
5967
  return node;
5866
5968
  }
5867
- if (!import_kysely12.TableNode.is(node)) {
5969
+ if (!import_kysely13.TableNode.is(node)) {
5868
5970
  return super.transformNode(node);
5869
5971
  }
5870
- return import_kysely12.TableNode.create(this.mapTableName(node.table.identifier.name));
5972
+ return import_kysely13.TableNode.create(this.mapTableName(node.table.identifier.name));
5871
5973
  }
5872
5974
  getMappedName(def) {
5873
5975
  const mapAttr = def.attributes?.find((attr) => attr.name === "@@map" || attr.name === "@map");
@@ -5895,86 +5997,49 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5895
5997
  return tableName;
5896
5998
  }
5897
5999
  }
5898
- stripAlias(node) {
5899
- if (!node) {
5900
- return {
5901
- alias: void 0,
5902
- node
5903
- };
5904
- }
5905
- if (import_kysely12.AliasNode.is(node)) {
5906
- (0, import_common_helpers10.invariant)(import_kysely12.IdentifierNode.is(node.alias), "Expected identifier as alias");
5907
- return {
5908
- alias: node.alias.name,
5909
- node: node.node
5910
- };
5911
- }
5912
- return {
5913
- alias: void 0,
5914
- node
5915
- };
5916
- }
5917
6000
  hasMappedColumns(modelName) {
5918
6001
  return [
5919
6002
  ...this.fieldToColumnMap.keys()
5920
6003
  ].some((key) => key.startsWith(modelName + "."));
5921
6004
  }
5922
- createScopesFromFroms(node, namesMapped) {
5923
- if (!node) {
5924
- return [];
5925
- }
5926
- return node.froms.map((from) => {
5927
- const { alias, node: innerNode } = this.stripAlias(from);
5928
- if (innerNode && import_kysely12.TableNode.is(innerNode)) {
5929
- return {
5930
- model: innerNode.table.identifier.name,
5931
- alias,
5932
- namesMapped
5933
- };
5934
- } else {
5935
- return void 0;
5936
- }
5937
- }).filter((s) => !!s);
5938
- }
5939
6005
  // convert a "from" node to a nested query if there are columns with name mapping
5940
- processFrom(node) {
5941
- return {
5942
- ...super.transformFrom(node),
5943
- froms: node.froms.map((from) => {
5944
- const { alias, node: innerNode } = this.stripAlias(from);
5945
- if (!innerNode) {
5946
- return super.transformNode(from);
5947
- }
5948
- if (import_kysely12.TableNode.is(innerNode)) {
5949
- if (this.hasMappedColumns(innerNode.table.identifier.name)) {
5950
- const selectAll = this.createSelectAll(innerNode.table.identifier.name);
5951
- return this.ensureAlias(selectAll, alias, innerNode.table.identifier.name);
5952
- }
6006
+ processSelectTable(node) {
6007
+ const { alias, node: innerNode } = stripAlias(node);
6008
+ if (innerNode && import_kysely13.TableNode.is(innerNode)) {
6009
+ const modelName = innerNode.table.identifier.name;
6010
+ const mappedName = this.mapTableName(modelName);
6011
+ const finalAlias = alias ?? (mappedName !== modelName ? modelName : void 0);
6012
+ return {
6013
+ node: this.wrapAlias(import_kysely13.TableNode.create(mappedName), finalAlias),
6014
+ scope: {
6015
+ alias: alias ?? modelName,
6016
+ model: modelName,
6017
+ namesMapped: !this.hasMappedColumns(modelName)
5953
6018
  }
5954
- return this.transformNode(from);
5955
- })
5956
- };
6019
+ };
6020
+ } else {
6021
+ return {
6022
+ node: super.transformNode(node),
6023
+ scope: {
6024
+ alias,
6025
+ model: void 0,
6026
+ namesMapped: true
6027
+ }
6028
+ };
6029
+ }
5957
6030
  }
5958
- // create a `SelectQueryNode` for the given model with all columns mapped
5959
- createSelectAll(model) {
6031
+ createSelectAllFields(model, alias) {
5960
6032
  const modelDef = requireModel(this.schema, model);
5961
- const tableName = this.mapTableName(model);
5962
- return {
5963
- kind: "SelectQueryNode",
5964
- from: import_kysely12.FromNode.create([
5965
- import_kysely12.TableNode.create(tableName)
5966
- ]),
5967
- selections: this.getModelFields(modelDef).map((fieldDef) => {
5968
- const columnName = this.mapFieldName(model, fieldDef.name);
5969
- const columnRef = import_kysely12.ReferenceNode.create(import_kysely12.ColumnNode.create(columnName), import_kysely12.TableNode.create(tableName));
5970
- if (columnName !== fieldDef.name) {
5971
- const aliased = import_kysely12.AliasNode.create(columnRef, import_kysely12.IdentifierNode.create(fieldDef.name));
5972
- return import_kysely12.SelectionNode.create(aliased);
5973
- } else {
5974
- return import_kysely12.SelectionNode.create(columnRef);
5975
- }
5976
- })
5977
- };
6033
+ return this.getModelFields(modelDef).map((fieldDef) => {
6034
+ const columnName = this.mapFieldName(model, fieldDef.name);
6035
+ const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName), alias ? import_kysely13.TableNode.create(alias) : void 0);
6036
+ if (columnName !== fieldDef.name) {
6037
+ const aliased = import_kysely13.AliasNode.create(columnRef, import_kysely13.IdentifierNode.create(fieldDef.name));
6038
+ return import_kysely13.SelectionNode.create(aliased);
6039
+ } else {
6040
+ return import_kysely13.SelectionNode.create(columnRef);
6041
+ }
6042
+ });
5978
6043
  }
5979
6044
  getModelFields(modelDef) {
5980
6045
  return Object.values(modelDef.fields).filter((f) => !f.relation && !f.computed && !f.originModel);
@@ -5982,44 +6047,48 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5982
6047
  processSelections(selections) {
5983
6048
  const result = [];
5984
6049
  selections.forEach((selection) => {
5985
- if (import_kysely12.SelectAllNode.is(selection.selection)) {
6050
+ if (import_kysely13.SelectAllNode.is(selection.selection)) {
5986
6051
  const processed = this.processSelectAll(selection.selection);
5987
6052
  if (Array.isArray(processed)) {
5988
- result.push(...processed.map((s) => import_kysely12.SelectionNode.create(s)));
6053
+ result.push(...processed.map((s) => import_kysely13.SelectionNode.create(s)));
5989
6054
  } else {
5990
- result.push(import_kysely12.SelectionNode.create(processed));
6055
+ result.push(import_kysely13.SelectionNode.create(processed));
5991
6056
  }
5992
6057
  } else {
5993
- result.push(import_kysely12.SelectionNode.create(this.processSelection(selection.selection)));
6058
+ result.push(import_kysely13.SelectionNode.create(this.processSelection(selection.selection)));
5994
6059
  }
5995
6060
  });
5996
6061
  return result;
5997
6062
  }
5998
6063
  processSelection(node) {
5999
6064
  let alias;
6000
- if (!import_kysely12.AliasNode.is(node)) {
6065
+ if (!import_kysely13.AliasNode.is(node)) {
6001
6066
  alias = this.extractFieldName(node);
6002
6067
  }
6003
6068
  const result = super.transformNode(node);
6004
6069
  return this.wrapAlias(result, alias);
6005
6070
  }
6006
6071
  processSelectAll(node) {
6007
- const scope = this.modelScopes[this.modelScopes.length - 1];
6008
- (0, import_common_helpers10.invariant)(scope);
6009
- if (!this.hasMappedColumns(scope.model)) {
6072
+ const scope = this.scopes[this.scopes.length - 1];
6073
+ (0, import_common_helpers11.invariant)(scope);
6074
+ if (!scope.model || !this.hasMappedColumns(scope.model)) {
6010
6075
  return super.transformSelectAll(node);
6011
6076
  }
6012
6077
  const modelDef = requireModel(this.schema, scope.model);
6013
6078
  return this.getModelFields(modelDef).map((fieldDef) => {
6014
- const columnName = this.mapFieldName(scope.model, fieldDef.name);
6015
- const columnRef = import_kysely12.ReferenceNode.create(import_kysely12.ColumnNode.create(columnName));
6079
+ const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
6080
+ const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName));
6016
6081
  return columnName !== fieldDef.name ? this.wrapAlias(columnRef, fieldDef.name) : columnRef;
6017
6082
  });
6018
6083
  }
6084
+ extractModelName(node) {
6085
+ const { node: innerNode } = stripAlias(node);
6086
+ return import_kysely13.TableNode.is(innerNode) ? innerNode.table.identifier.name : void 0;
6087
+ }
6019
6088
  extractFieldName(node) {
6020
- if (import_kysely12.ReferenceNode.is(node) && import_kysely12.ColumnNode.is(node.column)) {
6089
+ if (import_kysely13.ReferenceNode.is(node) && import_kysely13.ColumnNode.is(node.column)) {
6021
6090
  return node.column.column.name;
6022
- } else if (import_kysely12.ColumnNode.is(node)) {
6091
+ } else if (import_kysely13.ColumnNode.is(node)) {
6023
6092
  return node.column.name;
6024
6093
  } else {
6025
6094
  return void 0;
@@ -6028,7 +6097,7 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
6028
6097
  };
6029
6098
 
6030
6099
  // src/client/executor/zenstack-query-executor.ts
6031
- var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13.DefaultQueryExecutor {
6100
+ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14.DefaultQueryExecutor {
6032
6101
  static {
6033
6102
  __name(this, "ZenStackQueryExecutor");
6034
6103
  }
@@ -6036,9 +6105,10 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6036
6105
  driver;
6037
6106
  compiler;
6038
6107
  connectionProvider;
6108
+ suppressMutationHooks;
6039
6109
  nameMapper;
6040
- constructor(client, driver, compiler, adapter, connectionProvider, plugins = []) {
6041
- super(compiler, adapter, connectionProvider, plugins), this.client = client, this.driver = driver, this.compiler = compiler, this.connectionProvider = connectionProvider;
6110
+ constructor(client, driver, compiler, adapter, connectionProvider, plugins = [], suppressMutationHooks = false) {
6111
+ super(compiler, adapter, connectionProvider, plugins), this.client = client, this.driver = driver, this.compiler = compiler, this.connectionProvider = connectionProvider, this.suppressMutationHooks = suppressMutationHooks;
6042
6112
  this.nameMapper = new QueryNameMapper(client.$schema);
6043
6113
  }
6044
6114
  get kysely() {
@@ -6047,38 +6117,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6047
6117
  get options() {
6048
6118
  return this.client.$options;
6049
6119
  }
6050
- async executeQuery(compiledQuery, _queryId) {
6051
- let queryNode = compiledQuery.query;
6052
- let mutationInterceptionInfo;
6053
- if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
6054
- mutationInterceptionInfo = await this.callMutationInterceptionFilters(queryNode);
6055
- }
6056
- const task = /* @__PURE__ */ __name(async () => {
6057
- if (this.isMutationNode(queryNode)) {
6058
- await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
6059
- }
6060
- const oldQueryNode = queryNode;
6061
- if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntities) {
6062
- queryNode = {
6063
- ...queryNode,
6064
- returning: import_kysely13.ReturningNode.create([
6065
- import_kysely13.SelectionNode.createSelectAll()
6066
- ])
6067
- };
6068
- }
6069
- const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
6070
- const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
6071
- if (this.isMutationNode(queryNode)) {
6072
- await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
6073
- }
6074
- if (oldQueryNode !== queryNode) {
6075
- }
6076
- return result.result;
6077
- }, "task");
6078
- return task();
6120
+ async executeQuery(compiledQuery, queryId) {
6121
+ const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
6122
+ const result = await this.proceedQueryWithKyselyInterceptors(compiledQuery.query, queryParams, queryId.queryId);
6123
+ return result.result;
6079
6124
  }
6080
- proceedQueryWithKyselyInterceptors(queryNode, parameters) {
6081
- let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
6125
+ async proceedQueryWithKyselyInterceptors(queryNode, parameters, queryId) {
6126
+ let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters, queryId), "proceed");
6082
6127
  const hooks = [];
6083
6128
  for (const plugin of this.client.$options.plugins ?? []) {
6084
6129
  if (plugin.onKyselyQuery) {
@@ -6088,10 +6133,8 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6088
6133
  for (const hook of hooks) {
6089
6134
  const _proceed = proceed;
6090
6135
  proceed = /* @__PURE__ */ __name(async (query) => {
6091
- let connection;
6092
6136
  const _p = /* @__PURE__ */ __name(async (q) => {
6093
6137
  const r = await _proceed(q);
6094
- connection = r.connection;
6095
6138
  return r.result;
6096
6139
  }, "_p");
6097
6140
  const hookResult = await hook({
@@ -6102,190 +6145,232 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6102
6145
  proceed: _p
6103
6146
  });
6104
6147
  return {
6105
- result: hookResult,
6106
- connection
6148
+ result: hookResult
6107
6149
  };
6108
6150
  }, "proceed");
6109
6151
  }
6110
- return proceed(queryNode);
6152
+ const result = await proceed(queryNode);
6153
+ return result;
6111
6154
  }
6112
- async proceedQuery(query, parameters) {
6113
- const finalQuery = this.nameMapper.transformNode(query);
6114
- let compiled = this.compileQuery(finalQuery);
6115
- if (parameters) {
6116
- compiled = {
6117
- ...compiled,
6118
- parameters
6119
- };
6120
- }
6155
+ getMutationInfo(queryNode) {
6156
+ const model = this.getMutationModel(queryNode);
6157
+ const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, () => ({
6158
+ action: "create",
6159
+ where: void 0
6160
+ })).when(import_kysely14.UpdateQueryNode.is, (node) => ({
6161
+ action: "update",
6162
+ where: node.where
6163
+ })).when(import_kysely14.DeleteQueryNode.is, (node) => ({
6164
+ action: "delete",
6165
+ where: node.where
6166
+ })).exhaustive();
6167
+ return {
6168
+ model,
6169
+ action,
6170
+ where
6171
+ };
6172
+ }
6173
+ async proceedQuery(query, parameters, queryId) {
6174
+ let compiled;
6121
6175
  try {
6122
6176
  return await this.provideConnection(async (connection) => {
6123
- const result = await connection.executeQuery(compiled);
6124
- return {
6125
- result,
6126
- connection
6127
- };
6177
+ if (this.suppressMutationHooks || !this.isMutationNode(query) || !this.hasEntityMutationPlugins) {
6178
+ const finalQuery2 = this.nameMapper.transformNode(query);
6179
+ compiled = this.compileQuery(finalQuery2);
6180
+ if (parameters) {
6181
+ compiled = {
6182
+ ...compiled,
6183
+ parameters
6184
+ };
6185
+ }
6186
+ const result = await connection.executeQuery(compiled);
6187
+ return {
6188
+ result
6189
+ };
6190
+ }
6191
+ if ((import_kysely14.InsertQueryNode.is(query) || import_kysely14.UpdateQueryNode.is(query)) && this.hasEntityMutationPluginsWithAfterMutationHooks) {
6192
+ query = {
6193
+ ...query,
6194
+ returning: import_kysely14.ReturningNode.create([
6195
+ import_kysely14.SelectionNode.createSelectAll()
6196
+ ])
6197
+ };
6198
+ }
6199
+ const finalQuery = this.nameMapper.transformNode(query);
6200
+ compiled = this.compileQuery(finalQuery);
6201
+ if (parameters) {
6202
+ compiled = {
6203
+ ...compiled,
6204
+ parameters
6205
+ };
6206
+ }
6207
+ const currentlyInTx = this.driver.isTransactionConnection(connection);
6208
+ const connectionClient = this.createClientForConnection(connection, currentlyInTx);
6209
+ const mutationInfo = this.getMutationInfo(finalQuery);
6210
+ let beforeMutationEntities;
6211
+ const loadBeforeMutationEntities = /* @__PURE__ */ __name(async () => {
6212
+ if (beforeMutationEntities === void 0 && (import_kysely14.UpdateQueryNode.is(query) || import_kysely14.DeleteQueryNode.is(query))) {
6213
+ beforeMutationEntities = await this.loadEntities(mutationInfo.model, mutationInfo.where, connection);
6214
+ }
6215
+ return beforeMutationEntities;
6216
+ }, "loadBeforeMutationEntities");
6217
+ await this.callBeforeMutationHooks(finalQuery, mutationInfo, loadBeforeMutationEntities, connectionClient, queryId);
6218
+ const shouldCreateTx = this.hasPluginRequestingAfterMutationWithinTransaction && !this.driver.isTransactionConnection(connection);
6219
+ if (!shouldCreateTx) {
6220
+ const result = await connection.executeQuery(compiled);
6221
+ if (!this.driver.isTransactionConnection(connection)) {
6222
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "all", queryId);
6223
+ } else {
6224
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "inTx", queryId);
6225
+ this.driver.registerTransactionCommitCallback(connection, () => this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "outTx", queryId));
6226
+ }
6227
+ return {
6228
+ result
6229
+ };
6230
+ } else {
6231
+ await this.driver.beginTransaction(connection, {
6232
+ isolationLevel: TransactionIsolationLevel.ReadCommitted
6233
+ });
6234
+ try {
6235
+ const result = await connection.executeQuery(compiled);
6236
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "inTx", queryId);
6237
+ await this.driver.commitTransaction(connection);
6238
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "outTx", queryId);
6239
+ return {
6240
+ result
6241
+ };
6242
+ } catch (err) {
6243
+ await this.driver.rollbackTransaction(connection);
6244
+ throw err;
6245
+ }
6246
+ }
6128
6247
  });
6129
6248
  } catch (err) {
6130
- const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
6249
+ const message = `Failed to execute query: ${err}, sql: ${compiled?.sql}`;
6131
6250
  throw new QueryError(message, err);
6132
6251
  }
6133
6252
  }
6253
+ createClientForConnection(connection, inTx) {
6254
+ const innerExecutor = this.withConnectionProvider(new import_kysely14.SingleConnectionProvider(connection));
6255
+ innerExecutor.suppressMutationHooks = true;
6256
+ const innerClient = this.client.withExecutor(innerExecutor);
6257
+ if (inTx) {
6258
+ innerClient.forceTransaction();
6259
+ }
6260
+ return innerClient;
6261
+ }
6262
+ get hasEntityMutationPlugins() {
6263
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation);
6264
+ }
6265
+ get hasEntityMutationPluginsWithAfterMutationHooks() {
6266
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.afterEntityMutation);
6267
+ }
6268
+ get hasPluginRequestingAfterMutationWithinTransaction() {
6269
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.runAfterMutationWithinTransaction);
6270
+ }
6134
6271
  isMutationNode(queryNode) {
6135
- return import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode);
6272
+ return import_kysely14.InsertQueryNode.is(queryNode) || import_kysely14.UpdateQueryNode.is(queryNode) || import_kysely14.DeleteQueryNode.is(queryNode);
6136
6273
  }
6137
6274
  withPlugin(plugin) {
6138
6275
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
6139
6276
  ...this.plugins,
6140
6277
  plugin
6141
- ]);
6278
+ ], this.suppressMutationHooks);
6142
6279
  }
6143
6280
  withPlugins(plugins) {
6144
6281
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
6145
6282
  ...this.plugins,
6146
6283
  ...plugins
6147
- ]);
6284
+ ], this.suppressMutationHooks);
6148
6285
  }
6149
6286
  withPluginAtFront(plugin) {
6150
6287
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
6151
6288
  plugin,
6152
6289
  ...this.plugins
6153
- ]);
6290
+ ], this.suppressMutationHooks);
6154
6291
  }
6155
6292
  withoutPlugins() {
6156
- return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, []);
6293
+ return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [], this.suppressMutationHooks);
6157
6294
  }
6158
6295
  withConnectionProvider(connectionProvider) {
6159
- const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
6296
+ const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider, this.plugins, this.suppressMutationHooks);
6160
6297
  newExecutor.client = this.client.withExecutor(newExecutor);
6161
6298
  return newExecutor;
6162
6299
  }
6163
- get hasMutationHooks() {
6164
- return this.client.$options.plugins?.some((plugin) => !!plugin.onEntityMutation);
6165
- }
6166
6300
  getMutationModel(queryNode) {
6167
- return (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, (node) => node.into.table.identifier.name).when(import_kysely13.UpdateQueryNode.is, (node) => node.table.table.identifier.name).when(import_kysely13.DeleteQueryNode.is, (node) => {
6168
- if (node.from.froms.length !== 1) {
6169
- throw new InternalError(`Delete query must have exactly one from table`);
6170
- }
6171
- return node.from.froms[0].table.identifier.name;
6301
+ return (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, (node) => {
6302
+ (0, import_common_helpers12.invariant)(node.into, "InsertQueryNode must have an into clause");
6303
+ return node.into.table.identifier.name;
6304
+ }).when(import_kysely14.UpdateQueryNode.is, (node) => {
6305
+ (0, import_common_helpers12.invariant)(node.table, "UpdateQueryNode must have a table");
6306
+ const { node: tableNode } = stripAlias(node.table);
6307
+ (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "UpdateQueryNode must use a TableNode");
6308
+ return tableNode.table.identifier.name;
6309
+ }).when(import_kysely14.DeleteQueryNode.is, (node) => {
6310
+ (0, import_common_helpers12.invariant)(node.from.froms.length === 1, "Delete query must have exactly one from table");
6311
+ const { node: tableNode } = stripAlias(node.from.froms[0]);
6312
+ (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "DeleteQueryNode must use a TableNode");
6313
+ return tableNode.table.identifier.name;
6172
6314
  }).otherwise((node) => {
6173
6315
  throw new InternalError(`Invalid query node: ${node}`);
6174
6316
  });
6175
6317
  }
6176
- async callMutationInterceptionFilters(queryNode) {
6177
- const plugins = this.client.$options.plugins;
6178
- if (plugins) {
6179
- const mutationModel = this.getMutationModel(queryNode);
6180
- const result = {
6181
- intercept: false
6182
- };
6183
- const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
6184
- action: "create",
6185
- where: void 0
6186
- })).when(import_kysely13.UpdateQueryNode.is, (node) => ({
6187
- action: "update",
6188
- where: node.where
6189
- })).when(import_kysely13.DeleteQueryNode.is, (node) => ({
6190
- action: "delete",
6191
- where: node.where
6192
- })).exhaustive();
6193
- for (const plugin of plugins) {
6194
- const onEntityMutation = plugin.onEntityMutation;
6195
- if (!onEntityMutation) {
6196
- continue;
6197
- }
6198
- if (!onEntityMutation.mutationInterceptionFilter) {
6199
- result.intercept = true;
6200
- } else {
6201
- const filterResult = await onEntityMutation.mutationInterceptionFilter({
6202
- model: mutationModel,
6203
- action,
6204
- queryNode
6205
- });
6206
- result.intercept ||= filterResult.intercept;
6207
- result.loadBeforeMutationEntities ||= filterResult.loadBeforeMutationEntities;
6208
- result.loadAfterMutationEntities ||= filterResult.loadAfterMutationEntities;
6209
- }
6210
- }
6211
- let beforeMutationEntities;
6212
- if (result.loadBeforeMutationEntities && (import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode))) {
6213
- beforeMutationEntities = await this.loadEntities(mutationModel, where);
6214
- }
6215
- return {
6216
- ...result,
6217
- mutationModel,
6218
- action,
6219
- where,
6220
- beforeMutationEntities
6221
- };
6222
- } else {
6223
- return void 0;
6224
- }
6225
- }
6226
- async callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
6227
- if (!mutationInterceptionInfo?.intercept) {
6228
- return;
6229
- }
6318
+ async callBeforeMutationHooks(queryNode, mutationInfo, loadBeforeMutationEntities, client, queryId) {
6230
6319
  if (this.options.plugins) {
6231
- const mutationModel = this.getMutationModel(queryNode);
6232
6320
  for (const plugin of this.options.plugins) {
6233
6321
  const onEntityMutation = plugin.onEntityMutation;
6234
- if (onEntityMutation?.beforeEntityMutation) {
6235
- await onEntityMutation.beforeEntityMutation({
6236
- model: mutationModel,
6237
- action: mutationInterceptionInfo.action,
6238
- queryNode,
6239
- entities: mutationInterceptionInfo.beforeMutationEntities
6240
- });
6322
+ if (!onEntityMutation?.beforeEntityMutation) {
6323
+ continue;
6241
6324
  }
6325
+ await onEntityMutation.beforeEntityMutation({
6326
+ model: mutationInfo.model,
6327
+ action: mutationInfo.action,
6328
+ queryNode,
6329
+ loadBeforeMutationEntities,
6330
+ client,
6331
+ queryId
6332
+ });
6242
6333
  }
6243
6334
  }
6244
6335
  }
6245
- async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
6246
- if (!mutationInterceptionInfo?.intercept) {
6247
- return;
6248
- }
6336
+ async callAfterMutationHooks(queryResult, queryNode, mutationInfo, client, filterFor, queryId) {
6249
6337
  const hooks = [];
6250
6338
  for (const plugin of this.options.plugins ?? []) {
6251
6339
  const onEntityMutation = plugin.onEntityMutation;
6252
- if (onEntityMutation?.afterEntityMutation) {
6253
- hooks.push(onEntityMutation.afterEntityMutation.bind(plugin));
6340
+ if (!onEntityMutation?.afterEntityMutation) {
6341
+ continue;
6254
6342
  }
6343
+ if (filterFor === "inTx" && !onEntityMutation.runAfterMutationWithinTransaction) {
6344
+ continue;
6345
+ }
6346
+ if (filterFor === "outTx" && onEntityMutation.runAfterMutationWithinTransaction) {
6347
+ continue;
6348
+ }
6349
+ hooks.push(onEntityMutation.afterEntityMutation.bind(plugin));
6255
6350
  }
6256
6351
  if (hooks.length === 0) {
6257
6352
  return;
6258
6353
  }
6259
6354
  const mutationModel = this.getMutationModel(queryNode);
6260
- const inTransaction = this.driver.isTransactionConnection(connection);
6261
- for (const hook of hooks) {
6262
- let afterMutationEntities = void 0;
6263
- if (mutationInterceptionInfo.loadAfterMutationEntities) {
6264
- if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
6265
- afterMutationEntities = queryResult.rows;
6266
- }
6267
- }
6268
- const action = /* @__PURE__ */ __name(async () => {
6269
- try {
6270
- await hook({
6271
- model: mutationModel,
6272
- action: mutationInterceptionInfo.action,
6273
- queryNode,
6274
- beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
6275
- afterMutationEntities
6276
- });
6277
- } catch (err) {
6278
- console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
6279
- }
6280
- }, "action");
6281
- if (inTransaction) {
6282
- this.driver.registerTransactionCommitCallback(connection, action);
6355
+ const loadAfterMutationEntities = /* @__PURE__ */ __name(async () => {
6356
+ if (mutationInfo.action === "delete") {
6357
+ return void 0;
6283
6358
  } else {
6284
- await action();
6359
+ return queryResult.rows;
6285
6360
  }
6361
+ }, "loadAfterMutationEntities");
6362
+ for (const hook of hooks) {
6363
+ await hook({
6364
+ model: mutationModel,
6365
+ action: mutationInfo.action,
6366
+ queryNode,
6367
+ loadAfterMutationEntities,
6368
+ client,
6369
+ queryId
6370
+ });
6286
6371
  }
6287
6372
  }
6288
- async loadEntities(model, where) {
6373
+ async loadEntities(model, where, connection) {
6289
6374
  const selectQuery = this.kysely.selectFrom(model).selectAll();
6290
6375
  let selectQueryNode = selectQuery.toOperationNode();
6291
6376
  selectQueryNode = {
@@ -6293,16 +6378,14 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6293
6378
  where: this.andNodes(selectQueryNode.where, where)
6294
6379
  };
6295
6380
  const compiled = this.compileQuery(selectQueryNode);
6296
- const result = await this.executeQuery(compiled, {
6297
- queryId: `zenstack-${(0, import_nanoid2.nanoid)()}`
6298
- });
6381
+ const result = await connection.executeQuery(compiled);
6299
6382
  return result.rows;
6300
6383
  }
6301
6384
  andNodes(condition1, condition2) {
6302
6385
  if (condition1 && condition2) {
6303
- return import_kysely13.WhereNode.create(import_kysely13.AndNode.create(condition1, condition2));
6386
+ return import_kysely14.WhereNode.create(import_kysely14.AndNode.create(condition1, condition2));
6304
6387
  } else if (condition1) {
6305
- return import_kysely13.WhereNode.create(condition1);
6388
+ return import_kysely14.WhereNode.create(condition1);
6306
6389
  } else {
6307
6390
  return condition2;
6308
6391
  }
@@ -6324,8 +6407,8 @@ __export(functions_exports, {
6324
6407
  search: () => search,
6325
6408
  startsWith: () => startsWith
6326
6409
  });
6327
- var import_common_helpers11 = require("@zenstackhq/common-helpers");
6328
- var import_kysely14 = require("kysely");
6410
+ var import_common_helpers13 = require("@zenstackhq/common-helpers");
6411
+ var import_kysely15 = require("kysely");
6329
6412
  var import_ts_pattern17 = require("ts-pattern");
6330
6413
  var contains = /* @__PURE__ */ __name((eb, args) => {
6331
6414
  const [field, search2, caseInsensitive = false] = args;
@@ -6336,9 +6419,9 @@ var contains = /* @__PURE__ */ __name((eb, args) => {
6336
6419
  throw new Error('"search" parameter is required');
6337
6420
  }
6338
6421
  const searchExpr = eb.fn("CONCAT", [
6339
- import_kysely14.sql.lit("%"),
6422
+ import_kysely15.sql.lit("%"),
6340
6423
  search2,
6341
- import_kysely14.sql.lit("%")
6424
+ import_kysely15.sql.lit("%")
6342
6425
  ]);
6343
6426
  return eb(field, caseInsensitive ? "ilike" : "like", searchExpr);
6344
6427
  }, "contains");
@@ -6355,7 +6438,7 @@ var startsWith = /* @__PURE__ */ __name((eb, args) => {
6355
6438
  }
6356
6439
  return eb(field, "like", eb.fn("CONCAT", [
6357
6440
  search2,
6358
- import_kysely14.sql.lit("%")
6441
+ import_kysely15.sql.lit("%")
6359
6442
  ]));
6360
6443
  }, "startsWith");
6361
6444
  var endsWith = /* @__PURE__ */ __name((eb, args) => {
@@ -6367,7 +6450,7 @@ var endsWith = /* @__PURE__ */ __name((eb, args) => {
6367
6450
  throw new Error('"search" parameter is required');
6368
6451
  }
6369
6452
  return eb(field, "like", eb.fn("CONCAT", [
6370
- import_kysely14.sql.lit("%"),
6453
+ import_kysely15.sql.lit("%"),
6371
6454
  search2
6372
6455
  ]));
6373
6456
  }, "endsWith");
@@ -6408,10 +6491,10 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6408
6491
  if (!field) {
6409
6492
  throw new Error('"field" parameter is required');
6410
6493
  }
6411
- return eb(dialect.buildArrayLength(eb, field), "=", import_kysely14.sql.lit(0));
6494
+ return eb(dialect.buildArrayLength(eb, field), "=", import_kysely15.sql.lit(0));
6412
6495
  }, "isEmpty");
6413
6496
  var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6414
- return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6497
+ return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely15.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6415
6498
  }, "now");
6416
6499
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6417
6500
  let result = model;
@@ -6419,7 +6502,7 @@ var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6419
6502
  if (casing) {
6420
6503
  result = processCasing(casing, result, model);
6421
6504
  }
6422
- return import_kysely14.sql.lit(result);
6505
+ return import_kysely15.sql.lit(result);
6423
6506
  }, "currentModel");
6424
6507
  var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6425
6508
  let result = operation;
@@ -6427,12 +6510,12 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6427
6510
  if (casing) {
6428
6511
  result = processCasing(casing, result, operation);
6429
6512
  }
6430
- return import_kysely14.sql.lit(result);
6513
+ return import_kysely15.sql.lit(result);
6431
6514
  }, "currentOperation");
6432
6515
  function processCasing(casing, result, model) {
6433
6516
  const opNode = casing.toOperationNode();
6434
- (0, import_common_helpers11.invariant)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6435
- result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers11.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers11.lowerCaseFirst)(result)).otherwise(() => {
6517
+ (0, import_common_helpers13.invariant)(import_kysely15.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6518
+ result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers13.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers13.lowerCaseFirst)(result)).otherwise(() => {
6436
6519
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6437
6520
  });
6438
6521
  return result;
@@ -6440,8 +6523,8 @@ function processCasing(casing, result, model) {
6440
6523
  __name(processCasing, "processCasing");
6441
6524
 
6442
6525
  // src/client/helpers/schema-db-pusher.ts
6443
- var import_common_helpers12 = require("@zenstackhq/common-helpers");
6444
- var import_kysely15 = require("kysely");
6526
+ var import_common_helpers14 = require("@zenstackhq/common-helpers");
6527
+ var import_kysely16 = require("kysely");
6445
6528
  var import_toposort = __toESM(require("toposort"), 1);
6446
6529
  var import_ts_pattern18 = require("ts-pattern");
6447
6530
  var SchemaDbPusher = class {
@@ -6501,7 +6584,7 @@ var SchemaDbPusher = class {
6501
6584
  return (0, import_toposort.default)(graph).reverse().filter((m) => !!m);
6502
6585
  }
6503
6586
  createModelTable(kysely, modelDef) {
6504
- let table = kysely.schema.createTable(modelDef.name).ifNotExists();
6587
+ let table = kysely.schema.createTable(this.getTableName(modelDef)).ifNotExists();
6505
6588
  for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
6506
6589
  if (fieldDef.originModel && !fieldDef.id) {
6507
6590
  continue;
@@ -6520,6 +6603,26 @@ var SchemaDbPusher = class {
6520
6603
  table = this.addUniqueConstraint(table, modelDef);
6521
6604
  return table;
6522
6605
  }
6606
+ getTableName(modelDef) {
6607
+ const mapAttr = modelDef.attributes?.find((a) => a.name === "@@map");
6608
+ if (mapAttr && mapAttr.args?.[0]) {
6609
+ const mappedName = ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
6610
+ if (mappedName) {
6611
+ return mappedName;
6612
+ }
6613
+ }
6614
+ return modelDef.name;
6615
+ }
6616
+ getColumnName(fieldDef) {
6617
+ const mapAttr = fieldDef.attributes?.find((a) => a.name === "@map");
6618
+ if (mapAttr && mapAttr.args?.[0]) {
6619
+ const mappedName = ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
6620
+ if (mappedName) {
6621
+ return mappedName;
6622
+ }
6623
+ }
6624
+ return fieldDef.name;
6625
+ }
6523
6626
  isComputedField(fieldDef) {
6524
6627
  return fieldDef.attributes?.some((a) => a.name === "@computed");
6525
6628
  }
@@ -6530,36 +6633,36 @@ var SchemaDbPusher = class {
6530
6633
  }
6531
6634
  }
6532
6635
  if (modelDef.idFields.length > 0) {
6533
- table = table.addPrimaryKeyConstraint(`pk_${modelDef.name}`, modelDef.idFields);
6636
+ table = table.addPrimaryKeyConstraint(`pk_${modelDef.name}`, modelDef.idFields.map((f) => this.getColumnName(modelDef.fields[f])));
6534
6637
  }
6535
6638
  return table;
6536
6639
  }
6537
6640
  addUniqueConstraint(table, modelDef) {
6538
6641
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
6539
- (0, import_common_helpers12.invariant)(typeof value === "object", "expecting an object");
6642
+ (0, import_common_helpers14.invariant)(typeof value === "object", "expecting an object");
6540
6643
  if ("type" in value) {
6541
6644
  const fieldDef = modelDef.fields[key];
6542
6645
  if (fieldDef.unique) {
6543
6646
  continue;
6544
6647
  }
6545
6648
  table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, [
6546
- key
6649
+ this.getColumnName(fieldDef)
6547
6650
  ]);
6548
6651
  } else {
6549
- table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, Object.keys(value));
6652
+ table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, Object.keys(value).map((f) => this.getColumnName(modelDef.fields[f])));
6550
6653
  }
6551
6654
  }
6552
6655
  return table;
6553
6656
  }
6554
6657
  createModelField(table, fieldDef, modelDef) {
6555
- return table.addColumn(fieldDef.name, this.mapFieldType(fieldDef), (col) => {
6658
+ return table.addColumn(this.getColumnName(fieldDef), this.mapFieldType(fieldDef), (col) => {
6556
6659
  if (fieldDef.id && modelDef.idFields.length === 1) {
6557
6660
  col = col.primaryKey();
6558
6661
  }
6559
6662
  if (fieldDef.default !== void 0) {
6560
6663
  if (typeof fieldDef.default === "object" && "kind" in fieldDef.default) {
6561
6664
  if (ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "now") {
6562
- col = col.defaultTo(import_kysely15.sql`CURRENT_TIMESTAMP`);
6665
+ col = col.defaultTo(import_kysely16.sql`CURRENT_TIMESTAMP`);
6563
6666
  }
6564
6667
  } else {
6565
6668
  col = col.defaultTo(fieldDef.default);
@@ -6579,7 +6682,7 @@ var SchemaDbPusher = class {
6579
6682
  }
6580
6683
  mapFieldType(fieldDef) {
6581
6684
  if (this.schema.enums?.[fieldDef.type]) {
6582
- return this.schema.provider.type === "postgresql" ? import_kysely15.sql.ref(fieldDef.type) : "text";
6685
+ return this.schema.provider.type === "postgresql" ? import_kysely16.sql.ref(fieldDef.type) : "text";
6583
6686
  }
6584
6687
  if (this.isAutoIncrement(fieldDef) && this.schema.provider.type === "postgresql") {
6585
6688
  return "serial";
@@ -6592,7 +6695,7 @@ var SchemaDbPusher = class {
6592
6695
  throw new Error(`Unsupported field type: ${type}`);
6593
6696
  });
6594
6697
  if (fieldDef.array) {
6595
- return import_kysely15.sql.raw(`${result}[]`);
6698
+ return import_kysely16.sql.raw(`${result}[]`);
6596
6699
  } else {
6597
6700
  return result;
6598
6701
  }
@@ -6604,11 +6707,13 @@ var SchemaDbPusher = class {
6604
6707
  return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
6605
6708
  }
6606
6709
  addForeignKeyConstraint(table, model, fieldName, fieldDef) {
6607
- (0, import_common_helpers12.invariant)(fieldDef.relation, "field must be a relation");
6710
+ (0, import_common_helpers14.invariant)(fieldDef.relation, "field must be a relation");
6608
6711
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
6609
6712
  return table;
6610
6713
  }
6611
- table = table.addForeignKeyConstraint(`fk_${model}_${fieldName}`, fieldDef.relation.fields, fieldDef.type, fieldDef.relation.references, (cb) => {
6714
+ const modelDef = requireModel(this.schema, model);
6715
+ const relationModelDef = requireModel(this.schema, fieldDef.type);
6716
+ table = table.addForeignKeyConstraint(`fk_${model}_${fieldName}`, fieldDef.relation.fields.map((f) => this.getColumnName(modelDef.fields[f])), this.getTableName(relationModelDef), fieldDef.relation.references.map((f) => this.getColumnName(relationModelDef.fields[f])), (cb) => {
6612
6717
  if (fieldDef.relation?.onDelete) {
6613
6718
  cb = cb.onDelete(this.mapCascadeAction(fieldDef.relation.onDelete));
6614
6719
  }
@@ -6659,7 +6764,7 @@ function valueToPromise(thing) {
6659
6764
  __name(valueToPromise, "valueToPromise");
6660
6765
 
6661
6766
  // src/client/result-processor.ts
6662
- var import_common_helpers13 = require("@zenstackhq/common-helpers");
6767
+ var import_common_helpers15 = require("@zenstackhq/common-helpers");
6663
6768
  var import_decimal2 = __toESM(require("decimal.js"), 1);
6664
6769
  var import_ts_pattern19 = require("ts-pattern");
6665
6770
  var ResultProcessor = class {
@@ -6759,14 +6864,14 @@ var ResultProcessor = class {
6759
6864
  if (value instanceof import_decimal2.default) {
6760
6865
  return value;
6761
6866
  }
6762
- (0, import_common_helpers13.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6867
+ (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6763
6868
  return new import_decimal2.default(value);
6764
6869
  }
6765
6870
  transformBigInt(value) {
6766
6871
  if (typeof value === "bigint") {
6767
6872
  return value;
6768
6873
  }
6769
- (0, import_common_helpers13.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6874
+ (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6770
6875
  return BigInt(value);
6771
6876
  }
6772
6877
  transformBoolean(value) {
@@ -6810,7 +6915,7 @@ var ResultProcessor = class {
6810
6915
  }
6811
6916
  transformJson(value) {
6812
6917
  return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
6813
- (0, import_common_helpers13.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6918
+ (0, import_common_helpers15.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6814
6919
  return JSON.parse(value);
6815
6920
  }).otherwise(() => value);
6816
6921
  }
@@ -6844,15 +6949,15 @@ var ClientImpl = class _ClientImpl {
6844
6949
  if (baseClient) {
6845
6950
  this.kyselyProps = {
6846
6951
  ...baseClient.kyselyProps,
6847
- executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6952
+ executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely17.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6848
6953
  };
6849
6954
  this.kyselyRaw = baseClient.kyselyRaw;
6850
6955
  this.auth = baseClient.auth;
6851
6956
  } else {
6852
- const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely16.Log(this.$options.log ?? []));
6957
+ const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely17.Log(this.$options.log ?? []));
6853
6958
  const compiler = options.dialect.createQueryCompiler();
6854
6959
  const adapter = options.dialect.createAdapter();
6855
- const connectionProvider = new import_kysely16.DefaultConnectionProvider(driver);
6960
+ const connectionProvider = new import_kysely17.DefaultConnectionProvider(driver);
6856
6961
  this.kyselyProps = {
6857
6962
  config: {
6858
6963
  dialect: options.dialect,
@@ -6862,12 +6967,12 @@ var ClientImpl = class _ClientImpl {
6862
6967
  driver,
6863
6968
  executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
6864
6969
  };
6865
- this.kyselyRaw = new import_kysely16.Kysely({
6970
+ this.kyselyRaw = new import_kysely17.Kysely({
6866
6971
  ...this.kyselyProps,
6867
- executor: new import_kysely16.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
6972
+ executor: new import_kysely17.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
6868
6973
  });
6869
6974
  }
6870
- this.kysely = new import_kysely16.Kysely(this.kyselyProps);
6975
+ this.kysely = new import_kysely17.Kysely(this.kyselyProps);
6871
6976
  return createClientProxy(this);
6872
6977
  }
6873
6978
  get $qb() {
@@ -6887,13 +6992,18 @@ var ClientImpl = class _ClientImpl {
6887
6992
  }
6888
6993
  // implementation
6889
6994
  async $transaction(input, options) {
6890
- (0, import_common_helpers14.invariant)(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
6995
+ (0, import_common_helpers16.invariant)(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
6891
6996
  if (typeof input === "function") {
6892
6997
  return this.interactiveTransaction(input, options);
6893
6998
  } else {
6894
6999
  return this.sequentialTransaction(input, options);
6895
7000
  }
6896
7001
  }
7002
+ forceTransaction() {
7003
+ if (!this.kysely.isTransaction) {
7004
+ this.kysely = new import_kysely17.Transaction(this.kyselyProps);
7005
+ }
7006
+ }
6897
7007
  async interactiveTransaction(callback, options) {
6898
7008
  if (this.kysely.isTransaction) {
6899
7009
  return callback(this);
@@ -6998,7 +7108,7 @@ var ClientImpl = class _ClientImpl {
6998
7108
  }
6999
7109
  $executeRaw(query, ...values) {
7000
7110
  return createZenStackPromise(async () => {
7001
- const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
7111
+ const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
7002
7112
  return Number(result.numAffectedRows ?? 0);
7003
7113
  });
7004
7114
  }
@@ -7011,7 +7121,7 @@ var ClientImpl = class _ClientImpl {
7011
7121
  }
7012
7122
  $queryRaw(query, ...values) {
7013
7123
  return createZenStackPromise(async () => {
7014
- const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
7124
+ const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
7015
7125
  return result.rows;
7016
7126
  });
7017
7127
  }
@@ -7023,7 +7133,7 @@ var ClientImpl = class _ClientImpl {
7023
7133
  });
7024
7134
  }
7025
7135
  createRawCompiledQuery(query, values) {
7026
- const q = import_kysely16.CompiledQuery.raw(query, values);
7136
+ const q = import_kysely17.CompiledQuery.raw(query, values);
7027
7137
  return {
7028
7138
  ...q,
7029
7139
  $raw: true
@@ -7150,7 +7260,7 @@ function definePlugin(plugin) {
7150
7260
  __name(definePlugin, "definePlugin");
7151
7261
 
7152
7262
  // src/client/index.ts
7153
- var import_kysely17 = require("kysely");
7263
+ var import_kysely18 = require("kysely");
7154
7264
  // Annotate the CommonJS export names for ESM import in node:
7155
7265
  0 && (module.exports = {
7156
7266
  InputValidationError,