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