@zenstackhq/orm 3.5.0-beta.2 → 3.5.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
19
19
 
20
20
  // src/client/client-impl.ts
21
- import { invariant as invariant14, lowerCaseFirst as lowerCaseFirst3 } from "@zenstackhq/common-helpers";
21
+ import { invariant as invariant14, lowerCaseFirst as lowerCaseFirst4 } from "@zenstackhq/common-helpers";
22
22
  import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as DefaultQueryExecutor2, Kysely, Log, sql as sql8, Transaction } from "kysely";
23
23
  import z2 from "zod";
24
24
 
@@ -30,7 +30,7 @@ function formatError(error) {
30
30
  __name(formatError, "formatError");
31
31
 
32
32
  // src/client/crud/operations/aggregate.ts
33
- import { match as match8 } from "ts-pattern";
33
+ import { match as match5 } from "ts-pattern";
34
34
 
35
35
  // src/client/query-utils.ts
36
36
  var query_utils_exports = {};
@@ -63,6 +63,7 @@ __export(query_utils_exports, {
63
63
  isRelationField: () => isRelationField,
64
64
  isScalarField: () => isScalarField,
65
65
  isTypeDef: () => isTypeDef,
66
+ isUnsupportedField: () => isUnsupportedField,
66
67
  makeDefaultOrderBy: () => makeDefaultOrderBy,
67
68
  requireField: () => requireField,
68
69
  requireIdFields: () => requireIdFields,
@@ -264,10 +265,17 @@ function getModelFields(schema, model, options) {
264
265
  if (f.originModel && !options?.inherited) {
265
266
  return false;
266
267
  }
268
+ if (f.type === "Unsupported" && !options?.unsupported) {
269
+ return false;
270
+ }
267
271
  return true;
268
272
  });
269
273
  }
270
274
  __name(getModelFields, "getModelFields");
275
+ function isUnsupportedField(fieldDef) {
276
+ return fieldDef.type === "Unsupported";
277
+ }
278
+ __name(isUnsupportedField, "isUnsupportedField");
271
279
  function getIdFields(schema, model) {
272
280
  const modelDef = getModel(schema, model);
273
281
  return modelDef?.idFields;
@@ -601,7 +609,7 @@ import { clone, enumerate as enumerate2, invariant as invariant7, isPlainObject
601
609
  import { default as cuid1 } from "cuid";
602
610
  import { createQueryId, expressionBuilder as expressionBuilder5, sql as sql5 } from "kysely";
603
611
  import { nanoid } from "nanoid";
604
- import { match as match7 } from "ts-pattern";
612
+ import { match as match4 } from "ts-pattern";
605
613
  import { ulid } from "ulid";
606
614
  import * as uuid from "uuid";
607
615
 
@@ -684,13 +692,12 @@ var CRUD_EXT = [
684
692
  ];
685
693
 
686
694
  // src/client/crud/dialects/index.ts
687
- import { match as match6 } from "ts-pattern";
695
+ import { match as match3 } from "ts-pattern";
688
696
 
689
697
  // src/client/crud/dialects/mysql.ts
690
698
  import { invariant as invariant4 } from "@zenstackhq/common-helpers";
691
699
  import Decimal from "decimal.js";
692
700
  import { expressionBuilder as expressionBuilder2, ExpressionWrapper, sql as sql2, ValueListNode } from "kysely";
693
- import { match as match3 } from "ts-pattern";
694
701
 
695
702
  // src/common-types.ts
696
703
  var DbNullClass = class {
@@ -722,7 +729,7 @@ var AnyNull = new AnyNullClass();
722
729
  import { invariant as invariant3 } from "@zenstackhq/common-helpers";
723
730
 
724
731
  // src/client/crud/dialects/base-dialect.ts
725
- import { enumerate, invariant as invariant2, isPlainObject } from "@zenstackhq/common-helpers";
732
+ import { enumerate, invariant as invariant2, isPlainObject, lowerCaseFirst } from "@zenstackhq/common-helpers";
726
733
  import { expressionBuilder, sql } from "kysely";
727
734
  import { match as match2, P } from "ts-pattern";
728
735
  var BaseCrudDialect = class {
@@ -1405,27 +1412,28 @@ var BaseCrudDialect = class {
1405
1412
  return result;
1406
1413
  }
1407
1414
  buildSelectAllFields(model, query, omit, modelAlias) {
1408
- const modelDef = requireModel(this.schema, model);
1409
1415
  let result = query;
1410
- for (const field of Object.keys(modelDef.fields)) {
1411
- if (isRelationField(this.schema, model, field)) {
1416
+ for (const fieldDef of getModelFields(this.schema, model, {
1417
+ inherited: true,
1418
+ computed: true
1419
+ })) {
1420
+ if (this.shouldOmitField(omit, model, fieldDef.name)) {
1412
1421
  continue;
1413
1422
  }
1414
- if (this.shouldOmitField(omit, model, field)) {
1415
- continue;
1416
- }
1417
- result = this.buildSelectField(result, model, modelAlias, field);
1423
+ result = this.buildSelectField(result, model, modelAlias, fieldDef.name);
1418
1424
  }
1419
1425
  const descendants = getDelegateDescendantModels(this.schema, model);
1420
1426
  for (const subModel of descendants) {
1421
1427
  result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
1422
- result = result.select((eb) => {
1428
+ result = result.select(() => {
1423
1429
  const jsonObject = {};
1424
- for (const field of Object.keys(subModel.fields)) {
1425
- if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
1430
+ for (const fieldDef of getModelFields(this.schema, subModel.name, {
1431
+ computed: true
1432
+ })) {
1433
+ if (this.shouldOmitField(omit, subModel.name, fieldDef.name)) {
1426
1434
  continue;
1427
1435
  }
1428
- jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
1436
+ jsonObject[fieldDef.name] = this.fieldRef(subModel.name, fieldDef.name, subModel.name);
1429
1437
  }
1430
1438
  return this.buildJsonObject(jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
1431
1439
  });
@@ -1436,8 +1444,10 @@ var BaseCrudDialect = class {
1436
1444
  if (omit && typeof omit === "object" && typeof omit[field] === "boolean") {
1437
1445
  return omit[field];
1438
1446
  }
1439
- if (this.options.omit?.[model] && typeof this.options.omit[model] === "object" && typeof this.options.omit[model][field] === "boolean") {
1440
- return this.options.omit[model][field];
1447
+ const uncapModel = lowerCaseFirst(model);
1448
+ const omitConfig = this.options.omit?.[uncapModel] ?? this.options.omit?.[model];
1449
+ if (omitConfig && typeof omitConfig === "object" && typeof omitConfig[field] === "boolean") {
1450
+ return omitConfig[field];
1441
1451
  }
1442
1452
  const fieldDef = requireField(this.schema, model, field);
1443
1453
  return !!fieldDef.omit;
@@ -1555,7 +1565,8 @@ var BaseCrudDialect = class {
1555
1565
  let computer;
1556
1566
  if ("computedFields" in this.options) {
1557
1567
  const computedFields = this.options.computedFields;
1558
- computer = computedFields?.[fieldDef.originModel ?? model]?.[field];
1568
+ const computedModel = fieldDef.originModel ?? model;
1569
+ computer = computedFields?.[lowerCaseFirst(computedModel)]?.[field] ?? computedFields?.[computedModel]?.[field];
1559
1570
  }
1560
1571
  if (!computer) {
1561
1572
  throw createConfigError(`Computed field "${field}" implementation not provided for model "${model}"`);
@@ -1758,24 +1769,46 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
1758
1769
  throw createNotSupportedError(`MySQL does not support array literals`);
1759
1770
  }
1760
1771
  } else {
1761
- return match3(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => {
1762
- if (value instanceof Date) {
1763
- return value.toISOString().replace("Z", "+00:00");
1764
- } else if (typeof value === "string") {
1765
- return new Date(value).toISOString().replace("Z", "+00:00");
1766
- } else {
1772
+ switch (type) {
1773
+ case "Boolean":
1774
+ return value ? 1 : 0;
1775
+ case "DateTime":
1776
+ if (value instanceof Date) {
1777
+ return value.toISOString().replace("Z", "+00:00");
1778
+ } else if (typeof value === "string") {
1779
+ return new Date(value).toISOString().replace("Z", "+00:00");
1780
+ } else {
1781
+ return value;
1782
+ }
1783
+ case "Decimal":
1784
+ return value !== null ? value.toString() : value;
1785
+ case "Json":
1786
+ return this.eb.cast(this.eb.val(JSON.stringify(value)), "json");
1787
+ case "Bytes":
1788
+ return Buffer.isBuffer(value) ? value : value instanceof Uint8Array ? Buffer.from(value) : value;
1789
+ default:
1767
1790
  return value;
1768
- }
1769
- }).with("Decimal", () => value !== null ? value.toString() : value).with("Json", () => {
1770
- return this.eb.cast(this.eb.val(JSON.stringify(value)), "json");
1771
- }).with("Bytes", () => Buffer.isBuffer(value) ? value : value instanceof Uint8Array ? Buffer.from(value) : value).otherwise(() => value);
1791
+ }
1772
1792
  }
1773
1793
  }
1774
1794
  transformOutput(value, type, array) {
1775
1795
  if (value === null || value === void 0) {
1776
1796
  return value;
1777
1797
  }
1778
- return match3(type).with("Boolean", () => this.transformOutputBoolean(value)).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Decimal", () => this.transformDecimal(value)).otherwise(() => super.transformOutput(value, type, array));
1798
+ switch (type) {
1799
+ case "Boolean":
1800
+ return this.transformOutputBoolean(value);
1801
+ case "DateTime":
1802
+ return this.transformOutputDate(value);
1803
+ case "Bytes":
1804
+ return this.transformOutputBytes(value);
1805
+ case "BigInt":
1806
+ return this.transformOutputBigInt(value);
1807
+ case "Decimal":
1808
+ return this.transformDecimal(value);
1809
+ default:
1810
+ return super.transformOutput(value, type, array);
1811
+ }
1779
1812
  }
1780
1813
  transformOutputBoolean(value) {
1781
1814
  return !!value;
@@ -1881,15 +1914,25 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
1881
1914
  }
1882
1915
  }
1883
1916
  buildJsonArrayFilter(lhs, operation, value) {
1884
- return match3(operation).with("array_contains", () => {
1885
- const v = Array.isArray(value) ? value : [
1886
- value
1887
- ];
1888
- return sql2`JSON_CONTAINS(${lhs}, ${sql2.val(JSON.stringify(v))})`;
1889
- }).with("array_starts_with", () => this.eb(this.eb.fn("JSON_EXTRACT", [
1890
- lhs,
1891
- this.eb.val("$[0]")
1892
- ]), "=", this.transformInput(value, "Json", false))).with("array_ends_with", () => this.eb(sql2`JSON_EXTRACT(${lhs}, CONCAT('$[', JSON_LENGTH(${lhs}) - 1, ']'))`, "=", this.transformInput(value, "Json", false))).exhaustive();
1917
+ switch (operation) {
1918
+ case "array_contains": {
1919
+ const v = Array.isArray(value) ? value : [
1920
+ value
1921
+ ];
1922
+ return sql2`JSON_CONTAINS(${lhs}, ${sql2.val(JSON.stringify(v))})`;
1923
+ }
1924
+ case "array_starts_with": {
1925
+ return this.eb(this.eb.fn("JSON_EXTRACT", [
1926
+ lhs,
1927
+ this.eb.val("$[0]")
1928
+ ]), "=", this.transformInput(value, "Json", false));
1929
+ }
1930
+ case "array_ends_with": {
1931
+ return this.eb(sql2`JSON_EXTRACT(${lhs}, CONCAT('$[', JSON_LENGTH(${lhs}) - 1, ']'))`, "=", this.transformInput(value, "Json", false));
1932
+ }
1933
+ default:
1934
+ throw createInvalidInputError(`Unsupported array filter operation: ${operation}`);
1935
+ }
1893
1936
  }
1894
1937
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
1895
1938
  return this.eb.exists(this.eb.selectFrom(sql2`JSON_TABLE(${receiver}, '$[*]' COLUMNS(value JSON PATH '$'))`.as("$items")).select(this.eb.lit(1).as("_")).where(buildFilter(this.eb.ref("$items.value"))));
@@ -1932,12 +1975,22 @@ import { invariant as invariant5 } from "@zenstackhq/common-helpers";
1932
1975
  import Decimal2 from "decimal.js";
1933
1976
  import { expressionBuilder as expressionBuilder3, sql as sql3 } from "kysely";
1934
1977
  import { parse as parsePostgresArray } from "postgres-array";
1935
- import { match as match4 } from "ts-pattern";
1936
1978
  var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectBase {
1937
1979
  static {
1938
1980
  __name(this, "PostgresCrudDialect");
1939
1981
  }
1940
1982
  static typeParserOverrideApplied = false;
1983
+ zmodelToSqlTypeMap = {
1984
+ String: "text",
1985
+ Boolean: "boolean",
1986
+ Int: "integer",
1987
+ BigInt: "bigint",
1988
+ Float: "double precision",
1989
+ Decimal: "decimal",
1990
+ DateTime: "timestamp",
1991
+ Bytes: "bytea",
1992
+ Json: "jsonb"
1993
+ };
1941
1994
  constructor(schema, options) {
1942
1995
  super(schema, options);
1943
1996
  this.overrideTypeParsers();
@@ -1948,19 +2001,31 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
1948
2001
  overrideTypeParsers() {
1949
2002
  if (this.options.fixPostgresTimezone !== false && !_PostgresCrudDialect.typeParserOverrideApplied) {
1950
2003
  _PostgresCrudDialect.typeParserOverrideApplied = true;
2004
+ const fixTimezone = /* @__PURE__ */ __name((value) => {
2005
+ if (typeof value !== "string") {
2006
+ return value;
2007
+ }
2008
+ if (!this.hasTimezoneOffset(value)) {
2009
+ value += "Z";
2010
+ }
2011
+ const result = new Date(value);
2012
+ return isNaN(result.getTime()) ? value : result;
2013
+ }, "fixTimezone");
1951
2014
  import(
1952
2015
  /* webpackIgnore: true */
1953
2016
  "pg"
1954
2017
  ).then((pg) => {
1955
- pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, (value) => {
2018
+ pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, fixTimezone);
2019
+ pg.types.setTypeParser(1115, (value) => {
1956
2020
  if (typeof value !== "string") {
1957
2021
  return value;
1958
2022
  }
1959
- if (!this.hasTimezoneOffset(value)) {
1960
- value += "Z";
2023
+ try {
2024
+ const arr = parsePostgresArray(value);
2025
+ return arr.map(fixTimezone);
2026
+ } catch {
2027
+ return value;
1961
2028
  }
1962
- const result = new Date(value);
1963
- return isNaN(result.getTime()) ? value : result;
1964
2029
  });
1965
2030
  }).catch(() => {
1966
2031
  });
@@ -2014,20 +2079,42 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2014
2079
  return value.map((v) => this.transformInput(v, type, false));
2015
2080
  }
2016
2081
  } else {
2017
- return match4(type).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value !== null ? value.toString() : value).with("Json", () => {
2018
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2019
- return JSON.stringify(value);
2020
- } else {
2082
+ switch (type) {
2083
+ case "DateTime":
2084
+ return value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value;
2085
+ case "Decimal":
2086
+ return value !== null ? value.toString() : value;
2087
+ case "Json":
2088
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2089
+ return JSON.stringify(value);
2090
+ } else {
2091
+ return value;
2092
+ }
2093
+ default:
2021
2094
  return value;
2022
- }
2023
- }).otherwise(() => value);
2095
+ }
2024
2096
  }
2025
2097
  }
2026
2098
  transformOutput(value, type, array) {
2027
2099
  if (value === null || value === void 0) {
2028
2100
  return value;
2029
2101
  }
2030
- return match4(type).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Decimal", () => this.transformDecimal(value)).when((type2) => isEnum(this.schema, type2), () => this.transformOutputEnum(value, array)).otherwise(() => super.transformOutput(value, type, array));
2102
+ switch (type) {
2103
+ case "DateTime":
2104
+ return this.transformOutputDate(value);
2105
+ case "Bytes":
2106
+ return this.transformOutputBytes(value);
2107
+ case "BigInt":
2108
+ return this.transformOutputBigInt(value);
2109
+ case "Decimal":
2110
+ return this.transformDecimal(value);
2111
+ default:
2112
+ if (isEnum(this.schema, type)) {
2113
+ return this.transformOutputEnum(value, array);
2114
+ } else {
2115
+ return super.transformOutput(value, type, array);
2116
+ }
2117
+ }
2031
2118
  }
2032
2119
  transformOutputBigInt(value) {
2033
2120
  if (typeof value === "bigint") {
@@ -2136,18 +2223,24 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2136
2223
  }
2137
2224
  }
2138
2225
  buildJsonArrayFilter(lhs, operation, value) {
2139
- return match4(operation).with("array_contains", () => {
2140
- const v = Array.isArray(value) ? value : [
2141
- value
2142
- ];
2143
- return sql3`${lhs} @> ${sql3.val(JSON.stringify(v))}::jsonb`;
2144
- }).with("array_starts_with", () => this.eb(this.eb.fn("jsonb_extract_path", [
2145
- lhs,
2146
- this.eb.val("0")
2147
- ]), "=", this.transformInput(value, "Json", false))).with("array_ends_with", () => this.eb(this.eb.fn("jsonb_extract_path", [
2148
- lhs,
2149
- sql3`(jsonb_array_length(${lhs}) - 1)::text`
2150
- ]), "=", this.transformInput(value, "Json", false))).exhaustive();
2226
+ switch (operation) {
2227
+ case "array_contains": {
2228
+ const v = Array.isArray(value) ? value : [
2229
+ value
2230
+ ];
2231
+ return sql3`${lhs} @> ${sql3.val(JSON.stringify(v))}::jsonb`;
2232
+ }
2233
+ case "array_starts_with":
2234
+ return this.eb(this.eb.fn("jsonb_extract_path", [
2235
+ lhs,
2236
+ this.eb.val("0")
2237
+ ]), "=", this.transformInput(value, "Json", false));
2238
+ case "array_ends_with":
2239
+ return this.eb(this.eb.fn("jsonb_extract_path", [
2240
+ lhs,
2241
+ sql3`(jsonb_array_length(${lhs}) - 1)::text`
2242
+ ]), "=", this.transformInput(value, "Json", false));
2243
+ }
2151
2244
  }
2152
2245
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
2153
2246
  return this.eb.exists(this.eb.selectFrom(this.eb.fn("jsonb_array_elements", [
@@ -2158,7 +2251,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2158
2251
  if (isEnum(this.schema, zmodelType)) {
2159
2252
  return "text";
2160
2253
  } else {
2161
- return match4(zmodelType).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("BigInt", () => "bigint").with("Float", () => "double precision").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => "bytea").with("Json", () => "jsonb").otherwise(() => "text");
2254
+ return this.zmodelToSqlTypeMap[zmodelType] ?? "text";
2162
2255
  }
2163
2256
  }
2164
2257
  getStringCasingBehavior() {
@@ -2200,7 +2293,6 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2200
2293
  import { invariant as invariant6 } from "@zenstackhq/common-helpers";
2201
2294
  import Decimal3 from "decimal.js";
2202
2295
  import { expressionBuilder as expressionBuilder4, ExpressionWrapper as ExpressionWrapper2, sql as sql4, ValueListNode as ValueListNode2 } from "kysely";
2203
- import { match as match5 } from "ts-pattern";
2204
2296
  var SqliteCrudDialect = class extends BaseCrudDialect {
2205
2297
  static {
2206
2298
  __name(this, "SqliteCrudDialect");
@@ -2249,7 +2341,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2249
2341
  if (Array.isArray(value)) {
2250
2342
  return value.map((v) => this.transformInput(v, type, false));
2251
2343
  } else {
2252
- return match5(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).otherwise(() => value);
2344
+ switch (type) {
2345
+ case "Boolean":
2346
+ return value ? 1 : 0;
2347
+ case "DateTime":
2348
+ return value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value;
2349
+ case "Decimal":
2350
+ return value.toString();
2351
+ case "Bytes":
2352
+ return Buffer.from(value);
2353
+ default:
2354
+ return value;
2355
+ }
2253
2356
  }
2254
2357
  }
2255
2358
  transformOutput(value, type, array) {
@@ -2258,7 +2361,22 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2258
2361
  } else if (this.schema.typeDefs && type in this.schema.typeDefs) {
2259
2362
  return this.transformOutputJson(value);
2260
2363
  } else {
2261
- return match5(type).with("Boolean", () => this.transformOutputBoolean(value)).with("DateTime", () => this.transformOutputDate(value)).with("Bytes", () => this.transformOutputBytes(value)).with("Decimal", () => this.transformOutputDecimal(value)).with("BigInt", () => this.transformOutputBigInt(value)).with("Json", () => this.transformOutputJson(value)).otherwise(() => super.transformOutput(value, type, array));
2364
+ switch (type) {
2365
+ case "Boolean":
2366
+ return this.transformOutputBoolean(value);
2367
+ case "DateTime":
2368
+ return this.transformOutputDate(value);
2369
+ case "Bytes":
2370
+ return this.transformOutputBytes(value);
2371
+ case "Decimal":
2372
+ return this.transformOutputDecimal(value);
2373
+ case "BigInt":
2374
+ return this.transformOutputBigInt(value);
2375
+ case "Json":
2376
+ return this.transformOutputJson(value);
2377
+ default:
2378
+ return super.transformOutput(value, type, array);
2379
+ }
2262
2380
  }
2263
2381
  }
2264
2382
  transformOutputDecimal(value) {
@@ -2429,16 +2547,21 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2429
2547
  }
2430
2548
  }
2431
2549
  buildJsonArrayFilter(lhs, operation, value) {
2432
- return match5(operation).with("array_contains", () => {
2433
- if (Array.isArray(value)) {
2434
- throw createNotSupportedError('SQLite "array_contains" only supports checking for a single value, not an array of values');
2435
- } else {
2436
- return sql4`EXISTS (SELECT 1 FROM json_each(${lhs}) WHERE value = ${value})`;
2437
- }
2438
- }).with("array_starts_with", () => this.eb(this.eb.fn("json_extract", [
2439
- lhs,
2440
- this.eb.val("$[0]")
2441
- ]), "=", value)).with("array_ends_with", () => this.eb(sql4`json_extract(${lhs}, '$[' || (json_array_length(${lhs}) - 1) || ']')`, "=", value)).exhaustive();
2550
+ switch (operation) {
2551
+ case "array_contains":
2552
+ if (Array.isArray(value)) {
2553
+ throw createNotSupportedError('SQLite "array_contains" only supports checking for a single value, not an array of values');
2554
+ } else {
2555
+ return sql4`EXISTS (SELECT 1 FROM json_each(${lhs}) WHERE value = ${value})`;
2556
+ }
2557
+ case "array_starts_with":
2558
+ return this.eb(this.eb.fn("json_extract", [
2559
+ lhs,
2560
+ this.eb.val("$[0]")
2561
+ ]), "=", value);
2562
+ case "array_ends_with":
2563
+ return this.eb(sql4`json_extract(${lhs}, '$[' || (json_array_length(${lhs}) - 1) || ']')`, "=", value);
2564
+ }
2442
2565
  }
2443
2566
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
2444
2567
  return this.eb.exists(this.eb.selectFrom(this.eb.fn("json_each", [
@@ -2507,7 +2630,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2507
2630
 
2508
2631
  // src/client/crud/dialects/index.ts
2509
2632
  function getCrudDialect(schema, options) {
2510
- return match6(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).with("mysql", () => new MySqlCrudDialect(schema, options)).exhaustive();
2633
+ return match3(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).with("mysql", () => new MySqlCrudDialect(schema, options)).exhaustive();
2511
2634
  }
2512
2635
  __name(getCrudDialect, "getCrudDialect");
2513
2636
 
@@ -2793,7 +2916,9 @@ var BaseOperationHandler = class {
2793
2916
  }
2794
2917
  }
2795
2918
  if (fromRelation && m2m) {
2796
- await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, createdEntity, m2m.joinTable);
2919
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, [
2920
+ createdEntity
2921
+ ], m2m.joinTable);
2797
2922
  }
2798
2923
  if (updateParent) {
2799
2924
  updateParent(createdEntity);
@@ -2850,41 +2975,36 @@ var BaseOperationHandler = class {
2850
2975
  }
2851
2976
  return parentFkFields;
2852
2977
  }
2853
- async handleManyToManyRelation(kysely, action, leftModel, leftField, leftEntity, rightModel, rightField, rightEntity, joinTable) {
2854
- const sortedRecords = [
2855
- {
2856
- model: leftModel,
2857
- field: leftField,
2858
- entity: leftEntity
2859
- },
2860
- {
2861
- model: rightModel,
2862
- field: rightField,
2863
- entity: rightEntity
2864
- }
2865
- ].sort((a, b) => (
2866
- // the implicit m2m join table's "A", "B" fk fields' order is determined
2867
- // by model name's sort order, and when identical (for self-relations),
2868
- // field name's sort order
2869
- a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
2870
- ));
2871
- const firstIds = requireIdFields(this.schema, sortedRecords[0].model);
2872
- const secondIds = requireIdFields(this.schema, sortedRecords[1].model);
2873
- invariant7(firstIds.length === 1, "many-to-many relation must have exactly one id field");
2874
- invariant7(secondIds.length === 1, "many-to-many relation must have exactly one id field");
2978
+ async handleManyToManyRelation(kysely, action, leftModel, leftField, leftEntity, rightModel, rightField, rightEntities, joinTable) {
2979
+ if (rightEntities.length === 0) {
2980
+ return;
2981
+ }
2982
+ const leftFirst = leftModel !== rightModel ? leftModel.localeCompare(rightModel) <= 0 : leftField.localeCompare(rightField) <= 0;
2983
+ const leftIdField = requireIdFields(this.schema, leftModel);
2984
+ const rightIdField = requireIdFields(this.schema, rightModel);
2985
+ invariant7(leftIdField.length === 1, "many-to-many relation must have exactly one id field");
2986
+ invariant7(rightIdField.length === 1, "many-to-many relation must have exactly one id field");
2987
+ const leftIdValue = leftEntity[leftIdField[0]];
2988
+ const rightIdValues = rightEntities.map((e) => e[rightIdField[0]]);
2875
2989
  if (action === "connect") {
2876
- const result = await kysely.insertInto(joinTable).values({
2877
- A: sortedRecords[0].entity[firstIds[0]],
2878
- B: sortedRecords[1].entity[secondIds[0]]
2879
- }).$if(this.dialect.insertIgnoreMethod === "onConflict", (qb) => qb.onConflict((oc) => oc.columns([
2990
+ const values = rightIdValues.map((rightId) => ({
2991
+ A: leftFirst ? leftIdValue : rightId,
2992
+ B: leftFirst ? rightId : leftIdValue
2993
+ }));
2994
+ await kysely.insertInto(joinTable).values(values).$if(this.dialect.insertIgnoreMethod === "onConflict", (qb) => qb.onConflict((oc) => oc.columns([
2880
2995
  "A",
2881
2996
  "B"
2882
2997
  ]).doNothing())).$if(this.dialect.insertIgnoreMethod === "ignore", (qb) => qb.ignore()).execute();
2883
- return result[0];
2884
2998
  } else {
2885
2999
  const eb = expressionBuilder5();
2886
- const result = await kysely.deleteFrom(joinTable).where(eb(`${joinTable}.A`, "=", sortedRecords[0].entity[firstIds[0]])).where(eb(`${joinTable}.B`, "=", sortedRecords[1].entity[secondIds[0]])).execute();
2887
- return result[0];
3000
+ const [leftCol, rightCol] = leftFirst ? [
3001
+ "A",
3002
+ "B"
3003
+ ] : [
3004
+ "B",
3005
+ "A"
3006
+ ];
3007
+ await kysely.deleteFrom(joinTable).where(eb(`${joinTable}.${leftCol}`, "=", leftIdValue)).where(eb(`${joinTable}.${rightCol}`, "in", rightIdValues)).execute();
2888
3008
  }
2889
3009
  }
2890
3010
  resetManyToManyRelation(kysely, model, field, parentIds) {
@@ -3142,7 +3262,7 @@ var BaseOperationHandler = class {
3142
3262
  evalGenerator(defaultValue) {
3143
3263
  if (schema_exports.ExpressionUtils.isCall(defaultValue)) {
3144
3264
  const firstArgVal = defaultValue.args?.[0] && schema_exports.ExpressionUtils.isLiteral(defaultValue.args[0]) ? defaultValue.args[0].value : void 0;
3145
- return match7(defaultValue.function).with("cuid", () => {
3265
+ return match4(defaultValue.function).with("cuid", () => {
3146
3266
  const version = firstArgVal;
3147
3267
  const generated = version === 2 ? cuid2() : cuid1();
3148
3268
  return this.formatGeneratedValue(generated, defaultValue.args?.[1]);
@@ -3171,6 +3291,13 @@ var BaseOperationHandler = class {
3171
3291
  }
3172
3292
  return formatExpr.value.replace(/(?<!\\)%s/g, generated).replace(/\\%s/g, "%s");
3173
3293
  }
3294
+ /**
3295
+ * @returns
3296
+ * - throw if `throwIfNotFound` is true and the entity to update is not found
3297
+ * - otherwise, null if the entity to update is not found
3298
+ * - if found and `fieldsToReturn` is specified, return the post-update fields
3299
+ * - if found and `fieldsToReturn` is not specified, return true (indicating success)
3300
+ */
3174
3301
  async update(kysely, model, where, data, fromRelation, allowRelationUpdate = true, throwIfNotFound = true, fieldsToReturn) {
3175
3302
  if (!data || typeof data !== "object") {
3176
3303
  throw createInvalidInputError("data must be an object");
@@ -3185,6 +3312,7 @@ var BaseOperationHandler = class {
3185
3312
  ]
3186
3313
  } : parentWhere;
3187
3314
  }
3315
+ const origWhere = combinedWhere;
3188
3316
  const modelDef = this.requireModel(model);
3189
3317
  let finalData = data;
3190
3318
  const autoUpdatedFields = [];
@@ -3201,46 +3329,51 @@ var BaseOperationHandler = class {
3201
3329
  }
3202
3330
  }
3203
3331
  }
3204
- const thisEntity = await this.getEntityIds(kysely, model, combinedWhere);
3205
- if (!thisEntity) {
3206
- if (throwIfNotFound) {
3207
- throw createNotFoundError(model);
3208
- } else {
3209
- return null;
3332
+ let thisEntity;
3333
+ const loadThisEntity = /* @__PURE__ */ __name(async () => {
3334
+ if (thisEntity === void 0) {
3335
+ thisEntity = await this.getEntityIds(kysely, model, origWhere) ?? null;
3336
+ if (!thisEntity && throwIfNotFound) {
3337
+ throw createNotFoundError(model);
3338
+ }
3210
3339
  }
3211
- }
3212
- if (Object.keys(finalData).length === 0) {
3213
3340
  return thisEntity;
3214
- }
3215
- let needIdRead = false;
3216
- if (!this.isIdFilter(model, combinedWhere)) {
3217
- if (modelDef.baseModel) {
3218
- needIdRead = true;
3219
- }
3220
- if (!this.dialect.supportsReturning) {
3221
- needIdRead = true;
3222
- }
3223
- }
3224
- if (needIdRead) {
3225
- const readResult = await this.readUnique(kysely, model, {
3226
- where: combinedWhere,
3227
- select: this.makeIdSelect(model)
3228
- });
3229
- if (!readResult && throwIfNotFound) {
3230
- throw createNotFoundError(model);
3341
+ }, "loadThisEntity");
3342
+ if (Object.keys(finalData).length === 0) {
3343
+ return loadThisEntity();
3344
+ }
3345
+ if (
3346
+ // when updating a model with delegate base, base fields may be referenced in the filter,
3347
+ // so we read the id out if the filter and and use it as the update filter instead
3348
+ modelDef.baseModel || // for dialects that don't support RETURNING, we need to read the id fields
3349
+ // to identify the updated entity for toplevel updates
3350
+ !this.dialect.supportsReturning && !fromRelation
3351
+ ) {
3352
+ combinedWhere = await loadThisEntity();
3353
+ if (!combinedWhere) {
3354
+ return null;
3231
3355
  }
3232
- combinedWhere = readResult;
3233
3356
  }
3234
3357
  if (modelDef.baseModel) {
3235
3358
  const baseUpdateResult = await this.processBaseModelUpdate(kysely, modelDef.baseModel, combinedWhere, finalData, throwIfNotFound);
3359
+ if (!baseUpdateResult.baseEntity) {
3360
+ if (throwIfNotFound) {
3361
+ throw createNotFoundError(model);
3362
+ } else {
3363
+ return null;
3364
+ }
3365
+ }
3236
3366
  finalData = baseUpdateResult.remainingFields;
3237
- combinedWhere = baseUpdateResult.baseEntity ? getIdValues(this.schema, modelDef.baseModel, baseUpdateResult.baseEntity) : baseUpdateResult.baseEntity;
3238
- if (baseUpdateResult.baseEntity) {
3367
+ combinedWhere = getIdValues(this.schema, modelDef.baseModel, baseUpdateResult.baseEntity);
3368
+ await loadThisEntity();
3369
+ if (thisEntity) {
3239
3370
  for (const [key, value] of Object.entries(baseUpdateResult.baseEntity)) {
3240
3371
  if (key in thisEntity) {
3241
3372
  thisEntity[key] = value;
3242
3373
  }
3243
3374
  }
3375
+ } else {
3376
+ return null;
3244
3377
  }
3245
3378
  }
3246
3379
  const updateFields = {};
@@ -3252,7 +3385,11 @@ var BaseOperationHandler = class {
3252
3385
  if (!allowRelationUpdate) {
3253
3386
  throw createNotSupportedError(`Relation update not allowed for field "${field}"`);
3254
3387
  }
3255
- const parentUpdates = await this.processRelationUpdates(kysely, model, field, fieldDef, thisEntity, finalData[field]);
3388
+ const relationParent = await loadThisEntity();
3389
+ if (!relationParent) {
3390
+ return null;
3391
+ }
3392
+ const parentUpdates = await this.processRelationUpdates(kysely, model, field, fieldDef, relationParent, finalData[field]);
3256
3393
  if (Object.keys(parentUpdates).length > 0) {
3257
3394
  Object.assign(updateFields, parentUpdates);
3258
3395
  }
@@ -3263,17 +3400,41 @@ var BaseOperationHandler = class {
3263
3400
  hasFieldUpdate = Object.keys(updateFields).some((f) => !autoUpdatedFields.includes(f));
3264
3401
  }
3265
3402
  if (!hasFieldUpdate) {
3266
- return thisEntity;
3403
+ return loadThisEntity();
3267
3404
  } else {
3268
- fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
3269
3405
  let updatedEntity;
3270
3406
  if (this.dialect.supportsReturning) {
3271
- const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).returning(fieldsToReturn).modifyEnd(this.makeContextComment({
3407
+ const returnFields = fieldsToReturn !== void 0 && fieldsToReturn.length > 0;
3408
+ const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).$if(returnFields, (qb) => qb.returning(fieldsToReturn)).modifyEnd(this.makeContextComment({
3272
3409
  model,
3273
3410
  operation: "update"
3274
3411
  }));
3275
- updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3412
+ if (returnFields) {
3413
+ updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3414
+ } else {
3415
+ const r = await this.executeQuery(kysely, query, "update");
3416
+ if (!r.numAffectedRows) {
3417
+ updatedEntity = null;
3418
+ } else {
3419
+ updatedEntity = true;
3420
+ }
3421
+ }
3276
3422
  } else {
3423
+ let readFilter = combinedWhere;
3424
+ const idFields = requireIdFields(this.schema, model);
3425
+ const updatingIdFields = idFields.some((idField) => idField in updateFields);
3426
+ if (updatingIdFields) {
3427
+ const origIdValues = await loadThisEntity();
3428
+ invariant7(origIdValues, "Original entity should have been loaded for update without RETURNING");
3429
+ readFilter = {
3430
+ ...origIdValues
3431
+ };
3432
+ for (const idField of idFields) {
3433
+ if (idField in updateFields && updateFields[idField] !== void 0) {
3434
+ readFilter[idField] = updateFields[idField];
3435
+ }
3436
+ }
3437
+ }
3277
3438
  const updateQuery = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).modifyEnd(this.makeContextComment({
3278
3439
  model,
3279
3440
  operation: "update"
@@ -3281,26 +3442,12 @@ var BaseOperationHandler = class {
3281
3442
  const updateResult = await this.executeQuery(kysely, updateQuery, "update");
3282
3443
  if (!updateResult.numAffectedRows) {
3283
3444
  updatedEntity = null;
3445
+ } else if (fieldsToReturn === void 0 || fieldsToReturn.length === 0) {
3446
+ updatedEntity = true;
3284
3447
  } else {
3285
- const idFields = requireIdFields(this.schema, model);
3286
- const filterIdValues = {};
3287
- for (const key of idFields) {
3288
- if (combinedWhere[key] !== void 0 && typeof combinedWhere[key] !== "object") {
3289
- filterIdValues[key] = combinedWhere[key];
3290
- }
3291
- }
3292
- const updatingIdFields = idFields.some((idField) => idField in updateFields);
3293
- if (Object.keys(filterIdValues).length === idFields.length && !updatingIdFields) {
3294
- updatedEntity = filterIdValues;
3448
+ if (!updatingIdFields) {
3449
+ updatedEntity = await loadThisEntity();
3295
3450
  } else {
3296
- const readFilter = {
3297
- ...combinedWhere
3298
- };
3299
- for (const idField of idFields) {
3300
- if (idField in updateFields && updateFields[idField] !== void 0) {
3301
- readFilter[idField] = updateFields[idField];
3302
- }
3303
- }
3304
3451
  const selectQuery = kysely.selectFrom(model).select(fieldsToReturn).where(() => this.dialect.buildFilter(model, model, readFilter));
3305
3452
  updatedEntity = await this.executeQueryTakeFirst(kysely, selectQuery, "update");
3306
3453
  }
@@ -3370,13 +3517,6 @@ var BaseOperationHandler = class {
3370
3517
  "set"
3371
3518
  ].some((key) => key in value);
3372
3519
  }
3373
- isIdFilter(model, filter) {
3374
- if (!filter || typeof filter !== "object") {
3375
- return false;
3376
- }
3377
- const idFields = requireIdFields(this.schema, model);
3378
- return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3379
- }
3380
3520
  async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
3381
3521
  const thisUpdateFields = {};
3382
3522
  const remainingFields = {};
@@ -3388,7 +3528,7 @@ var BaseOperationHandler = class {
3388
3528
  remainingFields[field] = value;
3389
3529
  }
3390
3530
  });
3391
- const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound);
3531
+ const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound, requireIdFields(this.schema, model));
3392
3532
  return {
3393
3533
  baseEntity,
3394
3534
  remainingFields
@@ -3400,7 +3540,7 @@ var BaseOperationHandler = class {
3400
3540
  const value = this.dialect.transformInput(payload[key], fieldDef.type, false);
3401
3541
  const eb = expressionBuilder5();
3402
3542
  const fieldRef = this.dialect.fieldRef(model, field);
3403
- return match7(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3543
+ return match4(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
3404
3544
  throw createInvalidInputError(`Invalid incremental update operation: ${key}`);
3405
3545
  });
3406
3546
  }
@@ -3410,7 +3550,7 @@ var BaseOperationHandler = class {
3410
3550
  const value = this.dialect.transformInput(payload[key], fieldDef.type, true);
3411
3551
  const eb = expressionBuilder5();
3412
3552
  const fieldRef = this.dialect.fieldRef(model, field);
3413
- return match7(key).with("set", () => value).with("push", () => {
3553
+ return match4(key).with("set", () => value).with("push", () => {
3414
3554
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
3415
3555
  }).otherwise(() => {
3416
3556
  throw createInvalidInputError(`Invalid array update operation: ${key}`);
@@ -3650,18 +3790,11 @@ var BaseOperationHandler = class {
3650
3790
  }
3651
3791
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3652
3792
  if (m2m) {
3653
- const results = [];
3654
- for (const d of _data) {
3655
- const ids = await this.getEntityIds(kysely, model, d);
3656
- if (!ids) {
3657
- throw createNotFoundError(model);
3658
- }
3659
- const r = await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3660
- results.push(r);
3661
- }
3662
- if (_data.length > results.filter((r) => !!r).length) {
3793
+ const allIds = await this.getEntitiesIds(kysely, model, _data);
3794
+ if (allIds.length !== _data.length) {
3663
3795
  throw createNotFoundError(model);
3664
3796
  }
3797
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3665
3798
  } else {
3666
3799
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3667
3800
  if (ownedByModel) {
@@ -3738,12 +3871,9 @@ var BaseOperationHandler = class {
3738
3871
  }
3739
3872
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3740
3873
  if (m2m) {
3741
- for (const d of disconnectConditions) {
3742
- const ids = await this.getEntityIds(kysely, model, d);
3743
- if (!ids) {
3744
- return;
3745
- }
3746
- await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3874
+ const allIds = await this.getEntitiesIds(kysely, model, disconnectConditions);
3875
+ if (allIds.length > 0) {
3876
+ await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3747
3877
  }
3748
3878
  } else {
3749
3879
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
@@ -3808,16 +3938,12 @@ var BaseOperationHandler = class {
3808
3938
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3809
3939
  if (m2m) {
3810
3940
  await this.resetManyToManyRelation(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
3811
- const results = [];
3812
- for (const d of _data) {
3813
- const ids = await this.getEntityIds(kysely, model, d);
3814
- if (!ids) {
3941
+ if (_data.length > 0) {
3942
+ const allIds = await this.getEntitiesIds(kysely, model, _data);
3943
+ if (allIds.length !== _data.length) {
3815
3944
  throw createNotFoundError(model);
3816
3945
  }
3817
- results.push(await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable));
3818
- }
3819
- if (_data.length > results.filter((r) => !!r).length) {
3820
- throw createNotFoundError(model);
3946
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3821
3947
  }
3822
3948
  } else {
3823
3949
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
@@ -4029,6 +4155,13 @@ var BaseOperationHandler = class {
4029
4155
  return txBuilder.execute(callback);
4030
4156
  }
4031
4157
  }
4158
+ async safeTransactionIf(condition, callback, isolationLevel) {
4159
+ if (condition) {
4160
+ return this.safeTransaction(callback, isolationLevel);
4161
+ } else {
4162
+ return callback(this.kysely);
4163
+ }
4164
+ }
4032
4165
  // Given a unique filter of a model, load the entity and return its id fields
4033
4166
  getEntityIds(kysely, model, uniqueFilter) {
4034
4167
  return this.readUnique(kysely, model, {
@@ -4036,6 +4169,15 @@ var BaseOperationHandler = class {
4036
4169
  select: this.makeIdSelect(model)
4037
4170
  });
4038
4171
  }
4172
+ // Given multiple unique filters, load all matching entities and return their id fields in one query
4173
+ getEntitiesIds(kysely, model, uniqueFilters) {
4174
+ return this.read(kysely, model, {
4175
+ where: {
4176
+ OR: uniqueFilters
4177
+ },
4178
+ select: this.makeIdSelect(model)
4179
+ });
4180
+ }
4039
4181
  /**
4040
4182
  * Normalize input args to strip `undefined` fields
4041
4183
  */
@@ -4073,29 +4215,30 @@ var BaseOperationHandler = class {
4073
4215
  return result.rows[0];
4074
4216
  }
4075
4217
  mutationNeedsReadBack(model, args) {
4218
+ const idFields = requireIdFields(this.schema, model);
4076
4219
  if (this.hasPolicyEnabled) {
4077
4220
  return {
4078
4221
  needReadBack: true,
4079
- selectedFields: void 0
4222
+ selectedFields: idFields
4080
4223
  };
4081
4224
  }
4082
4225
  if (!this.dialect.supportsReturning) {
4083
4226
  return {
4084
4227
  needReadBack: true,
4085
- selectedFields: void 0
4228
+ selectedFields: idFields
4086
4229
  };
4087
4230
  }
4088
4231
  if (args.include && typeof args.include === "object" && Object.keys(args.include).length > 0) {
4089
4232
  return {
4090
4233
  needReadBack: true,
4091
- selectedFields: void 0
4234
+ selectedFields: idFields
4092
4235
  };
4093
4236
  }
4094
4237
  const modelDef = this.requireModel(model);
4095
4238
  if (modelDef.baseModel || modelDef.isDelegate) {
4096
4239
  return {
4097
4240
  needReadBack: true,
4098
- selectedFields: void 0
4241
+ selectedFields: idFields
4099
4242
  };
4100
4243
  }
4101
4244
  const allFields = Object.keys(modelDef.fields);
@@ -4110,7 +4253,7 @@ var BaseOperationHandler = class {
4110
4253
  if (allFieldsSelected.some((f) => relationFields.includes(f) || computedFields.includes(f))) {
4111
4254
  return {
4112
4255
  needReadBack: true,
4113
- selectedFields: void 0
4256
+ selectedFields: idFields
4114
4257
  };
4115
4258
  } else {
4116
4259
  return {
@@ -4182,7 +4325,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4182
4325
  Object.entries(value).forEach(([field, val]) => {
4183
4326
  if (val === true) {
4184
4327
  query = query.select((eb) => {
4185
- const fn = match8(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4328
+ const fn = match5(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4186
4329
  return fn(eb.ref(`$sub.${field}`)).as(`${key}.${field}`);
4187
4330
  });
4188
4331
  }
@@ -4215,7 +4358,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4215
4358
  val = parseFloat(val);
4216
4359
  } else {
4217
4360
  if (op === "_sum" || op === "_min" || op === "_max") {
4218
- val = match8(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4361
+ val = match5(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4219
4362
  }
4220
4363
  }
4221
4364
  }
@@ -4265,14 +4408,14 @@ var CountOperationHandler = class extends BaseOperationHandler {
4265
4408
  };
4266
4409
 
4267
4410
  // src/client/crud/operations/create.ts
4268
- import { match as match9 } from "ts-pattern";
4411
+ import { match as match6 } from "ts-pattern";
4269
4412
  var CreateOperationHandler = class extends BaseOperationHandler {
4270
4413
  static {
4271
4414
  __name(this, "CreateOperationHandler");
4272
4415
  }
4273
4416
  async handle(operation, args) {
4274
4417
  const normalizedArgs = this.normalizeArgs(args);
4275
- return match9(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4418
+ return match6(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4276
4419
  return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
4277
4420
  }).with("createManyAndReturn", () => {
4278
4421
  return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
@@ -4280,7 +4423,8 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4280
4423
  }
4281
4424
  async runCreate(args) {
4282
4425
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4283
- const result = await this.safeTransaction(async (tx) => {
4426
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4427
+ const result = await this.safeTransactionIf(needReadBack || needsNestedCreate, async (tx) => {
4284
4428
  const createResult = await this.create(tx, this.model, args.data, void 0, false, selectedFields);
4285
4429
  if (needReadBack) {
4286
4430
  return this.readUnique(tx, this.model, {
@@ -4304,14 +4448,16 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4304
4448
  count: 0
4305
4449
  };
4306
4450
  }
4307
- return this.safeTransaction((tx) => this.createMany(tx, this.model, args, false));
4451
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4452
+ return this.safeTransactionIf(needsNestedCreate, (tx) => this.createMany(tx, this.model, args, false));
4308
4453
  }
4309
4454
  async runCreateManyAndReturn(args) {
4310
4455
  if (args === void 0) {
4311
4456
  return [];
4312
4457
  }
4313
4458
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4314
- return this.safeTransaction(async (tx) => {
4459
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4460
+ return this.safeTransactionIf(needReadBack || needsNestedCreate, async (tx) => {
4315
4461
  const createResult = await this.createMany(tx, this.model, args, true, void 0, selectedFields);
4316
4462
  if (needReadBack) {
4317
4463
  return this.read(tx, this.model, {
@@ -4326,21 +4472,36 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4326
4472
  }
4327
4473
  });
4328
4474
  }
4475
+ needsNestedCreate(data) {
4476
+ const modelDef = this.requireModel(this.model);
4477
+ if (modelDef.baseModel) {
4478
+ return true;
4479
+ }
4480
+ const hasRelation = Object.entries(data).some(([field, value]) => {
4481
+ const fieldDef = this.getField(this.model, field);
4482
+ return fieldDef?.relation && value !== void 0;
4483
+ });
4484
+ if (hasRelation) {
4485
+ return true;
4486
+ }
4487
+ return false;
4488
+ }
4329
4489
  };
4330
4490
 
4331
4491
  // src/client/crud/operations/delete.ts
4332
- import { match as match10 } from "ts-pattern";
4492
+ import { match as match7 } from "ts-pattern";
4333
4493
  var DeleteOperationHandler = class extends BaseOperationHandler {
4334
4494
  static {
4335
4495
  __name(this, "DeleteOperationHandler");
4336
4496
  }
4337
4497
  async handle(operation, args) {
4338
4498
  const normalizedArgs = this.normalizeArgs(args);
4339
- return match10(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4499
+ return match7(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4340
4500
  }
4341
4501
  async runDelete(args) {
4342
4502
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4343
- const result = await this.safeTransaction(async (tx) => {
4503
+ const needsNestedDelete = this.needsNestedDelete();
4504
+ const result = await this.safeTransactionIf(needReadBack || needsNestedDelete, async (tx) => {
4344
4505
  let preDeleteRead = void 0;
4345
4506
  if (needReadBack) {
4346
4507
  preDeleteRead = await this.readUnique(tx, this.model, {
@@ -4362,13 +4523,30 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
4362
4523
  return result;
4363
4524
  }
4364
4525
  async runDeleteMany(args) {
4365
- return await this.safeTransaction(async (tx) => {
4526
+ const needsNestedDelete = this.needsNestedDelete();
4527
+ return await this.safeTransactionIf(needsNestedDelete, async (tx) => {
4366
4528
  const result = await this.delete(tx, this.model, args?.where, args?.limit);
4367
4529
  return {
4368
4530
  count: Number(result.numAffectedRows ?? 0)
4369
4531
  };
4370
4532
  });
4371
4533
  }
4534
+ needsNestedDelete() {
4535
+ const modelDef = this.requireModel(this.model);
4536
+ if (modelDef.baseModel) {
4537
+ return true;
4538
+ }
4539
+ for (const fieldDef of Object.values(modelDef.fields)) {
4540
+ if (fieldDef.relation?.opposite) {
4541
+ const oppositeModelDef = this.requireModel(fieldDef.type);
4542
+ const oppositeRelation = this.requireField(fieldDef.type, fieldDef.relation.opposite);
4543
+ if (oppositeModelDef.baseModel && oppositeRelation.relation?.onDelete === "Cascade") {
4544
+ return true;
4545
+ }
4546
+ }
4547
+ }
4548
+ return false;
4549
+ }
4372
4550
  };
4373
4551
 
4374
4552
  // src/client/crud/operations/exists.ts
@@ -4403,7 +4581,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4403
4581
  };
4404
4582
 
4405
4583
  // src/client/crud/operations/group-by.ts
4406
- import { match as match11 } from "ts-pattern";
4584
+ import { match as match8 } from "ts-pattern";
4407
4585
  var GroupByOperationHandler = class extends BaseOperationHandler {
4408
4586
  static {
4409
4587
  __name(this, "GroupByOperationHandler");
@@ -4491,7 +4669,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4491
4669
  val = parseFloat(val);
4492
4670
  } else {
4493
4671
  if (op === "_sum" || op === "_min" || op === "_max") {
4494
- val = match11(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4672
+ val = match8(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4495
4673
  }
4496
4674
  }
4497
4675
  }
@@ -4506,18 +4684,19 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4506
4684
  };
4507
4685
 
4508
4686
  // src/client/crud/operations/update.ts
4509
- import { match as match12 } from "ts-pattern";
4687
+ import { match as match9 } from "ts-pattern";
4510
4688
  var UpdateOperationHandler = class extends BaseOperationHandler {
4511
4689
  static {
4512
4690
  __name(this, "UpdateOperationHandler");
4513
4691
  }
4514
4692
  async handle(operation, args) {
4515
4693
  const normalizedArgs = this.normalizeArgs(args);
4516
- return match12(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))).exhaustive();
4694
+ return match9(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))).exhaustive();
4517
4695
  }
4518
4696
  async runUpdate(args) {
4519
4697
  const { needReadBack, selectedFields } = this.needReadBack(args);
4520
- const result = await this.safeTransaction(async (tx) => {
4698
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4699
+ const result = await this.safeTransactionIf(needReadBack || needsNestedUpdate, async (tx) => {
4521
4700
  const updateResult = await this.update(tx, this.model, args.where, args.data, void 0, void 0, void 0, selectedFields);
4522
4701
  if (needReadBack) {
4523
4702
  const readFilter = updateResult ? getIdValues(this.schema, this.model, updateResult) : args.where;
@@ -4544,7 +4723,8 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4544
4723
  }
4545
4724
  }
4546
4725
  async runUpdateMany(args) {
4547
- return this.safeTransaction(async (tx) => {
4726
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4727
+ return this.safeTransactionIf(needsNestedUpdate, async (tx) => {
4548
4728
  return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
4549
4729
  });
4550
4730
  }
@@ -4553,7 +4733,8 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4553
4733
  return [];
4554
4734
  }
4555
4735
  const { needReadBack, selectedFields } = this.needReadBack(args);
4556
- const { readBackResult, updateResult } = await this.safeTransaction(async (tx) => {
4736
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4737
+ const { readBackResult, updateResult } = await this.safeTransactionIf(needReadBack || needsNestedUpdate, async (tx) => {
4557
4738
  const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true, void 0, void 0, selectedFields);
4558
4739
  if (needReadBack) {
4559
4740
  const readBackResult2 = await this.read(tx, this.model, {
@@ -4607,10 +4788,11 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4607
4788
  if (baseResult.needReadBack) {
4608
4789
  return baseResult;
4609
4790
  }
4791
+ const idFields = requireIdFields(this.schema, this.model);
4610
4792
  if (!this.dialect.supportsReturning) {
4611
4793
  return {
4612
4794
  needReadBack: true,
4613
- selectedFields: void 0
4795
+ selectedFields: idFields
4614
4796
  };
4615
4797
  }
4616
4798
  const modelDef = this.requireModel(this.model);
@@ -4618,28 +4800,42 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4618
4800
  if (args.data && !Object.keys(args.data).some((field) => nonRelationFields.includes(field))) {
4619
4801
  return {
4620
4802
  needReadBack: true,
4621
- selectedFields: void 0
4803
+ selectedFields: idFields
4622
4804
  };
4623
4805
  }
4624
4806
  if (args.update && !Object.keys(args.update).some((field) => nonRelationFields.includes(field))) {
4625
4807
  return {
4626
4808
  needReadBack: true,
4627
- selectedFields: void 0
4809
+ selectedFields: idFields
4628
4810
  };
4629
4811
  }
4630
4812
  return baseResult;
4631
4813
  }
4814
+ needsNestedUpdate(data) {
4815
+ const modelDef = this.requireModel(this.model);
4816
+ if (modelDef.baseModel) {
4817
+ return true;
4818
+ }
4819
+ const hasRelation = Object.entries(data).some(([field, value]) => {
4820
+ const fieldDef = this.getField(this.model, field);
4821
+ return fieldDef?.relation && value !== void 0;
4822
+ });
4823
+ if (hasRelation) {
4824
+ return true;
4825
+ }
4826
+ return false;
4827
+ }
4632
4828
  };
4633
4829
 
4634
4830
  // src/client/crud/validator/validator.ts
4635
4831
  import { invariant as invariant9 } from "@zenstackhq/common-helpers";
4636
- import { match as match14 } from "ts-pattern";
4832
+ import { match as match11 } from "ts-pattern";
4637
4833
 
4638
4834
  // src/client/zod/factory.ts
4639
- import { enumerate as enumerate3, invariant as invariant8, lowerCaseFirst } from "@zenstackhq/common-helpers";
4835
+ import { enumerate as enumerate3, invariant as invariant8, lowerCaseFirst as lowerCaseFirst2 } from "@zenstackhq/common-helpers";
4640
4836
  import { ZodUtils } from "@zenstackhq/zod";
4641
4837
  import Decimal4 from "decimal.js";
4642
- import { match as match13, P as P2 } from "ts-pattern";
4838
+ import { match as match10, P as P2 } from "ts-pattern";
4643
4839
  import { z, ZodObject, ZodType } from "zod";
4644
4840
 
4645
4841
  // src/client/zod/cache-decorator.ts
@@ -4722,6 +4918,13 @@ var ZodSchemaFactory = class {
4722
4918
  get plugins() {
4723
4919
  return this.options.plugins ?? [];
4724
4920
  }
4921
+ /**
4922
+ * Returns model field entries, excluding Unsupported fields.
4923
+ */
4924
+ getModelFields(model) {
4925
+ const modelDef = requireModel(this.schema, model);
4926
+ return Object.entries(modelDef.fields).filter(([, def]) => def.type !== "Unsupported");
4927
+ }
4725
4928
  shouldIncludeRelations(options) {
4726
4929
  return options?.relationDepth === void 0 || options.relationDepth > 0;
4727
4930
  }
@@ -4807,7 +5010,7 @@ var ZodSchemaFactory = class {
4807
5010
  } else if (this.schema.enums && type in this.schema.enums) {
4808
5011
  return this.makeEnumSchema(type);
4809
5012
  } else {
4810
- return match13(type).with("String", () => this.extraValidationsEnabled ? ZodUtils.addStringValidation(z.string(), attributes) : z.string()).with("Int", () => this.extraValidationsEnabled ? ZodUtils.addNumberValidation(z.number().int(), attributes) : z.number().int()).with("Float", () => this.extraValidationsEnabled ? ZodUtils.addNumberValidation(z.number(), attributes) : z.number()).with("Boolean", () => z.boolean()).with("BigInt", () => z.union([
5013
+ return match10(type).with("String", () => this.extraValidationsEnabled ? ZodUtils.addStringValidation(z.string(), attributes) : z.string()).with("Int", () => this.extraValidationsEnabled ? ZodUtils.addNumberValidation(z.number().int(), attributes) : z.number().int()).with("Float", () => this.extraValidationsEnabled ? ZodUtils.addNumberValidation(z.number(), attributes) : z.number()).with("Boolean", () => z.boolean()).with("BigInt", () => z.union([
4811
5014
  this.extraValidationsEnabled ? ZodUtils.addNumberValidation(z.number().int(), attributes) : z.number().int(),
4812
5015
  this.extraValidationsEnabled ? ZodUtils.addBigIntValidation(z.bigint(), attributes) : z.bigint()
4813
5016
  ])).with("Decimal", () => {
@@ -4852,15 +5055,13 @@ var ZodSchemaFactory = class {
4852
5055
  return finalSchema;
4853
5056
  }
4854
5057
  makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false, options) {
4855
- const modelDef = requireModel(this.schema, model);
4856
5058
  const uniqueFieldNames = unique ? getUniqueFields(this.schema, model).filter((uf) => (
4857
5059
  // single-field unique
4858
5060
  "def" in uf
4859
5061
  )).map((uf) => uf.name) : void 0;
4860
5062
  const nextOpts = this.nextOptions(options);
4861
5063
  const fields = {};
4862
- for (const field of Object.keys(modelDef.fields)) {
4863
- const fieldDef = requireField(this.schema, model, field);
5064
+ for (const [field, fieldDef] of this.getModelFields(model)) {
4864
5065
  let fieldSchema;
4865
5066
  if (fieldDef.relation) {
4866
5067
  if (withoutRelationFields || !this.shouldIncludeRelations(options)) {
@@ -5055,7 +5256,7 @@ var ZodSchemaFactory = class {
5055
5256
  const allowedFilterKinds = ignoreSlicing ? void 0 : this.getEffectiveFilterKinds(contextModel, fieldInfo.name);
5056
5257
  const type = fieldInfo.type;
5057
5258
  const optional = !!fieldInfo.optional;
5058
- return match13(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)).with(P2.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makeScalarSchema(type2), optional, withAggregations, allowedFilterKinds)).with("Boolean", () => this.makeBooleanFilterSchema(optional, withAggregations, allowedFilterKinds)).with("DateTime", () => this.makeDateTimeFilterSchema(optional, withAggregations, allowedFilterKinds)).with("Bytes", () => this.makeBytesFilterSchema(optional, withAggregations, allowedFilterKinds)).with("Json", () => this.makeJsonFilterSchema(contextModel, fieldInfo.name, optional)).with("Unsupported", () => z.never()).exhaustive();
5259
+ return match10(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)).with(P2.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makeScalarSchema(type2), optional, withAggregations, allowedFilterKinds)).with("Boolean", () => this.makeBooleanFilterSchema(optional, withAggregations, allowedFilterKinds)).with("DateTime", () => this.makeDateTimeFilterSchema(optional, withAggregations, allowedFilterKinds)).with("Bytes", () => this.makeBytesFilterSchema(optional, withAggregations, allowedFilterKinds)).with("Json", () => this.makeJsonFilterSchema(contextModel, fieldInfo.name, optional)).with("Unsupported", () => z.never()).exhaustive();
5059
5260
  }
5060
5261
  makeJsonValueSchema(nullable, forFilter) {
5061
5262
  const options = [
@@ -5220,10 +5421,8 @@ var ZodSchemaFactory = class {
5220
5421
  ]);
5221
5422
  }
5222
5423
  makeSelectSchema(model, options) {
5223
- const modelDef = requireModel(this.schema, model);
5224
5424
  const fields = {};
5225
- for (const field of Object.keys(modelDef.fields)) {
5226
- const fieldDef = requireField(this.schema, model, field);
5425
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5227
5426
  if (fieldDef.relation) {
5228
5427
  if (!this.shouldIncludeRelations(options)) {
5229
5428
  continue;
@@ -5241,6 +5440,7 @@ var ZodSchemaFactory = class {
5241
5440
  fields["_count"] = _countSchema;
5242
5441
  }
5243
5442
  }
5443
+ this.addExtResultFields(model, fields);
5244
5444
  return z.strictObject(fields);
5245
5445
  }
5246
5446
  makeCountSelectionSchema(model, options) {
@@ -5295,10 +5495,8 @@ var ZodSchemaFactory = class {
5295
5495
  ]);
5296
5496
  }
5297
5497
  makeOmitSchema(model) {
5298
- const modelDef = requireModel(this.schema, model);
5299
5498
  const fields = {};
5300
- for (const field of Object.keys(modelDef.fields)) {
5301
- const fieldDef = requireField(this.schema, model, field);
5499
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5302
5500
  if (!fieldDef.relation) {
5303
5501
  if (this.options.allowQueryTimeOmitOverride !== false) {
5304
5502
  fields[field] = z.boolean().optional();
@@ -5307,8 +5505,22 @@ var ZodSchemaFactory = class {
5307
5505
  }
5308
5506
  }
5309
5507
  }
5508
+ this.addExtResultFields(model, fields);
5310
5509
  return z.strictObject(fields);
5311
5510
  }
5511
+ addExtResultFields(model, fields) {
5512
+ for (const plugin of this.plugins) {
5513
+ const resultConfig = plugin.result;
5514
+ if (resultConfig) {
5515
+ const modelConfig = resultConfig[lowerCaseFirst2(model)];
5516
+ if (modelConfig) {
5517
+ for (const field of Object.keys(modelConfig)) {
5518
+ fields[field] = z.boolean().optional();
5519
+ }
5520
+ }
5521
+ }
5522
+ }
5523
+ }
5312
5524
  makeIncludeSchema(model, options) {
5313
5525
  const modelDef = requireModel(this.schema, model);
5314
5526
  const fields = {};
@@ -5332,15 +5544,13 @@ var ZodSchemaFactory = class {
5332
5544
  return z.strictObject(fields);
5333
5545
  }
5334
5546
  makeOrderBySchema(model, withRelation, WithAggregation, options) {
5335
- const modelDef = requireModel(this.schema, model);
5336
5547
  const fields = {};
5337
5548
  const sort = z.union([
5338
5549
  z.literal("asc"),
5339
5550
  z.literal("desc")
5340
5551
  ]);
5341
5552
  const nextOpts = this.nextOptions(options);
5342
- for (const field of Object.keys(modelDef.fields)) {
5343
- const fieldDef = requireField(this.schema, model, field);
5553
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5344
5554
  if (fieldDef.relation) {
5345
5555
  if (withRelation && this.shouldIncludeRelations(options)) {
5346
5556
  fields[field] = z.lazy(() => {
@@ -5385,8 +5595,7 @@ var ZodSchemaFactory = class {
5385
5595
  return z.strictObject(fields);
5386
5596
  }
5387
5597
  makeDistinctSchema(model) {
5388
- const modelDef = requireModel(this.schema, model);
5389
- const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation);
5598
+ const nonRelationFields = this.getModelFields(model).filter(([, def]) => !def.relation).map(([name]) => name);
5390
5599
  return nonRelationFields.length > 0 ? this.orArray(z.enum(nonRelationFields), true) : z.never();
5391
5600
  }
5392
5601
  makeCursorSchema(model, options) {
@@ -5425,13 +5634,13 @@ var ZodSchemaFactory = class {
5425
5634
  const uncheckedVariantFields = {};
5426
5635
  const checkedVariantFields = {};
5427
5636
  const modelDef = requireModel(this.schema, model);
5428
- const hasRelation = !skipRelations && Object.entries(modelDef.fields).some(([f, def]) => !withoutFields.includes(f) && def.relation);
5637
+ const modelFields = this.getModelFields(model);
5638
+ const hasRelation = !skipRelations && modelFields.some(([f, def]) => !withoutFields.includes(f) && def.relation);
5429
5639
  const nextOpts = this.nextOptions(options);
5430
- Object.keys(modelDef.fields).forEach((field) => {
5640
+ modelFields.forEach(([field, fieldDef]) => {
5431
5641
  if (withoutFields.includes(field)) {
5432
5642
  return;
5433
5643
  }
5434
- const fieldDef = requireField(this.schema, model, field);
5435
5644
  if (fieldDef.computed || fieldDef.isDiscriminator) {
5436
5645
  return;
5437
5646
  }
@@ -5524,12 +5733,15 @@ var ZodSchemaFactory = class {
5524
5733
  const fieldDef = requireField(this.schema, model, field);
5525
5734
  const fieldType = fieldDef.type;
5526
5735
  const array = !!fieldDef.array;
5736
+ const canCreateModel = this.canCreateModel(fieldType);
5527
5737
  const fields = {
5528
- create: this.makeCreateDataSchema(fieldDef.type, !!fieldDef.array, withoutFields, false, options).optional(),
5529
- connect: this.makeConnectDataSchema(fieldType, array, options).optional(),
5530
- connectOrCreate: this.makeConnectOrCreateDataSchema(fieldType, array, withoutFields, options).optional()
5738
+ connect: this.makeConnectDataSchema(fieldType, array, options).optional()
5531
5739
  };
5532
- if (array) {
5740
+ if (canCreateModel) {
5741
+ fields["create"] = this.makeCreateDataSchema(fieldDef.type, !!fieldDef.array, withoutFields, false, options).optional();
5742
+ fields["connectOrCreate"] = this.makeConnectOrCreateDataSchema(fieldType, array, withoutFields, options).optional();
5743
+ }
5744
+ if (array && canCreateModel) {
5533
5745
  fields["createMany"] = this.makeCreateManyPayloadSchema(fieldType, withoutFields, options).optional();
5534
5746
  }
5535
5747
  if (mode === "update") {
@@ -5547,15 +5759,17 @@ var ZodSchemaFactory = class {
5547
5759
  }),
5548
5760
  this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5549
5761
  ]).optional();
5550
- let upsertWhere = this.makeWhereSchema(fieldType, true, false, false, options);
5551
- if (!fieldDef.array) {
5552
- upsertWhere = upsertWhere.optional();
5553
- }
5554
- fields["upsert"] = this.orArray(z.strictObject({
5555
- where: upsertWhere,
5556
- create: this.makeCreateDataSchema(fieldType, false, withoutFields, false, options),
5557
- update: this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5558
- }), true).optional();
5762
+ if (canCreateModel) {
5763
+ let upsertWhere = this.makeWhereSchema(fieldType, true, false, false, options);
5764
+ if (!fieldDef.array) {
5765
+ upsertWhere = upsertWhere.optional();
5766
+ }
5767
+ fields["upsert"] = this.orArray(z.strictObject({
5768
+ where: upsertWhere,
5769
+ create: this.makeCreateDataSchema(fieldType, false, withoutFields, false, options),
5770
+ update: this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5771
+ }), true).optional();
5772
+ }
5559
5773
  if (array) {
5560
5774
  fields["set"] = this.makeSetDataSchema(fieldType, true, options).optional();
5561
5775
  fields["updateMany"] = this.orArray(z.strictObject({
@@ -5656,13 +5870,13 @@ var ZodSchemaFactory = class {
5656
5870
  const uncheckedVariantFields = {};
5657
5871
  const checkedVariantFields = {};
5658
5872
  const modelDef = requireModel(this.schema, model);
5659
- const hasRelation = !skipRelations && Object.entries(modelDef.fields).some(([key, value]) => value.relation && !withoutFields.includes(key));
5873
+ const modelFields = this.getModelFields(model);
5874
+ const hasRelation = !skipRelations && modelFields.some(([key, value]) => value.relation && !withoutFields.includes(key));
5660
5875
  const nextOpts = this.nextOptions(options);
5661
- Object.keys(modelDef.fields).forEach((field) => {
5876
+ modelFields.forEach(([field, fieldDef]) => {
5662
5877
  if (withoutFields.includes(field)) {
5663
5878
  return;
5664
5879
  }
5665
- const fieldDef = requireField(this.schema, model, field);
5666
5880
  if (fieldDef.computed || fieldDef.isDiscriminator) {
5667
5881
  return;
5668
5882
  }
@@ -5779,12 +5993,11 @@ var ZodSchemaFactory = class {
5779
5993
  }), "count").optional();
5780
5994
  }
5781
5995
  makeCountAggregateInputSchema(model) {
5782
- const modelDef = requireModel(this.schema, model);
5783
5996
  return z.union([
5784
5997
  z.literal(true),
5785
5998
  z.strictObject({
5786
5999
  _all: z.literal(true).optional(),
5787
- ...Object.keys(modelDef.fields).reduce((acc, field) => {
6000
+ ...this.getModelFields(model).reduce((acc, [field]) => {
5788
6001
  acc[field] = z.literal(true).optional();
5789
6002
  return acc;
5790
6003
  }, {})
@@ -5807,9 +6020,7 @@ var ZodSchemaFactory = class {
5807
6020
  }), "aggregate").optional();
5808
6021
  }
5809
6022
  makeSumAvgInputSchema(model) {
5810
- const modelDef = requireModel(this.schema, model);
5811
- return z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
5812
- const fieldDef = requireField(this.schema, model, field);
6023
+ return z.strictObject(this.getModelFields(model).reduce((acc, [field, fieldDef]) => {
5813
6024
  if (this.isNumericField(fieldDef)) {
5814
6025
  acc[field] = z.literal(true).optional();
5815
6026
  }
@@ -5817,9 +6028,7 @@ var ZodSchemaFactory = class {
5817
6028
  }, {}));
5818
6029
  }
5819
6030
  makeMinMaxInputSchema(model) {
5820
- const modelDef = requireModel(this.schema, model);
5821
- return z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
5822
- const fieldDef = requireField(this.schema, model, field);
6031
+ return z.strictObject(this.getModelFields(model).reduce((acc, [field, fieldDef]) => {
5823
6032
  if (!fieldDef.relation && !fieldDef.array) {
5824
6033
  acc[field] = z.literal(true).optional();
5825
6034
  }
@@ -5829,8 +6038,7 @@ var ZodSchemaFactory = class {
5829
6038
  // #endregion
5830
6039
  // #region Group By
5831
6040
  makeGroupBySchema(model, options) {
5832
- const modelDef = requireModel(this.schema, model);
5833
- const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation);
6041
+ const nonRelationFields = this.getModelFields(model).filter(([, def]) => !def.relation).map(([name]) => name);
5834
6042
  const bySchema = nonRelationFields.length > 0 ? this.orArray(z.enum(nonRelationFields), true) : z.never();
5835
6043
  const baseSchema = z.strictObject({
5836
6044
  where: this.makeWhereSchema(model, false, false, false, options).optional(),
@@ -6019,7 +6227,7 @@ var ZodSchemaFactory = class {
6019
6227
  return void 0;
6020
6228
  }
6021
6229
  const modelsRecord = slicing.models;
6022
- const modelConfig = modelsRecord[lowerCaseFirst(model)];
6230
+ const modelConfig = modelsRecord[lowerCaseFirst2(model)];
6023
6231
  if (modelConfig?.fields) {
6024
6232
  const fieldConfig = modelConfig.fields[field];
6025
6233
  if (fieldConfig) {
@@ -6092,10 +6300,17 @@ var ZodSchemaFactory = class {
6092
6300
  return z.strictObject(components);
6093
6301
  }
6094
6302
  }
6095
- /**
6096
- * Checks if a model is included in the slicing configuration.
6097
- * Returns true if the model is allowed, false if it's excluded.
6098
- */
6303
+ canCreateModel(model) {
6304
+ const modelDef = requireModel(this.schema, model);
6305
+ if (modelDef.isDelegate) {
6306
+ return false;
6307
+ }
6308
+ const hasRequiredUnsupportedFields = Object.values(modelDef.fields).some((fieldDef) => fieldDef.type === "Unsupported" && !fieldDef.optional && !fieldHasDefaultValue(fieldDef));
6309
+ if (hasRequiredUnsupportedFields) {
6310
+ return false;
6311
+ }
6312
+ return true;
6313
+ }
6099
6314
  isModelAllowed(targetModel) {
6100
6315
  const slicing = this.options.slicing;
6101
6316
  if (!slicing) {
@@ -6572,7 +6787,7 @@ var InputValidator = class {
6572
6787
  }
6573
6788
  // #region Entry points
6574
6789
  validateFindArgs(model, args, operation) {
6575
- return this.validate(model, operation, (model2) => match14(operation).with("findFirst", () => this.zodFactory.makeFindFirstSchema(model2)).with("findUnique", () => this.zodFactory.makeFindUniqueSchema(model2)).with("findMany", () => this.zodFactory.makeFindManySchema(model2)).exhaustive(), args);
6790
+ return this.validate(model, operation, (model2) => match11(operation).with("findFirst", () => this.zodFactory.makeFindFirstSchema(model2)).with("findUnique", () => this.zodFactory.makeFindUniqueSchema(model2)).with("findMany", () => this.zodFactory.makeFindManySchema(model2)).exhaustive(), args);
6576
6791
  }
6577
6792
  validateExistsArgs(model, args) {
6578
6793
  return this.validate(model, "exists", (model2) => this.zodFactory.makeExistsSchema(model2), args);
@@ -6882,7 +7097,7 @@ __name(performanceNow, "performanceNow");
6882
7097
  // src/client/executor/zenstack-query-executor.ts
6883
7098
  import { invariant as invariant11 } from "@zenstackhq/common-helpers";
6884
7099
  import { AndNode, ColumnNode as ColumnNode3, ColumnUpdateNode as ColumnUpdateNode2, createQueryId as createQueryId2, DefaultQueryExecutor, DeleteQueryNode, expressionBuilder as expressionBuilder7, InsertQueryNode, PrimitiveValueListNode as PrimitiveValueListNode2, ReturningNode, SelectionNode as SelectionNode2, SingleConnectionProvider, TableNode as TableNode3, UpdateQueryNode, ValueNode as ValueNode2, ValuesNode as ValuesNode2, WhereNode } from "kysely";
6885
- import { match as match15 } from "ts-pattern";
7100
+ import { match as match12 } from "ts-pattern";
6886
7101
 
6887
7102
  // src/client/executor/name-mapper.ts
6888
7103
  import { invariant as invariant10 } from "@zenstackhq/common-helpers";
@@ -6905,7 +7120,7 @@ var QueryNameMapper = class extends OperationNodeTransformer {
6905
7120
  if (mappedName) {
6906
7121
  this.modelToTableMap.set(modelName, mappedName);
6907
7122
  }
6908
- for (const fieldDef of this.getModelFields(modelDef)) {
7123
+ for (const fieldDef of getModelFields(this.schema, modelName)) {
6909
7124
  const mappedName2 = this.getMappedName(fieldDef);
6910
7125
  if (mappedName2) {
6911
7126
  this.fieldToColumnMap.set(`${modelName}.${fieldDef.name}`, mappedName2);
@@ -7166,7 +7381,7 @@ var QueryNameMapper = class extends OperationNodeTransformer {
7166
7381
  if (!modelDef) {
7167
7382
  continue;
7168
7383
  }
7169
- if (this.getModelFields(modelDef).some((f) => f.name === name)) {
7384
+ if (getModelFields(this.schema, scope.model).some((f) => f.name === name)) {
7170
7385
  return scope;
7171
7386
  }
7172
7387
  }
@@ -7280,8 +7495,7 @@ var QueryNameMapper = class extends OperationNodeTransformer {
7280
7495
  return schema;
7281
7496
  }
7282
7497
  createSelectAllFields(model, alias) {
7283
- const modelDef = requireModel(this.schema, model);
7284
- return this.getModelFields(modelDef).map((fieldDef) => {
7498
+ return getModelFields(this.schema, model).map((fieldDef) => {
7285
7499
  const columnName = this.mapFieldName(model, fieldDef.name);
7286
7500
  const columnRef = ReferenceNode2.create(ColumnNode2.create(columnName), alias && IdentifierNode.is(alias) ? TableNode2.create(alias.name) : void 0);
7287
7501
  if (columnName !== fieldDef.name) {
@@ -7298,9 +7512,6 @@ var QueryNameMapper = class extends OperationNodeTransformer {
7298
7512
  }
7299
7513
  });
7300
7514
  }
7301
- getModelFields(modelDef) {
7302
- return Object.values(modelDef.fields).filter((f) => !f.relation && !f.computed && !f.originModel);
7303
- }
7304
7515
  processSelections(selections) {
7305
7516
  const result = [];
7306
7517
  selections.forEach((selection) => {
@@ -7337,9 +7548,8 @@ var QueryNameMapper = class extends OperationNodeTransformer {
7337
7548
  if (!scope.model || !(this.hasMappedColumns(scope.model) || this.modelUsesEnumWithMappedValues(scope.model))) {
7338
7549
  return super.transformSelectAll(node);
7339
7550
  }
7340
- const modelDef = requireModel(this.schema, scope.model);
7341
- return this.getModelFields(modelDef).map((fieldDef) => {
7342
- const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
7551
+ return getModelFields(this.schema, scope.model).map((fieldDef) => {
7552
+ const columnName = this.mapFieldName(scope.model, fieldDef.name);
7343
7553
  const columnRef = ReferenceNode2.create(ColumnNode2.create(columnName));
7344
7554
  const enumProcessed = this.processEnumSelection(columnRef, fieldDef.name);
7345
7555
  return columnName !== fieldDef.name && !AliasNode2.is(enumProcessed) ? this.wrapAlias(enumProcessed, IdentifierNode.create(fieldDef.name)) : enumProcessed;
@@ -7360,7 +7570,7 @@ var QueryNameMapper = class extends OperationNodeTransformer {
7360
7570
  if (!modelDef) {
7361
7571
  return false;
7362
7572
  }
7363
- return this.getModelFields(modelDef).some((fieldDef) => {
7573
+ return getModelFields(this.schema, model).some((fieldDef) => {
7364
7574
  const enumDef = getEnum(this.schema, fieldDef.type);
7365
7575
  if (!enumDef) {
7366
7576
  return false;
@@ -7561,14 +7771,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
7561
7771
  get hasEntityMutationPluginsWithAfterMutationHooks() {
7562
7772
  return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.afterEntityMutation);
7563
7773
  }
7774
+ get hasOnKyselyHooks() {
7775
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onKyselyQuery);
7776
+ }
7564
7777
  // #endregion
7565
7778
  // #region main entry point
7566
7779
  async executeQuery(compiledQuery) {
7567
7780
  const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
7781
+ const needEnsureTx = this.hasOnKyselyHooks || this.hasEntityMutationPlugins;
7568
7782
  const result = await this.provideConnection(async (connection) => {
7569
7783
  let startedTx = false;
7570
7784
  try {
7571
- if (this.isMutationNode(compiledQuery.query) && !this.driver.isTransactionConnection(connection)) {
7785
+ if (this.isMutationNode(compiledQuery.query) && !this.driver.isTransactionConnection(connection) && needEnsureTx) {
7572
7786
  await this.driver.beginTransaction(connection, {
7573
7787
  isolationLevel: TransactionIsolationLevel.ReadCommitted
7574
7788
  });
@@ -7858,7 +8072,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
7858
8072
  // #region utilities
7859
8073
  getMutationInfo(queryNode) {
7860
8074
  const model = this.getMutationModel(queryNode);
7861
- const { action, where } = match15(queryNode).when(InsertQueryNode.is, () => ({
8075
+ const { action, where } = match12(queryNode).when(InsertQueryNode.is, () => ({
7862
8076
  action: "create",
7863
8077
  where: void 0
7864
8078
  })).when(UpdateQueryNode.is, (node) => ({
@@ -7878,7 +8092,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
7878
8092
  return InsertQueryNode.is(queryNode) || UpdateQueryNode.is(queryNode) || DeleteQueryNode.is(queryNode);
7879
8093
  }
7880
8094
  getMutationModel(queryNode) {
7881
- return match15(queryNode).when(InsertQueryNode.is, (node) => {
8095
+ return match12(queryNode).when(InsertQueryNode.is, (node) => {
7882
8096
  invariant11(node.into, "InsertQueryNode must have an into clause");
7883
8097
  return node.into.table.identifier.name;
7884
8098
  }).when(UpdateQueryNode.is, (node) => {
@@ -8034,9 +8248,9 @@ __export(functions_exports, {
8034
8248
  search: () => search,
8035
8249
  startsWith: () => startsWith
8036
8250
  });
8037
- import { invariant as invariant12, lowerCaseFirst as lowerCaseFirst2, upperCaseFirst } from "@zenstackhq/common-helpers";
8251
+ import { invariant as invariant12, lowerCaseFirst as lowerCaseFirst3, upperCaseFirst } from "@zenstackhq/common-helpers";
8038
8252
  import { sql as sql6, ValueNode as ValueNode3 } from "kysely";
8039
- import { match as match16 } from "ts-pattern";
8253
+ import { match as match13 } from "ts-pattern";
8040
8254
  var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
8041
8255
  var search = /* @__PURE__ */ __name((_eb, _args) => {
8042
8256
  throw new Error(`"search" function is not implemented yet`);
@@ -8075,7 +8289,7 @@ var textMatch = /* @__PURE__ */ __name((eb, args, { dialect }, method) => {
8075
8289
  }
8076
8290
  searchExpr = eb.fn.coalesce(searchExpr, sql6.lit(""));
8077
8291
  const escapedSearch = sql6`REPLACE(REPLACE(REPLACE(${dialect.castText(searchExpr)}, ${sql6.val("\\")}, ${sql6.val("\\\\")}), ${sql6.val("%")}, ${sql6.val("\\%")}), ${sql6.val("_")}, ${sql6.val("\\_")})`;
8078
- searchExpr = match16(method).with("contains", () => eb.fn("CONCAT", [
8292
+ searchExpr = match13(method).with("contains", () => eb.fn("CONCAT", [
8079
8293
  sql6.lit("%"),
8080
8294
  escapedSearch,
8081
8295
  sql6.lit("%")
@@ -8125,7 +8339,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
8125
8339
  }
8126
8340
  return eb(dialect.buildArrayLength(field), "=", sql6.lit(0));
8127
8341
  }, "isEmpty");
8128
- var now = /* @__PURE__ */ __name((_eb, _args, context) => match16(context.dialect.provider).with("sqlite", () => sql6.raw("strftime('%Y-%m-%dT%H:%M:%fZ')")).with("mysql", () => sql6.raw("CONCAT(SUBSTRING(DATE_FORMAT(UTC_TIMESTAMP(3), '%Y-%m-%dT%H:%i:%s.%f'), 1, 23), '+00:00')")).with("postgresql", () => sql6.raw("CURRENT_TIMESTAMP")).exhaustive(), "now");
8342
+ var now = /* @__PURE__ */ __name((_eb, _args, context) => match13(context.dialect.provider).with("sqlite", () => sql6.raw("strftime('%Y-%m-%dT%H:%M:%fZ')")).with("mysql", () => sql6.raw("CONCAT(SUBSTRING(DATE_FORMAT(UTC_TIMESTAMP(3), '%Y-%m-%dT%H:%i:%s.%f'), 1, 23), '+00:00')")).with("postgresql", () => sql6.raw("CURRENT_TIMESTAMP")).exhaustive(), "now");
8129
8343
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
8130
8344
  let result = model;
8131
8345
  const [casing] = args;
@@ -8145,7 +8359,7 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
8145
8359
  function processCasing(casing, result, model) {
8146
8360
  const opNode = casing.toOperationNode();
8147
8361
  invariant12(ValueNode3.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
8148
- result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst2(result)).otherwise(() => {
8362
+ result = match13(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst3(result)).otherwise(() => {
8149
8363
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
8150
8364
  });
8151
8365
  return result;
@@ -8165,7 +8379,7 @@ __name(readBoolean, "readBoolean");
8165
8379
  import { invariant as invariant13 } from "@zenstackhq/common-helpers";
8166
8380
  import { sql as sql7 } from "kysely";
8167
8381
  import toposort from "toposort";
8168
- import { match as match17 } from "ts-pattern";
8382
+ import { match as match14 } from "ts-pattern";
8169
8383
  var SchemaDbPusher = class {
8170
8384
  static {
8171
8385
  __name(this, "SchemaDbPusher");
@@ -8252,6 +8466,9 @@ var SchemaDbPusher = class {
8252
8466
  if (fieldDef.originModel && !fieldDef.id) {
8253
8467
  continue;
8254
8468
  }
8469
+ if (isUnsupportedField(fieldDef)) {
8470
+ continue;
8471
+ }
8255
8472
  if (fieldDef.relation) {
8256
8473
  table = this.addForeignKeyConstraint(table, modelDef.name, fieldName, fieldDef);
8257
8474
  } else if (!this.isComputedField(fieldDef)) {
@@ -8368,7 +8585,7 @@ var SchemaDbPusher = class {
8368
8585
  });
8369
8586
  }
8370
8587
  isDefaultValueSupportedForType(type) {
8371
- return match17(this.schema.provider.type).with("postgresql", () => true).with("sqlite", () => true).with("mysql", () => ![
8588
+ return match14(this.schema.provider.type).with("postgresql", () => true).with("sqlite", () => true).with("mysql", () => ![
8372
8589
  "Json",
8373
8590
  "Bytes"
8374
8591
  ].includes(type)).exhaustive();
@@ -8406,7 +8623,7 @@ var SchemaDbPusher = class {
8406
8623
  return this.jsonType;
8407
8624
  }
8408
8625
  const type = fieldDef.type;
8409
- const result = match17(type).with("String", () => this.stringType).with("Boolean", () => this.booleanType).with("Int", () => this.intType).with("Float", () => this.floatType).with("BigInt", () => this.bigIntType).with("Decimal", () => this.decimalType).with("DateTime", () => this.dateTimeType).with("Bytes", () => this.bytesType).with("Json", () => this.jsonType).otherwise(() => {
8626
+ const result = match14(type).with("String", () => this.stringType).with("Boolean", () => this.booleanType).with("Int", () => this.intType).with("Float", () => this.floatType).with("BigInt", () => this.bigIntType).with("Decimal", () => this.decimalType).with("DateTime", () => this.dateTimeType).with("Bytes", () => this.bytesType).with("Json", () => this.jsonType).otherwise(() => {
8410
8627
  throw new Error(`Unsupported field type: ${type}`);
8411
8628
  });
8412
8629
  if (fieldDef.array) {
@@ -8446,35 +8663,35 @@ var SchemaDbPusher = class {
8446
8663
  return table;
8447
8664
  }
8448
8665
  mapCascadeAction(action) {
8449
- return match17(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
8666
+ return match14(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
8450
8667
  }
8451
8668
  // #region Type mappings and capabilities
8452
8669
  get jsonType() {
8453
- return match17(this.schema.provider.type).with("mysql", () => "json").otherwise(() => "jsonb");
8670
+ return match14(this.schema.provider.type).with("mysql", () => "json").otherwise(() => "jsonb");
8454
8671
  }
8455
8672
  get bytesType() {
8456
- return match17(this.schema.provider.type).with("postgresql", () => "bytea").with("mysql", () => "blob").otherwise(() => "blob");
8673
+ return match14(this.schema.provider.type).with("postgresql", () => "bytea").with("mysql", () => "blob").otherwise(() => "blob");
8457
8674
  }
8458
8675
  get stringType() {
8459
- return match17(this.schema.provider.type).with("mysql", () => sql7.raw("varchar(255)")).otherwise(() => "text");
8676
+ return match14(this.schema.provider.type).with("mysql", () => sql7.raw("varchar(255)")).otherwise(() => "text");
8460
8677
  }
8461
8678
  get booleanType() {
8462
- return match17(this.schema.provider.type).with("mysql", () => sql7.raw("tinyint(1)")).otherwise(() => "boolean");
8679
+ return match14(this.schema.provider.type).with("mysql", () => sql7.raw("tinyint(1)")).otherwise(() => "boolean");
8463
8680
  }
8464
8681
  get intType() {
8465
8682
  return "integer";
8466
8683
  }
8467
8684
  get floatType() {
8468
- return match17(this.schema.provider.type).with("postgresql", () => "double precision").with("mysql", () => sql7.raw("double")).otherwise(() => "real");
8685
+ return match14(this.schema.provider.type).with("postgresql", () => "double precision").with("mysql", () => sql7.raw("double")).otherwise(() => "real");
8469
8686
  }
8470
8687
  get bigIntType() {
8471
8688
  return "bigint";
8472
8689
  }
8473
8690
  get decimalType() {
8474
- return match17(this.schema.provider.type).with("mysql", () => sql7.raw("decimal(65, 30)")).otherwise(() => "decimal");
8691
+ return match14(this.schema.provider.type).with("mysql", () => sql7.raw("decimal(65, 30)")).otherwise(() => "decimal");
8475
8692
  }
8476
8693
  get dateTimeType() {
8477
- return match17(this.schema.provider.type).with("mysql", () => sql7.raw("datetime(3)")).otherwise(() => "timestamp");
8694
+ return match14(this.schema.provider.type).with("mysql", () => sql7.raw("datetime(3)")).otherwise(() => "timestamp");
8478
8695
  }
8479
8696
  columnSupportsAutoIncrement() {
8480
8697
  return [
@@ -8535,26 +8752,46 @@ var ResultProcessor = class {
8535
8752
  return result;
8536
8753
  }
8537
8754
  doProcessResult(data, model) {
8755
+ const firstRow = Array.isArray(data) ? data[0] : data;
8756
+ if (!firstRow || typeof firstRow !== "object") {
8757
+ return data;
8758
+ }
8759
+ const fields = this.resolveFields(firstRow, model);
8538
8760
  if (Array.isArray(data)) {
8539
- data.forEach((row, i) => data[i] = this.processRow(row, model));
8761
+ data.forEach((row, i) => data[i] = this.processRow(row, fields));
8540
8762
  return data;
8541
8763
  } else {
8542
- return this.processRow(data, model);
8764
+ return this.processRow(data, fields);
8543
8765
  }
8544
8766
  }
8545
- processRow(data, model) {
8767
+ resolveFields(row, model) {
8768
+ if (!row || typeof row !== "object") {
8769
+ return [];
8770
+ }
8771
+ const result = [];
8772
+ for (const key of Object.keys(row)) {
8773
+ if (key === "_count" || key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8774
+ continue;
8775
+ }
8776
+ const fieldDef = getField(this.schema, model, key);
8777
+ if (fieldDef) {
8778
+ result.push(fieldDef);
8779
+ }
8780
+ }
8781
+ return result;
8782
+ }
8783
+ processRow(data, fields) {
8546
8784
  if (!data || typeof data !== "object") {
8547
8785
  return data;
8548
8786
  }
8549
- for (const [key, value] of Object.entries(data)) {
8787
+ for (const key of Object.keys(data)) {
8788
+ const value = data[key];
8550
8789
  if (value === void 0) {
8551
8790
  continue;
8552
8791
  }
8553
8792
  if (key === "_count") {
8554
8793
  data[key] = typeof value === "string" ? JSON.parse(value) : value;
8555
- continue;
8556
- }
8557
- if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8794
+ } else if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8558
8795
  if (value) {
8559
8796
  const subRow = this.dialect.transformOutput(value, "Json", false);
8560
8797
  const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
@@ -8563,26 +8800,28 @@ var ResultProcessor = class {
8563
8800
  delete data[key];
8564
8801
  continue;
8565
8802
  }
8566
- const processedSubRow = this.processRow(subRow, subModel);
8803
+ const subFields = this.resolveFields(subRow, subModel);
8804
+ const processedSubRow = this.processRow(subRow, subFields);
8567
8805
  Object.assign(data, processedSubRow);
8568
8806
  }
8569
8807
  delete data[key];
8570
- continue;
8571
8808
  }
8572
- const fieldDef = getField(this.schema, model, key);
8573
- if (!fieldDef) {
8809
+ }
8810
+ for (const fieldDef of fields) {
8811
+ const value = data[fieldDef.name];
8812
+ if (value === void 0) {
8574
8813
  continue;
8575
8814
  }
8576
8815
  if (value === null) {
8577
- if (fieldDef.array && !fieldDef.relation && value === null) {
8578
- data[key] = [];
8816
+ if (fieldDef.array && !fieldDef.relation) {
8817
+ data[fieldDef.name] = [];
8579
8818
  }
8580
8819
  continue;
8581
8820
  }
8582
8821
  if (fieldDef.relation) {
8583
- data[key] = this.processRelation(value, fieldDef);
8822
+ data[fieldDef.name] = this.processRelation(value, fieldDef);
8584
8823
  } else {
8585
- data[key] = this.processFieldValue(value, fieldDef);
8824
+ data[fieldDef.name] = this.processFieldValue(value, fieldDef);
8586
8825
  }
8587
8826
  }
8588
8827
  return data;
@@ -8688,7 +8927,11 @@ var ClientImpl = class _ClientImpl {
8688
8927
  executor: new DefaultQueryExecutor2(compiler, adapter, connectionProvider, [])
8689
8928
  });
8690
8929
  }
8691
- this.kysely = new Kysely(this.kyselyProps);
8930
+ if (baseClient?.isTransaction && !executor) {
8931
+ this.kysely = baseClient.$qb;
8932
+ } else {
8933
+ this.kysely = new Kysely(this.kyselyProps);
8934
+ }
8692
8935
  this.inputValidator = baseClient?.inputValidator ?? new InputValidator(this, {
8693
8936
  enabled: this.$options.validateInput !== false
8694
8937
  });
@@ -8717,7 +8960,7 @@ var ClientImpl = class _ClientImpl {
8717
8960
  for (const [modelName, modelDef] of Object.entries(this.$schema.models)) {
8718
8961
  if (modelDef.computedFields) {
8719
8962
  for (const fieldName of Object.keys(modelDef.computedFields)) {
8720
- const modelConfig = computedFieldsConfig?.[modelName];
8963
+ const modelConfig = computedFieldsConfig?.[lowerCaseFirst4(modelName)] ?? computedFieldsConfig?.[modelName];
8721
8964
  const fieldConfig = modelConfig?.[fieldName];
8722
8965
  if (fieldConfig === null || fieldConfig === void 0) {
8723
8966
  throw createConfigError(`Computed field "${fieldName}" in model "${modelName}" does not have a configuration. Please provide an implementation in the computedFields option.`);
@@ -8926,13 +9169,13 @@ var ClientImpl = class _ClientImpl {
8926
9169
  };
8927
9170
  return this.$setOptions(newOptions);
8928
9171
  }
8929
- async $diagnostics() {
8930
- return {
9172
+ get $diagnostics() {
9173
+ return Promise.resolve({
8931
9174
  zodCache: this.inputValidator.zodFactory.cacheStats,
8932
9175
  slowQueries: this.slowQueries.map((q) => ({
8933
9176
  ...q
8934
9177
  })).sort((a, b) => b.durationMs - a.durationMs)
8935
- };
9178
+ });
8936
9179
  }
8937
9180
  $executeRaw(query, ...values) {
8938
9181
  return createZenStackPromise(async () => {
@@ -9036,26 +9279,34 @@ function isProcedureIncluded(options, procedureName) {
9036
9279
  }
9037
9280
  __name(isProcedureIncluded, "isProcedureIncluded");
9038
9281
  function createModelCrudHandler(client, model, inputValidator, resultProcessor) {
9282
+ const plugins = client.$options.plugins ?? [];
9283
+ const schema = client.$schema;
9284
+ const hasAnyExtResult = hasExtResultFieldDefs(plugins);
9039
9285
  const createPromise = /* @__PURE__ */ __name((operation, nominalOperation, args, handler, postProcess = false, throwIfNoResult = false) => {
9040
9286
  return createZenStackPromise(async (txClient) => {
9041
9287
  let proceed = /* @__PURE__ */ __name(async (_args) => {
9288
+ const shouldApplyExtResult = hasAnyExtResult && EXT_RESULT_OPERATIONS.has(operation);
9289
+ const processedArgs = shouldApplyExtResult ? prepareArgsForExtResult(_args, model, schema, plugins2) : _args;
9042
9290
  const _handler = txClient ? handler.withClient(txClient) : handler;
9043
- const r = await _handler.handle(operation, _args);
9291
+ const r = await _handler.handle(operation, processedArgs);
9044
9292
  if (!r && throwIfNoResult) {
9045
9293
  throw createNotFoundError(model);
9046
9294
  }
9047
9295
  let result;
9048
9296
  if (r && postProcess) {
9049
- result = resultProcessor.processResult(r, model, args);
9297
+ result = resultProcessor.processResult(r, model, processedArgs);
9050
9298
  } else {
9051
9299
  result = r ?? null;
9052
9300
  }
9301
+ if (result && shouldApplyExtResult) {
9302
+ result = applyExtResult(result, model, _args, schema, plugins2);
9303
+ }
9053
9304
  return result;
9054
9305
  }, "proceed");
9055
- const plugins = [
9306
+ const plugins2 = [
9056
9307
  ...client.$options.plugins ?? []
9057
9308
  ];
9058
- for (const plugin of plugins) {
9309
+ for (const plugin of plugins2) {
9059
9310
  const onQuery = plugin.onQuery;
9060
9311
  if (onQuery) {
9061
9312
  const _proceed = proceed;
@@ -9140,7 +9391,7 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
9140
9391
  };
9141
9392
  const slicing = client.$options.slicing;
9142
9393
  if (slicing?.models) {
9143
- const modelSlicing = slicing.models[lowerCaseFirst3(model)];
9394
+ const modelSlicing = slicing.models[lowerCaseFirst4(model)];
9144
9395
  const allSlicing = slicing.models.$all;
9145
9396
  const includedOperations = modelSlicing?.includedOperations ?? allSlicing?.includedOperations;
9146
9397
  const excludedOperations = modelSlicing?.excludedOperations ?? allSlicing?.excludedOperations;
@@ -9157,13 +9408,241 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
9157
9408
  }
9158
9409
  }
9159
9410
  }
9411
+ const modelDef = requireModel(client.$schema, model);
9412
+ if (Object.values(modelDef.fields).some((f) => isUnsupportedField(f) && !f.optional && !fieldHasDefaultValue(f))) {
9413
+ for (const op of [
9414
+ "create",
9415
+ "createMany",
9416
+ "createManyAndReturn",
9417
+ "upsert"
9418
+ ]) {
9419
+ delete operations[op];
9420
+ }
9421
+ }
9160
9422
  return operations;
9161
9423
  }
9162
9424
  __name(createModelCrudHandler, "createModelCrudHandler");
9425
+ var EXT_RESULT_OPERATIONS = /* @__PURE__ */ new Set([
9426
+ "findMany",
9427
+ "findUnique",
9428
+ "findFirst",
9429
+ "create",
9430
+ "createManyAndReturn",
9431
+ "update",
9432
+ "updateManyAndReturn",
9433
+ "upsert",
9434
+ "delete"
9435
+ ]);
9436
+ function hasExtResultFieldDefs(plugins) {
9437
+ return plugins.some((p) => p.result && Object.keys(p.result).length > 0);
9438
+ }
9439
+ __name(hasExtResultFieldDefs, "hasExtResultFieldDefs");
9440
+ function collectExtResultFieldDefs(model, schema, plugins) {
9441
+ const defs = /* @__PURE__ */ new Map();
9442
+ for (const plugin of plugins) {
9443
+ const resultConfig = plugin.result;
9444
+ if (resultConfig) {
9445
+ const modelConfig = resultConfig[lowerCaseFirst4(model)];
9446
+ if (modelConfig) {
9447
+ for (const [fieldName, fieldDef] of Object.entries(modelConfig)) {
9448
+ if (getField(schema, model, fieldName)) {
9449
+ throw new Error(`Plugin "${plugin.id}" registers ext result field "${fieldName}" on model "${model}" which conflicts with an existing model field`);
9450
+ }
9451
+ for (const needField of Object.keys(fieldDef.needs ?? {})) {
9452
+ const needDef = getField(schema, model, needField);
9453
+ if (!needDef || needDef.relation) {
9454
+ throw new Error(`Plugin "${plugin.id}" registers ext result field "${fieldName}" on model "${model}" with invalid need "${needField}"`);
9455
+ }
9456
+ }
9457
+ defs.set(fieldName, fieldDef);
9458
+ }
9459
+ }
9460
+ }
9461
+ }
9462
+ return defs;
9463
+ }
9464
+ __name(collectExtResultFieldDefs, "collectExtResultFieldDefs");
9465
+ function prepareArgsForExtResult(args, model, schema, plugins) {
9466
+ if (!args || typeof args !== "object") {
9467
+ return args;
9468
+ }
9469
+ const extResultDefs = collectExtResultFieldDefs(model, schema, plugins);
9470
+ const typedArgs = args;
9471
+ let result = typedArgs;
9472
+ let changed = false;
9473
+ const select = typedArgs["select"];
9474
+ const omit = typedArgs["omit"];
9475
+ const include = typedArgs["include"];
9476
+ if (select && extResultDefs.size > 0) {
9477
+ const newSelect = {
9478
+ ...select
9479
+ };
9480
+ for (const [fieldName, fieldDef] of extResultDefs) {
9481
+ if (newSelect[fieldName]) {
9482
+ delete newSelect[fieldName];
9483
+ for (const needField of Object.keys(fieldDef.needs)) {
9484
+ if (!newSelect[needField]) {
9485
+ newSelect[needField] = true;
9486
+ }
9487
+ }
9488
+ }
9489
+ }
9490
+ result = {
9491
+ ...result,
9492
+ select: newSelect
9493
+ };
9494
+ changed = true;
9495
+ }
9496
+ if (omit && extResultDefs.size > 0) {
9497
+ const newOmit = {
9498
+ ...omit
9499
+ };
9500
+ for (const [fieldName, fieldDef] of extResultDefs) {
9501
+ if (newOmit[fieldName]) {
9502
+ delete newOmit[fieldName];
9503
+ } else {
9504
+ for (const needField of Object.keys(fieldDef.needs)) {
9505
+ if (newOmit[needField]) {
9506
+ delete newOmit[needField];
9507
+ }
9508
+ }
9509
+ }
9510
+ }
9511
+ result = {
9512
+ ...result,
9513
+ omit: newOmit
9514
+ };
9515
+ changed = true;
9516
+ }
9517
+ if (include) {
9518
+ const newInclude = {
9519
+ ...include
9520
+ };
9521
+ let includeChanged = false;
9522
+ for (const [field, value] of Object.entries(newInclude)) {
9523
+ if (value && typeof value === "object") {
9524
+ const fieldDef = getField(schema, model, field);
9525
+ if (fieldDef?.relation) {
9526
+ const targetModel = fieldDef.type;
9527
+ const processed = prepareArgsForExtResult(value, targetModel, schema, plugins);
9528
+ if (processed !== value) {
9529
+ newInclude[field] = processed;
9530
+ includeChanged = true;
9531
+ }
9532
+ }
9533
+ }
9534
+ }
9535
+ if (includeChanged) {
9536
+ result = changed ? {
9537
+ ...result,
9538
+ include: newInclude
9539
+ } : {
9540
+ ...typedArgs,
9541
+ include: newInclude
9542
+ };
9543
+ changed = true;
9544
+ }
9545
+ }
9546
+ if (select) {
9547
+ const currentSelect = changed ? result["select"] : select;
9548
+ if (currentSelect) {
9549
+ const newSelect = {
9550
+ ...currentSelect
9551
+ };
9552
+ let selectChanged = false;
9553
+ for (const [field, value] of Object.entries(newSelect)) {
9554
+ if (value && typeof value === "object") {
9555
+ const fieldDef = getField(schema, model, field);
9556
+ if (fieldDef?.relation) {
9557
+ const targetModel = fieldDef.type;
9558
+ const processed = prepareArgsForExtResult(value, targetModel, schema, plugins);
9559
+ if (processed !== value) {
9560
+ newSelect[field] = processed;
9561
+ selectChanged = true;
9562
+ }
9563
+ }
9564
+ }
9565
+ }
9566
+ if (selectChanged) {
9567
+ result = {
9568
+ ...result,
9569
+ select: newSelect
9570
+ };
9571
+ changed = true;
9572
+ }
9573
+ }
9574
+ }
9575
+ return changed ? result : args;
9576
+ }
9577
+ __name(prepareArgsForExtResult, "prepareArgsForExtResult");
9578
+ function applyExtResult(result, model, originalArgs, schema, plugins) {
9579
+ const extResultDefs = collectExtResultFieldDefs(model, schema, plugins);
9580
+ if (Array.isArray(result)) {
9581
+ for (let i = 0; i < result.length; i++) {
9582
+ result[i] = applyExtResultToRow(result[i], model, originalArgs, schema, plugins, extResultDefs);
9583
+ }
9584
+ return result;
9585
+ } else {
9586
+ return applyExtResultToRow(result, model, originalArgs, schema, plugins, extResultDefs);
9587
+ }
9588
+ }
9589
+ __name(applyExtResult, "applyExtResult");
9590
+ function applyExtResultToRow(row, model, originalArgs, schema, plugins, extResultDefs) {
9591
+ if (!row || typeof row !== "object") {
9592
+ return row;
9593
+ }
9594
+ const data = row;
9595
+ const typedArgs = originalArgs && typeof originalArgs === "object" ? originalArgs : {};
9596
+ const select = typedArgs["select"];
9597
+ const omit = typedArgs["omit"];
9598
+ const include = typedArgs["include"];
9599
+ for (const [fieldName, fieldDef] of extResultDefs) {
9600
+ if (select && !select[fieldName]) {
9601
+ continue;
9602
+ }
9603
+ if (omit?.[fieldName]) {
9604
+ continue;
9605
+ }
9606
+ const needsSatisfied = Object.keys(fieldDef.needs).every((needField) => needField in data);
9607
+ if (needsSatisfied) {
9608
+ data[fieldName] = fieldDef.compute(data);
9609
+ }
9610
+ }
9611
+ if (select) {
9612
+ for (const key of Object.keys(data)) {
9613
+ if (!select[key] && !extResultDefs.has(key)) {
9614
+ delete data[key];
9615
+ }
9616
+ }
9617
+ } else if (omit) {
9618
+ for (const key of Object.keys(omit)) {
9619
+ if (omit[key] && !extResultDefs.has(key)) {
9620
+ delete data[key];
9621
+ }
9622
+ }
9623
+ }
9624
+ const relationSource = include ?? select;
9625
+ if (relationSource) {
9626
+ for (const [field, value] of Object.entries(relationSource)) {
9627
+ if (data[field] == null) {
9628
+ continue;
9629
+ }
9630
+ const fieldDef = getField(schema, model, field);
9631
+ if (!fieldDef?.relation) {
9632
+ continue;
9633
+ }
9634
+ const targetModel = fieldDef.type;
9635
+ const nestedArgs = value && typeof value === "object" ? value : void 0;
9636
+ data[field] = applyExtResult(data[field], targetModel, nestedArgs, schema, plugins);
9637
+ }
9638
+ }
9639
+ return data;
9640
+ }
9641
+ __name(applyExtResultToRow, "applyExtResultToRow");
9163
9642
 
9164
9643
  // src/client/plugin.ts
9165
- function definePlugin(plugin) {
9166
- return plugin;
9644
+ function definePlugin(...args) {
9645
+ return args.length === 2 ? args[1] : args[0];
9167
9646
  }
9168
9647
  __name(definePlugin, "definePlugin");
9169
9648
 
@@ -9489,13 +9968,13 @@ __export(schema_utils_exports, {
9489
9968
  ExpressionVisitor: () => ExpressionVisitor,
9490
9969
  MatchingExpressionVisitor: () => MatchingExpressionVisitor
9491
9970
  });
9492
- import { match as match18 } from "ts-pattern";
9971
+ import { match as match15 } from "ts-pattern";
9493
9972
  var ExpressionVisitor = class {
9494
9973
  static {
9495
9974
  __name(this, "ExpressionVisitor");
9496
9975
  }
9497
9976
  visit(expr) {
9498
- return match18(expr).with({
9977
+ return match15(expr).with({
9499
9978
  kind: "literal"
9500
9979
  }, (e) => this.visitLiteral(e)).with({
9501
9980
  kind: "array"