@zenstackhq/orm 3.5.0-beta.3 → 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 +806 -327
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +251 -82
- package/dist/index.d.ts +251 -82
- package/dist/index.js +812 -333
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
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
|
|
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
|
|
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
|
|
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
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
if (this.shouldOmitField(omit, model,
|
|
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,
|
|
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((
|
|
1474
|
+
result = result.select(() => {
|
|
1469
1475
|
const jsonObject = {};
|
|
1470
|
-
for (const
|
|
1471
|
-
|
|
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[
|
|
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
|
-
|
|
1486
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1808
|
-
|
|
1809
|
-
return value
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1931
|
-
|
|
1932
|
-
value
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
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,
|
|
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
|
-
|
|
2006
|
-
|
|
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
|
-
|
|
2064
|
-
|
|
2065
|
-
return
|
|
2066
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2186
|
-
|
|
2187
|
-
value
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
2900
|
-
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
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
|
|
2923
|
-
A:
|
|
2924
|
-
B:
|
|
2925
|
-
})
|
|
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
|
|
2933
|
-
|
|
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,
|
|
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
|
-
|
|
3251
|
-
|
|
3252
|
-
if (
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
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
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
if
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
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 =
|
|
3284
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
3332
|
-
|
|
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,
|
|
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,
|
|
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
|
|
3700
|
-
|
|
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
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
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
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
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
|
-
|
|
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:
|
|
4268
|
+
selectedFields: idFields
|
|
4126
4269
|
};
|
|
4127
4270
|
}
|
|
4128
4271
|
if (!this.dialect.supportsReturning) {
|
|
4129
4272
|
return {
|
|
4130
4273
|
needReadBack: true,
|
|
4131
|
-
selectedFields:
|
|
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:
|
|
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:
|
|
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:
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
...
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
6143
|
-
|
|
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,
|
|
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
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
7387
|
-
|
|
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.
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
8807
|
+
data.forEach((row, i) => data[i] = this.processRow(row, fields));
|
|
8586
8808
|
return data;
|
|
8587
8809
|
} else {
|
|
8588
|
-
return this.processRow(data,
|
|
8810
|
+
return this.processRow(data, fields);
|
|
8589
8811
|
}
|
|
8590
8812
|
}
|
|
8591
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
8619
|
-
|
|
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
|
|
8624
|
-
data[
|
|
8862
|
+
if (fieldDef.array && !fieldDef.relation) {
|
|
8863
|
+
data[fieldDef.name] = [];
|
|
8625
8864
|
}
|
|
8626
8865
|
continue;
|
|
8627
8866
|
}
|
|
8628
8867
|
if (fieldDef.relation) {
|
|
8629
|
-
data[
|
|
8868
|
+
data[fieldDef.name] = this.processRelation(value, fieldDef);
|
|
8630
8869
|
} else {
|
|
8631
|
-
data[
|
|
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
|
-
|
|
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.`);
|
|
@@ -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,
|
|
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,
|
|
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
|
|
9352
|
+
const plugins2 = [
|
|
9102
9353
|
...client.$options.plugins ?? []
|
|
9103
9354
|
];
|
|
9104
|
-
for (const plugin of
|
|
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(
|
|
9212
|
-
return
|
|
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
|
|
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,
|
|
10023
|
+
return (0, import_ts_pattern15.match)(expr).with({
|
|
9545
10024
|
kind: "literal"
|
|
9546
10025
|
}, (e) => this.visitLiteral(e)).with({
|
|
9547
10026
|
kind: "array"
|