@zenstackhq/runtime 3.0.0-alpha.30 → 3.0.0-alpha.32

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_helpers13 = 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");
@@ -2740,6 +2740,16 @@ function clone(value) {
2740
2740
  }
2741
2741
  __name(clone, "clone");
2742
2742
 
2743
+ // src/client/contract.ts
2744
+ var TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLevel2) {
2745
+ TransactionIsolationLevel2["ReadUncommitted"] = "read uncommitted";
2746
+ TransactionIsolationLevel2["ReadCommitted"] = "read committed";
2747
+ TransactionIsolationLevel2["RepeatableRead"] = "repeatable read";
2748
+ TransactionIsolationLevel2["Serializable"] = "serializable";
2749
+ TransactionIsolationLevel2["Snapshot"] = "snapshot";
2750
+ return TransactionIsolationLevel2;
2751
+ }({});
2752
+
2743
2753
  // src/client/crud/operations/base.ts
2744
2754
  var BaseOperationHandler = class {
2745
2755
  static {
@@ -3978,7 +3988,7 @@ var BaseOperationHandler = class {
3978
3988
  return callback(this.kysely);
3979
3989
  } else {
3980
3990
  let txBuilder = this.kysely.transaction();
3981
- txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? "repeatable read");
3991
+ txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? TransactionIsolationLevel.RepeatableRead);
3982
3992
  return txBuilder.execute(callback);
3983
3993
  }
3984
3994
  }
