@zenstackhq/orm 3.6.4 → 3.7.0
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/common-types.cjs +23 -0
- package/dist/common-types.cjs.map +1 -0
- package/dist/common-types.d.cts +25 -0
- package/dist/common-types.d.mts +25 -0
- package/dist/common-types.mjs +17 -0
- package/dist/common-types.mjs.map +1 -0
- package/dist/index.cjs +408 -111
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +364 -69
- package/dist/index.d.mts +366 -71
- package/dist/index.mjs +534 -239
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -10
package/dist/index.cjs
CHANGED
|
@@ -30,6 +30,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
30
30
|
enumerable: true
|
|
31
31
|
}) : target, mod));
|
|
32
32
|
//#endregion
|
|
33
|
+
const require_common_types = require("./common-types.cjs");
|
|
33
34
|
let _zenstackhq_common_helpers = require("@zenstackhq/common-helpers");
|
|
34
35
|
let kysely = require("kysely");
|
|
35
36
|
let zod = require("zod");
|
|
@@ -567,6 +568,8 @@ const FILTER_PROPERTY_TO_KIND = {
|
|
|
567
568
|
array_contains: "Json",
|
|
568
569
|
array_starts_with: "Json",
|
|
569
570
|
array_ends_with: "Json",
|
|
571
|
+
fuzzy: "Fuzzy",
|
|
572
|
+
fts: "FullText",
|
|
570
573
|
has: "List",
|
|
571
574
|
hasEvery: "List",
|
|
572
575
|
hasSome: "List",
|
|
@@ -586,6 +589,19 @@ let TransactionIsolationLevel = /* @__PURE__ */ function(TransactionIsolationLev
|
|
|
586
589
|
return TransactionIsolationLevel;
|
|
587
590
|
}({});
|
|
588
591
|
/**
|
|
592
|
+
* Symbol used as a type-only key on `ClientContract` to brand the `ExtQueryArgs`
|
|
593
|
+
* generic slot. Hidden from member-access autocomplete since symbol keys are
|
|
594
|
+
* not surfaced. Consumed by `InferExtQueryArgs` to recover the slot.
|
|
595
|
+
* @internal
|
|
596
|
+
*/
|
|
597
|
+
const ExtQueryArgsMarker = Symbol("zenstack.client.extQueryArgs");
|
|
598
|
+
/**
|
|
599
|
+
* Symbol used as a type-only key on `ClientContract` to brand the `ExtResult`
|
|
600
|
+
* generic slot. Consumed by `InferExtResult` to recover the slot.
|
|
601
|
+
* @internal
|
|
602
|
+
*/
|
|
603
|
+
const ExtResultMarker = Symbol("zenstack.client.extResult");
|
|
604
|
+
/**
|
|
589
605
|
* CRUD operations.
|
|
590
606
|
*/
|
|
591
607
|
const CRUD = [
|
|
@@ -599,20 +615,6 @@ const CRUD = [
|
|
|
599
615
|
*/
|
|
600
616
|
const CRUD_EXT = [...CRUD, "post-update"];
|
|
601
617
|
//#endregion
|
|
602
|
-
//#region src/common-types.ts
|
|
603
|
-
var DbNullClass = class {
|
|
604
|
-
__brand = "DbNull";
|
|
605
|
-
};
|
|
606
|
-
const DbNull = new DbNullClass();
|
|
607
|
-
var JsonNullClass = class {
|
|
608
|
-
__brand = "JsonNull";
|
|
609
|
-
};
|
|
610
|
-
const JsonNull = new JsonNullClass();
|
|
611
|
-
var AnyNullClass = class {
|
|
612
|
-
__brand = "AnyNull";
|
|
613
|
-
};
|
|
614
|
-
const AnyNull = new AnyNullClass();
|
|
615
|
-
//#endregion
|
|
616
618
|
//#region src/client/crud/dialects/base-dialect.ts
|
|
617
619
|
var BaseCrudDialect = class {
|
|
618
620
|
eb = (0, kysely.expressionBuilder)();
|
|
@@ -622,8 +624,13 @@ var BaseCrudDialect = class {
|
|
|
622
624
|
}
|
|
623
625
|
/**
|
|
624
626
|
* Transforms input value before sending to database.
|
|
627
|
+
*
|
|
628
|
+
* `fieldDef` is optional so existing callers that don't have it stay
|
|
629
|
+
* source-compatible. Dialects can use it to inspect `@db.*` native-type
|
|
630
|
+
* attributes (e.g. to format `@db.Time` values as `HH:MM:SS` rather than
|
|
631
|
+
* full ISO timestamps).
|
|
625
632
|
*/
|
|
626
|
-
transformInput(value, _type, _forArrayField) {
|
|
633
|
+
transformInput(value, _type, _forArrayField, _fieldDef) {
|
|
627
634
|
return value;
|
|
628
635
|
}
|
|
629
636
|
/**
|
|
@@ -666,7 +673,17 @@ var BaseCrudDialect = class {
|
|
|
666
673
|
if (existingOrderBy.length > 0 && !alreadySatisfied) effectiveOrderBy = [...distinctFields.map((f) => ({ [f]: "asc" })), ...existingOrderBy];
|
|
667
674
|
}
|
|
668
675
|
result = this.buildOrderBy(result, model, modelAlias, effectiveOrderBy, negateOrderBy, take);
|
|
669
|
-
if (args.cursor)
|
|
676
|
+
if (args.cursor) {
|
|
677
|
+
if (effectiveOrderBy) {
|
|
678
|
+
const offendingKey = (0, _zenstackhq_common_helpers.enumerate)(effectiveOrderBy).map((ob) => {
|
|
679
|
+
if (typeof ob !== "object" || ob === null) return void 0;
|
|
680
|
+
if ("_fuzzyRelevance" in ob) return "_fuzzyRelevance";
|
|
681
|
+
if ("_ftsRelevance" in ob) return "_ftsRelevance";
|
|
682
|
+
}).find((k) => k !== void 0);
|
|
683
|
+
if (offendingKey) throw createNotSupportedError(`cursor pagination cannot be combined with "${offendingKey}" ordering`);
|
|
684
|
+
}
|
|
685
|
+
result = this.buildCursorFilter(model, result, args.cursor, effectiveOrderBy, negateOrderBy, modelAlias);
|
|
686
|
+
}
|
|
670
687
|
return result;
|
|
671
688
|
}
|
|
672
689
|
buildFilter(model, modelAlias, where) {
|
|
@@ -806,7 +823,7 @@ var BaseCrudDialect = class {
|
|
|
806
823
|
for (const [key, _value] of Object.entries(payload)) {
|
|
807
824
|
if (_value === void 0) continue;
|
|
808
825
|
(0, _zenstackhq_common_helpers.invariant)(fieldDef.array, "Field must be an array type to build array filter");
|
|
809
|
-
const value = this.transformInput(_value, fieldType, true);
|
|
826
|
+
const value = this.transformInput(_value, fieldType, true, fieldDef);
|
|
810
827
|
let receiver = fieldRef;
|
|
811
828
|
if (isEnum(this.schema, fieldType)) receiver = this.eb.cast(fieldRef, kysely.sql.raw("text[]"));
|
|
812
829
|
const buildArray = (value) => {
|
|
@@ -838,10 +855,10 @@ var BaseCrudDialect = class {
|
|
|
838
855
|
if (payload === null) return this.eb(fieldRef, "is", null);
|
|
839
856
|
if (isEnum(this.schema, fieldDef.type)) return this.buildEnumFilter(fieldRef, fieldDef, payload);
|
|
840
857
|
if (isTypeDef(this.schema, fieldDef.type)) {
|
|
841
|
-
if (payload instanceof DbNullClass || payload instanceof JsonNullClass || payload instanceof AnyNullClass) return this.buildJsonValueFilterClause(fieldRef, payload);
|
|
858
|
+
if (payload instanceof require_common_types.DbNullClass || payload instanceof require_common_types.JsonNullClass || payload instanceof require_common_types.AnyNullClass) return this.buildJsonValueFilterClause(fieldRef, payload);
|
|
842
859
|
return this.buildJsonFilter(fieldRef, payload, fieldDef);
|
|
843
860
|
}
|
|
844
|
-
return (0, ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(fieldRef, payload)).with(ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(fieldRef, payload)).with("Json", () => this.buildJsonFilter(fieldRef, payload, fieldDef)).with("Unsupported", () => {
|
|
861
|
+
return (0, ts_pattern.match)(fieldDef.type).with("String", () => this.buildStringFilter(fieldRef, payload, fieldDef)).with(ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(fieldRef, payload)).with("Json", () => this.buildJsonFilter(fieldRef, payload, fieldDef)).with("Unsupported", () => {
|
|
845
862
|
throw createInvalidInputError(`Unsupported field cannot be used in filters`);
|
|
846
863
|
}).exhaustive();
|
|
847
864
|
}
|
|
@@ -953,9 +970,9 @@ var BaseCrudDialect = class {
|
|
|
953
970
|
return this.and(...clauses);
|
|
954
971
|
}
|
|
955
972
|
buildJsonValueFilterClause(lhs, value) {
|
|
956
|
-
if (value instanceof DbNullClass) return this.eb(lhs, "is", null);
|
|
957
|
-
else if (value instanceof JsonNullClass) return this.eb.and([this.eb(lhs, "=", this.transformInput(null, "Json", false)), this.eb(lhs, "is not", null)]);
|
|
958
|
-
else if (value instanceof AnyNullClass) return this.eb.or([this.eb(lhs, "is", null), this.eb(lhs, "=", this.transformInput(null, "Json", false))]);
|
|
973
|
+
if (value instanceof require_common_types.DbNullClass) return this.eb(lhs, "is", null);
|
|
974
|
+
else if (value instanceof require_common_types.JsonNullClass) return this.eb.and([this.eb(lhs, "=", this.transformInput(null, "Json", false)), this.eb(lhs, "is not", null)]);
|
|
975
|
+
else if (value instanceof require_common_types.AnyNullClass) return this.eb.or([this.eb(lhs, "is", null), this.eb(lhs, "=", this.transformInput(null, "Json", false))]);
|
|
959
976
|
else return this.buildJsonEqualityFilter(lhs, value);
|
|
960
977
|
}
|
|
961
978
|
buildJsonEqualityFilter(lhs, rhs) {
|
|
@@ -1009,13 +1026,23 @@ var BaseCrudDialect = class {
|
|
|
1009
1026
|
consumedKeys
|
|
1010
1027
|
};
|
|
1011
1028
|
}
|
|
1012
|
-
buildStringFilter(fieldRef, payload) {
|
|
1029
|
+
buildStringFilter(fieldRef, payload, fieldDef) {
|
|
1013
1030
|
let mode;
|
|
1014
1031
|
if (payload && typeof payload === "object" && "mode" in payload) mode = payload.mode;
|
|
1015
|
-
const { conditions, consumedKeys } = this.buildStandardFilter("String", payload, mode === "insensitive" ? this.eb.fn("lower", [fieldRef]) : fieldRef, (value) => this.prepStringCasing(this.eb, value, mode), (value) => this.buildStringFilter(fieldRef, value));
|
|
1032
|
+
const { conditions, consumedKeys } = this.buildStandardFilter("String", payload, mode === "insensitive" ? this.eb.fn("lower", [fieldRef]) : fieldRef, (value) => this.prepStringCasing(this.eb, value, mode), (value) => this.buildStringFilter(fieldRef, value, fieldDef));
|
|
1016
1033
|
if (payload && typeof payload === "object") for (const [key, value] of Object.entries(payload)) {
|
|
1017
1034
|
if (key === "mode" || consumedKeys.includes(key)) continue;
|
|
1018
1035
|
if (value === void 0) continue;
|
|
1036
|
+
if (key === "fuzzy") {
|
|
1037
|
+
(0, _zenstackhq_common_helpers.invariant)(fieldDef?.fuzzy === true, `field "${fieldDef?.name ?? "<unknown>"}" is not fuzzy-searchable; add the \`@fuzzy\` attribute to use the \`fuzzy\` filter`);
|
|
1038
|
+
conditions.push(this.buildFuzzyFilter(fieldRef, this.normalizeFuzzyOptions(value)));
|
|
1039
|
+
continue;
|
|
1040
|
+
}
|
|
1041
|
+
if (key === "fts") {
|
|
1042
|
+
(0, _zenstackhq_common_helpers.invariant)(fieldDef?.fullText === true, `field "${fieldDef?.name ?? "<unknown>"}" is not full-text-searchable; add the \`@fullText\` attribute to use the \`fts\` filter`);
|
|
1043
|
+
conditions.push(this.buildFullTextFilter(fieldRef, value));
|
|
1044
|
+
continue;
|
|
1045
|
+
}
|
|
1019
1046
|
(0, _zenstackhq_common_helpers.invariant)(typeof value === "string", `${key} value must be a string`);
|
|
1020
1047
|
const escapedValue = this.escapeLikePattern(value);
|
|
1021
1048
|
const condition = (0, ts_pattern.match)(key).with("contains", () => this.buildStringLike(fieldRef, `%${escapedValue}%`, mode === "insensitive")).with("startsWith", () => this.buildStringLike(fieldRef, `${escapedValue}%`, mode === "insensitive")).with("endsWith", () => this.buildStringLike(fieldRef, `%${escapedValue}`, mode === "insensitive")).otherwise(() => {
|
|
@@ -1084,6 +1111,14 @@ var BaseCrudDialect = class {
|
|
|
1084
1111
|
(0, _zenstackhq_common_helpers.enumerate)(orderBy).forEach((orderBy, index) => {
|
|
1085
1112
|
for (const [field, value] of Object.entries(orderBy)) {
|
|
1086
1113
|
if (!value) continue;
|
|
1114
|
+
if (field === "_fuzzyRelevance") {
|
|
1115
|
+
result = this.applyFuzzyRelevanceOrderBy(result, model, modelAlias, value, negated, buildFieldRef);
|
|
1116
|
+
continue;
|
|
1117
|
+
}
|
|
1118
|
+
if (field === "_ftsRelevance") {
|
|
1119
|
+
result = this.applyFtsRelevanceOrderBy(result, model, modelAlias, value, negated, buildFieldRef);
|
|
1120
|
+
continue;
|
|
1121
|
+
}
|
|
1087
1122
|
if ([
|
|
1088
1123
|
"_count",
|
|
1089
1124
|
"_avg",
|
|
@@ -1091,47 +1126,84 @@ var BaseCrudDialect = class {
|
|
|
1091
1126
|
"_min",
|
|
1092
1127
|
"_max"
|
|
1093
1128
|
].includes(field)) {
|
|
1094
|
-
|
|
1095
|
-
for (const [k, v] of Object.entries(value)) {
|
|
1096
|
-
(0, _zenstackhq_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
1097
|
-
result = result.orderBy((eb) => aggregate(eb, buildFieldRef(model, k, modelAlias), field), this.negateSort(v, negated));
|
|
1098
|
-
}
|
|
1129
|
+
result = this.applyAggregationOrderBy(result, model, modelAlias, field, value, negated, buildFieldRef);
|
|
1099
1130
|
continue;
|
|
1100
1131
|
}
|
|
1101
1132
|
const fieldDef = requireField(this.schema, model, field);
|
|
1102
|
-
if (!fieldDef.relation)
|
|
1103
|
-
|
|
1104
|
-
if (value === "asc" || value === "desc") result = result.orderBy(fieldRef, this.negateSort(value, negated));
|
|
1105
|
-
else if (typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) result = this.buildOrderByField(result, fieldRef, this.negateSort(value.sort, negated), value.nulls);
|
|
1106
|
-
} else {
|
|
1107
|
-
const relationModel = fieldDef.type;
|
|
1108
|
-
if (fieldDef.array) {
|
|
1109
|
-
if (typeof value !== "object") throw createInvalidInputError(`invalid orderBy value for field "${field}"`);
|
|
1110
|
-
if ("_count" in value) {
|
|
1111
|
-
(0, _zenstackhq_common_helpers.invariant)(value._count === "asc" || value._count === "desc", "invalid orderBy value for field \"_count\"");
|
|
1112
|
-
const sort = this.negateSort(value._count, negated);
|
|
1113
|
-
result = result.orderBy((eb) => {
|
|
1114
|
-
const subQueryAlias = tmpAlias(`${modelAlias}$ob$${field}$ct`);
|
|
1115
|
-
let subQuery = this.buildSelectModel(relationModel, subQueryAlias);
|
|
1116
|
-
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
|
|
1117
|
-
subQuery = subQuery.where(() => this.and(...joinPairs.map(([left, right]) => eb(this.eb.ref(left), "=", this.eb.ref(right)))));
|
|
1118
|
-
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
1119
|
-
return subQuery;
|
|
1120
|
-
}, sort);
|
|
1121
|
-
}
|
|
1122
|
-
} else {
|
|
1123
|
-
const joinAlias = tmpAlias(`${modelAlias}$ob$${index}`);
|
|
1124
|
-
result = result.leftJoin(`${relationModel} as ${joinAlias}`, (join) => {
|
|
1125
|
-
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, joinAlias);
|
|
1126
|
-
return join.on((eb) => this.and(...joinPairs.map(([left, right]) => eb(this.eb.ref(left), "=", this.eb.ref(right)))));
|
|
1127
|
-
});
|
|
1128
|
-
result = this.buildOrderBy(result, relationModel, joinAlias, value, negated, take);
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1133
|
+
if (!fieldDef.relation) result = this.applyScalarOrderBy(result, model, modelAlias, field, value, negated, buildFieldRef);
|
|
1134
|
+
else result = this.applyRelationOrderBy(result, model, modelAlias, field, fieldDef, value, negated, take, index);
|
|
1131
1135
|
}
|
|
1132
1136
|
});
|
|
1133
1137
|
return result;
|
|
1134
1138
|
}
|
|
1139
|
+
applyRelationOrderBy(query, model, modelAlias, field, fieldDef, value, negated, take, index) {
|
|
1140
|
+
const relationModel = fieldDef.type;
|
|
1141
|
+
if (fieldDef.array) {
|
|
1142
|
+
if (typeof value !== "object") throw createInvalidInputError(`invalid orderBy value for field "${field}"`);
|
|
1143
|
+
if ("_count" in value) {
|
|
1144
|
+
(0, _zenstackhq_common_helpers.invariant)(value._count === "asc" || value._count === "desc", "invalid orderBy value for field \"_count\"");
|
|
1145
|
+
const sort = this.negateSort(value._count, negated);
|
|
1146
|
+
return query.orderBy((eb) => {
|
|
1147
|
+
const subQueryAlias = tmpAlias(`${modelAlias}$ob$${field}$ct`);
|
|
1148
|
+
let subQuery = this.buildSelectModel(relationModel, subQueryAlias);
|
|
1149
|
+
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
|
|
1150
|
+
subQuery = subQuery.where(() => this.and(...joinPairs.map(([left, right]) => eb(this.eb.ref(left), "=", this.eb.ref(right)))));
|
|
1151
|
+
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
1152
|
+
return subQuery;
|
|
1153
|
+
}, sort);
|
|
1154
|
+
}
|
|
1155
|
+
return query;
|
|
1156
|
+
}
|
|
1157
|
+
const joinAlias = tmpAlias(`${modelAlias}$ob$${index}`);
|
|
1158
|
+
const joined = query.leftJoin(`${relationModel} as ${joinAlias}`, (join) => {
|
|
1159
|
+
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, joinAlias);
|
|
1160
|
+
return join.on((eb) => this.and(...joinPairs.map(([left, right]) => eb(this.eb.ref(left), "=", this.eb.ref(right)))));
|
|
1161
|
+
});
|
|
1162
|
+
return this.buildOrderBy(joined, relationModel, joinAlias, value, negated, take);
|
|
1163
|
+
}
|
|
1164
|
+
applyScalarOrderBy(query, model, modelAlias, field, value, negated, buildFieldRef) {
|
|
1165
|
+
const fieldRef = buildFieldRef(model, field, modelAlias);
|
|
1166
|
+
if (value === "asc" || value === "desc") return query.orderBy(fieldRef, this.negateSort(value, negated));
|
|
1167
|
+
if (typeof value === "object" && "sort" in value && (value.sort === "asc" || value.sort === "desc")) {
|
|
1168
|
+
const sort = this.negateSort(value.sort, negated);
|
|
1169
|
+
if (value.nulls === "first" || value.nulls === "last") return this.buildOrderByField(query, fieldRef, sort, value.nulls);
|
|
1170
|
+
else return query.orderBy(fieldRef, sort);
|
|
1171
|
+
}
|
|
1172
|
+
return query;
|
|
1173
|
+
}
|
|
1174
|
+
applyAggregationOrderBy(query, model, modelAlias, field, value, negated, buildFieldRef) {
|
|
1175
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
1176
|
+
let result = query;
|
|
1177
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1178
|
+
(0, _zenstackhq_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
1179
|
+
result = result.orderBy((eb) => aggregate(eb, buildFieldRef(model, k, modelAlias), field), this.negateSort(v, negated));
|
|
1180
|
+
}
|
|
1181
|
+
return result;
|
|
1182
|
+
}
|
|
1183
|
+
applyFuzzyRelevanceOrderBy(query, model, modelAlias, value, negated, buildFieldRef) {
|
|
1184
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof value === "object" && "fields" in value && "search" in value && "sort" in value, "invalid orderBy value for \"_fuzzyRelevance\"");
|
|
1185
|
+
(0, _zenstackhq_common_helpers.invariant)(Array.isArray(value.fields) && value.fields.length > 0, "_fuzzyRelevance.fields must be a non-empty array");
|
|
1186
|
+
(0, _zenstackhq_common_helpers.invariant)(value.sort === "asc" || value.sort === "desc", "invalid sort value for \"_fuzzyRelevance\"");
|
|
1187
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof value.search === "string" && value.search.length > 0, "_fuzzyRelevance.search must be a non-empty string");
|
|
1188
|
+
const mode = value.mode ?? "simple";
|
|
1189
|
+
(0, _zenstackhq_common_helpers.invariant)(mode === "simple" || mode === "word" || mode === "strictWord", "_fuzzyRelevance.mode must be \"simple\", \"word\" or \"strictWord\"");
|
|
1190
|
+
const unaccent = value.unaccent ?? false;
|
|
1191
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof unaccent === "boolean", "_fuzzyRelevance.unaccent must be a boolean");
|
|
1192
|
+
for (const fieldName of value.fields) (0, _zenstackhq_common_helpers.invariant)(requireField(this.schema, model, fieldName).fuzzy === true, `field "${fieldName}" is not fuzzy-searchable; add the \`@fuzzy\` attribute to use it in \`_fuzzyRelevance\``);
|
|
1193
|
+
const fieldRefs = value.fields.map((f) => buildFieldRef(model, f, modelAlias));
|
|
1194
|
+
return this.buildFuzzyRelevanceOrderBy(query, fieldRefs, value.search, this.negateSort(value.sort, negated), mode, unaccent);
|
|
1195
|
+
}
|
|
1196
|
+
applyFtsRelevanceOrderBy(query, model, modelAlias, value, negated, buildFieldRef) {
|
|
1197
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof value === "object" && "fields" in value && "search" in value && "sort" in value, "invalid orderBy value for \"_ftsRelevance\"");
|
|
1198
|
+
(0, _zenstackhq_common_helpers.invariant)(Array.isArray(value.fields) && value.fields.length > 0, "_ftsRelevance.fields must be a non-empty array");
|
|
1199
|
+
(0, _zenstackhq_common_helpers.invariant)(value.sort === "asc" || value.sort === "desc", "invalid sort value for \"_ftsRelevance\"");
|
|
1200
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof value.search === "string" && value.search.length > 0, "_ftsRelevance.search must be a non-empty string");
|
|
1201
|
+
if (value.config !== void 0) (0, _zenstackhq_common_helpers.invariant)(typeof value.config === "string" && value.config.length > 0, "_ftsRelevance.config must be a non-empty string");
|
|
1202
|
+
const config = value.config;
|
|
1203
|
+
for (const fieldName of value.fields) (0, _zenstackhq_common_helpers.invariant)(requireField(this.schema, model, fieldName).fullText === true, `field "${fieldName}" is not full-text-searchable; add the \`@fullText\` attribute to use it in \`_ftsRelevance\``);
|
|
1204
|
+
const fieldRefs = value.fields.map((f) => buildFieldRef(model, f, modelAlias));
|
|
1205
|
+
return this.buildFtsRelevanceOrderBy(query, fieldRefs, value.search, config, this.negateSort(value.sort, negated));
|
|
1206
|
+
}
|
|
1135
1207
|
buildSelectAllFields(model, query, omit, modelAlias) {
|
|
1136
1208
|
let result = query;
|
|
1137
1209
|
for (const fieldDef of getModelFields(this.schema, model, {
|
|
@@ -1274,6 +1346,27 @@ var BaseCrudDialect = class {
|
|
|
1274
1346
|
buildComparison(left, _leftFieldDef, op, right, _rightFieldDef) {
|
|
1275
1347
|
return this.eb(left, op, right);
|
|
1276
1348
|
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Validate the user-provided fuzzy filter payload and apply defaults so dialects
|
|
1351
|
+
* always receive a fully-resolved {@link FuzzyFilterOptions} value.
|
|
1352
|
+
*/
|
|
1353
|
+
normalizeFuzzyOptions(value) {
|
|
1354
|
+
(0, _zenstackhq_common_helpers.invariant)(value !== null && typeof value === "object" && !Array.isArray(value), "fuzzy filter must be an object with at least a \"search\" field");
|
|
1355
|
+
const raw = value;
|
|
1356
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof raw["search"] === "string" && raw["search"].length > 0, "fuzzy.search must be a non-empty string");
|
|
1357
|
+
const mode = raw["mode"] ?? "simple";
|
|
1358
|
+
(0, _zenstackhq_common_helpers.invariant)(mode === "simple" || mode === "word" || mode === "strictWord", "fuzzy.mode must be \"simple\", \"word\" or \"strictWord\"");
|
|
1359
|
+
const threshold = raw["threshold"];
|
|
1360
|
+
if (threshold !== void 0) (0, _zenstackhq_common_helpers.invariant)(typeof threshold === "number" && threshold >= 0 && threshold <= 1, "fuzzy.threshold must be a number between 0 and 1");
|
|
1361
|
+
const unaccent = raw["unaccent"] ?? false;
|
|
1362
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof unaccent === "boolean", "fuzzy.unaccent must be a boolean");
|
|
1363
|
+
return {
|
|
1364
|
+
search: raw["search"],
|
|
1365
|
+
mode,
|
|
1366
|
+
threshold,
|
|
1367
|
+
unaccent
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1277
1370
|
};
|
|
1278
1371
|
//#endregion
|
|
1279
1372
|
//#region src/client/crud/dialects/lateral-join-dialect-base.ts
|
|
@@ -1422,9 +1515,9 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
1422
1515
|
}
|
|
1423
1516
|
transformInput(value, type, forArrayField) {
|
|
1424
1517
|
if (value === void 0) return value;
|
|
1425
|
-
if (value instanceof JsonNullClass) return this.eb.cast(kysely.sql.lit("null"), "json");
|
|
1426
|
-
else if (value instanceof DbNullClass) return null;
|
|
1427
|
-
else if (value instanceof AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1518
|
+
if (value instanceof require_common_types.JsonNullClass) return this.eb.cast(kysely.sql.lit("null"), "json");
|
|
1519
|
+
else if (value instanceof require_common_types.DbNullClass) return null;
|
|
1520
|
+
else if (value instanceof require_common_types.AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1428
1521
|
if (isTypeDef(this.schema, type)) if (typeof value !== "string") return this.transformInput(value, "Json", forArrayField);
|
|
1429
1522
|
else return value;
|
|
1430
1523
|
else if (Array.isArray(value)) if (type === "Json") return JSON.stringify(value);
|
|
@@ -1558,9 +1651,32 @@ var MySqlCrudDialect = class extends LateralJoinDialectBase {
|
|
|
1558
1651
|
}
|
|
1559
1652
|
return result;
|
|
1560
1653
|
}
|
|
1654
|
+
buildFuzzyFilter(_fieldRef, _options) {
|
|
1655
|
+
throw createNotSupportedError("\"fuzzy\" filter is not supported by the \"mysql\" provider");
|
|
1656
|
+
}
|
|
1657
|
+
buildFuzzyRelevanceOrderBy(_query, _fieldRefs, _search, _sort, _mode, _unaccent) {
|
|
1658
|
+
throw createNotSupportedError("\"_fuzzyRelevance\" ordering is not supported by the \"mysql\" provider");
|
|
1659
|
+
}
|
|
1660
|
+
buildFullTextFilter(_fieldRef, _payload) {
|
|
1661
|
+
throw createNotSupportedError("\"fts\" filter is not supported by the \"mysql\" provider");
|
|
1662
|
+
}
|
|
1663
|
+
buildFtsRelevanceOrderBy(_query, _fieldRefs, _search, _config, _sort) {
|
|
1664
|
+
throw createNotSupportedError("\"_ftsRelevance\" ordering is not supported by the \"mysql\" provider");
|
|
1665
|
+
}
|
|
1561
1666
|
};
|
|
1562
1667
|
//#endregion
|
|
1563
1668
|
//#region src/client/crud/dialects/postgresql.ts
|
|
1669
|
+
/**
|
|
1670
|
+
* Formats a JS `Date` as a Postgres TIME / TIMETZ literal (`HH:MM:SS.fff`,
|
|
1671
|
+
* optionally with `+ZZ:ZZ` for TIMETZ). Reads UTC components so the value
|
|
1672
|
+
* round-trips with ISO-input parsing — callers anchor time-only inputs to
|
|
1673
|
+
* the Unix epoch.
|
|
1674
|
+
*/
|
|
1675
|
+
function formatTimeOfDay(date, withTimezone) {
|
|
1676
|
+
const pad = (n, w = 2) => String(n).padStart(w, "0");
|
|
1677
|
+
const time = `${pad(date.getUTCHours())}:${pad(date.getUTCMinutes())}:${pad(date.getUTCSeconds())}.${pad(date.getUTCMilliseconds(), 3)}`;
|
|
1678
|
+
return withTimezone ? `${time}+00:00` : time;
|
|
1679
|
+
}
|
|
1564
1680
|
var PostgresCrudDialect = class PostgresCrudDialect extends LateralJoinDialectBase {
|
|
1565
1681
|
static typeParserOverrideApplied = false;
|
|
1566
1682
|
zmodelToSqlTypeMap = {
|
|
@@ -1654,17 +1770,23 @@ var PostgresCrudDialect = class PostgresCrudDialect extends LateralJoinDialectBa
|
|
|
1654
1770
|
get insertIgnoreMethod() {
|
|
1655
1771
|
return "onConflict";
|
|
1656
1772
|
}
|
|
1657
|
-
transformInput(value, type, forArrayField) {
|
|
1773
|
+
transformInput(value, type, forArrayField, fieldDef) {
|
|
1658
1774
|
if (value === void 0) return value;
|
|
1659
|
-
if (value instanceof JsonNullClass) return "null";
|
|
1660
|
-
else if (value instanceof DbNullClass) return null;
|
|
1661
|
-
else if (value instanceof AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1775
|
+
if (value instanceof require_common_types.JsonNullClass) return "null";
|
|
1776
|
+
else if (value instanceof require_common_types.DbNullClass) return null;
|
|
1777
|
+
else if (value instanceof require_common_types.AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1662
1778
|
if (isTypeDef(this.schema, type)) if (typeof value !== "string") return JSON.stringify(value);
|
|
1663
1779
|
else return value;
|
|
1664
1780
|
else if (Array.isArray(value)) if (type === "Json" && !forArrayField) return JSON.stringify(value);
|
|
1665
|
-
else return value.map((v) => this.transformInput(v, type, false));
|
|
1781
|
+
else return value.map((v) => this.transformInput(v, type, false, fieldDef));
|
|
1666
1782
|
else switch (type) {
|
|
1667
|
-
case "DateTime":
|
|
1783
|
+
case "DateTime": {
|
|
1784
|
+
const date = value instanceof Date ? value : typeof value === "string" ? new Date(value) : null;
|
|
1785
|
+
if (date === null || isNaN(date.getTime())) return value;
|
|
1786
|
+
const dbAttrName = fieldDef?.attributes?.find((a) => a.name.startsWith("@db."))?.name;
|
|
1787
|
+
if (dbAttrName === "@db.Time" || dbAttrName === "@db.Timetz") return formatTimeOfDay(date, dbAttrName === "@db.Timetz");
|
|
1788
|
+
return date.toISOString();
|
|
1789
|
+
}
|
|
1668
1790
|
case "Decimal": return value !== null ? value.toString() : value;
|
|
1669
1791
|
case "Json": if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return JSON.stringify(value);
|
|
1670
1792
|
else return value;
|
|
@@ -1836,6 +1958,72 @@ var PostgresCrudDialect = class PostgresCrudDialect extends LateralJoinDialectBa
|
|
|
1836
1958
|
return ob;
|
|
1837
1959
|
});
|
|
1838
1960
|
}
|
|
1961
|
+
/**
|
|
1962
|
+
* Wraps an expression with `unaccent(lower(...))` or just `lower(...)` depending on
|
|
1963
|
+
* whether the user opted into accent-insensitive matching. The lowering is always
|
|
1964
|
+
* applied so trigram comparisons are case-insensitive on both sides.
|
|
1965
|
+
*/
|
|
1966
|
+
normalizeForTrigram(expr, applyUnaccent) {
|
|
1967
|
+
return applyUnaccent ? kysely.sql`unaccent(lower(${expr}))` : kysely.sql`lower(${expr})`;
|
|
1968
|
+
}
|
|
1969
|
+
buildFuzzyFilter(fieldRef, options) {
|
|
1970
|
+
const fieldExpr = this.normalizeForTrigram(fieldRef, options.unaccent);
|
|
1971
|
+
const valueExpr = this.normalizeForTrigram(kysely.sql.val(options.search), options.unaccent);
|
|
1972
|
+
if (options.threshold === void 0) switch (options.mode) {
|
|
1973
|
+
case "simple": return kysely.sql`${fieldExpr} % ${valueExpr}`;
|
|
1974
|
+
case "word": return kysely.sql`${valueExpr} <% ${fieldExpr}`;
|
|
1975
|
+
case "strictWord": return kysely.sql`${valueExpr} <<% ${fieldExpr}`;
|
|
1976
|
+
}
|
|
1977
|
+
const threshold = kysely.sql.val(options.threshold);
|
|
1978
|
+
switch (options.mode) {
|
|
1979
|
+
case "simple": return kysely.sql`similarity(${fieldExpr}, ${valueExpr}) > ${threshold}`;
|
|
1980
|
+
case "word": return kysely.sql`word_similarity(${valueExpr}, ${fieldExpr}) > ${threshold}`;
|
|
1981
|
+
case "strictWord": return kysely.sql`strict_word_similarity(${valueExpr}, ${fieldExpr}) > ${threshold}`;
|
|
1982
|
+
}
|
|
1983
|
+
}
|
|
1984
|
+
buildFuzzyRelevanceOrderBy(query, fieldRefs, search, sort, mode, unaccent) {
|
|
1985
|
+
const valueExpr = this.normalizeForTrigram(kysely.sql.val(search), unaccent);
|
|
1986
|
+
const buildSimilarity = (fieldRef) => {
|
|
1987
|
+
const fieldExpr = this.normalizeForTrigram(fieldRef, unaccent);
|
|
1988
|
+
switch (mode) {
|
|
1989
|
+
case "simple": return kysely.sql`similarity(${fieldExpr}, ${valueExpr})`;
|
|
1990
|
+
case "word": return kysely.sql`word_similarity(${valueExpr}, ${fieldExpr})`;
|
|
1991
|
+
case "strictWord": return kysely.sql`strict_word_similarity(${valueExpr}, ${fieldExpr})`;
|
|
1992
|
+
}
|
|
1993
|
+
};
|
|
1994
|
+
if (fieldRefs.length === 1) return query.orderBy(buildSimilarity(fieldRefs[0]), sort);
|
|
1995
|
+
const similarities = fieldRefs.map((ref) => buildSimilarity(ref));
|
|
1996
|
+
return query.orderBy(kysely.sql`GREATEST(${kysely.sql.join(similarities)})`, sort);
|
|
1997
|
+
}
|
|
1998
|
+
buildFullTextFilter(fieldRef, payload) {
|
|
1999
|
+
const options = this.normalizeFullTextOptions(payload);
|
|
2000
|
+
const query = kysely.sql.val(options.search);
|
|
2001
|
+
if (options.config === void 0) return kysely.sql`to_tsvector(${fieldRef}) @@ to_tsquery(${query})`;
|
|
2002
|
+
const cfg = kysely.sql.val(options.config);
|
|
2003
|
+
return kysely.sql`to_tsvector(${cfg}::regconfig, ${fieldRef}) @@ to_tsquery(${cfg}::regconfig, ${query})`;
|
|
2004
|
+
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Validate the user-provided `fts` filter payload. When `config` is omitted
|
|
2007
|
+
* it stays `undefined` so {@link buildFullTextFilter} can emit the no-regconfig
|
|
2008
|
+
* SQL form and let Postgres fall back to `default_text_search_config`.
|
|
2009
|
+
*/
|
|
2010
|
+
normalizeFullTextOptions(value) {
|
|
2011
|
+
(0, _zenstackhq_common_helpers.invariant)(value !== null && typeof value === "object" && !Array.isArray(value), "fts filter must be an object with at least a \"search\" field");
|
|
2012
|
+
const raw = value;
|
|
2013
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof raw["search"] === "string" && raw["search"].length > 0, "fts.search must be a non-empty string");
|
|
2014
|
+
if (raw["config"] !== void 0) (0, _zenstackhq_common_helpers.invariant)(typeof raw["config"] === "string" && raw["config"].length > 0, "fts.config must be a non-empty string");
|
|
2015
|
+
return {
|
|
2016
|
+
search: raw["search"],
|
|
2017
|
+
config: raw["config"]
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
buildFtsRelevanceOrderBy(query, fieldRefs, search, config, sort) {
|
|
2021
|
+
const q = kysely.sql.val(search);
|
|
2022
|
+
const document = fieldRefs.length === 1 ? kysely.sql`coalesce(${fieldRefs[0]}, '')` : kysely.sql`concat_ws(' ', ${kysely.sql.join(fieldRefs)})`;
|
|
2023
|
+
if (config === void 0) return query.orderBy(kysely.sql`ts_rank(to_tsvector(${document}), to_tsquery(${q}))`, sort);
|
|
2024
|
+
const cfg = kysely.sql.val(config);
|
|
2025
|
+
return query.orderBy(kysely.sql`ts_rank(to_tsvector(${cfg}::regconfig, ${document}), to_tsquery(${cfg}::regconfig, ${q}))`, sort);
|
|
2026
|
+
}
|
|
1839
2027
|
};
|
|
1840
2028
|
//#endregion
|
|
1841
2029
|
//#region src/client/crud/dialects/sqlite.ts
|
|
@@ -1866,9 +2054,9 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1866
2054
|
}
|
|
1867
2055
|
transformInput(value, type, _forArrayField) {
|
|
1868
2056
|
if (value === void 0) return value;
|
|
1869
|
-
if (value instanceof JsonNullClass) return "null";
|
|
1870
|
-
else if (value instanceof DbNullClass) return null;
|
|
1871
|
-
else if (value instanceof AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
2057
|
+
if (value instanceof require_common_types.JsonNullClass) return "null";
|
|
2058
|
+
else if (value instanceof require_common_types.DbNullClass) return null;
|
|
2059
|
+
else if (value instanceof require_common_types.AnyNullClass) (0, _zenstackhq_common_helpers.invariant)(false, "should not reach here: AnyNull is not a valid input value");
|
|
1872
2060
|
if (type === "Json" || this.schema.typeDefs && type in this.schema.typeDefs) return JSON.stringify(value);
|
|
1873
2061
|
if (Array.isArray(value)) return value.map((v) => this.transformInput(v, type, false));
|
|
1874
2062
|
else switch (type) {
|
|
@@ -2053,6 +2241,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
2053
2241
|
return ob;
|
|
2054
2242
|
});
|
|
2055
2243
|
}
|
|
2244
|
+
buildFuzzyFilter(_fieldRef, _options) {
|
|
2245
|
+
throw createNotSupportedError("\"fuzzy\" filter is not supported by the \"sqlite\" provider");
|
|
2246
|
+
}
|
|
2247
|
+
buildFuzzyRelevanceOrderBy(_query, _fieldRefs, _search, _sort, _mode, _unaccent) {
|
|
2248
|
+
throw createNotSupportedError("\"_fuzzyRelevance\" ordering is not supported by the \"sqlite\" provider");
|
|
2249
|
+
}
|
|
2250
|
+
buildFullTextFilter(_fieldRef, _payload) {
|
|
2251
|
+
throw createNotSupportedError("\"fts\" filter is not supported by the \"sqlite\" provider");
|
|
2252
|
+
}
|
|
2253
|
+
buildFtsRelevanceOrderBy(_query, _fieldRefs, _search, _config, _sort) {
|
|
2254
|
+
throw createNotSupportedError("\"_ftsRelevance\" ordering is not supported by the \"sqlite\" provider");
|
|
2255
|
+
}
|
|
2056
2256
|
};
|
|
2057
2257
|
//#endregion
|
|
2058
2258
|
//#region src/client/crud/dialects/index.ts
|
|
@@ -2108,6 +2308,33 @@ function createQuerySchemaFactory(clientOrSchema, options) {
|
|
|
2108
2308
|
return new ZodSchemaFactory(clientOrSchema, options);
|
|
2109
2309
|
}
|
|
2110
2310
|
/**
|
|
2311
|
+
* Builds a `DateTime` value schema that accepts a `Date` object or any string
|
|
2312
|
+
* the JS `Date` constructor parses, and coerces it to a `Date`. ISO datetime,
|
|
2313
|
+
* ISO date, and time-only strings (e.g. `"09:00:00"` for `@db.Time` fields,
|
|
2314
|
+
* anchored to the Unix epoch) are the documented happy paths; other formats
|
|
2315
|
+
* accepted by `new Date(...)` also pass through, mirroring Prisma's pre-3.5
|
|
2316
|
+
* behaviour. Strings the engine can't parse fall through and are rejected by
|
|
2317
|
+
* `z.date()` with the standard error.
|
|
2318
|
+
*
|
|
2319
|
+
* @see https://github.com/zenstackhq/zenstack/issues/2631
|
|
2320
|
+
*/
|
|
2321
|
+
function coercedDateTimeSchema() {
|
|
2322
|
+
return zod.z.preprocess((val) => {
|
|
2323
|
+
if (typeof val !== "string") return val;
|
|
2324
|
+
if (/^\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d\d(?::\d\d)?)?$/.test(val)) {
|
|
2325
|
+
const hasTz = val.endsWith("Z") || /[+-]\d\d(?::\d\d)?$/.test(val);
|
|
2326
|
+
const d = /* @__PURE__ */ new Date(`1970-01-01T${val}${hasTz ? "" : "Z"}`);
|
|
2327
|
+
return isNaN(d.getTime()) ? val : d;
|
|
2328
|
+
}
|
|
2329
|
+
const d = new Date(val);
|
|
2330
|
+
return isNaN(d.getTime()) ? val : d;
|
|
2331
|
+
}, zod.z.union([
|
|
2332
|
+
zod.z.iso.datetime(),
|
|
2333
|
+
zod.z.iso.date(),
|
|
2334
|
+
zod.z.date()
|
|
2335
|
+
]));
|
|
2336
|
+
}
|
|
2337
|
+
/**
|
|
2111
2338
|
* Factory class responsible for creating and caching Zod schemas for ORM input validation.
|
|
2112
2339
|
*/
|
|
2113
2340
|
var ZodSchemaFactory = class {
|
|
@@ -2276,7 +2503,7 @@ var ZodSchemaFactory = class {
|
|
|
2276
2503
|
const typeDef = getTypeDef(this.schema, type);
|
|
2277
2504
|
(0, _zenstackhq_common_helpers.invariant)(typeDef, `Type definition "${type}" not found in schema`);
|
|
2278
2505
|
const schema = zod.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
|
|
2279
|
-
let fieldSchema = this.makeScalarSchema(def.type);
|
|
2506
|
+
let fieldSchema = isTypeDef(this.schema, def.type) ? zod.z.lazy(() => this.makeTypeDefSchema(def.type)) : this.makeScalarSchema(def.type);
|
|
2280
2507
|
if (def.array) fieldSchema = fieldSchema.array();
|
|
2281
2508
|
if (def.optional) fieldSchema = fieldSchema.nullish();
|
|
2282
2509
|
return [field, fieldSchema];
|
|
@@ -2320,7 +2547,7 @@ var ZodSchemaFactory = class {
|
|
|
2320
2547
|
if (Object.keys(enumDef.values).length > 0) fieldSchema = this.makeEnumFilterSchema(fieldDef.type, !!fieldDef.optional, !!fieldDef.array, withAggregations, allowedFilterKinds);
|
|
2321
2548
|
} else if (fieldDef.array) fieldSchema = this.makeArrayFilterSchema(fieldDef.type, allowedFilterKinds);
|
|
2322
2549
|
else if (this.isTypeDefType(fieldDef.type)) fieldSchema = this.makeTypedJsonFilterSchema(fieldDef.type, !!fieldDef.optional, !!fieldDef.array, allowedFilterKinds);
|
|
2323
|
-
else fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations, allowedFilterKinds);
|
|
2550
|
+
else fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations, allowedFilterKinds, !!fieldDef.fuzzy, !!fieldDef.fullText);
|
|
2324
2551
|
}
|
|
2325
2552
|
if (fieldSchema) fields[field] = fieldSchema.optional();
|
|
2326
2553
|
}
|
|
@@ -2381,9 +2608,9 @@ var ZodSchemaFactory = class {
|
|
|
2381
2608
|
candidates.push(this.makeJsonFilterSchema(optional, allowedFilterKinds));
|
|
2382
2609
|
if (optional) {
|
|
2383
2610
|
candidates.push(zod.z.null());
|
|
2384
|
-
candidates.push(zod.z.instanceof(DbNullClass));
|
|
2385
|
-
candidates.push(zod.z.instanceof(JsonNullClass));
|
|
2386
|
-
candidates.push(zod.z.instanceof(AnyNullClass));
|
|
2611
|
+
candidates.push(zod.z.instanceof(require_common_types.DbNullClass));
|
|
2612
|
+
candidates.push(zod.z.instanceof(require_common_types.JsonNullClass));
|
|
2613
|
+
candidates.push(zod.z.instanceof(require_common_types.AnyNullClass));
|
|
2387
2614
|
}
|
|
2388
2615
|
const result = zod.z.union(candidates);
|
|
2389
2616
|
this.registerSchema(`${type}Filter${this.filterSchemaSuffix({
|
|
@@ -2395,7 +2622,7 @@ var ZodSchemaFactory = class {
|
|
|
2395
2622
|
}
|
|
2396
2623
|
makeNullableTypedJsonMutationSchema(fieldSchema) {
|
|
2397
2624
|
return zod.z.any().superRefine((value, ctx) => {
|
|
2398
|
-
if (value instanceof DbNullClass || value instanceof JsonNullClass || value === null || value === void 0) return;
|
|
2625
|
+
if (value instanceof require_common_types.DbNullClass || value instanceof require_common_types.JsonNullClass || value === null || value === void 0) return;
|
|
2399
2626
|
const parseResult = fieldSchema.safeParse(value);
|
|
2400
2627
|
if (!parseResult.success) parseResult.error.issues.forEach((issue) => ctx.addIssue(issue));
|
|
2401
2628
|
}).optional();
|
|
@@ -2449,15 +2676,15 @@ var ZodSchemaFactory = class {
|
|
|
2449
2676
|
const filteredOperators = this.trimFilterOperators(operators, allowedFilterKinds);
|
|
2450
2677
|
return zod.z.strictObject(filteredOperators);
|
|
2451
2678
|
}
|
|
2452
|
-
makePrimitiveFilterSchema(type, optional, withAggregations, allowedFilterKinds) {
|
|
2453
|
-
return (0, ts_pattern.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)).with(ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.makeNumberFilterSchema(type, 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(optional, allowedFilterKinds)).with("Unsupported", () => zod.z.never()).exhaustive();
|
|
2679
|
+
makePrimitiveFilterSchema(type, optional, withAggregations, allowedFilterKinds, withFuzzy = false, withFullText = false) {
|
|
2680
|
+
return (0, ts_pattern.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds, withFuzzy, withFullText)).with(ts_pattern.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.makeNumberFilterSchema(type, 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(optional, allowedFilterKinds)).with("Unsupported", () => zod.z.never()).exhaustive();
|
|
2454
2681
|
}
|
|
2455
2682
|
makeJsonValueSchema() {
|
|
2456
2683
|
const schema = zod.z.union([
|
|
2457
2684
|
zod.z.string(),
|
|
2458
2685
|
zod.z.number(),
|
|
2459
2686
|
zod.z.boolean(),
|
|
2460
|
-
zod.z.instanceof(JsonNullClass),
|
|
2687
|
+
zod.z.instanceof(require_common_types.JsonNullClass),
|
|
2461
2688
|
zod.z.lazy(() => zod.z.union([this.makeJsonValueSchema(), zod.z.null()]).array()),
|
|
2462
2689
|
zod.z.record(zod.z.string(), zod.z.lazy(() => zod.z.union([this.makeJsonValueSchema(), zod.z.null()])))
|
|
2463
2690
|
]);
|
|
@@ -2468,8 +2695,8 @@ var ZodSchemaFactory = class {
|
|
|
2468
2695
|
if (allowedFilterKinds && !allowedFilterKinds.includes("Json")) return zod.z.never();
|
|
2469
2696
|
const filterMembers = [
|
|
2470
2697
|
this.makeJsonValueSchema(),
|
|
2471
|
-
zod.z.instanceof(DbNullClass),
|
|
2472
|
-
zod.z.instanceof(AnyNullClass)
|
|
2698
|
+
zod.z.instanceof(require_common_types.DbNullClass),
|
|
2699
|
+
zod.z.instanceof(require_common_types.AnyNullClass)
|
|
2473
2700
|
];
|
|
2474
2701
|
if (optional) filterMembers.push(zod.z.null());
|
|
2475
2702
|
const filterValueSchema = zod.z.union(filterMembers);
|
|
@@ -2492,11 +2719,7 @@ var ZodSchemaFactory = class {
|
|
|
2492
2719
|
return schema;
|
|
2493
2720
|
}
|
|
2494
2721
|
makeDateTimeValueSchema() {
|
|
2495
|
-
const schema =
|
|
2496
|
-
zod.z.iso.datetime(),
|
|
2497
|
-
zod.z.iso.date(),
|
|
2498
|
-
zod.z.date()
|
|
2499
|
-
]);
|
|
2722
|
+
const schema = coercedDateTimeSchema();
|
|
2500
2723
|
this.registerSchema("DateTime", schema);
|
|
2501
2724
|
return schema;
|
|
2502
2725
|
}
|
|
@@ -2592,8 +2815,8 @@ var ZodSchemaFactory = class {
|
|
|
2592
2815
|
})}`, schema);
|
|
2593
2816
|
return schema;
|
|
2594
2817
|
}
|
|
2595
|
-
makeStringFilterSchema(optional, withAggregations, allowedFilterKinds) {
|
|
2596
|
-
const baseComponents = this.makeCommonPrimitiveFilterComponents(zod.z.string(), optional, () => zod.z.lazy(() => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds)), void 0, withAggregations ? [
|
|
2818
|
+
makeStringFilterSchema(optional, withAggregations, allowedFilterKinds, withFuzzy = false, withFullText = false) {
|
|
2819
|
+
const baseComponents = this.makeCommonPrimitiveFilterComponents(zod.z.string(), optional, () => zod.z.lazy(() => this.makeStringFilterSchema(optional, withAggregations, allowedFilterKinds, withFuzzy, withFullText)), void 0, withAggregations ? [
|
|
2597
2820
|
"_count",
|
|
2598
2821
|
"_min",
|
|
2599
2822
|
"_max"
|
|
@@ -2602,6 +2825,8 @@ var ZodSchemaFactory = class {
|
|
|
2602
2825
|
startsWith: zod.z.string().optional(),
|
|
2603
2826
|
endsWith: zod.z.string().optional(),
|
|
2604
2827
|
contains: zod.z.string().optional(),
|
|
2828
|
+
...withFuzzy && this.providerSupportsFuzzySearch ? { fuzzy: this.makeFuzzyFilterSchema().optional() } : {},
|
|
2829
|
+
...withFullText && this.providerSupportsFullTextSearch ? { fts: this.makeFullTextFilterSchema().optional() } : {},
|
|
2605
2830
|
...this.providerSupportsCaseSensitivity ? { mode: this.makeStringModeSchema().optional() } : {}
|
|
2606
2831
|
};
|
|
2607
2832
|
const filteredStringOperators = this.trimFilterOperators(stringSpecificOperators, allowedFilterKinds);
|
|
@@ -2610,16 +2835,35 @@ var ZodSchemaFactory = class {
|
|
|
2610
2835
|
...filteredStringOperators
|
|
2611
2836
|
};
|
|
2612
2837
|
const schema = this.createUnionFilterSchema(zod.z.string(), optional, allComponents, allowedFilterKinds);
|
|
2838
|
+
const featureSuffix = `${withFuzzy ? "Fuzzy" : ""}${withFullText ? "FullText" : ""}`;
|
|
2613
2839
|
this.registerSchema(`StringFilter${this.filterSchemaSuffix({
|
|
2614
2840
|
optional,
|
|
2615
2841
|
allowedFilterKinds,
|
|
2616
2842
|
withAggregations
|
|
2617
|
-
})}`, schema);
|
|
2843
|
+
})}${featureSuffix}`, schema);
|
|
2618
2844
|
return schema;
|
|
2619
2845
|
}
|
|
2620
2846
|
makeStringModeSchema() {
|
|
2621
2847
|
return zod.z.union([zod.z.literal("default"), zod.z.literal("insensitive")]);
|
|
2622
2848
|
}
|
|
2849
|
+
makeFuzzyFilterSchema() {
|
|
2850
|
+
return zod.z.strictObject({
|
|
2851
|
+
search: zod.z.string().min(1),
|
|
2852
|
+
mode: zod.z.union([
|
|
2853
|
+
zod.z.literal("simple"),
|
|
2854
|
+
zod.z.literal("word"),
|
|
2855
|
+
zod.z.literal("strictWord")
|
|
2856
|
+
]).default("simple"),
|
|
2857
|
+
threshold: zod.z.number().min(0).max(1).optional(),
|
|
2858
|
+
unaccent: zod.z.boolean().default(false)
|
|
2859
|
+
});
|
|
2860
|
+
}
|
|
2861
|
+
makeFullTextFilterSchema() {
|
|
2862
|
+
return zod.z.strictObject({
|
|
2863
|
+
search: zod.z.string().min(1),
|
|
2864
|
+
config: zod.z.string().min(1).optional()
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2623
2867
|
makeSelectSchema(model, options) {
|
|
2624
2868
|
const fields = {};
|
|
2625
2869
|
for (const [field, fieldDef] of this.getModelFields(model)) if (fieldDef.relation) {
|
|
@@ -2720,7 +2964,7 @@ var ZodSchemaFactory = class {
|
|
|
2720
2964
|
}).optional();
|
|
2721
2965
|
} else if (fieldDef.optional) fields[field] = zod.z.union([sort, zod.z.strictObject({
|
|
2722
2966
|
sort,
|
|
2723
|
-
nulls: zod.z.union([zod.z.literal("first"), zod.z.literal("last")])
|
|
2967
|
+
nulls: zod.z.union([zod.z.literal("first"), zod.z.literal("last")]).optional()
|
|
2724
2968
|
})]).optional();
|
|
2725
2969
|
else fields[field] = sort.optional();
|
|
2726
2970
|
if (WithAggregation) for (const agg of [
|
|
@@ -2730,6 +2974,29 @@ var ZodSchemaFactory = class {
|
|
|
2730
2974
|
"_min",
|
|
2731
2975
|
"_max"
|
|
2732
2976
|
]) fields[agg] = zod.z.lazy(() => this.makeOrderBySchema(model, true, false, options).optional());
|
|
2977
|
+
if (this.providerSupportsFuzzySearch) {
|
|
2978
|
+
const fuzzyFieldNames = this.getModelFields(model).filter(([, def]) => !def.relation && def.type === "String" && def.fuzzy === true).map(([name]) => name);
|
|
2979
|
+
if (fuzzyFieldNames.length > 0) fields["_fuzzyRelevance"] = zod.z.strictObject({
|
|
2980
|
+
fields: zod.z.array(zod.z.enum(fuzzyFieldNames)).min(1),
|
|
2981
|
+
search: zod.z.string(),
|
|
2982
|
+
mode: zod.z.union([
|
|
2983
|
+
zod.z.literal("simple"),
|
|
2984
|
+
zod.z.literal("word"),
|
|
2985
|
+
zod.z.literal("strictWord")
|
|
2986
|
+
]).default("simple"),
|
|
2987
|
+
unaccent: zod.z.boolean().default(false),
|
|
2988
|
+
sort
|
|
2989
|
+
}).optional();
|
|
2990
|
+
}
|
|
2991
|
+
if (this.providerSupportsFullTextSearch) {
|
|
2992
|
+
const fullTextFieldNames = this.getModelFields(model).filter(([, def]) => !def.relation && def.type === "String" && def.fullText === true).map(([name]) => name);
|
|
2993
|
+
if (fullTextFieldNames.length > 0) fields["_ftsRelevance"] = zod.z.strictObject({
|
|
2994
|
+
fields: zod.z.array(zod.z.enum(fullTextFieldNames)).min(1),
|
|
2995
|
+
search: zod.z.string().min(1),
|
|
2996
|
+
config: zod.z.string().min(1).optional(),
|
|
2997
|
+
sort
|
|
2998
|
+
}).optional();
|
|
2999
|
+
}
|
|
2733
3000
|
const schema = refineAtMostOneKey(zod.z.strictObject(fields));
|
|
2734
3001
|
let schemaId = `${model}OrderBy`;
|
|
2735
3002
|
if (withRelation) schemaId += "WithRelation";
|
|
@@ -2820,7 +3087,7 @@ var ZodSchemaFactory = class {
|
|
|
2820
3087
|
fieldSchema = zod.z.union([fieldSchema, zod.z.strictObject({ set: fieldSchema })]).optional();
|
|
2821
3088
|
}
|
|
2822
3089
|
if (fieldDef.optional || fieldHasDefaultValue(fieldDef)) fieldSchema = fieldSchema.optional();
|
|
2823
|
-
if (fieldDef.optional) if (fieldDef.type === "Json") fieldSchema = zod.z.union([fieldSchema, zod.z.instanceof(DbNullClass)]);
|
|
3090
|
+
if (fieldDef.optional) if (fieldDef.type === "Json") fieldSchema = zod.z.union([fieldSchema, zod.z.instanceof(require_common_types.DbNullClass)]);
|
|
2824
3091
|
else if (this.isTypeDefType(fieldDef.type)) fieldSchema = this.makeNullableTypedJsonMutationSchema(fieldSchema);
|
|
2825
3092
|
else fieldSchema = fieldSchema.nullable();
|
|
2826
3093
|
uncheckedVariantFields[field] = fieldSchema;
|
|
@@ -3007,7 +3274,7 @@ var ZodSchemaFactory = class {
|
|
|
3007
3274
|
push: zod.z.union([fieldSchema, fieldSchema.array()]).optional()
|
|
3008
3275
|
}).refine((v) => Object.keys(v).length === 1, "Only one of \"set\", \"push\" can be provided")]);
|
|
3009
3276
|
}
|
|
3010
|
-
if (fieldDef.optional) if (fieldDef.type === "Json") fieldSchema = zod.z.union([fieldSchema, zod.z.instanceof(DbNullClass)]);
|
|
3277
|
+
if (fieldDef.optional) if (fieldDef.type === "Json") fieldSchema = zod.z.union([fieldSchema, zod.z.instanceof(require_common_types.DbNullClass)]);
|
|
3011
3278
|
else if (this.isTypeDefType(fieldDef.type)) fieldSchema = this.makeNullableTypedJsonMutationSchema(fieldSchema);
|
|
3012
3279
|
else fieldSchema = fieldSchema.nullable();
|
|
3013
3280
|
fieldSchema = fieldSchema.optional();
|
|
@@ -3231,6 +3498,12 @@ var ZodSchemaFactory = class {
|
|
|
3231
3498
|
get providerSupportsCaseSensitivity() {
|
|
3232
3499
|
return this.schema.provider.type === "postgresql";
|
|
3233
3500
|
}
|
|
3501
|
+
get providerSupportsFullTextSearch() {
|
|
3502
|
+
return this.schema.provider.type === "postgresql";
|
|
3503
|
+
}
|
|
3504
|
+
get providerSupportsFuzzySearch() {
|
|
3505
|
+
return this.schema.provider.type === "postgresql";
|
|
3506
|
+
}
|
|
3234
3507
|
/**
|
|
3235
3508
|
* Gets the effective set of allowed FilterKind values for a specific model and field.
|
|
3236
3509
|
* Respects the precedence: model[field] > model.$all > $all[field] > $all.$all.
|
|
@@ -3392,6 +3665,8 @@ __decorate([
|
|
|
3392
3665
|
Object,
|
|
3393
3666
|
Boolean,
|
|
3394
3667
|
Boolean,
|
|
3668
|
+
Object,
|
|
3669
|
+
Object,
|
|
3395
3670
|
Object
|
|
3396
3671
|
]),
|
|
3397
3672
|
__decorateMetadata("design:returntype", void 0)
|
|
@@ -3461,6 +3736,8 @@ __decorate([
|
|
|
3461
3736
|
__decorateMetadata("design:paramtypes", [
|
|
3462
3737
|
Boolean,
|
|
3463
3738
|
Boolean,
|
|
3739
|
+
Object,
|
|
3740
|
+
Object,
|
|
3464
3741
|
Object
|
|
3465
3742
|
]),
|
|
3466
3743
|
__decorateMetadata("design:returntype", typeof (_ref10 = typeof zod.ZodType !== "undefined" && zod.ZodType) === "function" ? _ref10 : Object)
|
|
@@ -3950,7 +4227,7 @@ var BaseOperationHandler = class {
|
|
|
3950
4227
|
return new this.constructor(client, this.model, this.inputValidator);
|
|
3951
4228
|
}
|
|
3952
4229
|
get hasPolicyEnabled() {
|
|
3953
|
-
return this.options.plugins?.some((plugin) => plugin.
|
|
4230
|
+
return this.options.plugins?.some((plugin) => plugin.id === "policy") ?? false;
|
|
3954
4231
|
}
|
|
3955
4232
|
requireModel(model) {
|
|
3956
4233
|
return requireModel(this.schema, model);
|
|
@@ -4051,8 +4328,8 @@ var BaseOperationHandler = class {
|
|
|
4051
4328
|
const postCreateRelations = {};
|
|
4052
4329
|
for (const [field, value] of Object.entries(data)) {
|
|
4053
4330
|
const fieldDef = this.requireField(model, field);
|
|
4054
|
-
if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) if (fieldDef.array && value && typeof value === "object" && "set" in value && Array.isArray(value.set)) createFields[field] = this.dialect.transformInput(value.set, fieldDef.type, true);
|
|
4055
|
-
else createFields[field] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array);
|
|
4331
|
+
if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) if (fieldDef.array && value && typeof value === "object" && "set" in value && Array.isArray(value.set)) createFields[field] = this.dialect.transformInput(value.set, fieldDef.type, true, fieldDef);
|
|
4332
|
+
else createFields[field] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4056
4333
|
else if (!getManyToManyRelation(this.schema, model, field) && fieldDef.relation?.fields && fieldDef.relation?.references) {
|
|
4057
4334
|
const fkValues = await this.processOwnedRelationForCreate(kysely$7, fieldDef, value);
|
|
4058
4335
|
for (let i = 0; i < fieldDef.relation.fields.length; i++) createFields[fieldDef.relation.fields[i]] = fkValues[fieldDef.relation.references[i]];
|
|
@@ -4252,7 +4529,7 @@ var BaseOperationHandler = class {
|
|
|
4252
4529
|
for (const [name, value] of Object.entries(item)) {
|
|
4253
4530
|
const fieldDef = this.requireField(model, name);
|
|
4254
4531
|
(0, _zenstackhq_common_helpers.invariant)(!fieldDef.relation, "createMany does not support relations");
|
|
4255
|
-
newItem[name] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array);
|
|
4532
|
+
newItem[name] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4256
4533
|
}
|
|
4257
4534
|
if (fromRelation) for (const { fk, pk } of relationKeyPairs) newItem[fk] = fromRelation.ids[pk];
|
|
4258
4535
|
return this.fillGeneratedAndDefaultValues(modelDef, newItem);
|
|
@@ -4268,7 +4545,7 @@ var BaseOperationHandler = class {
|
|
|
4268
4545
|
if (Object.keys(item).length === allPassedFields.length) continue;
|
|
4269
4546
|
for (const field of allPassedFields) if (!(field in item)) {
|
|
4270
4547
|
const fieldDef = this.requireField(model, field);
|
|
4271
|
-
if (fieldDef.default !== void 0 && fieldDef.default !== null && typeof fieldDef.default !== "object") item[field] = this.dialect.transformInput(fieldDef.default, fieldDef.type, !!fieldDef.array);
|
|
4548
|
+
if (fieldDef.default !== void 0 && fieldDef.default !== null && typeof fieldDef.default !== "object") item[field] = this.dialect.transformInput(fieldDef.default, fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4272
4549
|
}
|
|
4273
4550
|
}
|
|
4274
4551
|
}
|
|
@@ -4331,15 +4608,15 @@ var BaseOperationHandler = class {
|
|
|
4331
4608
|
if (!(field in data)) {
|
|
4332
4609
|
if (typeof fieldDef?.default === "object" && "kind" in fieldDef.default) {
|
|
4333
4610
|
const generated = this.evalGenerator(fieldDef.default);
|
|
4334
|
-
if (generated !== void 0) values[field] = this.dialect.transformInput(generated, fieldDef.type, !!fieldDef.array);
|
|
4335
|
-
} else if (fieldDef?.updatedAt) values[field] = this.dialect.transformInput(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
4611
|
+
if (generated !== void 0) values[field] = this.dialect.transformInput(generated, fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4612
|
+
} else if (fieldDef?.updatedAt) values[field] = this.dialect.transformInput(/* @__PURE__ */ new Date(), "DateTime", false, fieldDef);
|
|
4336
4613
|
else if (fieldDef?.default !== void 0) {
|
|
4337
4614
|
let value = fieldDef.default;
|
|
4338
4615
|
if (fieldDef.type === "Json") {
|
|
4339
4616
|
if (fieldDef.array && Array.isArray(value)) value = value.map((v) => typeof v === "string" ? JSON.parse(v) : v);
|
|
4340
4617
|
else if (typeof value === "string") value = JSON.parse(value);
|
|
4341
4618
|
}
|
|
4342
|
-
values[field] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array);
|
|
4619
|
+
values[field] = this.dialect.transformInput(value, fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4343
4620
|
}
|
|
4344
4621
|
}
|
|
4345
4622
|
}
|
|
@@ -4389,7 +4666,7 @@ var BaseOperationHandler = class {
|
|
|
4389
4666
|
const ignoredFields = new Set(typeof fieldDef.updatedAt === "boolean" ? [] : fieldDef.updatedAt.ignore);
|
|
4390
4667
|
if (Object.keys(data).some((field) => (isScalarField(this.schema, modelDef.name, field) || isForeignKeyField(this.schema, modelDef.name, field)) && !ignoredFields.has(field))) {
|
|
4391
4668
|
if (finalData === data) finalData = (0, _zenstackhq_common_helpers.clone)(data);
|
|
4392
|
-
finalData[fieldName] = this.dialect.transformInput(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
4669
|
+
finalData[fieldName] = this.dialect.transformInput(/* @__PURE__ */ new Date(), "DateTime", false, fieldDef);
|
|
4393
4670
|
autoUpdatedFields.push(fieldName);
|
|
4394
4671
|
}
|
|
4395
4672
|
}
|
|
@@ -4493,7 +4770,7 @@ var BaseOperationHandler = class {
|
|
|
4493
4770
|
const fieldDef = this.requireField(model, field);
|
|
4494
4771
|
if (this.isNumericIncrementalUpdate(fieldDef, data[field])) return this.transformIncrementalUpdate(model, field, fieldDef, data[field]);
|
|
4495
4772
|
if (fieldDef.array && typeof data[field] === "object" && !Array.isArray(data[field]) && data[field]) return this.transformScalarListUpdate(model, field, fieldDef, data[field]);
|
|
4496
|
-
return this.dialect.transformInput(data[field], fieldDef.type, !!fieldDef.array);
|
|
4773
|
+
return this.dialect.transformInput(data[field], fieldDef.type, !!fieldDef.array, fieldDef);
|
|
4497
4774
|
}
|
|
4498
4775
|
isNumericIncrementalUpdate(fieldDef, value) {
|
|
4499
4776
|
if (!this.isNumericField(fieldDef)) return false;
|
|
@@ -4521,7 +4798,7 @@ var BaseOperationHandler = class {
|
|
|
4521
4798
|
transformIncrementalUpdate(model, field, fieldDef, payload) {
|
|
4522
4799
|
(0, _zenstackhq_common_helpers.invariant)(Object.keys(payload).length === 1, "Only one of \"set\", \"increment\", \"decrement\", \"multiply\", or \"divide\" can be provided");
|
|
4523
4800
|
const key = Object.keys(payload)[0];
|
|
4524
|
-
const value = this.dialect.transformInput(payload[key], fieldDef.type, false);
|
|
4801
|
+
const value = this.dialect.transformInput(payload[key], fieldDef.type, false, fieldDef);
|
|
4525
4802
|
const eb = (0, kysely.expressionBuilder)();
|
|
4526
4803
|
const fieldRef = this.dialect.fieldRef(model, field);
|
|
4527
4804
|
return (0, ts_pattern.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
|
|
@@ -4531,7 +4808,7 @@ var BaseOperationHandler = class {
|
|
|
4531
4808
|
transformScalarListUpdate(model, field, fieldDef, payload) {
|
|
4532
4809
|
(0, _zenstackhq_common_helpers.invariant)(Object.keys(payload).length === 1, "Only one of \"set\", \"push\" can be provided");
|
|
4533
4810
|
const key = Object.keys(payload)[0];
|
|
4534
|
-
const value = this.dialect.transformInput(payload[key], fieldDef.type, true);
|
|
4811
|
+
const value = this.dialect.transformInput(payload[key], fieldDef.type, true, fieldDef);
|
|
4535
4812
|
const eb = (0, kysely.expressionBuilder)();
|
|
4536
4813
|
const fieldRef = this.dialect.fieldRef(model, field);
|
|
4537
4814
|
return (0, ts_pattern.match)(key).with("set", () => value).with("push", () => {
|
|
@@ -6942,12 +7219,21 @@ var ClientImpl = class ClientImpl {
|
|
|
6942
7219
|
});
|
|
6943
7220
|
}
|
|
6944
7221
|
}
|
|
7222
|
+
getPromiseCallback(promise) {
|
|
7223
|
+
(0, _zenstackhq_common_helpers.invariant)(promise.cb, "Invalid ZenStackPromise, missing cb property");
|
|
7224
|
+
const cb = promise.cb;
|
|
7225
|
+
(0, _zenstackhq_common_helpers.invariant)(typeof cb === "function", "Invalid ZenStackPromise, cb property is not a function");
|
|
7226
|
+
return promise.cb;
|
|
7227
|
+
}
|
|
6945
7228
|
async sequentialTransaction(arg, options) {
|
|
6946
7229
|
const execute = async (tx) => {
|
|
6947
7230
|
const txClient = new ClientImpl(this.schema, this.$options, this);
|
|
6948
7231
|
txClient.kysely = tx;
|
|
6949
7232
|
const result = [];
|
|
6950
|
-
for (const promise of arg)
|
|
7233
|
+
for (const promise of arg) {
|
|
7234
|
+
const cb = this.getPromiseCallback(promise);
|
|
7235
|
+
result.push(await cb(txClient));
|
|
7236
|
+
}
|
|
6951
7237
|
return result;
|
|
6952
7238
|
};
|
|
6953
7239
|
if (this.kysely.isTransaction) return execute(this.kysely);
|
|
@@ -7734,6 +8020,15 @@ var DefaultOperationNodeVisitor = class extends kysely.OperationNodeVisitor {
|
|
|
7734
8020
|
visitCollate(node) {
|
|
7735
8021
|
this.defaultVisit(node);
|
|
7736
8022
|
}
|
|
8023
|
+
visitAlterType(node) {
|
|
8024
|
+
this.defaultVisit(node);
|
|
8025
|
+
}
|
|
8026
|
+
visitAddValue(node) {
|
|
8027
|
+
this.defaultVisit(node);
|
|
8028
|
+
}
|
|
8029
|
+
visitRenameValue(node) {
|
|
8030
|
+
this.defaultVisit(node);
|
|
8031
|
+
}
|
|
7737
8032
|
};
|
|
7738
8033
|
//#endregion
|
|
7739
8034
|
//#region src/utils/schema-utils.ts
|
|
@@ -7796,8 +8091,8 @@ var MatchingExpressionVisitor = class extends ExpressionVisitor {
|
|
|
7796
8091
|
exports.AllCrudOperations = AllCrudOperations;
|
|
7797
8092
|
exports.AllReadOperations = AllReadOperations;
|
|
7798
8093
|
exports.AllWriteOperations = AllWriteOperations;
|
|
7799
|
-
exports.AnyNull = AnyNull;
|
|
7800
|
-
exports.AnyNullClass = AnyNullClass;
|
|
8094
|
+
exports.AnyNull = require_common_types.AnyNull;
|
|
8095
|
+
exports.AnyNullClass = require_common_types.AnyNullClass;
|
|
7801
8096
|
exports.BaseCrudDialect = BaseCrudDialect;
|
|
7802
8097
|
exports.CRUD = CRUD;
|
|
7803
8098
|
exports.CRUD_EXT = CRUD_EXT;
|
|
@@ -7807,11 +8102,13 @@ exports.CoreDeleteOperations = CoreDeleteOperations;
|
|
|
7807
8102
|
exports.CoreReadOperations = CoreReadOperations;
|
|
7808
8103
|
exports.CoreUpdateOperations = CoreUpdateOperations;
|
|
7809
8104
|
exports.CoreWriteOperations = CoreWriteOperations;
|
|
7810
|
-
exports.DbNull = DbNull;
|
|
7811
|
-
exports.DbNullClass = DbNullClass;
|
|
8105
|
+
exports.DbNull = require_common_types.DbNull;
|
|
8106
|
+
exports.DbNullClass = require_common_types.DbNullClass;
|
|
8107
|
+
exports.ExtQueryArgsMarker = ExtQueryArgsMarker;
|
|
8108
|
+
exports.ExtResultMarker = ExtResultMarker;
|
|
7812
8109
|
exports.InputValidator = InputValidator;
|
|
7813
|
-
exports.JsonNull = JsonNull;
|
|
7814
|
-
exports.JsonNullClass = JsonNullClass;
|
|
8110
|
+
exports.JsonNull = require_common_types.JsonNull;
|
|
8111
|
+
exports.JsonNullClass = require_common_types.JsonNullClass;
|
|
7815
8112
|
Object.defineProperty(exports, "KyselyUtils", {
|
|
7816
8113
|
enumerable: true,
|
|
7817
8114
|
get: function() {
|