@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.cjs CHANGED
@@ -77,7 +77,7 @@ function formatError(error) {
77
77
  __name(formatError, "formatError");
78
78
 
79
79
  // src/client/crud/operations/aggregate.ts
80
- var import_ts_pattern8 = require("ts-pattern");
80
+ var import_ts_pattern5 = require("ts-pattern");
81
81
 
82
82
  // src/client/query-utils.ts
83
83
  var query_utils_exports = {};
@@ -110,6 +110,7 @@ __export(query_utils_exports, {
110
110
  isRelationField: () => isRelationField,
111
111
  isScalarField: () => isScalarField,
112
112
  isTypeDef: () => isTypeDef,
113
+ isUnsupportedField: () => isUnsupportedField,
113
114
  makeDefaultOrderBy: () => makeDefaultOrderBy,
114
115
  requireField: () => requireField,
115
116
  requireIdFields: () => requireIdFields,
@@ -310,10 +311,17 @@ function getModelFields(schema, model, options) {
310
311
  if (f.originModel && !options?.inherited) {
311
312
  return false;
312
313
  }
314
+ if (f.type === "Unsupported" && !options?.unsupported) {
315
+ return false;
316
+ }
313
317
  return true;
314
318
  });
315
319
  }
316
320
  __name(getModelFields, "getModelFields");
321
+ function isUnsupportedField(fieldDef) {
322
+ return fieldDef.type === "Unsupported";
323
+ }
324
+ __name(isUnsupportedField, "isUnsupportedField");
317
325
  function getIdFields(schema, model) {
318
326
  const modelDef = getModel(schema, model);
319
327
  return modelDef?.idFields;
@@ -647,7 +655,7 @@ var import_common_helpers7 = require("@zenstackhq/common-helpers");
647
655
  var import_cuid = __toESM(require("cuid"), 1);
648
656
  var import_kysely6 = require("kysely");
649
657
  var import_nanoid = require("nanoid");
650
- var import_ts_pattern7 = require("ts-pattern");
658
+ var import_ts_pattern4 = require("ts-pattern");
651
659
  var import_ulid = require("ulid");
652
660
  var uuid = __toESM(require("uuid"), 1);
653
661
 
@@ -730,13 +738,12 @@ var CRUD_EXT = [
730
738
  ];
731
739
 
732
740
  // src/client/crud/dialects/index.ts
733
- var import_ts_pattern6 = require("ts-pattern");
741
+ var import_ts_pattern3 = require("ts-pattern");
734
742
 
735
743
  // src/client/crud/dialects/mysql.ts
736
744
  var import_common_helpers4 = require("@zenstackhq/common-helpers");
737
745
  var import_decimal = __toESM(require("decimal.js"), 1);
738
746
  var import_kysely3 = require("kysely");
739
- var import_ts_pattern3 = require("ts-pattern");
740
747
 
741
748
  // src/common-types.ts
742
749
  var DbNullClass = class {
@@ -1451,27 +1458,28 @@ var BaseCrudDialect = class {
1451
1458
  return result;
1452
1459
  }
1453
1460
  buildSelectAllFields(model, query, omit, modelAlias) {
1454
- const modelDef = requireModel(this.schema, model);
1455
1461
  let result = query;
1456
- for (const field of Object.keys(modelDef.fields)) {
1457
- if (isRelationField(this.schema, model, field)) {
1458
- continue;
1459
- }
1460
- if (this.shouldOmitField(omit, model, field)) {
1462
+ for (const fieldDef of getModelFields(this.schema, model, {
1463
+ inherited: true,
1464
+ computed: true
1465
+ })) {
1466
+ if (this.shouldOmitField(omit, model, fieldDef.name)) {
1461
1467
  continue;
1462
1468
  }
1463
- result = this.buildSelectField(result, model, modelAlias, field);
1469
+ result = this.buildSelectField(result, model, modelAlias, fieldDef.name);
1464
1470
  }
1465
1471
  const descendants = getDelegateDescendantModels(this.schema, model);
1466
1472
  for (const subModel of descendants) {
1467
1473
  result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
1468
- result = result.select((eb) => {
1474
+ result = result.select(() => {
1469
1475
  const jsonObject = {};
1470
- for (const field of Object.keys(subModel.fields)) {
1471
- if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
1476
+ for (const fieldDef of getModelFields(this.schema, subModel.name, {
1477
+ computed: true
1478
+ })) {
1479
+ if (this.shouldOmitField(omit, subModel.name, fieldDef.name)) {
1472
1480
  continue;
1473
1481
  }
1474
- jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
1482
+ jsonObject[fieldDef.name] = this.fieldRef(subModel.name, fieldDef.name, subModel.name);
1475
1483
  }
1476
1484
  return this.buildJsonObject(jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
1477
1485
  });
@@ -1482,8 +1490,10 @@ var BaseCrudDialect = class {
1482
1490
  if (omit && typeof omit === "object" && typeof omit[field] === "boolean") {
1483
1491
  return omit[field];
1484
1492
  }
1485
- if (this.options.omit?.[model] && typeof this.options.omit[model] === "object" && typeof this.options.omit[model][field] === "boolean") {
1486
- return this.options.omit[model][field];
1493
+ const uncapModel = (0, import_common_helpers2.lowerCaseFirst)(model);
1494
+ const omitConfig = this.options.omit?.[uncapModel] ?? this.options.omit?.[model];
1495
+ if (omitConfig && typeof omitConfig === "object" && typeof omitConfig[field] === "boolean") {
1496
+ return omitConfig[field];
1487
1497
  }
1488
1498
  const fieldDef = requireField(this.schema, model, field);
1489
1499
  return !!fieldDef.omit;
@@ -1601,7 +1611,8 @@ var BaseCrudDialect = class {
1601
1611
  let computer;
1602
1612
  if ("computedFields" in this.options) {
1603
1613
  const computedFields = this.options.computedFields;
1604
- computer = computedFields?.[fieldDef.originModel ?? model]?.[field];
1614
+ const computedModel = fieldDef.originModel ?? model;
1615
+ computer = computedFields?.[(0, import_common_helpers2.lowerCaseFirst)(computedModel)]?.[field] ?? computedFields?.[computedModel]?.[field];
1605
1616
  }
1606
1617
  if (!computer) {
1607
1618
  throw createConfigError(`Computed field "${field}" implementation not provided for model "${model}"`);
@@ -1804,24 +1815,46 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
1804
1815
  throw createNotSupportedError(`MySQL does not support array literals`);
1805
1816
  }
1806
1817
  } else {
1807
- return (0, import_ts_pattern3.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => {
1808
- if (value instanceof Date) {
1809
- return value.toISOString().replace("Z", "+00:00");
1810
- } else if (typeof value === "string") {
1811
- return new Date(value).toISOString().replace("Z", "+00:00");
1812
- } else {
1818
+ switch (type) {
1819
+ case "Boolean":
1820
+ return value ? 1 : 0;
1821
+ case "DateTime":
1822
+ if (value instanceof Date) {
1823
+ return value.toISOString().replace("Z", "+00:00");
1824
+ } else if (typeof value === "string") {
1825
+ return new Date(value).toISOString().replace("Z", "+00:00");
1826
+ } else {
1827
+ return value;
1828
+ }
1829
+ case "Decimal":
1830
+ return value !== null ? value.toString() : value;
1831
+ case "Json":
1832
+ return this.eb.cast(this.eb.val(JSON.stringify(value)), "json");
1833
+ case "Bytes":
1834
+ return Buffer.isBuffer(value) ? value : value instanceof Uint8Array ? Buffer.from(value) : value;
1835
+ default:
1813
1836
  return value;
1814
- }
1815
- }).with("Decimal", () => value !== null ? value.toString() : value).with("Json", () => {
1816
- return this.eb.cast(this.eb.val(JSON.stringify(value)), "json");
1817
- }).with("Bytes", () => Buffer.isBuffer(value) ? value : value instanceof Uint8Array ? Buffer.from(value) : value).otherwise(() => value);
1837
+ }
1818
1838
  }
1819
1839
  }
1820
1840
  transformOutput(value, type, array) {
1821
1841
  if (value === null || value === void 0) {
1822
1842
  return value;
1823
1843
  }
1824
- return (0, import_ts_pattern3.match)(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));
1844
+ switch (type) {
1845
+ case "Boolean":
1846
+ return this.transformOutputBoolean(value);
1847
+ case "DateTime":
1848
+ return this.transformOutputDate(value);
1849
+ case "Bytes":
1850
+ return this.transformOutputBytes(value);
1851
+ case "BigInt":
1852
+ return this.transformOutputBigInt(value);
1853
+ case "Decimal":
1854
+ return this.transformDecimal(value);
1855
+ default:
1856
+ return super.transformOutput(value, type, array);
1857
+ }
1825
1858
  }
1826
1859
  transformOutputBoolean(value) {
1827
1860
  return !!value;
@@ -1927,15 +1960,25 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
1927
1960
  }
1928
1961
  }
1929
1962
  buildJsonArrayFilter(lhs, operation, value) {
1930
- return (0, import_ts_pattern3.match)(operation).with("array_contains", () => {
1931
- const v = Array.isArray(value) ? value : [
1932
- value
1933
- ];
1934
- return import_kysely3.sql`JSON_CONTAINS(${lhs}, ${import_kysely3.sql.val(JSON.stringify(v))})`;
1935
- }).with("array_starts_with", () => this.eb(this.eb.fn("JSON_EXTRACT", [
1936
- lhs,
1937
- this.eb.val("$[0]")
1938
- ]), "=", this.transformInput(value, "Json", false))).with("array_ends_with", () => this.eb(import_kysely3.sql`JSON_EXTRACT(${lhs}, CONCAT('$[', JSON_LENGTH(${lhs}) - 1, ']'))`, "=", this.transformInput(value, "Json", false))).exhaustive();
1963
+ switch (operation) {
1964
+ case "array_contains": {
1965
+ const v = Array.isArray(value) ? value : [
1966
+ value
1967
+ ];
1968
+ return import_kysely3.sql`JSON_CONTAINS(${lhs}, ${import_kysely3.sql.val(JSON.stringify(v))})`;
1969
+ }
1970
+ case "array_starts_with": {
1971
+ return this.eb(this.eb.fn("JSON_EXTRACT", [
1972
+ lhs,
1973
+ this.eb.val("$[0]")
1974
+ ]), "=", this.transformInput(value, "Json", false));
1975
+ }
1976
+ case "array_ends_with": {
1977
+ return this.eb(import_kysely3.sql`JSON_EXTRACT(${lhs}, CONCAT('$[', JSON_LENGTH(${lhs}) - 1, ']'))`, "=", this.transformInput(value, "Json", false));
1978
+ }
1979
+ default:
1980
+ throw createInvalidInputError(`Unsupported array filter operation: ${operation}`);
1981
+ }
1939
1982
  }
1940
1983
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
1941
1984
  return this.eb.exists(this.eb.selectFrom(import_kysely3.sql`JSON_TABLE(${receiver}, '$[*]' COLUMNS(value JSON PATH '$'))`.as("$items")).select(this.eb.lit(1).as("_")).where(buildFilter(this.eb.ref("$items.value"))));
@@ -1978,12 +2021,22 @@ var import_common_helpers5 = require("@zenstackhq/common-helpers");
1978
2021
  var import_decimal2 = __toESM(require("decimal.js"), 1);
1979
2022
  var import_kysely4 = require("kysely");
1980
2023
  var import_postgres_array = require("postgres-array");
1981
- var import_ts_pattern4 = require("ts-pattern");
1982
2024
  var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectBase {
1983
2025
  static {
1984
2026
  __name(this, "PostgresCrudDialect");
1985
2027
  }
1986
2028
  static typeParserOverrideApplied = false;
2029
+ zmodelToSqlTypeMap = {
2030
+ String: "text",
2031
+ Boolean: "boolean",
2032
+ Int: "integer",
2033
+ BigInt: "bigint",
2034
+ Float: "double precision",
2035
+ Decimal: "decimal",
2036
+ DateTime: "timestamp",
2037
+ Bytes: "bytea",
2038
+ Json: "jsonb"
2039
+ };
1987
2040
  constructor(schema, options) {
1988
2041
  super(schema, options);
1989
2042
  this.overrideTypeParsers();
@@ -1994,19 +2047,31 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
1994
2047
  overrideTypeParsers() {
1995
2048
  if (this.options.fixPostgresTimezone !== false && !_PostgresCrudDialect.typeParserOverrideApplied) {
1996
2049
  _PostgresCrudDialect.typeParserOverrideApplied = true;
2050
+ const fixTimezone = /* @__PURE__ */ __name((value) => {
2051
+ if (typeof value !== "string") {
2052
+ return value;
2053
+ }
2054
+ if (!this.hasTimezoneOffset(value)) {
2055
+ value += "Z";
2056
+ }
2057
+ const result = new Date(value);
2058
+ return isNaN(result.getTime()) ? value : result;
2059
+ }, "fixTimezone");
1997
2060
  import(
1998
2061
  /* webpackIgnore: true */
1999
2062
  "pg"
2000
2063
  ).then((pg) => {
2001
- pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, (value) => {
2064
+ pg.types.setTypeParser(pg.types.builtins.TIMESTAMP, fixTimezone);
2065
+ pg.types.setTypeParser(1115, (value) => {
2002
2066
  if (typeof value !== "string") {
2003
2067
  return value;
2004
2068
  }
2005
- if (!this.hasTimezoneOffset(value)) {
2006
- value += "Z";
2069
+ try {
2070
+ const arr = (0, import_postgres_array.parse)(value);
2071
+ return arr.map(fixTimezone);
2072
+ } catch {
2073
+ return value;
2007
2074
  }
2008
- const result = new Date(value);
2009
- return isNaN(result.getTime()) ? value : result;
2010
2075
  });
2011
2076
  }).catch(() => {
2012
2077
  });
@@ -2060,20 +2125,42 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2060
2125
  return value.map((v) => this.transformInput(v, type, false));
2061
2126
  }
2062
2127
  } else {
2063
- return (0, import_ts_pattern4.match)(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", () => {
2064
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2065
- return JSON.stringify(value);
2066
- } else {
2128
+ switch (type) {
2129
+ case "DateTime":
2130
+ return value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value;
2131
+ case "Decimal":
2132
+ return value !== null ? value.toString() : value;
2133
+ case "Json":
2134
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
2135
+ return JSON.stringify(value);
2136
+ } else {
2137
+ return value;
2138
+ }
2139
+ default:
2067
2140
  return value;
2068
- }
2069
- }).otherwise(() => value);
2141
+ }
2070
2142
  }
2071
2143
  }
2072
2144
  transformOutput(value, type, array) {
2073
2145
  if (value === null || value === void 0) {
2074
2146
  return value;
2075
2147
  }
2076
- return (0, import_ts_pattern4.match)(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));
2148
+ switch (type) {
2149
+ case "DateTime":
2150
+ return this.transformOutputDate(value);
2151
+ case "Bytes":
2152
+ return this.transformOutputBytes(value);
2153
+ case "BigInt":
2154
+ return this.transformOutputBigInt(value);
2155
+ case "Decimal":
2156
+ return this.transformDecimal(value);
2157
+ default:
2158
+ if (isEnum(this.schema, type)) {
2159
+ return this.transformOutputEnum(value, array);
2160
+ } else {
2161
+ return super.transformOutput(value, type, array);
2162
+ }
2163
+ }
2077
2164
  }
2078
2165
  transformOutputBigInt(value) {
2079
2166
  if (typeof value === "bigint") {
@@ -2182,18 +2269,24 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2182
2269
  }
2183
2270
  }
2184
2271
  buildJsonArrayFilter(lhs, operation, value) {
2185
- return (0, import_ts_pattern4.match)(operation).with("array_contains", () => {
2186
- const v = Array.isArray(value) ? value : [
2187
- value
2188
- ];
2189
- return import_kysely4.sql`${lhs} @> ${import_kysely4.sql.val(JSON.stringify(v))}::jsonb`;
2190
- }).with("array_starts_with", () => this.eb(this.eb.fn("jsonb_extract_path", [
2191
- lhs,
2192
- this.eb.val("0")
2193
- ]), "=", this.transformInput(value, "Json", false))).with("array_ends_with", () => this.eb(this.eb.fn("jsonb_extract_path", [
2194
- lhs,
2195
- import_kysely4.sql`(jsonb_array_length(${lhs}) - 1)::text`
2196
- ]), "=", this.transformInput(value, "Json", false))).exhaustive();
2272
+ switch (operation) {
2273
+ case "array_contains": {
2274
+ const v = Array.isArray(value) ? value : [
2275
+ value
2276
+ ];
2277
+ return import_kysely4.sql`${lhs} @> ${import_kysely4.sql.val(JSON.stringify(v))}::jsonb`;
2278
+ }
2279
+ case "array_starts_with":
2280
+ return this.eb(this.eb.fn("jsonb_extract_path", [
2281
+ lhs,
2282
+ this.eb.val("0")
2283
+ ]), "=", this.transformInput(value, "Json", false));
2284
+ case "array_ends_with":
2285
+ return this.eb(this.eb.fn("jsonb_extract_path", [
2286
+ lhs,
2287
+ import_kysely4.sql`(jsonb_array_length(${lhs}) - 1)::text`
2288
+ ]), "=", this.transformInput(value, "Json", false));
2289
+ }
2197
2290
  }
2198
2291
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
2199
2292
  return this.eb.exists(this.eb.selectFrom(this.eb.fn("jsonb_array_elements", [
@@ -2204,7 +2297,7 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2204
2297
  if (isEnum(this.schema, zmodelType)) {
2205
2298
  return "text";
2206
2299
  } else {
2207
- return (0, import_ts_pattern4.match)(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");
2300
+ return this.zmodelToSqlTypeMap[zmodelType] ?? "text";
2208
2301
  }
2209
2302
  }
2210
2303
  getStringCasingBehavior() {
@@ -2246,7 +2339,6 @@ var PostgresCrudDialect = class _PostgresCrudDialect extends LateralJoinDialectB
2246
2339
  var import_common_helpers6 = require("@zenstackhq/common-helpers");
2247
2340
  var import_decimal3 = __toESM(require("decimal.js"), 1);
2248
2341
  var import_kysely5 = require("kysely");
2249
- var import_ts_pattern5 = require("ts-pattern");
2250
2342
  var SqliteCrudDialect = class extends BaseCrudDialect {
2251
2343
  static {
2252
2344
  __name(this, "SqliteCrudDialect");
@@ -2295,7 +2387,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2295
2387
  if (Array.isArray(value)) {
2296
2388
  return value.map((v) => this.transformInput(v, type, false));
2297
2389
  } else {
2298
- return (0, import_ts_pattern5.match)(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);
2390
+ switch (type) {
2391
+ case "Boolean":
2392
+ return value ? 1 : 0;
2393
+ case "DateTime":
2394
+ return value instanceof Date ? value.toISOString() : typeof value === "string" ? new Date(value).toISOString() : value;
2395
+ case "Decimal":
2396
+ return value.toString();
2397
+ case "Bytes":
2398
+ return Buffer.from(value);
2399
+ default:
2400
+ return value;
2401
+ }
2299
2402
  }
2300
2403
  }
2301
2404
  transformOutput(value, type, array) {
@@ -2304,7 +2407,22 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2304
2407
  } else if (this.schema.typeDefs && type in this.schema.typeDefs) {
2305
2408
  return this.transformOutputJson(value);
2306
2409
  } else {
2307
- return (0, import_ts_pattern5.match)(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));
2410
+ switch (type) {
2411
+ case "Boolean":
2412
+ return this.transformOutputBoolean(value);
2413
+ case "DateTime":
2414
+ return this.transformOutputDate(value);
2415
+ case "Bytes":
2416
+ return this.transformOutputBytes(value);
2417
+ case "Decimal":
2418
+ return this.transformOutputDecimal(value);
2419
+ case "BigInt":
2420
+ return this.transformOutputBigInt(value);
2421
+ case "Json":
2422
+ return this.transformOutputJson(value);
2423
+ default:
2424
+ return super.transformOutput(value, type, array);
2425
+ }
2308
2426
  }
2309
2427
  }
2310
2428
  transformOutputDecimal(value) {
@@ -2475,16 +2593,21 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2475
2593
  }
2476
2594
  }
2477
2595
  buildJsonArrayFilter(lhs, operation, value) {
2478
- return (0, import_ts_pattern5.match)(operation).with("array_contains", () => {
2479
- if (Array.isArray(value)) {
2480
- throw createNotSupportedError('SQLite "array_contains" only supports checking for a single value, not an array of values');
2481
- } else {
2482
- return import_kysely5.sql`EXISTS (SELECT 1 FROM json_each(${lhs}) WHERE value = ${value})`;
2483
- }
2484
- }).with("array_starts_with", () => this.eb(this.eb.fn("json_extract", [
2485
- lhs,
2486
- this.eb.val("$[0]")
2487
- ]), "=", value)).with("array_ends_with", () => this.eb(import_kysely5.sql`json_extract(${lhs}, '$[' || (json_array_length(${lhs}) - 1) || ']')`, "=", value)).exhaustive();
2596
+ switch (operation) {
2597
+ case "array_contains":
2598
+ if (Array.isArray(value)) {
2599
+ throw createNotSupportedError('SQLite "array_contains" only supports checking for a single value, not an array of values');
2600
+ } else {
2601
+ return import_kysely5.sql`EXISTS (SELECT 1 FROM json_each(${lhs}) WHERE value = ${value})`;
2602
+ }
2603
+ case "array_starts_with":
2604
+ return this.eb(this.eb.fn("json_extract", [
2605
+ lhs,
2606
+ this.eb.val("$[0]")
2607
+ ]), "=", value);
2608
+ case "array_ends_with":
2609
+ return this.eb(import_kysely5.sql`json_extract(${lhs}, '$[' || (json_array_length(${lhs}) - 1) || ']')`, "=", value);
2610
+ }
2488
2611
  }
2489
2612
  buildJsonArrayExistsPredicate(receiver, buildFilter) {
2490
2613
  return this.eb.exists(this.eb.selectFrom(this.eb.fn("json_each", [
@@ -2553,7 +2676,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
2553
2676
 
2554
2677
  // src/client/crud/dialects/index.ts
2555
2678
  function getCrudDialect(schema, options) {
2556
- return (0, import_ts_pattern6.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).with("mysql", () => new MySqlCrudDialect(schema, options)).exhaustive();
2679
+ return (0, import_ts_pattern3.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).with("mysql", () => new MySqlCrudDialect(schema, options)).exhaustive();
2557
2680
  }
2558
2681
  __name(getCrudDialect, "getCrudDialect");
2559
2682
 
@@ -2839,7 +2962,9 @@ var BaseOperationHandler = class {
2839
2962
  }
2840
2963
  }
2841
2964
  if (fromRelation && m2m) {
2842
- await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, createdEntity, m2m.joinTable);
2965
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, [
2966
+ createdEntity
2967
+ ], m2m.joinTable);
2843
2968
  }
2844
2969
  if (updateParent) {
2845
2970
  updateParent(createdEntity);
@@ -2896,41 +3021,36 @@ var BaseOperationHandler = class {
2896
3021
  }
2897
3022
  return parentFkFields;
2898
3023
  }
2899
- async handleManyToManyRelation(kysely, action, leftModel, leftField, leftEntity, rightModel, rightField, rightEntity, joinTable) {
2900
- const sortedRecords = [
2901
- {
2902
- model: leftModel,
2903
- field: leftField,
2904
- entity: leftEntity
2905
- },
2906
- {
2907
- model: rightModel,
2908
- field: rightField,
2909
- entity: rightEntity
2910
- }
2911
- ].sort((a, b) => (
2912
- // the implicit m2m join table's "A", "B" fk fields' order is determined
2913
- // by model name's sort order, and when identical (for self-relations),
2914
- // field name's sort order
2915
- a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
2916
- ));
2917
- const firstIds = requireIdFields(this.schema, sortedRecords[0].model);
2918
- const secondIds = requireIdFields(this.schema, sortedRecords[1].model);
2919
- (0, import_common_helpers7.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
2920
- (0, import_common_helpers7.invariant)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
3024
+ async handleManyToManyRelation(kysely, action, leftModel, leftField, leftEntity, rightModel, rightField, rightEntities, joinTable) {
3025
+ if (rightEntities.length === 0) {
3026
+ return;
3027
+ }
3028
+ const leftFirst = leftModel !== rightModel ? leftModel.localeCompare(rightModel) <= 0 : leftField.localeCompare(rightField) <= 0;
3029
+ const leftIdField = requireIdFields(this.schema, leftModel);
3030
+ const rightIdField = requireIdFields(this.schema, rightModel);
3031
+ (0, import_common_helpers7.invariant)(leftIdField.length === 1, "many-to-many relation must have exactly one id field");
3032
+ (0, import_common_helpers7.invariant)(rightIdField.length === 1, "many-to-many relation must have exactly one id field");
3033
+ const leftIdValue = leftEntity[leftIdField[0]];
3034
+ const rightIdValues = rightEntities.map((e) => e[rightIdField[0]]);
2921
3035
  if (action === "connect") {
2922
- const result = await kysely.insertInto(joinTable).values({
2923
- A: sortedRecords[0].entity[firstIds[0]],
2924
- B: sortedRecords[1].entity[secondIds[0]]
2925
- }).$if(this.dialect.insertIgnoreMethod === "onConflict", (qb) => qb.onConflict((oc) => oc.columns([
3036
+ const values = rightIdValues.map((rightId) => ({
3037
+ A: leftFirst ? leftIdValue : rightId,
3038
+ B: leftFirst ? rightId : leftIdValue
3039
+ }));
3040
+ await kysely.insertInto(joinTable).values(values).$if(this.dialect.insertIgnoreMethod === "onConflict", (qb) => qb.onConflict((oc) => oc.columns([
2926
3041
  "A",
2927
3042
  "B"
2928
3043
  ]).doNothing())).$if(this.dialect.insertIgnoreMethod === "ignore", (qb) => qb.ignore()).execute();
2929
- return result[0];
2930
3044
  } else {
2931
3045
  const eb = (0, import_kysely6.expressionBuilder)();
2932
- 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();
2933
- return result[0];
3046
+ const [leftCol, rightCol] = leftFirst ? [
3047
+ "A",
3048
+ "B"
3049
+ ] : [
3050
+ "B",
3051
+ "A"
3052
+ ];
3053
+ await kysely.deleteFrom(joinTable).where(eb(`${joinTable}.${leftCol}`, "=", leftIdValue)).where(eb(`${joinTable}.${rightCol}`, "in", rightIdValues)).execute();
2934
3054
  }
2935
3055
  }
2936
3056
  resetManyToManyRelation(kysely, model, field, parentIds) {
@@ -3188,7 +3308,7 @@ var BaseOperationHandler = class {
3188
3308
  evalGenerator(defaultValue) {
3189
3309
  if (schema_exports.ExpressionUtils.isCall(defaultValue)) {
3190
3310
  const firstArgVal = defaultValue.args?.[0] && schema_exports.ExpressionUtils.isLiteral(defaultValue.args[0]) ? defaultValue.args[0].value : void 0;
3191
- return (0, import_ts_pattern7.match)(defaultValue.function).with("cuid", () => {
3311
+ return (0, import_ts_pattern4.match)(defaultValue.function).with("cuid", () => {
3192
3312
  const version = firstArgVal;
3193
3313
  const generated = version === 2 ? (0, import_cuid2.createId)() : (0, import_cuid.default)();
3194
3314
  return this.formatGeneratedValue(generated, defaultValue.args?.[1]);
@@ -3217,6 +3337,13 @@ var BaseOperationHandler = class {
3217
3337
  }
3218
3338
  return formatExpr.value.replace(/(?<!\\)%s/g, generated).replace(/\\%s/g, "%s");
3219
3339
  }
3340
+ /**
3341
+ * @returns
3342
+ * - throw if `throwIfNotFound` is true and the entity to update is not found
3343
+ * - otherwise, null if the entity to update is not found
3344
+ * - if found and `fieldsToReturn` is specified, return the post-update fields
3345
+ * - if found and `fieldsToReturn` is not specified, return true (indicating success)
3346
+ */
3220
3347
  async update(kysely, model, where, data, fromRelation, allowRelationUpdate = true, throwIfNotFound = true, fieldsToReturn) {
3221
3348
  if (!data || typeof data !== "object") {
3222
3349
  throw createInvalidInputError("data must be an object");
@@ -3231,6 +3358,7 @@ var BaseOperationHandler = class {
3231
3358
  ]
3232
3359
  } : parentWhere;
3233
3360
  }
3361
+ const origWhere = combinedWhere;
3234
3362
  const modelDef = this.requireModel(model);
3235
3363
  let finalData = data;
3236
3364
  const autoUpdatedFields = [];
@@ -3247,46 +3375,51 @@ var BaseOperationHandler = class {
3247
3375
  }
3248
3376
  }
3249
3377
  }
3250
- const thisEntity = await this.getEntityIds(kysely, model, combinedWhere);
3251
- if (!thisEntity) {
3252
- if (throwIfNotFound) {
3253
- throw createNotFoundError(model);
3254
- } else {
3255
- return null;
3378
+ let thisEntity;
3379
+ const loadThisEntity = /* @__PURE__ */ __name(async () => {
3380
+ if (thisEntity === void 0) {
3381
+ thisEntity = await this.getEntityIds(kysely, model, origWhere) ?? null;
3382
+ if (!thisEntity && throwIfNotFound) {
3383
+ throw createNotFoundError(model);
3384
+ }
3256
3385
  }
3257
- }
3258
- if (Object.keys(finalData).length === 0) {
3259
3386
  return thisEntity;
3260
- }
3261
- let needIdRead = false;
3262
- if (!this.isIdFilter(model, combinedWhere)) {
3263
- if (modelDef.baseModel) {
3264
- needIdRead = true;
3265
- }
3266
- if (!this.dialect.supportsReturning) {
3267
- needIdRead = true;
3268
- }
3269
- }
3270
- if (needIdRead) {
3271
- const readResult = await this.readUnique(kysely, model, {
3272
- where: combinedWhere,
3273
- select: this.makeIdSelect(model)
3274
- });
3275
- if (!readResult && throwIfNotFound) {
3276
- throw createNotFoundError(model);
3387
+ }, "loadThisEntity");
3388
+ if (Object.keys(finalData).length === 0) {
3389
+ return loadThisEntity();
3390
+ }
3391
+ if (
3392
+ // when updating a model with delegate base, base fields may be referenced in the filter,
3393
+ // so we read the id out if the filter and and use it as the update filter instead
3394
+ modelDef.baseModel || // for dialects that don't support RETURNING, we need to read the id fields
3395
+ // to identify the updated entity for toplevel updates
3396
+ !this.dialect.supportsReturning && !fromRelation
3397
+ ) {
3398
+ combinedWhere = await loadThisEntity();
3399
+ if (!combinedWhere) {
3400
+ return null;
3277
3401
  }
3278
- combinedWhere = readResult;
3279
3402
  }
3280
3403
  if (modelDef.baseModel) {
3281
3404
  const baseUpdateResult = await this.processBaseModelUpdate(kysely, modelDef.baseModel, combinedWhere, finalData, throwIfNotFound);
3405
+ if (!baseUpdateResult.baseEntity) {
3406
+ if (throwIfNotFound) {
3407
+ throw createNotFoundError(model);
3408
+ } else {
3409
+ return null;
3410
+ }
3411
+ }
3282
3412
  finalData = baseUpdateResult.remainingFields;
3283
- combinedWhere = baseUpdateResult.baseEntity ? getIdValues(this.schema, modelDef.baseModel, baseUpdateResult.baseEntity) : baseUpdateResult.baseEntity;
3284
- if (baseUpdateResult.baseEntity) {
3413
+ combinedWhere = getIdValues(this.schema, modelDef.baseModel, baseUpdateResult.baseEntity);
3414
+ await loadThisEntity();
3415
+ if (thisEntity) {
3285
3416
  for (const [key, value] of Object.entries(baseUpdateResult.baseEntity)) {
3286
3417
  if (key in thisEntity) {
3287
3418
  thisEntity[key] = value;
3288
3419
  }
3289
3420
  }
3421
+ } else {
3422
+ return null;
3290
3423
  }
3291
3424
  }
3292
3425
  const updateFields = {};
@@ -3298,7 +3431,11 @@ var BaseOperationHandler = class {
3298
3431
  if (!allowRelationUpdate) {
3299
3432
  throw createNotSupportedError(`Relation update not allowed for field "${field}"`);
3300
3433
  }
3301
- const parentUpdates = await this.processRelationUpdates(kysely, model, field, fieldDef, thisEntity, finalData[field]);
3434
+ const relationParent = await loadThisEntity();
3435
+ if (!relationParent) {
3436
+ return null;
3437
+ }
3438
+ const parentUpdates = await this.processRelationUpdates(kysely, model, field, fieldDef, relationParent, finalData[field]);
3302
3439
  if (Object.keys(parentUpdates).length > 0) {
3303
3440
  Object.assign(updateFields, parentUpdates);
3304
3441
  }
@@ -3309,17 +3446,41 @@ var BaseOperationHandler = class {
3309
3446
  hasFieldUpdate = Object.keys(updateFields).some((f) => !autoUpdatedFields.includes(f));
3310
3447
  }
3311
3448
  if (!hasFieldUpdate) {
3312
- return thisEntity;
3449
+ return loadThisEntity();
3313
3450
  } else {
3314
- fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
3315
3451
  let updatedEntity;
3316
3452
  if (this.dialect.supportsReturning) {
3317
- const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).returning(fieldsToReturn).modifyEnd(this.makeContextComment({
3453
+ const returnFields = fieldsToReturn !== void 0 && fieldsToReturn.length > 0;
3454
+ const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).$if(returnFields, (qb) => qb.returning(fieldsToReturn)).modifyEnd(this.makeContextComment({
3318
3455
  model,
3319
3456
  operation: "update"
3320
3457
  }));
3321
- updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3458
+ if (returnFields) {
3459
+ updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
3460
+ } else {
3461
+ const r = await this.executeQuery(kysely, query, "update");
3462
+ if (!r.numAffectedRows) {
3463
+ updatedEntity = null;
3464
+ } else {
3465
+ updatedEntity = true;
3466
+ }
3467
+ }
3322
3468
  } else {
3469
+ let readFilter = combinedWhere;
3470
+ const idFields = requireIdFields(this.schema, model);
3471
+ const updatingIdFields = idFields.some((idField) => idField in updateFields);
3472
+ if (updatingIdFields) {
3473
+ const origIdValues = await loadThisEntity();
3474
+ (0, import_common_helpers7.invariant)(origIdValues, "Original entity should have been loaded for update without RETURNING");
3475
+ readFilter = {
3476
+ ...origIdValues
3477
+ };
3478
+ for (const idField of idFields) {
3479
+ if (idField in updateFields && updateFields[idField] !== void 0) {
3480
+ readFilter[idField] = updateFields[idField];
3481
+ }
3482
+ }
3483
+ }
3323
3484
  const updateQuery = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).modifyEnd(this.makeContextComment({
3324
3485
  model,
3325
3486
  operation: "update"
@@ -3327,26 +3488,12 @@ var BaseOperationHandler = class {
3327
3488
  const updateResult = await this.executeQuery(kysely, updateQuery, "update");
3328
3489
  if (!updateResult.numAffectedRows) {
3329
3490
  updatedEntity = null;
3491
+ } else if (fieldsToReturn === void 0 || fieldsToReturn.length === 0) {
3492
+ updatedEntity = true;
3330
3493
  } else {
3331
- const idFields = requireIdFields(this.schema, model);
3332
- const filterIdValues = {};
3333
- for (const key of idFields) {
3334
- if (combinedWhere[key] !== void 0 && typeof combinedWhere[key] !== "object") {
3335
- filterIdValues[key] = combinedWhere[key];
3336
- }
3337
- }
3338
- const updatingIdFields = idFields.some((idField) => idField in updateFields);
3339
- if (Object.keys(filterIdValues).length === idFields.length && !updatingIdFields) {
3340
- updatedEntity = filterIdValues;
3494
+ if (!updatingIdFields) {
3495
+ updatedEntity = await loadThisEntity();
3341
3496
  } else {
3342
- const readFilter = {
3343
- ...combinedWhere
3344
- };
3345
- for (const idField of idFields) {
3346
- if (idField in updateFields && updateFields[idField] !== void 0) {
3347
- readFilter[idField] = updateFields[idField];
3348
- }
3349
- }
3350
3497
  const selectQuery = kysely.selectFrom(model).select(fieldsToReturn).where(() => this.dialect.buildFilter(model, model, readFilter));
3351
3498
  updatedEntity = await this.executeQueryTakeFirst(kysely, selectQuery, "update");
3352
3499
  }
@@ -3416,13 +3563,6 @@ var BaseOperationHandler = class {
3416
3563
  "set"
3417
3564
  ].some((key) => key in value);
3418
3565
  }
3419
- isIdFilter(model, filter) {
3420
- if (!filter || typeof filter !== "object") {
3421
- return false;
3422
- }
3423
- const idFields = requireIdFields(this.schema, model);
3424
- return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
3425
- }
3426
3566
  async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
3427
3567
  const thisUpdateFields = {};
3428
3568
  const remainingFields = {};
@@ -3434,7 +3574,7 @@ var BaseOperationHandler = class {
3434
3574
  remainingFields[field] = value;
3435
3575
  }
3436
3576
  });
3437
- const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound);
3577
+ const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound, requireIdFields(this.schema, model));
3438
3578
  return {
3439
3579
  baseEntity,
3440
3580
  remainingFields
@@ -3446,7 +3586,7 @@ var BaseOperationHandler = class {
3446
3586
  const value = this.dialect.transformInput(payload[key], fieldDef.type, false);
3447
3587
  const eb = (0, import_kysely6.expressionBuilder)();
3448
3588
  const fieldRef = this.dialect.fieldRef(model, field);
3449
- return (0, import_ts_pattern7.match)(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(() => {
3589
+ return (0, import_ts_pattern4.match)(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(() => {
3450
3590
  throw createInvalidInputError(`Invalid incremental update operation: ${key}`);
3451
3591
  });
3452
3592
  }
@@ -3456,7 +3596,7 @@ var BaseOperationHandler = class {
3456
3596
  const value = this.dialect.transformInput(payload[key], fieldDef.type, true);
3457
3597
  const eb = (0, import_kysely6.expressionBuilder)();
3458
3598
  const fieldRef = this.dialect.fieldRef(model, field);
3459
- return (0, import_ts_pattern7.match)(key).with("set", () => value).with("push", () => {
3599
+ return (0, import_ts_pattern4.match)(key).with("set", () => value).with("push", () => {
3460
3600
  return eb(fieldRef, "||", eb.val(ensureArray(value)));
3461
3601
  }).otherwise(() => {
3462
3602
  throw createInvalidInputError(`Invalid array update operation: ${key}`);
@@ -3696,18 +3836,11 @@ var BaseOperationHandler = class {
3696
3836
  }
3697
3837
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3698
3838
  if (m2m) {
3699
- const results = [];
3700
- for (const d of _data) {
3701
- const ids = await this.getEntityIds(kysely, model, d);
3702
- if (!ids) {
3703
- throw createNotFoundError(model);
3704
- }
3705
- const r = await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3706
- results.push(r);
3707
- }
3708
- if (_data.length > results.filter((r) => !!r).length) {
3839
+ const allIds = await this.getEntitiesIds(kysely, model, _data);
3840
+ if (allIds.length !== _data.length) {
3709
3841
  throw createNotFoundError(model);
3710
3842
  }
3843
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3711
3844
  } else {
3712
3845
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
3713
3846
  if (ownedByModel) {
@@ -3784,12 +3917,9 @@ var BaseOperationHandler = class {
3784
3917
  }
3785
3918
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3786
3919
  if (m2m) {
3787
- for (const d of disconnectConditions) {
3788
- const ids = await this.getEntityIds(kysely, model, d);
3789
- if (!ids) {
3790
- return;
3791
- }
3792
- await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable);
3920
+ const allIds = await this.getEntitiesIds(kysely, model, disconnectConditions);
3921
+ if (allIds.length > 0) {
3922
+ await this.handleManyToManyRelation(kysely, "disconnect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3793
3923
  }
3794
3924
  } else {
3795
3925
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
@@ -3854,16 +3984,12 @@ var BaseOperationHandler = class {
3854
3984
  const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
3855
3985
  if (m2m) {
3856
3986
  await this.resetManyToManyRelation(kysely, fromRelation.model, fromRelation.field, fromRelation.ids);
3857
- const results = [];
3858
- for (const d of _data) {
3859
- const ids = await this.getEntityIds(kysely, model, d);
3860
- if (!ids) {
3987
+ if (_data.length > 0) {
3988
+ const allIds = await this.getEntitiesIds(kysely, model, _data);
3989
+ if (allIds.length !== _data.length) {
3861
3990
  throw createNotFoundError(model);
3862
3991
  }
3863
- results.push(await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, ids, m2m.joinTable));
3864
- }
3865
- if (_data.length > results.filter((r) => !!r).length) {
3866
- throw createNotFoundError(model);
3992
+ await this.handleManyToManyRelation(kysely, "connect", fromRelation.model, fromRelation.field, fromRelation.ids, m2m.otherModel, m2m.otherField, allIds, m2m.joinTable);
3867
3993
  }
3868
3994
  } else {
3869
3995
  const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
@@ -4075,6 +4201,13 @@ var BaseOperationHandler = class {
4075
4201
  return txBuilder.execute(callback);
4076
4202
  }
4077
4203
  }
4204
+ async safeTransactionIf(condition, callback, isolationLevel) {
4205
+ if (condition) {
4206
+ return this.safeTransaction(callback, isolationLevel);
4207
+ } else {
4208
+ return callback(this.kysely);
4209
+ }
4210
+ }
4078
4211
  // Given a unique filter of a model, load the entity and return its id fields
4079
4212
  getEntityIds(kysely, model, uniqueFilter) {
4080
4213
  return this.readUnique(kysely, model, {
@@ -4082,6 +4215,15 @@ var BaseOperationHandler = class {
4082
4215
  select: this.makeIdSelect(model)
4083
4216
  });
4084
4217
  }
4218
+ // Given multiple unique filters, load all matching entities and return their id fields in one query
4219
+ getEntitiesIds(kysely, model, uniqueFilters) {
4220
+ return this.read(kysely, model, {
4221
+ where: {
4222
+ OR: uniqueFilters
4223
+ },
4224
+ select: this.makeIdSelect(model)
4225
+ });
4226
+ }
4085
4227
  /**
4086
4228
  * Normalize input args to strip `undefined` fields
4087
4229
  */
@@ -4119,29 +4261,30 @@ var BaseOperationHandler = class {
4119
4261
  return result.rows[0];
4120
4262
  }
4121
4263
  mutationNeedsReadBack(model, args) {
4264
+ const idFields = requireIdFields(this.schema, model);
4122
4265
  if (this.hasPolicyEnabled) {
4123
4266
  return {
4124
4267
  needReadBack: true,
4125
- selectedFields: void 0
4268
+ selectedFields: idFields
4126
4269
  };
4127
4270
  }
4128
4271
  if (!this.dialect.supportsReturning) {
4129
4272
  return {
4130
4273
  needReadBack: true,
4131
- selectedFields: void 0
4274
+ selectedFields: idFields
4132
4275
  };
4133
4276
  }
4134
4277
  if (args.include && typeof args.include === "object" && Object.keys(args.include).length > 0) {
4135
4278
  return {
4136
4279
  needReadBack: true,
4137
- selectedFields: void 0
4280
+ selectedFields: idFields
4138
4281
  };
4139
4282
  }
4140
4283
  const modelDef = this.requireModel(model);
4141
4284
  if (modelDef.baseModel || modelDef.isDelegate) {
4142
4285
  return {
4143
4286
  needReadBack: true,
4144
- selectedFields: void 0
4287
+ selectedFields: idFields
4145
4288
  };
4146
4289
  }
4147
4290
  const allFields = Object.keys(modelDef.fields);
@@ -4156,7 +4299,7 @@ var BaseOperationHandler = class {
4156
4299
  if (allFieldsSelected.some((f) => relationFields.includes(f) || computedFields.includes(f))) {
4157
4300
  return {
4158
4301
  needReadBack: true,
4159
- selectedFields: void 0
4302
+ selectedFields: idFields
4160
4303
  };
4161
4304
  } else {
4162
4305
  return {
@@ -4228,7 +4371,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4228
4371
  Object.entries(value).forEach(([field, val]) => {
4229
4372
  if (val === true) {
4230
4373
  query = query.select((eb) => {
4231
- const fn = (0, import_ts_pattern8.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4374
+ const fn = (0, import_ts_pattern5.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
4232
4375
  return fn(eb.ref(`$sub.${field}`)).as(`${key}.${field}`);
4233
4376
  });
4234
4377
  }
@@ -4261,7 +4404,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
4261
4404
  val = parseFloat(val);
4262
4405
  } else {
4263
4406
  if (op === "_sum" || op === "_min" || op === "_max") {
4264
- val = (0, import_ts_pattern8.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4407
+ val = (0, import_ts_pattern5.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4265
4408
  }
4266
4409
  }
4267
4410
  }
@@ -4311,14 +4454,14 @@ var CountOperationHandler = class extends BaseOperationHandler {
4311
4454
  };
4312
4455
 
4313
4456
  // src/client/crud/operations/create.ts
4314
- var import_ts_pattern9 = require("ts-pattern");
4457
+ var import_ts_pattern6 = require("ts-pattern");
4315
4458
  var CreateOperationHandler = class extends BaseOperationHandler {
4316
4459
  static {
4317
4460
  __name(this, "CreateOperationHandler");
4318
4461
  }
4319
4462
  async handle(operation, args) {
4320
4463
  const normalizedArgs = this.normalizeArgs(args);
4321
- return (0, import_ts_pattern9.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4464
+ return (0, import_ts_pattern6.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
4322
4465
  return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
4323
4466
  }).with("createManyAndReturn", () => {
4324
4467
  return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
@@ -4326,7 +4469,8 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4326
4469
  }
4327
4470
  async runCreate(args) {
4328
4471
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4329
- const result = await this.safeTransaction(async (tx) => {
4472
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4473
+ const result = await this.safeTransactionIf(needReadBack || needsNestedCreate, async (tx) => {
4330
4474
  const createResult = await this.create(tx, this.model, args.data, void 0, false, selectedFields);
4331
4475
  if (needReadBack) {
4332
4476
  return this.readUnique(tx, this.model, {
@@ -4350,14 +4494,16 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4350
4494
  count: 0
4351
4495
  };
4352
4496
  }
4353
- return this.safeTransaction((tx) => this.createMany(tx, this.model, args, false));
4497
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4498
+ return this.safeTransactionIf(needsNestedCreate, (tx) => this.createMany(tx, this.model, args, false));
4354
4499
  }
4355
4500
  async runCreateManyAndReturn(args) {
4356
4501
  if (args === void 0) {
4357
4502
  return [];
4358
4503
  }
4359
4504
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4360
- return this.safeTransaction(async (tx) => {
4505
+ const needsNestedCreate = this.needsNestedCreate(args.data);
4506
+ return this.safeTransactionIf(needReadBack || needsNestedCreate, async (tx) => {
4361
4507
  const createResult = await this.createMany(tx, this.model, args, true, void 0, selectedFields);
4362
4508
  if (needReadBack) {
4363
4509
  return this.read(tx, this.model, {
@@ -4372,21 +4518,36 @@ var CreateOperationHandler = class extends BaseOperationHandler {
4372
4518
  }
4373
4519
  });
4374
4520
  }
4521
+ needsNestedCreate(data) {
4522
+ const modelDef = this.requireModel(this.model);
4523
+ if (modelDef.baseModel) {
4524
+ return true;
4525
+ }
4526
+ const hasRelation = Object.entries(data).some(([field, value]) => {
4527
+ const fieldDef = this.getField(this.model, field);
4528
+ return fieldDef?.relation && value !== void 0;
4529
+ });
4530
+ if (hasRelation) {
4531
+ return true;
4532
+ }
4533
+ return false;
4534
+ }
4375
4535
  };
4376
4536
 
4377
4537
  // src/client/crud/operations/delete.ts
4378
- var import_ts_pattern10 = require("ts-pattern");
4538
+ var import_ts_pattern7 = require("ts-pattern");
4379
4539
  var DeleteOperationHandler = class extends BaseOperationHandler {
4380
4540
  static {
4381
4541
  __name(this, "DeleteOperationHandler");
4382
4542
  }
4383
4543
  async handle(operation, args) {
4384
4544
  const normalizedArgs = this.normalizeArgs(args);
4385
- return (0, import_ts_pattern10.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4545
+ return (0, import_ts_pattern7.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
4386
4546
  }
4387
4547
  async runDelete(args) {
4388
4548
  const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
4389
- const result = await this.safeTransaction(async (tx) => {
4549
+ const needsNestedDelete = this.needsNestedDelete();
4550
+ const result = await this.safeTransactionIf(needReadBack || needsNestedDelete, async (tx) => {
4390
4551
  let preDeleteRead = void 0;
4391
4552
  if (needReadBack) {
4392
4553
  preDeleteRead = await this.readUnique(tx, this.model, {
@@ -4408,13 +4569,30 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
4408
4569
  return result;
4409
4570
  }
4410
4571
  async runDeleteMany(args) {
4411
- return await this.safeTransaction(async (tx) => {
4572
+ const needsNestedDelete = this.needsNestedDelete();
4573
+ return await this.safeTransactionIf(needsNestedDelete, async (tx) => {
4412
4574
  const result = await this.delete(tx, this.model, args?.where, args?.limit);
4413
4575
  return {
4414
4576
  count: Number(result.numAffectedRows ?? 0)
4415
4577
  };
4416
4578
  });
4417
4579
  }
4580
+ needsNestedDelete() {
4581
+ const modelDef = this.requireModel(this.model);
4582
+ if (modelDef.baseModel) {
4583
+ return true;
4584
+ }
4585
+ for (const fieldDef of Object.values(modelDef.fields)) {
4586
+ if (fieldDef.relation?.opposite) {
4587
+ const oppositeModelDef = this.requireModel(fieldDef.type);
4588
+ const oppositeRelation = this.requireField(fieldDef.type, fieldDef.relation.opposite);
4589
+ if (oppositeModelDef.baseModel && oppositeRelation.relation?.onDelete === "Cascade") {
4590
+ return true;
4591
+ }
4592
+ }
4593
+ }
4594
+ return false;
4595
+ }
4418
4596
  };
4419
4597
 
4420
4598
  // src/client/crud/operations/exists.ts
@@ -4449,7 +4627,7 @@ var FindOperationHandler = class extends BaseOperationHandler {
4449
4627
  };
4450
4628
 
4451
4629
  // src/client/crud/operations/group-by.ts
4452
- var import_ts_pattern11 = require("ts-pattern");
4630
+ var import_ts_pattern8 = require("ts-pattern");
4453
4631
  var GroupByOperationHandler = class extends BaseOperationHandler {
4454
4632
  static {
4455
4633
  __name(this, "GroupByOperationHandler");
@@ -4537,7 +4715,7 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4537
4715
  val = parseFloat(val);
4538
4716
  } else {
4539
4717
  if (op === "_sum" || op === "_min" || op === "_max") {
4540
- val = (0, import_ts_pattern11.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4718
+ val = (0, import_ts_pattern8.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
4541
4719
  }
4542
4720
  }
4543
4721
  }
@@ -4552,18 +4730,19 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
4552
4730
  };
4553
4731
 
4554
4732
  // src/client/crud/operations/update.ts
4555
- var import_ts_pattern12 = require("ts-pattern");
4733
+ var import_ts_pattern9 = require("ts-pattern");
4556
4734
  var UpdateOperationHandler = class extends BaseOperationHandler {
4557
4735
  static {
4558
4736
  __name(this, "UpdateOperationHandler");
4559
4737
  }
4560
4738
  async handle(operation, args) {
4561
4739
  const normalizedArgs = this.normalizeArgs(args);
4562
- return (0, import_ts_pattern12.match)(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();
4740
+ return (0, import_ts_pattern9.match)(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();
4563
4741
  }
4564
4742
  async runUpdate(args) {
4565
4743
  const { needReadBack, selectedFields } = this.needReadBack(args);
4566
- const result = await this.safeTransaction(async (tx) => {
4744
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4745
+ const result = await this.safeTransactionIf(needReadBack || needsNestedUpdate, async (tx) => {
4567
4746
  const updateResult = await this.update(tx, this.model, args.where, args.data, void 0, void 0, void 0, selectedFields);
4568
4747
  if (needReadBack) {
4569
4748
  const readFilter = updateResult ? getIdValues(this.schema, this.model, updateResult) : args.where;
@@ -4590,7 +4769,8 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4590
4769
  }
4591
4770
  }
4592
4771
  async runUpdateMany(args) {
4593
- return this.safeTransaction(async (tx) => {
4772
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4773
+ return this.safeTransactionIf(needsNestedUpdate, async (tx) => {
4594
4774
  return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
4595
4775
  });
4596
4776
  }
@@ -4599,7 +4779,8 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4599
4779
  return [];
4600
4780
  }
4601
4781
  const { needReadBack, selectedFields } = this.needReadBack(args);
4602
- const { readBackResult, updateResult } = await this.safeTransaction(async (tx) => {
4782
+ const needsNestedUpdate = this.needsNestedUpdate(args.data);
4783
+ const { readBackResult, updateResult } = await this.safeTransactionIf(needReadBack || needsNestedUpdate, async (tx) => {
4603
4784
  const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true, void 0, void 0, selectedFields);
4604
4785
  if (needReadBack) {
4605
4786
  const readBackResult2 = await this.read(tx, this.model, {
@@ -4653,10 +4834,11 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4653
4834
  if (baseResult.needReadBack) {
4654
4835
  return baseResult;
4655
4836
  }
4837
+ const idFields = requireIdFields(this.schema, this.model);
4656
4838
  if (!this.dialect.supportsReturning) {
4657
4839
  return {
4658
4840
  needReadBack: true,
4659
- selectedFields: void 0
4841
+ selectedFields: idFields
4660
4842
  };
4661
4843
  }
4662
4844
  const modelDef = this.requireModel(this.model);
@@ -4664,28 +4846,42 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
4664
4846
  if (args.data && !Object.keys(args.data).some((field) => nonRelationFields.includes(field))) {
4665
4847
  return {
4666
4848
  needReadBack: true,
4667
- selectedFields: void 0
4849
+ selectedFields: idFields
4668
4850
  };
4669
4851
  }
4670
4852
  if (args.update && !Object.keys(args.update).some((field) => nonRelationFields.includes(field))) {
4671
4853
  return {
4672
4854
  needReadBack: true,
4673
- selectedFields: void 0
4855
+ selectedFields: idFields
4674
4856
  };
4675
4857
  }
4676
4858
  return baseResult;
4677
4859
  }
4860
+ needsNestedUpdate(data) {
4861
+ const modelDef = this.requireModel(this.model);
4862
+ if (modelDef.baseModel) {
4863
+ return true;
4864
+ }
4865
+ const hasRelation = Object.entries(data).some(([field, value]) => {
4866
+ const fieldDef = this.getField(this.model, field);
4867
+ return fieldDef?.relation && value !== void 0;
4868
+ });
4869
+ if (hasRelation) {
4870
+ return true;
4871
+ }
4872
+ return false;
4873
+ }
4678
4874
  };
4679
4875
 
4680
4876
  // src/client/crud/validator/validator.ts
4681
4877
  var import_common_helpers9 = require("@zenstackhq/common-helpers");
4682
- var import_ts_pattern14 = require("ts-pattern");
4878
+ var import_ts_pattern11 = require("ts-pattern");
4683
4879
 
4684
4880
  // src/client/zod/factory.ts
4685
4881
  var import_common_helpers8 = require("@zenstackhq/common-helpers");
4686
4882
  var import_zod = require("@zenstackhq/zod");
4687
4883
  var import_decimal4 = __toESM(require("decimal.js"), 1);
4688
- var import_ts_pattern13 = require("ts-pattern");
4884
+ var import_ts_pattern10 = require("ts-pattern");
4689
4885
  var import_zod2 = require("zod");
4690
4886
 
4691
4887
  // src/client/zod/cache-decorator.ts
@@ -4768,6 +4964,13 @@ var ZodSchemaFactory = class {
4768
4964
  get plugins() {
4769
4965
  return this.options.plugins ?? [];
4770
4966
  }
4967
+ /**
4968
+ * Returns model field entries, excluding Unsupported fields.
4969
+ */
4970
+ getModelFields(model) {
4971
+ const modelDef = requireModel(this.schema, model);
4972
+ return Object.entries(modelDef.fields).filter(([, def]) => def.type !== "Unsupported");
4973
+ }
4771
4974
  shouldIncludeRelations(options) {
4772
4975
  return options?.relationDepth === void 0 || options.relationDepth > 0;
4773
4976
  }
@@ -4853,7 +5056,7 @@ var ZodSchemaFactory = class {
4853
5056
  } else if (this.schema.enums && type in this.schema.enums) {
4854
5057
  return this.makeEnumSchema(type);
4855
5058
  } else {
4856
- return (0, import_ts_pattern13.match)(type).with("String", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addStringValidation(import_zod2.z.string(), attributes) : import_zod2.z.string()).with("Int", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addNumberValidation(import_zod2.z.number().int(), attributes) : import_zod2.z.number().int()).with("Float", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addNumberValidation(import_zod2.z.number(), attributes) : import_zod2.z.number()).with("Boolean", () => import_zod2.z.boolean()).with("BigInt", () => import_zod2.z.union([
5059
+ return (0, import_ts_pattern10.match)(type).with("String", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addStringValidation(import_zod2.z.string(), attributes) : import_zod2.z.string()).with("Int", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addNumberValidation(import_zod2.z.number().int(), attributes) : import_zod2.z.number().int()).with("Float", () => this.extraValidationsEnabled ? import_zod.ZodUtils.addNumberValidation(import_zod2.z.number(), attributes) : import_zod2.z.number()).with("Boolean", () => import_zod2.z.boolean()).with("BigInt", () => import_zod2.z.union([
4857
5060
  this.extraValidationsEnabled ? import_zod.ZodUtils.addNumberValidation(import_zod2.z.number().int(), attributes) : import_zod2.z.number().int(),
4858
5061
  this.extraValidationsEnabled ? import_zod.ZodUtils.addBigIntValidation(import_zod2.z.bigint(), attributes) : import_zod2.z.bigint()
4859
5062
  ])).with("Decimal", () => {
@@ -4898,15 +5101,13 @@ var ZodSchemaFactory = class {
4898
5101
  return finalSchema;
4899
5102
  }
4900
5103
  makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false, options) {
4901
- const modelDef = requireModel(this.schema, model);
4902
5104
  const uniqueFieldNames = unique ? getUniqueFields(this.schema, model).filter((uf) => (
4903
5105
  // single-field unique
4904
5106
  "def" in uf
4905
5107
  )).map((uf) => uf.name) : void 0;
4906
5108
  const nextOpts = this.nextOptions(options);
4907
5109
  const fields = {};
4908
- for (const field of Object.keys(modelDef.fields)) {
4909
- const fieldDef = requireField(this.schema, model, field);
5110
+ for (const [field, fieldDef] of this.getModelFields(model)) {
4910
5111
  let fieldSchema;
4911
5112
  if (fieldDef.relation) {
4912
5113
  if (withoutRelationFields || !this.shouldIncludeRelations(options)) {
@@ -5101,7 +5302,7 @@ var ZodSchemaFactory = class {
5101
5302
  const allowedFilterKinds = ignoreSlicing ? void 0 : this.getEffectiveFilterKinds(contextModel, fieldInfo.name);
5102
5303
  const type = fieldInfo.type;
5103
5304
  const optional = !!fieldInfo.optional;
5104
- return (0, import_ts_pattern13.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)).with(import_ts_pattern13.P.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", () => import_zod2.z.never()).exhaustive();
5305
+ return (0, import_ts_pattern10.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)).with(import_ts_pattern10.P.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", () => import_zod2.z.never()).exhaustive();
5105
5306
  }
5106
5307
  makeJsonValueSchema(nullable, forFilter) {
5107
5308
  const options = [
@@ -5266,10 +5467,8 @@ var ZodSchemaFactory = class {
5266
5467
  ]);
5267
5468
  }
5268
5469
  makeSelectSchema(model, options) {
5269
- const modelDef = requireModel(this.schema, model);
5270
5470
  const fields = {};
5271
- for (const field of Object.keys(modelDef.fields)) {
5272
- const fieldDef = requireField(this.schema, model, field);
5471
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5273
5472
  if (fieldDef.relation) {
5274
5473
  if (!this.shouldIncludeRelations(options)) {
5275
5474
  continue;
@@ -5287,6 +5486,7 @@ var ZodSchemaFactory = class {
5287
5486
  fields["_count"] = _countSchema;
5288
5487
  }
5289
5488
  }
5489
+ this.addExtResultFields(model, fields);
5290
5490
  return import_zod2.z.strictObject(fields);
5291
5491
  }
5292
5492
  makeCountSelectionSchema(model, options) {
@@ -5341,10 +5541,8 @@ var ZodSchemaFactory = class {
5341
5541
  ]);
5342
5542
  }
5343
5543
  makeOmitSchema(model) {
5344
- const modelDef = requireModel(this.schema, model);
5345
5544
  const fields = {};
5346
- for (const field of Object.keys(modelDef.fields)) {
5347
- const fieldDef = requireField(this.schema, model, field);
5545
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5348
5546
  if (!fieldDef.relation) {
5349
5547
  if (this.options.allowQueryTimeOmitOverride !== false) {
5350
5548
  fields[field] = import_zod2.z.boolean().optional();
@@ -5353,8 +5551,22 @@ var ZodSchemaFactory = class {
5353
5551
  }
5354
5552
  }
5355
5553
  }
5554
+ this.addExtResultFields(model, fields);
5356
5555
  return import_zod2.z.strictObject(fields);
5357
5556
  }
5557
+ addExtResultFields(model, fields) {
5558
+ for (const plugin of this.plugins) {
5559
+ const resultConfig = plugin.result;
5560
+ if (resultConfig) {
5561
+ const modelConfig = resultConfig[(0, import_common_helpers8.lowerCaseFirst)(model)];
5562
+ if (modelConfig) {
5563
+ for (const field of Object.keys(modelConfig)) {
5564
+ fields[field] = import_zod2.z.boolean().optional();
5565
+ }
5566
+ }
5567
+ }
5568
+ }
5569
+ }
5358
5570
  makeIncludeSchema(model, options) {
5359
5571
  const modelDef = requireModel(this.schema, model);
5360
5572
  const fields = {};
@@ -5378,15 +5590,13 @@ var ZodSchemaFactory = class {
5378
5590
  return import_zod2.z.strictObject(fields);
5379
5591
  }
5380
5592
  makeOrderBySchema(model, withRelation, WithAggregation, options) {
5381
- const modelDef = requireModel(this.schema, model);
5382
5593
  const fields = {};
5383
5594
  const sort = import_zod2.z.union([
5384
5595
  import_zod2.z.literal("asc"),
5385
5596
  import_zod2.z.literal("desc")
5386
5597
  ]);
5387
5598
  const nextOpts = this.nextOptions(options);
5388
- for (const field of Object.keys(modelDef.fields)) {
5389
- const fieldDef = requireField(this.schema, model, field);
5599
+ for (const [field, fieldDef] of this.getModelFields(model)) {
5390
5600
  if (fieldDef.relation) {
5391
5601
  if (withRelation && this.shouldIncludeRelations(options)) {
5392
5602
  fields[field] = import_zod2.z.lazy(() => {
@@ -5431,8 +5641,7 @@ var ZodSchemaFactory = class {
5431
5641
  return import_zod2.z.strictObject(fields);
5432
5642
  }
5433
5643
  makeDistinctSchema(model) {
5434
- const modelDef = requireModel(this.schema, model);
5435
- const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation);
5644
+ const nonRelationFields = this.getModelFields(model).filter(([, def]) => !def.relation).map(([name]) => name);
5436
5645
  return nonRelationFields.length > 0 ? this.orArray(import_zod2.z.enum(nonRelationFields), true) : import_zod2.z.never();
5437
5646
  }
5438
5647
  makeCursorSchema(model, options) {
@@ -5471,13 +5680,13 @@ var ZodSchemaFactory = class {
5471
5680
  const uncheckedVariantFields = {};
5472
5681
  const checkedVariantFields = {};
5473
5682
  const modelDef = requireModel(this.schema, model);
5474
- const hasRelation = !skipRelations && Object.entries(modelDef.fields).some(([f, def]) => !withoutFields.includes(f) && def.relation);
5683
+ const modelFields = this.getModelFields(model);
5684
+ const hasRelation = !skipRelations && modelFields.some(([f, def]) => !withoutFields.includes(f) && def.relation);
5475
5685
  const nextOpts = this.nextOptions(options);
5476
- Object.keys(modelDef.fields).forEach((field) => {
5686
+ modelFields.forEach(([field, fieldDef]) => {
5477
5687
  if (withoutFields.includes(field)) {
5478
5688
  return;
5479
5689
  }
5480
- const fieldDef = requireField(this.schema, model, field);
5481
5690
  if (fieldDef.computed || fieldDef.isDiscriminator) {
5482
5691
  return;
5483
5692
  }
@@ -5570,12 +5779,15 @@ var ZodSchemaFactory = class {
5570
5779
  const fieldDef = requireField(this.schema, model, field);
5571
5780
  const fieldType = fieldDef.type;
5572
5781
  const array = !!fieldDef.array;
5782
+ const canCreateModel = this.canCreateModel(fieldType);
5573
5783
  const fields = {
5574
- create: this.makeCreateDataSchema(fieldDef.type, !!fieldDef.array, withoutFields, false, options).optional(),
5575
- connect: this.makeConnectDataSchema(fieldType, array, options).optional(),
5576
- connectOrCreate: this.makeConnectOrCreateDataSchema(fieldType, array, withoutFields, options).optional()
5784
+ connect: this.makeConnectDataSchema(fieldType, array, options).optional()
5577
5785
  };
5578
- if (array) {
5786
+ if (canCreateModel) {
5787
+ fields["create"] = this.makeCreateDataSchema(fieldDef.type, !!fieldDef.array, withoutFields, false, options).optional();
5788
+ fields["connectOrCreate"] = this.makeConnectOrCreateDataSchema(fieldType, array, withoutFields, options).optional();
5789
+ }
5790
+ if (array && canCreateModel) {
5579
5791
  fields["createMany"] = this.makeCreateManyPayloadSchema(fieldType, withoutFields, options).optional();
5580
5792
  }
5581
5793
  if (mode === "update") {
@@ -5593,15 +5805,17 @@ var ZodSchemaFactory = class {
5593
5805
  }),
5594
5806
  this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5595
5807
  ]).optional();
5596
- let upsertWhere = this.makeWhereSchema(fieldType, true, false, false, options);
5597
- if (!fieldDef.array) {
5598
- upsertWhere = upsertWhere.optional();
5599
- }
5600
- fields["upsert"] = this.orArray(import_zod2.z.strictObject({
5601
- where: upsertWhere,
5602
- create: this.makeCreateDataSchema(fieldType, false, withoutFields, false, options),
5603
- update: this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5604
- }), true).optional();
5808
+ if (canCreateModel) {
5809
+ let upsertWhere = this.makeWhereSchema(fieldType, true, false, false, options);
5810
+ if (!fieldDef.array) {
5811
+ upsertWhere = upsertWhere.optional();
5812
+ }
5813
+ fields["upsert"] = this.orArray(import_zod2.z.strictObject({
5814
+ where: upsertWhere,
5815
+ create: this.makeCreateDataSchema(fieldType, false, withoutFields, false, options),
5816
+ update: this.makeUpdateDataSchema(fieldType, withoutFields, false, options)
5817
+ }), true).optional();
5818
+ }
5605
5819
  if (array) {
5606
5820
  fields["set"] = this.makeSetDataSchema(fieldType, true, options).optional();
5607
5821
  fields["updateMany"] = this.orArray(import_zod2.z.strictObject({
@@ -5702,13 +5916,13 @@ var ZodSchemaFactory = class {
5702
5916
  const uncheckedVariantFields = {};
5703
5917
  const checkedVariantFields = {};
5704
5918
  const modelDef = requireModel(this.schema, model);
5705
- const hasRelation = !skipRelations && Object.entries(modelDef.fields).some(([key, value]) => value.relation && !withoutFields.includes(key));
5919
+ const modelFields = this.getModelFields(model);
5920
+ const hasRelation = !skipRelations && modelFields.some(([key, value]) => value.relation && !withoutFields.includes(key));
5706
5921
  const nextOpts = this.nextOptions(options);
5707
- Object.keys(modelDef.fields).forEach((field) => {
5922
+ modelFields.forEach(([field, fieldDef]) => {
5708
5923
  if (withoutFields.includes(field)) {
5709
5924
  return;
5710
5925
  }
5711
- const fieldDef = requireField(this.schema, model, field);
5712
5926
  if (fieldDef.computed || fieldDef.isDiscriminator) {
5713
5927
  return;
5714
5928
  }
@@ -5825,12 +6039,11 @@ var ZodSchemaFactory = class {
5825
6039
  }), "count").optional();
5826
6040
  }
5827
6041
  makeCountAggregateInputSchema(model) {
5828
- const modelDef = requireModel(this.schema, model);
5829
6042
  return import_zod2.z.union([
5830
6043
  import_zod2.z.literal(true),
5831
6044
  import_zod2.z.strictObject({
5832
6045
  _all: import_zod2.z.literal(true).optional(),
5833
- ...Object.keys(modelDef.fields).reduce((acc, field) => {
6046
+ ...this.getModelFields(model).reduce((acc, [field]) => {
5834
6047
  acc[field] = import_zod2.z.literal(true).optional();
5835
6048
  return acc;
5836
6049
  }, {})
@@ -5853,9 +6066,7 @@ var ZodSchemaFactory = class {
5853
6066
  }), "aggregate").optional();
5854
6067
  }
5855
6068
  makeSumAvgInputSchema(model) {
5856
- const modelDef = requireModel(this.schema, model);
5857
- return import_zod2.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
5858
- const fieldDef = requireField(this.schema, model, field);
6069
+ return import_zod2.z.strictObject(this.getModelFields(model).reduce((acc, [field, fieldDef]) => {
5859
6070
  if (this.isNumericField(fieldDef)) {
5860
6071
  acc[field] = import_zod2.z.literal(true).optional();
5861
6072
  }
@@ -5863,9 +6074,7 @@ var ZodSchemaFactory = class {
5863
6074
  }, {}));
5864
6075
  }
5865
6076
  makeMinMaxInputSchema(model) {
5866
- const modelDef = requireModel(this.schema, model);
5867
- return import_zod2.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
5868
- const fieldDef = requireField(this.schema, model, field);
6077
+ return import_zod2.z.strictObject(this.getModelFields(model).reduce((acc, [field, fieldDef]) => {
5869
6078
  if (!fieldDef.relation && !fieldDef.array) {
5870
6079
  acc[field] = import_zod2.z.literal(true).optional();
5871
6080
  }
@@ -5875,8 +6084,7 @@ var ZodSchemaFactory = class {
5875
6084
  // #endregion
5876
6085
  // #region Group By
5877
6086
  makeGroupBySchema(model, options) {
5878
- const modelDef = requireModel(this.schema, model);
5879
- const nonRelationFields = Object.keys(modelDef.fields).filter((field) => !modelDef.fields[field]?.relation);
6087
+ const nonRelationFields = this.getModelFields(model).filter(([, def]) => !def.relation).map(([name]) => name);
5880
6088
  const bySchema = nonRelationFields.length > 0 ? this.orArray(import_zod2.z.enum(nonRelationFields), true) : import_zod2.z.never();
5881
6089
  const baseSchema = import_zod2.z.strictObject({
5882
6090
  where: this.makeWhereSchema(model, false, false, false, options).optional(),
@@ -6138,10 +6346,17 @@ var ZodSchemaFactory = class {
6138
6346
  return import_zod2.z.strictObject(components);
6139
6347
  }
6140
6348
  }
6141
- /**
6142
- * Checks if a model is included in the slicing configuration.
6143
- * Returns true if the model is allowed, false if it's excluded.
6144
- */
6349
+ canCreateModel(model) {
6350
+ const modelDef = requireModel(this.schema, model);
6351
+ if (modelDef.isDelegate) {
6352
+ return false;
6353
+ }
6354
+ const hasRequiredUnsupportedFields = Object.values(modelDef.fields).some((fieldDef) => fieldDef.type === "Unsupported" && !fieldDef.optional && !fieldHasDefaultValue(fieldDef));
6355
+ if (hasRequiredUnsupportedFields) {
6356
+ return false;
6357
+ }
6358
+ return true;
6359
+ }
6145
6360
  isModelAllowed(targetModel) {
6146
6361
  const slicing = this.options.slicing;
6147
6362
  if (!slicing) {
@@ -6618,7 +6833,7 @@ var InputValidator = class {
6618
6833
  }
6619
6834
  // #region Entry points
6620
6835
  validateFindArgs(model, args, operation) {
6621
- return this.validate(model, operation, (model2) => (0, import_ts_pattern14.match)(operation).with("findFirst", () => this.zodFactory.makeFindFirstSchema(model2)).with("findUnique", () => this.zodFactory.makeFindUniqueSchema(model2)).with("findMany", () => this.zodFactory.makeFindManySchema(model2)).exhaustive(), args);
6836
+ return this.validate(model, operation, (model2) => (0, import_ts_pattern11.match)(operation).with("findFirst", () => this.zodFactory.makeFindFirstSchema(model2)).with("findUnique", () => this.zodFactory.makeFindUniqueSchema(model2)).with("findMany", () => this.zodFactory.makeFindManySchema(model2)).exhaustive(), args);
6622
6837
  }
6623
6838
  validateExistsArgs(model, args) {
6624
6839
  return this.validate(model, "exists", (model2) => this.zodFactory.makeExistsSchema(model2), args);
@@ -6928,7 +7143,7 @@ __name(performanceNow, "performanceNow");
6928
7143
  // src/client/executor/zenstack-query-executor.ts
6929
7144
  var import_common_helpers11 = require("@zenstackhq/common-helpers");
6930
7145
  var import_kysely9 = require("kysely");
6931
- var import_ts_pattern15 = require("ts-pattern");
7146
+ var import_ts_pattern12 = require("ts-pattern");
6932
7147
 
6933
7148
  // src/client/executor/name-mapper.ts
6934
7149
  var import_common_helpers10 = require("@zenstackhq/common-helpers");
@@ -6951,7 +7166,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
6951
7166
  if (mappedName) {
6952
7167
  this.modelToTableMap.set(modelName, mappedName);
6953
7168
  }
6954
- for (const fieldDef of this.getModelFields(modelDef)) {
7169
+ for (const fieldDef of getModelFields(this.schema, modelName)) {
6955
7170
  const mappedName2 = this.getMappedName(fieldDef);
6956
7171
  if (mappedName2) {
6957
7172
  this.fieldToColumnMap.set(`${modelName}.${fieldDef.name}`, mappedName2);
@@ -7212,7 +7427,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
7212
7427
  if (!modelDef) {
7213
7428
  continue;
7214
7429
  }
7215
- if (this.getModelFields(modelDef).some((f) => f.name === name)) {
7430
+ if (getModelFields(this.schema, scope.model).some((f) => f.name === name)) {
7216
7431
  return scope;
7217
7432
  }
7218
7433
  }
@@ -7326,8 +7541,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
7326
7541
  return schema;
7327
7542
  }
7328
7543
  createSelectAllFields(model, alias) {
7329
- const modelDef = requireModel(this.schema, model);
7330
- return this.getModelFields(modelDef).map((fieldDef) => {
7544
+ return getModelFields(this.schema, model).map((fieldDef) => {
7331
7545
  const columnName = this.mapFieldName(model, fieldDef.name);
7332
7546
  const columnRef = import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(columnName), alias && import_kysely7.IdentifierNode.is(alias) ? import_kysely7.TableNode.create(alias.name) : void 0);
7333
7547
  if (columnName !== fieldDef.name) {
@@ -7344,9 +7558,6 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
7344
7558
  }
7345
7559
  });
7346
7560
  }
7347
- getModelFields(modelDef) {
7348
- return Object.values(modelDef.fields).filter((f) => !f.relation && !f.computed && !f.originModel);
7349
- }
7350
7561
  processSelections(selections) {
7351
7562
  const result = [];
7352
7563
  selections.forEach((selection) => {
@@ -7383,9 +7594,8 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
7383
7594
  if (!scope.model || !(this.hasMappedColumns(scope.model) || this.modelUsesEnumWithMappedValues(scope.model))) {
7384
7595
  return super.transformSelectAll(node);
7385
7596
  }
7386
- const modelDef = requireModel(this.schema, scope.model);
7387
- return this.getModelFields(modelDef).map((fieldDef) => {
7388
- const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
7597
+ return getModelFields(this.schema, scope.model).map((fieldDef) => {
7598
+ const columnName = this.mapFieldName(scope.model, fieldDef.name);
7389
7599
  const columnRef = import_kysely7.ReferenceNode.create(import_kysely7.ColumnNode.create(columnName));
7390
7600
  const enumProcessed = this.processEnumSelection(columnRef, fieldDef.name);
7391
7601
  return columnName !== fieldDef.name && !import_kysely7.AliasNode.is(enumProcessed) ? this.wrapAlias(enumProcessed, import_kysely7.IdentifierNode.create(fieldDef.name)) : enumProcessed;
@@ -7406,7 +7616,7 @@ var QueryNameMapper = class extends import_kysely7.OperationNodeTransformer {
7406
7616
  if (!modelDef) {
7407
7617
  return false;
7408
7618
  }
7409
- return this.getModelFields(modelDef).some((fieldDef) => {
7619
+ return getModelFields(this.schema, model).some((fieldDef) => {
7410
7620
  const enumDef = getEnum(this.schema, fieldDef.type);
7411
7621
  if (!enumDef) {
7412
7622
  return false;
@@ -7607,14 +7817,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely9.
7607
7817
  get hasEntityMutationPluginsWithAfterMutationHooks() {
7608
7818
  return (this.client.$options.plugins ?? []).some((plugin) => plugin.onEntityMutation?.afterEntityMutation);
7609
7819
  }
7820
+ get hasOnKyselyHooks() {
7821
+ return (this.client.$options.plugins ?? []).some((plugin) => plugin.onKyselyQuery);
7822
+ }
7610
7823
  // #endregion
7611
7824
  // #region main entry point
7612
7825
  async executeQuery(compiledQuery) {
7613
7826
  const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
7827
+ const needEnsureTx = this.hasOnKyselyHooks || this.hasEntityMutationPlugins;
7614
7828
  const result = await this.provideConnection(async (connection) => {
7615
7829
  let startedTx = false;
7616
7830
  try {
7617
- if (this.isMutationNode(compiledQuery.query) && !this.driver.isTransactionConnection(connection)) {
7831
+ if (this.isMutationNode(compiledQuery.query) && !this.driver.isTransactionConnection(connection) && needEnsureTx) {
7618
7832
  await this.driver.beginTransaction(connection, {
7619
7833
  isolationLevel: TransactionIsolationLevel.ReadCommitted
7620
7834
  });
@@ -7904,7 +8118,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
7904
8118
  // #region utilities
7905
8119
  getMutationInfo(queryNode) {
7906
8120
  const model = this.getMutationModel(queryNode);
7907
- const { action, where } = (0, import_ts_pattern15.match)(queryNode).when(import_kysely9.InsertQueryNode.is, () => ({
8121
+ const { action, where } = (0, import_ts_pattern12.match)(queryNode).when(import_kysely9.InsertQueryNode.is, () => ({
7908
8122
  action: "create",
7909
8123
  where: void 0
7910
8124
  })).when(import_kysely9.UpdateQueryNode.is, (node) => ({
@@ -7924,7 +8138,7 @@ In such cases, ZenStack cannot reliably determine the IDs of the mutated entitie
7924
8138
  return import_kysely9.InsertQueryNode.is(queryNode) || import_kysely9.UpdateQueryNode.is(queryNode) || import_kysely9.DeleteQueryNode.is(queryNode);
7925
8139
  }
7926
8140
  getMutationModel(queryNode) {
7927
- return (0, import_ts_pattern15.match)(queryNode).when(import_kysely9.InsertQueryNode.is, (node) => {
8141
+ return (0, import_ts_pattern12.match)(queryNode).when(import_kysely9.InsertQueryNode.is, (node) => {
7928
8142
  (0, import_common_helpers11.invariant)(node.into, "InsertQueryNode must have an into clause");
7929
8143
  return node.into.table.identifier.name;
7930
8144
  }).when(import_kysely9.UpdateQueryNode.is, (node) => {
@@ -8082,7 +8296,7 @@ __export(functions_exports, {
8082
8296
  });
8083
8297
  var import_common_helpers12 = require("@zenstackhq/common-helpers");
8084
8298
  var import_kysely10 = require("kysely");
8085
- var import_ts_pattern16 = require("ts-pattern");
8299
+ var import_ts_pattern13 = require("ts-pattern");
8086
8300
  var contains = /* @__PURE__ */ __name((eb, args, context) => textMatch(eb, args, context, "contains"), "contains");
8087
8301
  var search = /* @__PURE__ */ __name((_eb, _args) => {
8088
8302
  throw new Error(`"search" function is not implemented yet`);
@@ -8121,7 +8335,7 @@ var textMatch = /* @__PURE__ */ __name((eb, args, { dialect }, method) => {
8121
8335
  }
8122
8336
  searchExpr = eb.fn.coalesce(searchExpr, import_kysely10.sql.lit(""));
8123
8337
  const escapedSearch = import_kysely10.sql`REPLACE(REPLACE(REPLACE(${dialect.castText(searchExpr)}, ${import_kysely10.sql.val("\\")}, ${import_kysely10.sql.val("\\\\")}), ${import_kysely10.sql.val("%")}, ${import_kysely10.sql.val("\\%")}), ${import_kysely10.sql.val("_")}, ${import_kysely10.sql.val("\\_")})`;
8124
- searchExpr = (0, import_ts_pattern16.match)(method).with("contains", () => eb.fn("CONCAT", [
8338
+ searchExpr = (0, import_ts_pattern13.match)(method).with("contains", () => eb.fn("CONCAT", [
8125
8339
  import_kysely10.sql.lit("%"),
8126
8340
  escapedSearch,
8127
8341
  import_kysely10.sql.lit("%")
@@ -8171,7 +8385,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
8171
8385
  }
8172
8386
  return eb(dialect.buildArrayLength(field), "=", import_kysely10.sql.lit(0));
8173
8387
  }, "isEmpty");
8174
- var now = /* @__PURE__ */ __name((_eb, _args, context) => (0, import_ts_pattern16.match)(context.dialect.provider).with("sqlite", () => import_kysely10.sql.raw("strftime('%Y-%m-%dT%H:%M:%fZ')")).with("mysql", () => import_kysely10.sql.raw("CONCAT(SUBSTRING(DATE_FORMAT(UTC_TIMESTAMP(3), '%Y-%m-%dT%H:%i:%s.%f'), 1, 23), '+00:00')")).with("postgresql", () => import_kysely10.sql.raw("CURRENT_TIMESTAMP")).exhaustive(), "now");
8388
+ var now = /* @__PURE__ */ __name((_eb, _args, context) => (0, import_ts_pattern13.match)(context.dialect.provider).with("sqlite", () => import_kysely10.sql.raw("strftime('%Y-%m-%dT%H:%M:%fZ')")).with("mysql", () => import_kysely10.sql.raw("CONCAT(SUBSTRING(DATE_FORMAT(UTC_TIMESTAMP(3), '%Y-%m-%dT%H:%i:%s.%f'), 1, 23), '+00:00')")).with("postgresql", () => import_kysely10.sql.raw("CURRENT_TIMESTAMP")).exhaustive(), "now");
8175
8389
  var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
8176
8390
  let result = model;
8177
8391
  const [casing] = args;
@@ -8191,7 +8405,7 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
8191
8405
  function processCasing(casing, result, model) {
8192
8406
  const opNode = casing.toOperationNode();
8193
8407
  (0, import_common_helpers12.invariant)(import_kysely10.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
8194
- result = (0, import_ts_pattern16.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers12.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers12.lowerCaseFirst)(result)).otherwise(() => {
8408
+ result = (0, import_ts_pattern13.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers12.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers12.lowerCaseFirst)(result)).otherwise(() => {
8195
8409
  throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
8196
8410
  });
8197
8411
  return result;
@@ -8211,7 +8425,7 @@ __name(readBoolean, "readBoolean");
8211
8425
  var import_common_helpers13 = require("@zenstackhq/common-helpers");
8212
8426
  var import_kysely11 = require("kysely");
8213
8427
  var import_toposort = __toESM(require("toposort"), 1);
8214
- var import_ts_pattern17 = require("ts-pattern");
8428
+ var import_ts_pattern14 = require("ts-pattern");
8215
8429
  var SchemaDbPusher = class {
8216
8430
  static {
8217
8431
  __name(this, "SchemaDbPusher");
@@ -8298,6 +8512,9 @@ var SchemaDbPusher = class {
8298
8512
  if (fieldDef.originModel && !fieldDef.id) {
8299
8513
  continue;
8300
8514
  }
8515
+ if (isUnsupportedField(fieldDef)) {
8516
+ continue;
8517
+ }
8301
8518
  if (fieldDef.relation) {
8302
8519
  table = this.addForeignKeyConstraint(table, modelDef.name, fieldName, fieldDef);
8303
8520
  } else if (!this.isComputedField(fieldDef)) {
@@ -8414,7 +8631,7 @@ var SchemaDbPusher = class {
8414
8631
  });
8415
8632
  }
8416
8633
  isDefaultValueSupportedForType(type) {
8417
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("postgresql", () => true).with("sqlite", () => true).with("mysql", () => ![
8634
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("postgresql", () => true).with("sqlite", () => true).with("mysql", () => ![
8418
8635
  "Json",
8419
8636
  "Bytes"
8420
8637
  ].includes(type)).exhaustive();
@@ -8452,7 +8669,7 @@ var SchemaDbPusher = class {
8452
8669
  return this.jsonType;
8453
8670
  }
8454
8671
  const type = fieldDef.type;
8455
- const result = (0, import_ts_pattern17.match)(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(() => {
8672
+ const result = (0, import_ts_pattern14.match)(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(() => {
8456
8673
  throw new Error(`Unsupported field type: ${type}`);
8457
8674
  });
8458
8675
  if (fieldDef.array) {
@@ -8492,35 +8709,35 @@ var SchemaDbPusher = class {
8492
8709
  return table;
8493
8710
  }
8494
8711
  mapCascadeAction(action) {
8495
- return (0, import_ts_pattern17.match)(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
8712
+ return (0, import_ts_pattern14.match)(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
8496
8713
  }
8497
8714
  // #region Type mappings and capabilities
8498
8715
  get jsonType() {
8499
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("mysql", () => "json").otherwise(() => "jsonb");
8716
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("mysql", () => "json").otherwise(() => "jsonb");
8500
8717
  }
8501
8718
  get bytesType() {
8502
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("postgresql", () => "bytea").with("mysql", () => "blob").otherwise(() => "blob");
8719
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("postgresql", () => "bytea").with("mysql", () => "blob").otherwise(() => "blob");
8503
8720
  }
8504
8721
  get stringType() {
8505
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("varchar(255)")).otherwise(() => "text");
8722
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("varchar(255)")).otherwise(() => "text");
8506
8723
  }
8507
8724
  get booleanType() {
8508
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("tinyint(1)")).otherwise(() => "boolean");
8725
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("tinyint(1)")).otherwise(() => "boolean");
8509
8726
  }
8510
8727
  get intType() {
8511
8728
  return "integer";
8512
8729
  }
8513
8730
  get floatType() {
8514
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("postgresql", () => "double precision").with("mysql", () => import_kysely11.sql.raw("double")).otherwise(() => "real");
8731
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("postgresql", () => "double precision").with("mysql", () => import_kysely11.sql.raw("double")).otherwise(() => "real");
8515
8732
  }
8516
8733
  get bigIntType() {
8517
8734
  return "bigint";
8518
8735
  }
8519
8736
  get decimalType() {
8520
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("decimal(65, 30)")).otherwise(() => "decimal");
8737
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("decimal(65, 30)")).otherwise(() => "decimal");
8521
8738
  }
8522
8739
  get dateTimeType() {
8523
- return (0, import_ts_pattern17.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("datetime(3)")).otherwise(() => "timestamp");
8740
+ return (0, import_ts_pattern14.match)(this.schema.provider.type).with("mysql", () => import_kysely11.sql.raw("datetime(3)")).otherwise(() => "timestamp");
8524
8741
  }
8525
8742
  columnSupportsAutoIncrement() {
8526
8743
  return [
@@ -8581,26 +8798,46 @@ var ResultProcessor = class {
8581
8798
  return result;
8582
8799
  }
8583
8800
  doProcessResult(data, model) {
8801
+ const firstRow = Array.isArray(data) ? data[0] : data;
8802
+ if (!firstRow || typeof firstRow !== "object") {
8803
+ return data;
8804
+ }
8805
+ const fields = this.resolveFields(firstRow, model);
8584
8806
  if (Array.isArray(data)) {
8585
- data.forEach((row, i) => data[i] = this.processRow(row, model));
8807
+ data.forEach((row, i) => data[i] = this.processRow(row, fields));
8586
8808
  return data;
8587
8809
  } else {
8588
- return this.processRow(data, model);
8810
+ return this.processRow(data, fields);
8589
8811
  }
8590
8812
  }
8591
- processRow(data, model) {
8813
+ resolveFields(row, model) {
8814
+ if (!row || typeof row !== "object") {
8815
+ return [];
8816
+ }
8817
+ const result = [];
8818
+ for (const key of Object.keys(row)) {
8819
+ if (key === "_count" || key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8820
+ continue;
8821
+ }
8822
+ const fieldDef = getField(this.schema, model, key);
8823
+ if (fieldDef) {
8824
+ result.push(fieldDef);
8825
+ }
8826
+ }
8827
+ return result;
8828
+ }
8829
+ processRow(data, fields) {
8592
8830
  if (!data || typeof data !== "object") {
8593
8831
  return data;
8594
8832
  }
8595
- for (const [key, value] of Object.entries(data)) {
8833
+ for (const key of Object.keys(data)) {
8834
+ const value = data[key];
8596
8835
  if (value === void 0) {
8597
8836
  continue;
8598
8837
  }
8599
8838
  if (key === "_count") {
8600
8839
  data[key] = typeof value === "string" ? JSON.parse(value) : value;
8601
- continue;
8602
- }
8603
- if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8840
+ } else if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
8604
8841
  if (value) {
8605
8842
  const subRow = this.dialect.transformOutput(value, "Json", false);
8606
8843
  const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
@@ -8609,26 +8846,28 @@ var ResultProcessor = class {
8609
8846
  delete data[key];
8610
8847
  continue;
8611
8848
  }
8612
- const processedSubRow = this.processRow(subRow, subModel);
8849
+ const subFields = this.resolveFields(subRow, subModel);
8850
+ const processedSubRow = this.processRow(subRow, subFields);
8613
8851
  Object.assign(data, processedSubRow);
8614
8852
  }
8615
8853
  delete data[key];
8616
- continue;
8617
8854
  }
8618
- const fieldDef = getField(this.schema, model, key);
8619
- if (!fieldDef) {
8855
+ }
8856
+ for (const fieldDef of fields) {
8857
+ const value = data[fieldDef.name];
8858
+ if (value === void 0) {
8620
8859
  continue;
8621
8860
  }
8622
8861
  if (value === null) {
8623
- if (fieldDef.array && !fieldDef.relation && value === null) {
8624
- data[key] = [];
8862
+ if (fieldDef.array && !fieldDef.relation) {
8863
+ data[fieldDef.name] = [];
8625
8864
  }
8626
8865
  continue;
8627
8866
  }
8628
8867
  if (fieldDef.relation) {
8629
- data[key] = this.processRelation(value, fieldDef);
8868
+ data[fieldDef.name] = this.processRelation(value, fieldDef);
8630
8869
  } else {
8631
- data[key] = this.processFieldValue(value, fieldDef);
8870
+ data[fieldDef.name] = this.processFieldValue(value, fieldDef);
8632
8871
  }
8633
8872
  }
8634
8873
  return data;
@@ -8734,7 +8973,11 @@ var ClientImpl = class _ClientImpl {
8734
8973
  executor: new import_kysely12.DefaultQueryExecutor(compiler, adapter, connectionProvider, [])
8735
8974
  });
8736
8975
  }
8737
- this.kysely = new import_kysely12.Kysely(this.kyselyProps);
8976
+ if (baseClient?.isTransaction && !executor) {
8977
+ this.kysely = baseClient.$qb;
8978
+ } else {
8979
+ this.kysely = new import_kysely12.Kysely(this.kyselyProps);
8980
+ }
8738
8981
  this.inputValidator = baseClient?.inputValidator ?? new InputValidator(this, {
8739
8982
  enabled: this.$options.validateInput !== false
8740
8983
  });
@@ -8763,7 +9006,7 @@ var ClientImpl = class _ClientImpl {
8763
9006
  for (const [modelName, modelDef] of Object.entries(this.$schema.models)) {
8764
9007
  if (modelDef.computedFields) {
8765
9008
  for (const fieldName of Object.keys(modelDef.computedFields)) {
8766
- const modelConfig = computedFieldsConfig?.[modelName];
9009
+ const modelConfig = computedFieldsConfig?.[(0, import_common_helpers14.lowerCaseFirst)(modelName)] ?? computedFieldsConfig?.[modelName];
8767
9010
  const fieldConfig = modelConfig?.[fieldName];
8768
9011
  if (fieldConfig === null || fieldConfig === void 0) {
8769
9012
  throw createConfigError(`Computed field "${fieldName}" in model "${modelName}" does not have a configuration. Please provide an implementation in the computedFields option.`);
@@ -8972,13 +9215,13 @@ var ClientImpl = class _ClientImpl {
8972
9215
  };
8973
9216
  return this.$setOptions(newOptions);
8974
9217
  }
8975
- async $diagnostics() {
8976
- return {
9218
+ get $diagnostics() {
9219
+ return Promise.resolve({
8977
9220
  zodCache: this.inputValidator.zodFactory.cacheStats,
8978
9221
  slowQueries: this.slowQueries.map((q) => ({
8979
9222
  ...q
8980
9223
  })).sort((a, b) => b.durationMs - a.durationMs)
8981
- };
9224
+ });
8982
9225
  }
8983
9226
  $executeRaw(query, ...values) {
8984
9227
  return createZenStackPromise(async () => {
@@ -9082,26 +9325,34 @@ function isProcedureIncluded(options, procedureName) {
9082
9325
  }
9083
9326
  __name(isProcedureIncluded, "isProcedureIncluded");
9084
9327
  function createModelCrudHandler(client, model, inputValidator, resultProcessor) {
9328
+ const plugins = client.$options.plugins ?? [];
9329
+ const schema = client.$schema;
9330
+ const hasAnyExtResult = hasExtResultFieldDefs(plugins);
9085
9331
  const createPromise = /* @__PURE__ */ __name((operation, nominalOperation, args, handler, postProcess = false, throwIfNoResult = false) => {
9086
9332
  return createZenStackPromise(async (txClient) => {
9087
9333
  let proceed = /* @__PURE__ */ __name(async (_args) => {
9334
+ const shouldApplyExtResult = hasAnyExtResult && EXT_RESULT_OPERATIONS.has(operation);
9335
+ const processedArgs = shouldApplyExtResult ? prepareArgsForExtResult(_args, model, schema, plugins2) : _args;
9088
9336
  const _handler = txClient ? handler.withClient(txClient) : handler;
9089
- const r = await _handler.handle(operation, _args);
9337
+ const r = await _handler.handle(operation, processedArgs);
9090
9338
  if (!r && throwIfNoResult) {
9091
9339
  throw createNotFoundError(model);
9092
9340
  }
9093
9341
  let result;
9094
9342
  if (r && postProcess) {
9095
- result = resultProcessor.processResult(r, model, args);
9343
+ result = resultProcessor.processResult(r, model, processedArgs);
9096
9344
  } else {
9097
9345
  result = r ?? null;
9098
9346
  }
9347
+ if (result && shouldApplyExtResult) {
9348
+ result = applyExtResult(result, model, _args, schema, plugins2);
9349
+ }
9099
9350
  return result;
9100
9351
  }, "proceed");
9101
- const plugins = [
9352
+ const plugins2 = [
9102
9353
  ...client.$options.plugins ?? []
9103
9354
  ];
9104
- for (const plugin of plugins) {
9355
+ for (const plugin of plugins2) {
9105
9356
  const onQuery = plugin.onQuery;
9106
9357
  if (onQuery) {
9107
9358
  const _proceed = proceed;
@@ -9203,13 +9454,241 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
9203
9454
  }
9204
9455
  }
9205
9456
  }
9457
+ const modelDef = requireModel(client.$schema, model);
9458
+ if (Object.values(modelDef.fields).some((f) => isUnsupportedField(f) && !f.optional && !fieldHasDefaultValue(f))) {
9459
+ for (const op of [
9460
+ "create",
9461
+ "createMany",
9462
+ "createManyAndReturn",
9463
+ "upsert"
9464
+ ]) {
9465
+ delete operations[op];
9466
+ }
9467
+ }
9206
9468
  return operations;
9207
9469
  }
9208
9470
  __name(createModelCrudHandler, "createModelCrudHandler");
9471
+ var EXT_RESULT_OPERATIONS = /* @__PURE__ */ new Set([
9472
+ "findMany",
9473
+ "findUnique",
9474
+ "findFirst",
9475
+ "create",
9476
+ "createManyAndReturn",
9477
+ "update",
9478
+ "updateManyAndReturn",
9479
+ "upsert",
9480
+ "delete"
9481
+ ]);
9482
+ function hasExtResultFieldDefs(plugins) {
9483
+ return plugins.some((p) => p.result && Object.keys(p.result).length > 0);
9484
+ }
9485
+ __name(hasExtResultFieldDefs, "hasExtResultFieldDefs");
9486
+ function collectExtResultFieldDefs(model, schema, plugins) {
9487
+ const defs = /* @__PURE__ */ new Map();
9488
+ for (const plugin of plugins) {
9489
+ const resultConfig = plugin.result;
9490
+ if (resultConfig) {
9491
+ const modelConfig = resultConfig[(0, import_common_helpers14.lowerCaseFirst)(model)];
9492
+ if (modelConfig) {
9493
+ for (const [fieldName, fieldDef] of Object.entries(modelConfig)) {
9494
+ if (getField(schema, model, fieldName)) {
9495
+ throw new Error(`Plugin "${plugin.id}" registers ext result field "${fieldName}" on model "${model}" which conflicts with an existing model field`);
9496
+ }
9497
+ for (const needField of Object.keys(fieldDef.needs ?? {})) {
9498
+ const needDef = getField(schema, model, needField);
9499
+ if (!needDef || needDef.relation) {
9500
+ throw new Error(`Plugin "${plugin.id}" registers ext result field "${fieldName}" on model "${model}" with invalid need "${needField}"`);
9501
+ }
9502
+ }
9503
+ defs.set(fieldName, fieldDef);
9504
+ }
9505
+ }
9506
+ }
9507
+ }
9508
+ return defs;
9509
+ }
9510
+ __name(collectExtResultFieldDefs, "collectExtResultFieldDefs");
9511
+ function prepareArgsForExtResult(args, model, schema, plugins) {
9512
+ if (!args || typeof args !== "object") {
9513
+ return args;
9514
+ }
9515
+ const extResultDefs = collectExtResultFieldDefs(model, schema, plugins);
9516
+ const typedArgs = args;
9517
+ let result = typedArgs;
9518
+ let changed = false;
9519
+ const select = typedArgs["select"];
9520
+ const omit = typedArgs["omit"];
9521
+ const include = typedArgs["include"];
9522
+ if (select && extResultDefs.size > 0) {
9523
+ const newSelect = {
9524
+ ...select
9525
+ };
9526
+ for (const [fieldName, fieldDef] of extResultDefs) {
9527
+ if (newSelect[fieldName]) {
9528
+ delete newSelect[fieldName];
9529
+ for (const needField of Object.keys(fieldDef.needs)) {
9530
+ if (!newSelect[needField]) {
9531
+ newSelect[needField] = true;
9532
+ }
9533
+ }
9534
+ }
9535
+ }
9536
+ result = {
9537
+ ...result,
9538
+ select: newSelect
9539
+ };
9540
+ changed = true;
9541
+ }
9542
+ if (omit && extResultDefs.size > 0) {
9543
+ const newOmit = {
9544
+ ...omit
9545
+ };
9546
+ for (const [fieldName, fieldDef] of extResultDefs) {
9547
+ if (newOmit[fieldName]) {
9548
+ delete newOmit[fieldName];
9549
+ } else {
9550
+ for (const needField of Object.keys(fieldDef.needs)) {
9551
+ if (newOmit[needField]) {
9552
+ delete newOmit[needField];
9553
+ }
9554
+ }
9555
+ }
9556
+ }
9557
+ result = {
9558
+ ...result,
9559
+ omit: newOmit
9560
+ };
9561
+ changed = true;
9562
+ }
9563
+ if (include) {
9564
+ const newInclude = {
9565
+ ...include
9566
+ };
9567
+ let includeChanged = false;
9568
+ for (const [field, value] of Object.entries(newInclude)) {
9569
+ if (value && typeof value === "object") {
9570
+ const fieldDef = getField(schema, model, field);
9571
+ if (fieldDef?.relation) {
9572
+ const targetModel = fieldDef.type;
9573
+ const processed = prepareArgsForExtResult(value, targetModel, schema, plugins);
9574
+ if (processed !== value) {
9575
+ newInclude[field] = processed;
9576
+ includeChanged = true;
9577
+ }
9578
+ }
9579
+ }
9580
+ }
9581
+ if (includeChanged) {
9582
+ result = changed ? {
9583
+ ...result,
9584
+ include: newInclude
9585
+ } : {
9586
+ ...typedArgs,
9587
+ include: newInclude
9588
+ };
9589
+ changed = true;
9590
+ }
9591
+ }
9592
+ if (select) {
9593
+ const currentSelect = changed ? result["select"] : select;
9594
+ if (currentSelect) {
9595
+ const newSelect = {
9596
+ ...currentSelect
9597
+ };
9598
+ let selectChanged = false;
9599
+ for (const [field, value] of Object.entries(newSelect)) {
9600
+ if (value && typeof value === "object") {
9601
+ const fieldDef = getField(schema, model, field);
9602
+ if (fieldDef?.relation) {
9603
+ const targetModel = fieldDef.type;
9604
+ const processed = prepareArgsForExtResult(value, targetModel, schema, plugins);
9605
+ if (processed !== value) {
9606
+ newSelect[field] = processed;
9607
+ selectChanged = true;
9608
+ }
9609
+ }
9610
+ }
9611
+ }
9612
+ if (selectChanged) {
9613
+ result = {
9614
+ ...result,
9615
+ select: newSelect
9616
+ };
9617
+ changed = true;
9618
+ }
9619
+ }
9620
+ }
9621
+ return changed ? result : args;
9622
+ }
9623
+ __name(prepareArgsForExtResult, "prepareArgsForExtResult");
9624
+ function applyExtResult(result, model, originalArgs, schema, plugins) {
9625
+ const extResultDefs = collectExtResultFieldDefs(model, schema, plugins);
9626
+ if (Array.isArray(result)) {
9627
+ for (let i = 0; i < result.length; i++) {
9628
+ result[i] = applyExtResultToRow(result[i], model, originalArgs, schema, plugins, extResultDefs);
9629
+ }
9630
+ return result;
9631
+ } else {
9632
+ return applyExtResultToRow(result, model, originalArgs, schema, plugins, extResultDefs);
9633
+ }
9634
+ }
9635
+ __name(applyExtResult, "applyExtResult");
9636
+ function applyExtResultToRow(row, model, originalArgs, schema, plugins, extResultDefs) {
9637
+ if (!row || typeof row !== "object") {
9638
+ return row;
9639
+ }
9640
+ const data = row;
9641
+ const typedArgs = originalArgs && typeof originalArgs === "object" ? originalArgs : {};
9642
+ const select = typedArgs["select"];
9643
+ const omit = typedArgs["omit"];
9644
+ const include = typedArgs["include"];
9645
+ for (const [fieldName, fieldDef] of extResultDefs) {
9646
+ if (select && !select[fieldName]) {
9647
+ continue;
9648
+ }
9649
+ if (omit?.[fieldName]) {
9650
+ continue;
9651
+ }
9652
+ const needsSatisfied = Object.keys(fieldDef.needs).every((needField) => needField in data);
9653
+ if (needsSatisfied) {
9654
+ data[fieldName] = fieldDef.compute(data);
9655
+ }
9656
+ }
9657
+ if (select) {
9658
+ for (const key of Object.keys(data)) {
9659
+ if (!select[key] && !extResultDefs.has(key)) {
9660
+ delete data[key];
9661
+ }
9662
+ }
9663
+ } else if (omit) {
9664
+ for (const key of Object.keys(omit)) {
9665
+ if (omit[key] && !extResultDefs.has(key)) {
9666
+ delete data[key];
9667
+ }
9668
+ }
9669
+ }
9670
+ const relationSource = include ?? select;
9671
+ if (relationSource) {
9672
+ for (const [field, value] of Object.entries(relationSource)) {
9673
+ if (data[field] == null) {
9674
+ continue;
9675
+ }
9676
+ const fieldDef = getField(schema, model, field);
9677
+ if (!fieldDef?.relation) {
9678
+ continue;
9679
+ }
9680
+ const targetModel = fieldDef.type;
9681
+ const nestedArgs = value && typeof value === "object" ? value : void 0;
9682
+ data[field] = applyExtResult(data[field], targetModel, nestedArgs, schema, plugins);
9683
+ }
9684
+ }
9685
+ return data;
9686
+ }
9687
+ __name(applyExtResultToRow, "applyExtResultToRow");
9209
9688
 
9210
9689
  // src/client/plugin.ts
9211
- function definePlugin(plugin) {
9212
- return plugin;
9690
+ function definePlugin(...args) {
9691
+ return args.length === 2 ? args[1] : args[0];
9213
9692
  }
9214
9693
  __name(definePlugin, "definePlugin");
9215
9694
 
@@ -9535,13 +10014,13 @@ __export(schema_utils_exports, {
9535
10014
  ExpressionVisitor: () => ExpressionVisitor,
9536
10015
  MatchingExpressionVisitor: () => MatchingExpressionVisitor
9537
10016
  });
9538
- var import_ts_pattern18 = require("ts-pattern");
10017
+ var import_ts_pattern15 = require("ts-pattern");
9539
10018
  var ExpressionVisitor = class {
9540
10019
  static {
9541
10020
  __name(this, "ExpressionVisitor");
9542
10021
  }
9543
10022
  visit(expr) {
9544
- return (0, import_ts_pattern18.match)(expr).with({
10023
+ return (0, import_ts_pattern15.match)(expr).with({
9545
10024
  kind: "literal"
9546
10025
  }, (e) => this.visitLiteral(e)).with({
9547
10026
  kind: "array"