@@ -5386,10 +5396,11 @@ var InputValidator = class {
5386
5396
  makeGroupBySchema(model) {
5387
5397
  const modelDef = requireModel(this.schema, model);
5388
5398
  const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation);
5399
+ const bySchema = nonRelationFields.length > 0 ? this.orArray(import_zod.z.enum(nonRelationFields), true) : import_zod.z.never();
5389
5400
  let schema = import_zod.z.strictObject({
5390
5401
  where: this.makeWhereSchema(model, false).optional(),
5391
5402
  orderBy: this.orArray(this.makeOrderBySchema(model, false, true), true).optional(),
5392
- by: this.orArray(import_zod.z.enum(nonRelationFields), true),
5403
+ by: bySchema,
5393
5404
  having: this.makeHavingSchema(model).optional(),
5394
5405
  skip: this.makeSkipSchema().optional(),
5395
5406
  take: this.makeTakeSchema().optional(),
@@ -5543,7 +5554,11 @@ var ZenStackDriver = class {
5543
5554
  this.#txConnections.delete(connection);
5544
5555
  if (callbacks) {
5545
5556
  for (const callback of callbacks) {
5546
- await callback();
5557
+ try {
5558
+ await callback();
5559
+ } catch (err) {
5560
+ console.error(`Error executing transaction commit callback: ${err}`);
5561
+ }
5547
5562
  }
5548
5563
  }
5549
5564
  return result;
@@ -5661,20 +5676,40 @@ function performanceNow() {
5661
5676
  __name(performanceNow, "performanceNow");
5662
5677
 
5663
5678
  // src/client/executor/zenstack-query-executor.ts
5664
- var import_kysely13 = require("kysely");
5665
- var import_nanoid2 = require("nanoid");
5679
+ var import_common_helpers12 = require("@zenstackhq/common-helpers");
5680
+ var import_kysely14 = require("kysely");
5666
5681
  var import_ts_pattern16 = require("ts-pattern");
5667
5682
 
5668
- // src/client/executor/name-mapper.ts
5683
+ // src/client/executor/kysely-utils.ts
5684
+ var import_common_helpers10 = require("@zenstackhq/common-helpers");
5669
5685
  var import_kysely12 = require("kysely");
5670
- var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5686
+ function stripAlias(node) {
5687
+ if (import_kysely12.AliasNode.is(node)) {
5688
+ (0, import_common_helpers10.invariant)(import_kysely12.IdentifierNode.is(node.alias), "Expected identifier as alias");
5689
+ return {
5690
+ alias: node.alias.name,
5691
+ node: node.node
5692
+ };
5693
+ } else {
5694
+ return {
5695
+ alias: void 0,
5696
+ node
5697
+ };
5698
+ }
5699
+ }
5700
+ __name(stripAlias, "stripAlias");
5701
+
5702
+ // src/client/executor/name-mapper.ts
5703
+ var import_common_helpers11 = require("@zenstackhq/common-helpers");
5704
+ var import_kysely13 = require("kysely");
5705
+ var QueryNameMapper = class extends import_kysely13.OperationNodeTransformer {
5671
5706
  static {
5672
5707
  __name(this, "QueryNameMapper");
5673
5708
  }
5674
5709
  schema;
5675
5710
  modelToTableMap = /* @__PURE__ */ new Map();
5676
5711
  fieldToColumnMap = /* @__PURE__ */ new Map();
5677
- modelStack = [];
5712
+ modelScopes = [];
5678
5713
  constructor(schema) {
5679
5714
  super(), this.schema = schema;
5680
5715
  for (const [modelName, modelDef] of Object.entries(schema.models)) {
@@ -5690,150 +5725,185 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5690
5725
  }
5691
5726
  }
5692
5727
  }
5693
- get currentModel() {
5694
- return this.modelStack[this.modelStack.length - 1];
5695
- }
5696
- transformCreateTable(node) {
5697
- try {
5698
- this.modelStack.push(node.table.table.identifier.name);
5699
- return super.transformCreateTable(node);
5700
- } finally {
5701
- this.modelStack.pop();
5728
+ // #region overrides
5729
+ transformSelectQuery(node) {
5730
+ if (!node.from?.froms) {
5731
+ return super.transformSelectQuery(node);
5702
5732
  }
5733
+ const scopes = this.createScopesFromFroms(node.from, true);
5734
+ return this.withScopes(scopes, () => {
5735
+ return {
5736
+ ...super.transformSelectQuery(node),
5737
+ // convert "from" to nested query as needed
5738
+ from: this.processFrom(node.from)
5739
+ };
5740
+ });
5703
5741
  }
5704
5742
  transformInsertQuery(node) {
5705
- try {
5706
- if (node.into?.table.identifier.name) {
5707
- this.modelStack.push(node.into.table.identifier.name);
5708
- }
5743
+ if (!node.into) {
5709
5744
  return super.transformInsertQuery(node);
5710
- } finally {
5711
- if (node.into?.table.identifier.name) {
5712
- this.modelStack.pop();
5713
- }
5714
5745
  }
5746
+ return this.withScope({
5747
+ model: node.into.table.identifier.name
5748
+ }, () => ({
5749
+ ...super.transformInsertQuery(node),
5750
+ // map table name
5751
+ into: this.processTableRef(node.into)
5752
+ }));
5715
5753
  }
5716
5754
  transformReturning(node) {
5717
- return import_kysely12.ReturningNode.create(this.transformSelections(node.selections, node));
5755
+ return {
5756
+ kind: node.kind,
5757
+ // map column names in returning selections (include returningAll)
5758
+ selections: this.processSelections(node.selections)
5759
+ };
5718
5760
  }
5719
- transformUpdateQuery(node) {
5720
- let pushed = false;
5721
- if (node.table && import_kysely12.TableNode.is(node.table)) {
5722
- this.modelStack.push(node.table.table.identifier.name);
5723
- pushed = true;
5724
- }
5725
- try {
5726
- return super.transformUpdateQuery(node);
5727
- } finally {
5728
- if (pushed) {
5729
- this.modelStack.pop();
5761
+ transformJoin(node) {
5762
+ const { alias, node: innerNode } = stripAlias(node.table);
5763
+ if (import_kysely13.TableNode.is(innerNode)) {
5764
+ const modelName = innerNode.table.identifier.name;
5765
+ if (this.hasMappedColumns(modelName)) {
5766
+ const select = this.createSelectAll(modelName);
5767
+ return {
5768
+ ...super.transformJoin(node),
5769
+ table: this.wrapAlias(select, alias ?? modelName)
5770
+ };
5730
5771
  }
5731
5772
  }
5773
+ return super.transformJoin(node);
5732
5774
  }
5733
- transformDeleteQuery(node) {
5734
- let pushed = false;
5735
- if (node.from?.froms && node.from.froms.length === 1 && node.from.froms[0]) {
5736
- const from = node.from.froms[0];
5737
- if (import_kysely12.TableNode.is(from)) {
5738
- this.modelStack.push(from.table.identifier.name);
5739
- pushed = true;
5740
- } else if (import_kysely12.AliasNode.is(from) && import_kysely12.TableNode.is(from.node)) {
5741
- this.modelStack.push(from.node.table.identifier.name);
5742
- pushed = true;
5743
- }
5775
+ transformReference(node) {
5776
+ if (!import_kysely13.ColumnNode.is(node.column)) {
5777
+ return super.transformReference(node);
5744
5778
  }
5745
- try {
5746
- return super.transformDeleteQuery(node);
5747
- } finally {
5748
- if (pushed) {
5749
- this.modelStack.pop();
5779
+ const { fieldDef, modelDef, scope } = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
5780
+ if (fieldDef && !scope.namesMapped) {
5781
+ const mappedFieldName = this.mapFieldName(modelDef.name, fieldDef.name);
5782
+ let mappedTableName = node.table?.table.identifier.name;
5783
+ if (mappedTableName) {
5784
+ if (scope.alias === mappedTableName) {
5785
+ } else if (scope.model === mappedTableName) {
5786
+ mappedTableName = this.mapTableName(scope.model);
5787
+ }
5750
5788
  }
5789
+ return import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(mappedFieldName), mappedTableName ? import_kysely13.TableNode.create(mappedTableName) : void 0);
5790
+ } else {
5791
+ return super.transformReference(node);
5751
5792
  }
5752
5793
  }
5753
- transformSelectQuery(node) {
5754
- if (!node.from?.froms || node.from.froms.length === 0) {
5755
- return super.transformSelectQuery(node);
5794
+ transformColumn(node) {
5795
+ const { modelDef, fieldDef, scope } = this.resolveFieldFromScopes(node.column.name);
5796
+ if (!fieldDef || scope.namesMapped) {
5797
+ return super.transformColumn(node);
5756
5798
  }
5757
- if (node.from.froms.length > 1) {
5758
- throw new InternalError(`SelectQueryNode must have a single table in from clause`);
5799
+ const mappedName = this.mapFieldName(modelDef.name, fieldDef.name);
5800
+ return import_kysely13.ColumnNode.create(mappedName);
5801
+ }
5802
+ transformUpdateQuery(node) {
5803
+ if (!node.table) {
5804
+ return super.transformUpdateQuery(node);
5759
5805
  }
5760
- let pushed = false;
5761
- const from = node.from.froms[0];
5762
- if (import_kysely12.TableNode.is(from)) {
5763
- this.modelStack.push(from.table.identifier.name);
5764
- pushed = true;
5765
- } else if (import_kysely12.AliasNode.is(from) && import_kysely12.TableNode.is(from.node)) {
5766
- this.modelStack.push(from.node.table.identifier.name);
5767
- pushed = true;
5806
+ const { alias, node: innerTable } = stripAlias(node.table);
5807
+ if (!innerTable || !import_kysely13.TableNode.is(innerTable)) {
5808
+ return super.transformUpdateQuery(node);
5768
5809
  }
5769
- const selections = node.selections ? this.transformSelections(node.selections, node) : node.selections;
5770
- try {
5810
+ return this.withScope({
5811
+ model: innerTable.table.identifier.name,
5812
+ alias
5813
+ }, () => {
5771
5814
  return {
5772
- ...super.transformSelectQuery(node),
5773
- selections
5815
+ ...super.transformUpdateQuery(node),
5816
+ // map table name
5817
+ table: this.wrapAlias(this.processTableRef(innerTable), alias)
5774
5818
  };
5775
- } finally {
5776
- if (pushed) {
5777
- this.modelStack.pop();
5819
+ });
5820
+ }
5821
+ transformDeleteQuery(node) {
5822
+ const scopes = this.createScopesFromFroms(node.from, false);
5823
+ const froms = node.from.froms.map((from) => {
5824
+ const { alias, node: innerNode } = stripAlias(from);
5825
+ if (import_kysely13.TableNode.is(innerNode)) {
5826
+ return this.wrapAlias(this.processTableRef(innerNode), alias);
5827
+ } else {
5828
+ return super.transformNode(from);
5778
5829
  }
5779
- }
5830
+ });
5831
+ return this.withScopes(scopes, () => {
5832
+ return {
5833
+ ...super.transformDeleteQuery(node),
5834
+ from: import_kysely13.FromNode.create(froms)
5835
+ };
5836
+ });
5780
5837
  }
5781
- transformSelections(selections, contextNode) {
5782
- const result = [];
5783
- for (const selection of selections) {
5784
- let selectAllFromModel = void 0;
5785
- let isSelectAll = false;
5786
- if (import_kysely12.SelectAllNode.is(selection.selection)) {
5787
- selectAllFromModel = this.currentModel;
5788
- isSelectAll = true;
5789
- } else if (import_kysely12.ReferenceNode.is(selection.selection) && import_kysely12.SelectAllNode.is(selection.selection.column)) {
5790
- selectAllFromModel = selection.selection.table?.table.identifier.name ?? this.currentModel;
5791
- isSelectAll = true;
5792
- }
5793
- if (isSelectAll) {
5794
- if (!selectAllFromModel) {
5795
- continue;
5838
+ // #endregion
5839
+ // #region utils
5840
+ resolveFieldFromScopes(name, qualifier) {
5841
+ for (const scope of this.modelScopes.toReversed()) {
5842
+ if (qualifier) {
5843
+ if (scope.alias) {
5844
+ if (qualifier !== scope.alias) {
5845
+ continue;
5846
+ }
5796
5847
  } else {
5797
- const scalarFields = this.getModelScalarFields(contextNode, selectAllFromModel);
5798
- const fromModelDef = requireModel(this.schema, selectAllFromModel);
5799
- const mappedTableName = this.getMappedName(fromModelDef) ?? selectAllFromModel;
5800
- result.push(...scalarFields.map((fieldName) => {
5801
- const fieldRef = import_kysely12.ReferenceNode.create(import_kysely12.ColumnNode.create(this.mapFieldName(fieldName)), import_kysely12.TableNode.create(mappedTableName));
5802
- return import_kysely12.SelectionNode.create(this.fieldHasMappedName(fieldName) ? import_kysely12.AliasNode.create(fieldRef, import_kysely12.IdentifierNode.create(fieldName)) : fieldRef);
5803
- }));
5848
+ if (qualifier !== scope.model) {
5849
+ continue;
5850
+ }
5804
5851
  }
5805
- } else {
5806
- result.push(this.transformSelectionWithAlias(selection));
5852
+ }
5853
+ const modelDef = getModel(this.schema, scope.model);
5854
+ if (!modelDef) {
5855
+ continue;
5856
+ }
5857
+ if (modelDef.fields[name]) {
5858
+ return {
5859
+ modelDef,
5860
+ fieldDef: modelDef.fields[name],
5861
+ scope
5862
+ };
5807
5863
  }
5808
5864
  }
5809
- return result;
5865
+ return {
5866
+ modelDef: void 0,
5867
+ fieldDef: void 0,
5868
+ scope: void 0
5869
+ };
5810
5870
  }
5811
- transformSelectionWithAlias(node) {
5812
- if (import_kysely12.ColumnNode.is(node.selection) && this.fieldHasMappedName(node.selection.column.name)) {
5813
- return import_kysely12.SelectionNode.create(import_kysely12.AliasNode.create(this.transformColumn(node.selection), import_kysely12.IdentifierNode.create(node.selection.column.name)));
5814
- } else if (import_kysely12.ReferenceNode.is(node.selection) && this.fieldHasMappedName(node.selection.column.column.name)) {
5815
- return import_kysely12.SelectionNode.create(import_kysely12.AliasNode.create(this.transformReference(node.selection), import_kysely12.IdentifierNode.create(node.selection.column.column.name)));
5816
- } else {
5817
- return this.transformSelection(node);
5871
+ pushScope(scope) {
5872
+ this.modelScopes.push(scope);
5873
+ }
5874
+ withScope(scope, fn) {
5875
+ this.pushScope(scope);
5876
+ try {
5877
+ return fn();
5878
+ } finally {
5879
+ this.modelScopes.pop();
5818
5880
  }
5819
5881
  }
5820
- fieldHasMappedName(name) {
5821
- if (!this.currentModel) {
5822
- return false;
5882
+ withScopes(scopes, fn) {
5883
+ scopes.forEach((s) => this.pushScope(s));
5884
+ try {
5885
+ return fn();
5886
+ } finally {
5887
+ scopes.forEach(() => this.modelScopes.pop());
5823
5888
  }
5824
- return this.fieldToColumnMap.has(`${this.currentModel}.${name}`);
5825
5889
  }
5826
- transformTable(node) {
5827
- const tableName = node.table.identifier.name;
5828
- const mappedName = this.modelToTableMap.get(tableName);
5829
- if (mappedName) {
5830
- return import_kysely12.TableNode.create(mappedName);
5831
- } else {
5890
+ wrapAlias(node, alias) {
5891
+ return alias ? import_kysely13.AliasNode.create(node, import_kysely13.IdentifierNode.create(alias)) : node;
5892
+ }
5893
+ ensureAlias(node, alias, fallbackName) {
5894
+ if (!node) {
5832
5895
  return node;
5833
5896
  }
5897
+ return alias ? import_kysely13.AliasNode.create(node, import_kysely13.IdentifierNode.create(alias)) : import_kysely13.AliasNode.create(node, import_kysely13.IdentifierNode.create(fallbackName));
5834
5898
  }
5835
- transformColumn(node) {
5836
- return import_kysely12.ColumnNode.create(this.mapFieldName(node.column.name));
5899
+ processTableRef(node) {
5900
+ if (!node) {
5901
+ return node;
5902
+ }
5903
+ if (!import_kysely13.TableNode.is(node)) {
5904
+ return super.transformNode(node);
5905
+ }
5906
+ return import_kysely13.TableNode.create(this.mapTableName(node.table.identifier.name));
5837
5907
  }
5838
5908
  getMappedName(def) {
5839
5909
  const mapAttr = def.attributes?.find((attr) => attr.name === "@@map" || attr.name === "@map");
@@ -5845,33 +5915,137 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
5845
5915
  }
5846
5916
  return void 0;
5847
5917
  }
5848
- mapFieldName(fieldName) {
5849
- if (!this.currentModel) {
5850
- return fieldName;
5918
+ mapFieldName(model, field) {
5919
+ const mappedName = this.fieldToColumnMap.get(`${model}.${field}`);
5920
+ if (mappedName) {
5921
+ return mappedName;
5922
+ } else {
5923
+ return field;
5851
5924
  }
5852
- const mappedName = this.fieldToColumnMap.get(`${this.currentModel}.${fieldName}`);
5925
+ }
5926
+ mapTableName(tableName) {
5927
+ const mappedName = this.modelToTableMap.get(tableName);
5853
5928
  if (mappedName) {
5854
5929
  return mappedName;
5855
5930
  } else {
5856
- return fieldName;
5931
+ return tableName;
5857
5932
  }
5858
5933
  }
5859
- requireCurrentModel(node) {
5860
- if (!this.currentModel) {
5861
- throw new InternalError(`Missing model context for "${node}"`);
5934
+ hasMappedColumns(modelName) {
5935
+ return [
5936
+ ...this.fieldToColumnMap.keys()
5937
+ ].some((key) => key.startsWith(modelName + "."));
5938
+ }
5939
+ createScopesFromFroms(node, namesMapped) {
5940
+ if (!node) {
5941
+ return [];
5862
5942
  }
5943
+ return node.froms.map((from) => {
5944
+ const { alias, node: innerNode } = stripAlias(from);
5945
+ if (innerNode && import_kysely13.TableNode.is(innerNode)) {
5946
+ return {
5947
+ model: innerNode.table.identifier.name,
5948
+ alias,
5949
+ namesMapped
5950
+ };
5951
+ } else {
5952
+ return void 0;
5953
+ }
5954
+ }).filter((s) => !!s);
5863
5955
  }
5864
- getModelScalarFields(contextNode, model) {
5865
- this.requireCurrentModel(contextNode);
5866
- model = model ?? this.currentModel;
5956
+ // convert a "from" node to a nested query if there are columns with name mapping
5957
+ processFrom(node) {
5958
+ return {
5959
+ ...super.transformFrom(node),
5960
+ froms: node.froms.map((from) => {
5961
+ const { alias, node: innerNode } = stripAlias(from);
5962
+ if (!innerNode) {
5963
+ return super.transformNode(from);
5964
+ }
5965
+ if (import_kysely13.TableNode.is(innerNode)) {
5966
+ if (this.hasMappedColumns(innerNode.table.identifier.name)) {
5967
+ const selectAll = this.createSelectAll(innerNode.table.identifier.name);
5968
+ return this.ensureAlias(selectAll, alias, innerNode.table.identifier.name);
5969
+ }
5970
+ }
5971
+ return this.transformNode(from);
5972
+ })
5973
+ };
5974
+ }
5975
+ // create a `SelectQueryNode` for the given model with all columns mapped
5976
+ createSelectAll(model) {
5867
5977
  const modelDef = requireModel(this.schema, model);
5868
- const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed && !fieldDef.originModel).map(([fieldName]) => fieldName);
5869
- return scalarFields;
5978
+ const tableName = this.mapTableName(model);
5979
+ return {
5980
+ kind: "SelectQueryNode",
5981
+ from: import_kysely13.FromNode.create([
5982
+ import_kysely13.TableNode.create(tableName)
5983
+ ]),
5984
+ selections: this.getModelFields(modelDef).map((fieldDef) => {
5985
+ const columnName = this.mapFieldName(model, fieldDef.name);
5986
+ const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName), import_kysely13.TableNode.create(tableName));
5987
+ if (columnName !== fieldDef.name) {
5988
+ const aliased = import_kysely13.AliasNode.create(columnRef, import_kysely13.IdentifierNode.create(fieldDef.name));
5989
+ return import_kysely13.SelectionNode.create(aliased);
5990
+ } else {
5991
+ return import_kysely13.SelectionNode.create(columnRef);
5992
+ }
5993
+ })
5994
+ };
5995
+ }
5996
+ getModelFields(modelDef) {
5997
+ return Object.values(modelDef.fields).filter((f) => !f.relation && !f.computed && !f.originModel);
5998
+ }
5999
+ processSelections(selections) {
6000
+ const result = [];
6001
+ selections.forEach((selection) => {
6002
+ if (import_kysely13.SelectAllNode.is(selection.selection)) {
6003
+ const processed = this.processSelectAll(selection.selection);
6004
+ if (Array.isArray(processed)) {
6005
+ result.push(...processed.map((s) => import_kysely13.SelectionNode.create(s)));
6006
+ } else {
6007
+ result.push(import_kysely13.SelectionNode.create(processed));
6008
+ }
6009
+ } else {
6010
+ result.push(import_kysely13.SelectionNode.create(this.processSelection(selection.selection)));
6011
+ }
6012
+ });
6013
+ return result;
6014
+ }
6015
+ processSelection(node) {
6016
+ let alias;
6017
+ if (!import_kysely13.AliasNode.is(node)) {
6018
+ alias = this.extractFieldName(node);
6019
+ }
6020
+ const result = super.transformNode(node);
6021
+ return this.wrapAlias(result, alias);
6022
+ }
6023
+ processSelectAll(node) {
6024
+ const scope = this.modelScopes[this.modelScopes.length - 1];
6025
+ (0, import_common_helpers11.invariant)(scope);
6026
+ if (!this.hasMappedColumns(scope.model)) {
6027
+ return super.transformSelectAll(node);
6028
+ }
6029
+ const modelDef = requireModel(this.schema, scope.model);
6030
+ return this.getModelFields(modelDef).map((fieldDef) => {
6031
+ const columnName = this.mapFieldName(scope.model, fieldDef.name);
6032
+ const columnRef = import_kysely13.ReferenceNode.create(import_kysely13.ColumnNode.create(columnName));
6033
+ return columnName !== fieldDef.name ? this.wrapAlias(columnRef, fieldDef.name) : columnRef;
6034
+ });
6035
+ }
6036
+ extractFieldName(node) {
6037
+ if (import_kysely13.ReferenceNode.is(node) && import_kysely13.ColumnNode.is(node.column)) {
6038
+ return node.column.column.name;
6039
+ } else if (import_kysely13.ColumnNode.is(node)) {
6040
+ return node.column.name;
6041
+ } else {
6042
+ return void 0;
6043
+ }
5870
6044
  }
5871
6045
  };
5872
6046
 
5873
6047
  // src/client/executor/zenstack-query-executor.ts
5874
- var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13.DefaultQueryExecutor {
6048
+ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely14.DefaultQueryExecutor {
5875
6049
  static {
5876
6050
  __name(this, "ZenStackQueryExecutor");
5877
6051
  }
@@ -5879,9 +6053,10 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5879
6053
  driver;
5880
6054
  compiler;
5881
6055
  connectionProvider;
6056
+ suppressMutationHooks;
5882
6057
  nameMapper;
5883
- constructor(client, driver, compiler, adapter, connectionProvider, plugins = []) {
5884
- super(compiler, adapter, connectionProvider, plugins), this.client = client, this.driver = driver, this.compiler = compiler, this.connectionProvider = connectionProvider;
6058
+ constructor(client, driver, compiler, adapter, connectionProvider, plugins = [], suppressMutationHooks = false) {
6059
+ super(compiler, adapter, connectionProvider, plugins), this.client = client, this.driver = driver, this.compiler = compiler, this.connectionProvider = connectionProvider, this.suppressMutationHooks = suppressMutationHooks;
5885
6060
  this.nameMapper = new QueryNameMapper(client.$schema);
5886
6061
  }
5887
6062
  get kysely() {
@@ -5890,38 +6065,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5890
6065
  get options() {
5891
6066
  return this.client.$options;
5892
6067
  }
5893
- async executeQuery(compiledQuery, _queryId) {
5894
- let queryNode = compiledQuery.query;
5895
- let mutationInterceptionInfo;
5896
- if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
5897
- mutationInterceptionInfo = await this.callMutationInterceptionFilters(queryNode);
5898
- }
5899
- const task = /* @__PURE__ */ __name(async () => {
5900
- if (this.isMutationNode(queryNode)) {
5901
- await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
5902
- }
5903
- const oldQueryNode = queryNode;
5904
- if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntities) {
5905
- queryNode = {
5906
- ...queryNode,
5907
- returning: import_kysely13.ReturningNode.create([
5908
- import_kysely13.SelectionNode.createSelectAll()
5909
- ])
5910
- };
5911
- }
5912
- const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
5913
- const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
5914
- if (this.isMutationNode(queryNode)) {
5915
- await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
5916
- }
5917
- if (oldQueryNode !== queryNode) {
5918
- }
5919
- return result.result;
5920
- }, "task");
5921
- return task();
6068
+ async executeQuery(compiledQuery, queryId) {
6069
+ const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
6070
+ const result = await this.proceedQueryWithKyselyInterceptors(compiledQuery.query, queryParams, queryId.queryId);
6071
+ return result.result;
5922
6072
  }
5923
- proceedQueryWithKyselyInterceptors(queryNode, parameters) {
5924
- let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
6073
+ async proceedQueryWithKyselyInterceptors(queryNode, parameters, queryId) {
6074
+ let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters, queryId), "proceed");
5925
6075
  const hooks = [];
5926
6076
  for (const plugin of this.client.$options.plugins ?? []) {
5927
6077
  if (plugin.onKyselyQuery) {
@@ -5931,10 +6081,8 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5931
6081
  for (const hook of hooks) {
5932
6082
  const _proceed = proceed;
5933
6083
  proceed = /* @__PURE__ */ __name(async (query) => {
5934
- let connection;
5935
6084
  const _p = /* @__PURE__ */ __name(async (q) => {
5936
6085
  const r = await _proceed(q);
5937
- connection = r.connection;
5938
6086
  return r.result;
5939
6087
  }, "_p");
5940
6088
  const hookResult = await hook({
@@ -5945,190 +6093,232 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
5945
6093
  proceed: _p
5946
6094
  });
5947
6095
  return {
5948
- result: hookResult,
5949
- connection
6096
+ result: hookResult
5950
6097
  };
5951
6098
  }, "proceed");
5952
6099
  }
5953
- return proceed(queryNode);
6100
+ const result = await proceed(queryNode);
6101
+ return result;
5954
6102
  }
5955
- async proceedQuery(query, parameters) {
5956
- const finalQuery = this.nameMapper.transformNode(query);
5957
- let compiled = this.compileQuery(finalQuery);
5958
- if (parameters) {
5959
- compiled = {
5960
- ...compiled,
5961
- parameters
5962
- };
5963
- }
6103
+ getMutationInfo(queryNode) {
6104
+ const model = this.getMutationModel(queryNode);
6105
+ const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, () => ({
6106
+ action: "create",
6107
+ where: void 0
6108
+ })).when(import_kysely14.UpdateQueryNode.is, (node) => ({
6109
+ action: "update",
6110
+ where: node.where
6111
+ })).when(import_kysely14.DeleteQueryNode.is, (node) => ({
6112
+ action: "delete",
6113
+ where: node.where
6114
+ })).exhaustive();
6115
+ return {
6116
+ model,
6117
+ action,
6118
+ where
6119
+ };
6120
+ }
6121
+ async proceedQuery(query, parameters, queryId) {
6122
+ let compiled;
5964
6123
  try {
5965
6124
  return await this.provideConnection(async (connection) => {
5966
- const result = await connection.executeQuery(compiled);
5967
- return {
5968
- result,
5969
- connection
5970
- };
6125
+ if (this.suppressMutationHooks || !this.isMutationNode(query) || !this.hasEntityMutationPlugins) {
6126
+ const finalQuery2 = this.nameMapper.transformNode(query);
6127
+ compiled = this.compileQuery(finalQuery2);
6128
+ if (parameters) {
6129
+ compiled = {
6130
+ ...compiled,
6131
+ parameters
6132
+ };
6133
+ }
6134
+ const result = await connection.executeQuery(compiled);
6135
+ return {
6136
+ result
6137
+ };
6138
+ }
6139
+ if ((import_kysely14.InsertQueryNode.is(query) || import_kysely14.UpdateQueryNode.is(query)) && this.hasEntityMutationPluginsWithAfterMutationHooks) {
6140
+ query = {
6141
+ ...query,
6142
+ returning: import_kysely14.ReturningNode.create([
6143
+ import_kysely14.SelectionNode.createSelectAll()
6144
+ ])
6145
+ };
6146
+ }
6147
+ const finalQuery = this.nameMapper.transformNode(query);
6148
+ compiled = this.compileQuery(finalQuery);
6149
+ if (parameters) {
6150
+ compiled = {
6151
+ ...compiled,
6152
+ parameters
6153
+ };
6154
+ }
6155
+ const currentlyInTx = this.driver.isTransactionConnection(connection);
6156
+ const connectionClient = this.createClientForConnection(connection, currentlyInTx);
6157
+ const mutationInfo = this.getMutationInfo(finalQuery);
6158
+ let beforeMutationEntities;
6159
+ const loadBeforeMutationEntities = /* @__PURE__ */ __name(async () => {
6160
+ if (beforeMutationEntities === void 0 && (import_kysely14.UpdateQueryNode.is(query) || import_kysely14.DeleteQueryNode.is(query))) {
6161
+ beforeMutationEntities = await this.loadEntities(mutationInfo.model, mutationInfo.where, connection);
6162
+ }
6163
+ return beforeMutationEntities;
6164
+ }, "loadBeforeMutationEntities");
6165
+ await this.callBeforeMutationHooks(finalQuery, mutationInfo, loadBeforeMutationEntities, connectionClient, queryId);
6166
+ const shouldCreateTx = this.hasPluginRequestingAfterMutationWithinTransaction && !this.driver.isTransactionConnection(connection);
6167
+ if (!shouldCreateTx) {
6168
+ const result = await connection.executeQuery(compiled);
6169
+ if (!this.driver.isTransactionConnection(connection)) {
6170
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "all", queryId);
6171
+ } else {
6172
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "inTx", queryId);
6173
+ this.driver.registerTransactionCommitCallback(connection, () => this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "outTx", queryId));
6174
+ }
6175
+ return {
6176
+ result
6177
+ };
6178
+ } else {
6179
+ await this.driver.beginTransaction(connection, {
6180
+ isolationLevel: TransactionIsolationLevel.ReadCommitted
6181
+ });
6182
+ try {
6183
+ const result = await connection.executeQuery(compiled);
6184
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "inTx", queryId);
6185
+ await this.driver.commitTransaction(connection);
6186
+ await this.callAfterMutationHooks(result, finalQuery, mutationInfo, connectionClient, "outTx", queryId);
6187
+ return {
6188
+ result
6189
+ };
6190
+ } catch (err) {
6191
+ await this.driver.rollbackTransaction(connection);
6192
+ throw err;
6193
+ }
6194
+ }
5971
6195
  });
5972
6196
  } catch (err) {
5973
- const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
6197
+ const message = `Failed to execute query: ${err}, sql: ${compiled?.sql}`;
5974
6198
  throw new QueryError(message, err);
5975
6199
  }
5976
6200
  }
6201
+ createClientForConnection(connection, inTx) {
6202
+ const innerExecutor = this.withConnectionProvider(new import_kysely14.SingleConnectionProvider(connection));
6203
+ innerExecutor.suppressMutationHooks = true;
6204
+ const innerClient = this.client.withExecutor(innerExecutor);
6205
+ if (inTx) {
6206
+ innerClient.forceTransaction();
6207
+ }
6208
+ return innerClient;
6209
+ }
6210
+ get hasEntityMutationPlugins() {
6211
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation);
6212
+ }
6213
+ get hasEntityMutationPluginsWithAfterMutationHooks() {
6214
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.afterEntityMutation);
6215
+ }
6216
+ get hasPluginRequestingAfterMutationWithinTransaction() {
6217
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.runAfterMutationWithinTransaction);
6218
+ }
5977
6219
  isMutationNode(queryNode) {
5978
- return import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode);
6220
+ return import_kysely14.InsertQueryNode.is(queryNode) || import_kysely14.UpdateQueryNode.is(queryNode) || import_kysely14.DeleteQueryNode.is(queryNode);
5979
6221
  }
5980
6222
  withPlugin(plugin) {
5981
6223
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
5982
6224
  ...this.plugins,
5983
6225
  plugin
5984
- ]);
6226
+ ], this.suppressMutationHooks);
5985
6227
  }
5986
6228
  withPlugins(plugins) {
5987
6229
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
5988
6230
  ...this.plugins,
5989
6231
  ...plugins
5990
- ]);
6232
+ ], this.suppressMutationHooks);
5991
6233
  }
5992
6234
  withPluginAtFront(plugin) {
5993
6235
  return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [
5994
6236
  plugin,
5995
6237
  ...this.plugins
5996
- ]);
6238
+ ], this.suppressMutationHooks);
5997
6239
  }
5998
6240
  withoutPlugins() {
5999
- return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, []);
6241
+ return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, [], this.suppressMutationHooks);
6000
6242
  }
6001
6243
  withConnectionProvider(connectionProvider) {
6002
- const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
6244
+ const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider, this.plugins, this.suppressMutationHooks);
6003
6245
  newExecutor.client = this.client.withExecutor(newExecutor);
6004
6246
  return newExecutor;
6005
6247
  }
6006
- get hasMutationHooks() {
6007
- return this.client.$options.plugins?.some((plugin) => !!plugin.onEntityMutation);
6008
- }
6009
6248
  getMutationModel(queryNode) {
6010
- 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) => {
6011
- if (node.from.froms.length !== 1) {
6012
- throw new InternalError(`Delete query must have exactly one from table`);
6013
- }
6014
- return node.from.froms[0].table.identifier.name;
6249
+ return (0, import_ts_pattern16.match)(queryNode).when(import_kysely14.InsertQueryNode.is, (node) => {
6250
+ (0, import_common_helpers12.invariant)(node.into, "InsertQueryNode must have an into clause");
6251
+ return node.into.table.identifier.name;
6252
+ }).when(import_kysely14.UpdateQueryNode.is, (node) => {
6253
+ (0, import_common_helpers12.invariant)(node.table, "UpdateQueryNode must have a table");
6254
+ const { node: tableNode } = stripAlias(node.table);
6255
+ (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "UpdateQueryNode must use a TableNode");
6256
+ return tableNode.table.identifier.name;
6257
+ }).when(import_kysely14.DeleteQueryNode.is, (node) => {
6258
+ (0, import_common_helpers12.invariant)(node.from.froms.length === 1, "Delete query must have exactly one from table");
6259
+ const { node: tableNode } = stripAlias(node.from.froms[0]);
6260
+ (0, import_common_helpers12.invariant)(import_kysely14.TableNode.is(tableNode), "DeleteQueryNode must use a TableNode");
6261
+ return tableNode.table.identifier.name;
6015
6262
  }).otherwise((node) => {
6016
6263
  throw new InternalError(`Invalid query node: ${node}`);
6017
6264
  });
6018
6265
  }
6019
- async callMutationInterceptionFilters(queryNode) {
6020
- const plugins = this.client.$options.plugins;
6021
- if (plugins) {
6022
- const mutationModel = this.getMutationModel(queryNode);
6023
- const result = {
6024
- intercept: false
6025
- };
6026
- const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
6027
- action: "create",
6028
- where: void 0
6029
- })).when(import_kysely13.UpdateQueryNode.is, (node) => ({
6030
- action: "update",
6031
- where: node.where
6032
- })).when(import_kysely13.DeleteQueryNode.is, (node) => ({
6033
- action: "delete",
6034
- where: node.where
6035
- })).exhaustive();
6036
- for (const plugin of plugins) {
6037
- const onEntityMutation = plugin.onEntityMutation;
6038
- if (!onEntityMutation) {
6039
- continue;
6040
- }
6041
- if (!onEntityMutation.mutationInterceptionFilter) {
6042
- result.intercept = true;
6043
- } else {
6044
- const filterResult = await onEntityMutation.mutationInterceptionFilter({
6045
- model: mutationModel,
6046
- action,
6047
- queryNode
6048
- });
6049
- result.intercept ||= filterResult.intercept;
6050
- result.loadBeforeMutationEntities ||= filterResult.loadBeforeMutationEntities;
6051
- result.loadAfterMutationEntities ||= filterResult.loadAfterMutationEntities;
6052
- }
6053
- }
6054
- let beforeMutationEntities;
6055
- if (result.loadBeforeMutationEntities && (import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode))) {
6056
- beforeMutationEntities = await this.loadEntities(mutationModel, where);
6057
- }
6058
- return {
6059
- ...result,
6060
- mutationModel,
6061
- action,
6062
- where,
6063
- beforeMutationEntities
6064
- };
6065
- } else {
6066
- return void 0;
6067
- }
6068
- }
6069
- async callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
6070
- if (!mutationInterceptionInfo?.intercept) {
6071
- return;
6072
- }
6266
+ async callBeforeMutationHooks(queryNode, mutationInfo, loadBeforeMutationEntities, client, queryId) {
6073
6267
  if (this.options.plugins) {
6074
- const mutationModel = this.getMutationModel(queryNode);
6075
6268
  for (const plugin of this.options.plugins) {
6076
6269
  const onEntityMutation = plugin.onEntityMutation;
6077
- if (onEntityMutation?.beforeEntityMutation) {
6078
- await onEntityMutation.beforeEntityMutation({
6079
- model: mutationModel,
6080
- action: mutationInterceptionInfo.action,
6081
- queryNode,
6082
- entities: mutationInterceptionInfo.beforeMutationEntities
6083
- });
6270
+ if (!onEntityMutation?.beforeEntityMutation) {
6271
+ continue;
6084
6272
  }
6273
+ await onEntityMutation.beforeEntityMutation({
6274
+ model: mutationInfo.model,
6275
+ action: mutationInfo.action,
6276
+ queryNode,
6277
+ loadBeforeMutationEntities,
6278
+ client,
6279
+ queryId
6280
+ });
6085
6281
  }
6086
6282
  }
6087
6283
  }
6088
- async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
6089
- if (!mutationInterceptionInfo?.intercept) {
6090
- return;
6091
- }
6284
+ async callAfterMutationHooks(queryResult, queryNode, mutationInfo, client, filterFor, queryId) {
6092
6285
  const hooks = [];
6093
6286
  for (const plugin of this.options.plugins ?? []) {
6094
6287
  const onEntityMutation = plugin.onEntityMutation;
6095
- if (onEntityMutation?.afterEntityMutation) {
6096
- hooks.push(onEntityMutation.afterEntityMutation.bind(plugin));
6288
+ if (!onEntityMutation?.afterEntityMutation) {
6289
+ continue;
6290
+ }
6291
+ if (filterFor === "inTx" && !onEntityMutation.runAfterMutationWithinTransaction) {
6292
+ continue;
6293
+ }
6294
+ if (filterFor === "outTx" && onEntityMutation.runAfterMutationWithinTransaction) {
6295
+ continue;
6097
6296
  }
6297
+ hooks.push(onEntityMutation.afterEntityMutation.bind(plugin));
6098
6298
  }
6099
6299
  if (hooks.length === 0) {
6100
6300
  return;
6101
6301
  }
6102
6302
  const mutationModel = this.getMutationModel(queryNode);
6103
- const inTransaction = this.driver.isTransactionConnection(connection);
6104
- for (const hook of hooks) {
6105
- let afterMutationEntities = void 0;
6106
- if (mutationInterceptionInfo.loadAfterMutationEntities) {
6107
- if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
6108
- afterMutationEntities = queryResult.rows;
6109
- }
6110
- }
6111
- const action = /* @__PURE__ */ __name(async () => {
6112
- try {
6113
- await hook({
6114
- model: mutationModel,
6115
- action: mutationInterceptionInfo.action,
6116
- queryNode,
6117
- beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
6118
- afterMutationEntities
6119
- });
6120
- } catch (err) {
6121
- console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
6122
- }
6123
- }, "action");
6124
- if (inTransaction) {
6125
- this.driver.registerTransactionCommitCallback(connection, action);
6303
+ const loadAfterMutationEntities = /* @__PURE__ */ __name(async () => {
6304
+ if (mutationInfo.action === "delete") {
6305
+ return void 0;
6126
6306
  } else {
6127
- await action();
6307
+ return queryResult.rows;
6128
6308
  }
6309
+ }, "loadAfterMutationEntities");
6310
+ for (const hook of hooks) {
6311
+ await hook({
6312
+ model: mutationModel,
6313
+ action: mutationInfo.action,
6314
+ queryNode,
6315
+ loadAfterMutationEntities,
6316
+ client,
6317
+ queryId
6318
+ });
6129
6319
  }
6130
6320
  }
6131
- async loadEntities(model, where) {
6321
+ async loadEntities(model, where, connection) {
6132
6322
  const selectQuery = this.kysely.selectFrom(model).selectAll();
6133
6323
  let selectQueryNode = selectQuery.toOperationNode();
6134
6324
  selectQueryNode = {
@@ -6136,16 +6326,14 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
6136
6326
  where: this.andNodes(selectQueryNode.where, where)
6137
6327
  };
6138
6328
  const compiled = this.compileQuery(selectQueryNode);
6139
- const result = await this.executeQuery(compiled, {
6140
- queryId: `zenstack-${(0, import_nanoid2.nanoid)()}`
6141
- });
6329
+ const result = await connection.executeQuery(compiled);
6142
6330
  return result.rows;
6143
6331
  }
6144
6332
  andNodes(condition1, condition2) {
6145
6333
  if (condition1 && condition2) {
6146
- return import_kysely13.WhereNode.create(import_kysely13.AndNode.create(condition1, condition2));
6334
+ return import_kysely14.WhereNode.create(import_kysely14.AndNode.create(condition1, condition2));
6147
6335
  } else if (condition1) {
6148
- return import_kysely13.WhereNode.create(condition1);
6336
+ return import_kysely14.WhereNode.create(condition1);
6149
6337
  } else {
6150
6338
  return condition2;
6151
6339
  }
@@ -6167,8 +6355,8 @@ __export(functions_exports, {
6167
6355
  search: () => search,
6168
6356
  startsWith: () => startsWith
6169
6357
  });
6170
- var import_common_helpers10 = require("@zenstackhq/common-helpers");
6171
- var import_kysely14 = require("kysely");
6358
+ var import_common_helpers13 = require("@zenstackhq/common-helpers");
6359
+ var import_kysely15 = require("kysely");
6172
6360
  var import_ts_pattern17 = require("ts-pattern");
6173
6361
  var contains = /* @__PURE__ */ __name((eb, args) => {
6174
6362
  const [field, search2, caseInsensitive = false] = args;
@@ -6179,9 +6367,9 @@ var contains = /* @__PURE__ */ __name((eb, args) => {
6179
6367
  throw new Error('"search" parameter is required');
6180
6368
  }
6181
6369
  const searchExpr = eb.fn("CONCAT", [
6182
- import_kysely14.sql.lit("%"),
6370
+ import_kysely15.sql.lit("%"),
6183
6371
  search2,
6184
- import_kysely14.sql.lit("%")
6372
+ import_kysely15.sql.lit("%")
6185
6373
  ]);
6186
6374
  return eb(field, caseInsensitive ? "ilike" : "like", searchExpr);
6187
6375
  }, "contains");
@@ -6198,7 +6386,7 @@ var startsWith = /* @__PURE__ */ __name((eb, args) => {
6198
6386
  }
6199
6387
  return eb(field, "like", eb.fn("CONCAT", [
6200
6388
  search2,
6201
- import_kysely14.sql.lit("%")
6389
+ import_kysely15.sql.lit("%")
6202
6390
  ]));
6203
6391
  }, "startsWith");
6204
6392
  var endsWith = /* @__PURE__ */ __name((eb, args) => {
@@ -6210,7 +6398,7 @@ var endsWith = /* @__PURE__ */ __name((eb, args) => {
6210
6398
  throw new Error('"search" parameter is required');
6211
6399
  }
6212
6400
  return eb(field, "like", eb.fn("CONCAT", [
6213
- import_kysely14.sql.lit("%"),
6401
+ import_kysely15.sql.lit("%"),
6214
6402
  search2
6215
6403
  ]));
6216
6404
  }, "endsWith");
@@ -6251,10 +6439,10 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
6251
6439
  if (!field) {
6252
6440
  throw new Error('"field" parameter is required');
6253
6441
  }
6254
- return eb(dialect.buildArrayLength(eb, field), "=", import_kysely14.sql.lit(0));
6442
+ return eb(dialect.buildArrayLength(eb, field), "=", import_kysely15.sql.lit(0));
6255
6443
  }, "isEmpty");
6256
6444
  var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
6257
- return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6445
+ return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely15.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
6258
6446
  }, "now");
6259
6447
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6260
6448
  let result = model;
@@ -6262,7 +6450,7 @@ var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
6262
6450
  if (casing) {
6263
6451
  result = processCasing(casing, result, model);
6264
6452
  }
6265
- return import_kysely14.sql.lit(result);
6453
+ return import_kysely15.sql.lit(result);
6266
6454
  }, "currentModel");
6267
6455
  var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6268
6456
  let result = operation;
@@ -6270,12 +6458,12 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
6270
6458
  if (casing) {
6271
6459
  result = processCasing(casing, result, operation);
6272
6460
  }
6273
- return import_kysely14.sql.lit(result);
6461
+ return import_kysely15.sql.lit(result);
6274
6462
  }, "currentOperation");
6275
6463
  function processCasing(casing, result, model) {
6276
6464
  const opNode = casing.toOperationNode();
6277
- (0, import_common_helpers10.invariant)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6278
- result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers10.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers10.lowerCaseFirst)(result)).otherwise(() => {
6465
+ (0, import_common_helpers13.invariant)(import_kysely15.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
6466
+ 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(() => {
6279
6467
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
6280
6468
  });
6281
6469
  return result;
@@ -6283,8 +6471,8 @@ function processCasing(casing, result, model) {
6283
6471
  __name(processCasing, "processCasing");
6284
6472
 
6285
6473
  // src/client/helpers/schema-db-pusher.ts
6286
- var import_common_helpers11 = require("@zenstackhq/common-helpers");
6287
- var import_kysely15 = require("kysely");
6474
+ var import_common_helpers14 = require("@zenstackhq/common-helpers");
6475
+ var import_kysely16 = require("kysely");
6288
6476
  var import_toposort = __toESM(require("toposort"), 1);
6289
6477
  var import_ts_pattern18 = require("ts-pattern");
6290
6478
  var SchemaDbPusher = class {
@@ -6379,7 +6567,7 @@ var SchemaDbPusher = class {
6379
6567
  }
6380
6568
  addUniqueConstraint(table, modelDef) {
6381
6569
  for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
6382
- (0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
6570
+ (0, import_common_helpers14.invariant)(typeof value === "object", "expecting an object");
6383
6571
  if ("type" in value) {
6384
6572
  const fieldDef = modelDef.fields[key];
6385
6573
  if (fieldDef.unique) {
@@ -6402,7 +6590,7 @@ var SchemaDbPusher = class {
6402
6590
  if (fieldDef.default !== void 0) {
6403
6591
  if (typeof fieldDef.default === "object" && "kind" in fieldDef.default) {
6404
6592
  if (ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "now") {
6405
- col = col.defaultTo(import_kysely15.sql`CURRENT_TIMESTAMP`);
6593
+ col = col.defaultTo(import_kysely16.sql`CURRENT_TIMESTAMP`);
6406
6594
  }
6407
6595
  } else {
6408
6596
  col = col.defaultTo(fieldDef.default);
@@ -6422,7 +6610,7 @@ var SchemaDbPusher = class {
6422
6610
  }
6423
6611
  mapFieldType(fieldDef) {
6424
6612
  if (this.schema.enums?.[fieldDef.type]) {
6425
- return this.schema.provider.type === "postgresql" ? import_kysely15.sql.ref(fieldDef.type) : "text";
6613
+ return this.schema.provider.type === "postgresql" ? import_kysely16.sql.ref(fieldDef.type) : "text";
6426
6614
  }
6427
6615
  if (this.isAutoIncrement(fieldDef) && this.schema.provider.type === "postgresql") {
6428
6616
  return "serial";
@@ -6435,7 +6623,7 @@ var SchemaDbPusher = class {
6435
6623
  throw new Error(`Unsupported field type: ${type}`);
6436
6624
  });
6437
6625
  if (fieldDef.array) {
6438
- return import_kysely15.sql.raw(`${result}[]`);
6626
+ return import_kysely16.sql.raw(`${result}[]`);
6439
6627
  } else {
6440
6628
  return result;
6441
6629
  }
@@ -6447,7 +6635,7 @@ var SchemaDbPusher = class {
6447
6635
  return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
6448
6636
  }
6449
6637
  addForeignKeyConstraint(table, model, fieldName, fieldDef) {
6450
- (0, import_common_helpers11.invariant)(fieldDef.relation, "field must be a relation");
6638
+ (0, import_common_helpers14.invariant)(fieldDef.relation, "field must be a relation");
6451
6639
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
6452
6640
  return table;
6453
6641
  }
@@ -6502,7 +6690,7 @@ function valueToPromise(thing) {
6502
6690
  __name(valueToPromise, "valueToPromise");
6503
6691
 
6504
6692
  // src/client/result-processor.ts
6505
- var import_common_helpers12 = require("@zenstackhq/common-helpers");
6693
+ var import_common_helpers15 = require("@zenstackhq/common-helpers");
6506
6694
  var import_decimal2 = __toESM(require("decimal.js"), 1);
6507
6695
  var import_ts_pattern19 = require("ts-pattern");
6508
6696
  var ResultProcessor = class {
@@ -6602,14 +6790,14 @@ var ResultProcessor = class {
6602
6790
  if (value instanceof import_decimal2.default) {
6603
6791
  return value;
6604
6792
  }
6605
- (0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6793
+ (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
6606
6794
  return new import_decimal2.default(value);
6607
6795
  }
6608
6796
  transformBigInt(value) {
6609
6797
  if (typeof value === "bigint") {
6610
6798
  return value;
6611
6799
  }
6612
- (0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6800
+ (0, import_common_helpers15.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
6613
6801
  return BigInt(value);
6614
6802
  }
6615
6803
  transformBoolean(value) {
@@ -6653,7 +6841,7 @@ var ResultProcessor = class {
6653
6841
  }
6654
6842
  transformJson(value) {
6655
6843
  return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
6656
- (0, import_common_helpers12.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6844
+ (0, import_common_helpers15.invariant)(typeof value === "string", "Expected string, got " + typeof value);
6657
6845
  return JSON.parse(value);
6658
6846
  }).otherwise(() => value);
6659
6847
  }
@@ -6687,15 +6875,15 @@ var ClientImpl = class _ClientImpl {
6687
6875
  if (baseClient) {
6688
6876
  this.kyselyProps = {
6689
6877
  ...baseClient.kyselyProps,
6690
- executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6878
+ executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely17.DefaultConnectionProvider(baseClient.kyselyProps.driver))
6691
6879
  };
6692
6880
  this.kyselyRaw = baseClient.kyselyRaw;
6693
6881
  this.auth = baseClient.auth;
6694
6882
  } else {
6695
- const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely16.Log(this.$options.log ?? []));
6883
+ const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely17.Log(this.$options.log ?? []));
6696
6884
  const compiler = options.dialect.createQueryCompiler();
6697
6885
  const adapter = options.dialect.createAdapter();
6698
- const connectionProvider = new import_kysely16.DefaultConnectionProvider(driver);
6886
+ const connectionProvider = new import_kysely17.DefaultConnectionProvider(driver);
6699
6887
  this.kyselyProps = {
6700
6888
  config: {
6701
6889
  dialect: options.dialect,
@@ -6705,12 +6893,12 @@ var ClientImpl = class _ClientImpl {
6705
6893
  driver,
6706
6894
  executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
6707
6895
  };
6708
- this.kyselyRaw = new import_kysely16.Kysely({
6896
+ this.kyselyRaw = new import_kysely17.Kysely({
6709
6897
  ...this.kyselyProps,
6710
- executor: new import_kysely16.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
6898
+ executor: new import_kysely17.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
6711
6899
  });
6712
6900
  }
6713
- this.kysely = new import_kysely16.Kysely(this.kyselyProps);
6901
+ this.kysely = new import_kysely17.Kysely(this.kyselyProps);
6714
6902
  return createClientProxy(this);
6715
6903
  }
6716
6904
  get $qb() {
@@ -6730,13 +6918,18 @@ var ClientImpl = class _ClientImpl {
6730
6918
  }
6731
6919
  // implementation
6732
6920
  async $transaction(input, options) {
6733
- (0, import_common_helpers13.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");
6921
+ (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");
6734
6922
  if (typeof input === "function") {
6735
6923
  return this.interactiveTransaction(input, options);
6736
6924
  } else {
6737
6925
  return this.sequentialTransaction(input, options);
6738
6926
  }
6739
6927
  }
6928
+ forceTransaction() {
6929
+ if (!this.kysely.isTransaction) {
6930
+ this.kysely = new import_kysely17.Transaction(this.kyselyProps);
6931
+ }
6932
+ }
6740
6933
  async interactiveTransaction(callback, options) {
6741
6934
  if (this.kysely.isTransaction) {
6742
6935
  return callback(this);
@@ -6841,7 +7034,7 @@ var ClientImpl = class _ClientImpl {
6841
7034
  }
6842
7035
  $executeRaw(query, ...values) {
6843
7036
  return createZenStackPromise(async () => {
6844
- const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
7037
+ const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
6845
7038
  return Number(result.numAffectedRows ?? 0);
6846
7039
  });
6847
7040
  }
@@ -6854,7 +7047,7 @@ var ClientImpl = class _ClientImpl {
6854
7047
  }
6855
7048
  $queryRaw(query, ...values) {
6856
7049
  return createZenStackPromise(async () => {
6857
- const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
7050
+ const result = await (0, import_kysely17.sql)(query, ...values).execute(this.kysely);
6858
7051
  return result.rows;
6859
7052
  });
6860
7053
  }
@@ -6866,7 +7059,7 @@ var ClientImpl = class _ClientImpl {
6866
7059
  });
6867
7060
  }
6868
7061
  createRawCompiledQuery(query, values) {
6869
- const q = import_kysely16.CompiledQuery.raw(query, values);
7062
+ const q = import_kysely17.CompiledQuery.raw(query, values);
6870
7063
  return {
6871
7064
  ...q,
6872
7065
  $raw: true
@@ -6993,7 +7186,7 @@ function definePlugin(plugin) {
6993
7186
  __name(definePlugin, "definePlugin");
6994
7187
 
6995
7188
  // src/client/index.ts
6996
- var import_kysely17 = require("kysely");
7189
+ var import_kysely18 = require("kysely");
6997
7190
  // Annotate the CommonJS export names for ESM import in node:
6998
7191
  0 && (module.exports = {
6999
7192
  InputValidationError,