@zenstackhq/runtime 3.0.0-beta.2 → 3.0.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/{contract-CusA0mQO.d.cts → contract-hoS-Sd87.d.cts} +4 -5
- package/dist/{contract-CusA0mQO.d.ts → contract-hoS-Sd87.d.ts} +4 -5
- package/dist/index.cjs +284 -190
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +287 -193
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +172 -88
- package/dist/plugins/policy/index.cjs.map +1 -1
- package/dist/plugins/policy/index.d.cts +1 -1
- package/dist/plugins/policy/index.d.ts +1 -1
- package/dist/plugins/policy/index.js +173 -89
- package/dist/plugins/policy/index.js.map +1 -1
- package/dist/schema.cjs +3 -0
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -1
- package/package.json +8 -8
|
@@ -134,6 +134,9 @@ var ExpressionUtils = {
|
|
|
134
134
|
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
135
135
|
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
136
136
|
}, "or"),
|
|
137
|
+
not: /* @__PURE__ */ __name((expr2) => {
|
|
138
|
+
return ExpressionUtils.unary("!", expr2);
|
|
139
|
+
}, "not"),
|
|
137
140
|
is: /* @__PURE__ */ __name((value, kind) => {
|
|
138
141
|
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
139
142
|
}, "is"),
|
|
@@ -170,15 +173,19 @@ var InternalError = class extends Error {
|
|
|
170
173
|
|
|
171
174
|
// src/client/query-utils.ts
|
|
172
175
|
function getModel(schema, model) {
|
|
173
|
-
return schema.models
|
|
176
|
+
return Object.values(schema.models).find((m) => m.name.toLowerCase() === model.toLowerCase());
|
|
174
177
|
}
|
|
175
178
|
__name(getModel, "getModel");
|
|
179
|
+
function getTypeDef(schema, type) {
|
|
180
|
+
return schema.typeDefs?.[type];
|
|
181
|
+
}
|
|
182
|
+
__name(getTypeDef, "getTypeDef");
|
|
176
183
|
function requireModel(schema, model) {
|
|
177
|
-
const
|
|
178
|
-
if (!
|
|
184
|
+
const modelDef = getModel(schema, model);
|
|
185
|
+
if (!modelDef) {
|
|
179
186
|
throw new QueryError(`Model "${model}" not found in schema`);
|
|
180
187
|
}
|
|
181
|
-
return
|
|
188
|
+
return modelDef;
|
|
182
189
|
}
|
|
183
190
|
__name(requireModel, "requireModel");
|
|
184
191
|
function getField(schema, model, field) {
|
|
@@ -186,12 +193,24 @@ function getField(schema, model, field) {
|
|
|
186
193
|
return modelDef?.fields[field];
|
|
187
194
|
}
|
|
188
195
|
__name(getField, "getField");
|
|
189
|
-
function requireField(schema,
|
|
190
|
-
const modelDef =
|
|
191
|
-
if (
|
|
192
|
-
|
|
196
|
+
function requireField(schema, modelOrType, field) {
|
|
197
|
+
const modelDef = getModel(schema, modelOrType);
|
|
198
|
+
if (modelDef) {
|
|
199
|
+
if (!modelDef.fields[field]) {
|
|
200
|
+
throw new QueryError(`Field "${field}" not found in model "${modelOrType}"`);
|
|
201
|
+
} else {
|
|
202
|
+
return modelDef.fields[field];
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const typeDef = getTypeDef(schema, modelOrType);
|
|
206
|
+
if (typeDef) {
|
|
207
|
+
if (!typeDef.fields[field]) {
|
|
208
|
+
throw new QueryError(`Field "${field}" not found in type "${modelOrType}"`);
|
|
209
|
+
} else {
|
|
210
|
+
return typeDef.fields[field];
|
|
211
|
+
}
|
|
193
212
|
}
|
|
194
|
-
|
|
213
|
+
throw new QueryError(`Model or type "${modelOrType}" not found in schema`);
|
|
195
214
|
}
|
|
196
215
|
__name(requireField, "requireField");
|
|
197
216
|
function getIdFields(schema, model) {
|
|
@@ -417,7 +436,7 @@ function aggregate(eb, expr2, op) {
|
|
|
417
436
|
}
|
|
418
437
|
__name(aggregate, "aggregate");
|
|
419
438
|
|
|
420
|
-
// src/client/crud/dialects/base.ts
|
|
439
|
+
// src/client/crud/dialects/base-dialect.ts
|
|
421
440
|
var import_common_helpers = require("@zenstackhq/common-helpers");
|
|
422
441
|
var import_kysely = require("kysely");
|
|
423
442
|
var import_ts_pattern2 = require("ts-pattern");
|
|
@@ -436,7 +455,7 @@ function enumerate(x) {
|
|
|
436
455
|
}
|
|
437
456
|
__name(enumerate, "enumerate");
|
|
438
457
|
|
|
439
|
-
// src/client/crud/dialects/base.ts
|
|
458
|
+
// src/client/crud/dialects/base-dialect.ts
|
|
440
459
|
var BaseCrudDialect = class {
|
|
441
460
|
static {
|
|
442
461
|
__name(this, "BaseCrudDialect");
|
|
@@ -1810,6 +1829,12 @@ function isFalseNode(node) {
|
|
|
1810
1829
|
}
|
|
1811
1830
|
__name(isFalseNode, "isFalseNode");
|
|
1812
1831
|
function conjunction(dialect, nodes) {
|
|
1832
|
+
if (nodes.length === 0) {
|
|
1833
|
+
return trueNode(dialect);
|
|
1834
|
+
}
|
|
1835
|
+
if (nodes.length === 1) {
|
|
1836
|
+
return nodes[0];
|
|
1837
|
+
}
|
|
1813
1838
|
if (nodes.some(isFalseNode)) {
|
|
1814
1839
|
return falseNode(dialect);
|
|
1815
1840
|
}
|
|
@@ -1817,10 +1842,16 @@ function conjunction(dialect, nodes) {
|
|
|
1817
1842
|
if (items.length === 0) {
|
|
1818
1843
|
return trueNode(dialect);
|
|
1819
1844
|
}
|
|
1820
|
-
return items.reduce((acc, node) => import_kysely5.
|
|
1845
|
+
return items.reduce((acc, node) => import_kysely5.AndNode.create(wrapParensIf(acc, import_kysely5.OrNode.is), wrapParensIf(node, import_kysely5.OrNode.is)));
|
|
1821
1846
|
}
|
|
1822
1847
|
__name(conjunction, "conjunction");
|
|
1823
1848
|
function disjunction(dialect, nodes) {
|
|
1849
|
+
if (nodes.length === 0) {
|
|
1850
|
+
return falseNode(dialect);
|
|
1851
|
+
}
|
|
1852
|
+
if (nodes.length === 1) {
|
|
1853
|
+
return nodes[0];
|
|
1854
|
+
}
|
|
1824
1855
|
if (nodes.some(isTrueNode)) {
|
|
1825
1856
|
return trueNode(dialect);
|
|
1826
1857
|
}
|
|
@@ -1828,13 +1859,23 @@ function disjunction(dialect, nodes) {
|
|
|
1828
1859
|
if (items.length === 0) {
|
|
1829
1860
|
return falseNode(dialect);
|
|
1830
1861
|
}
|
|
1831
|
-
return items.reduce((acc, node) => import_kysely5.
|
|
1862
|
+
return items.reduce((acc, node) => import_kysely5.OrNode.create(wrapParensIf(acc, import_kysely5.AndNode.is), wrapParensIf(node, import_kysely5.AndNode.is)));
|
|
1832
1863
|
}
|
|
1833
1864
|
__name(disjunction, "disjunction");
|
|
1834
|
-
function logicalNot(node) {
|
|
1835
|
-
|
|
1865
|
+
function logicalNot(dialect, node) {
|
|
1866
|
+
if (isTrueNode(node)) {
|
|
1867
|
+
return falseNode(dialect);
|
|
1868
|
+
}
|
|
1869
|
+
if (isFalseNode(node)) {
|
|
1870
|
+
return trueNode(dialect);
|
|
1871
|
+
}
|
|
1872
|
+
return import_kysely5.UnaryOperationNode.create(import_kysely5.OperatorNode.create("not"), wrapParensIf(node, (n) => import_kysely5.AndNode.is(n) || import_kysely5.OrNode.is(n)));
|
|
1836
1873
|
}
|
|
1837
1874
|
__name(logicalNot, "logicalNot");
|
|
1875
|
+
function wrapParensIf(node, predicate) {
|
|
1876
|
+
return predicate(node) ? import_kysely5.ParensNode.create(node) : node;
|
|
1877
|
+
}
|
|
1878
|
+
__name(wrapParensIf, "wrapParensIf");
|
|
1838
1879
|
function buildIsFalse(node, dialect) {
|
|
1839
1880
|
if (isFalseNode(node)) {
|
|
1840
1881
|
return trueNode(dialect);
|
|
@@ -1925,11 +1966,7 @@ var ExpressionTransformer = class {
|
|
|
1925
1966
|
_field(expr2, context) {
|
|
1926
1967
|
const fieldDef = requireField(this.schema, context.model, expr2.field);
|
|
1927
1968
|
if (!fieldDef.relation) {
|
|
1928
|
-
|
|
1929
|
-
return context.thisEntity[expr2.field];
|
|
1930
|
-
} else {
|
|
1931
|
-
return this.createColumnRef(expr2.field, context);
|
|
1932
|
-
}
|
|
1969
|
+
return this.createColumnRef(expr2.field, context);
|
|
1933
1970
|
} else {
|
|
1934
1971
|
const { memberFilter, memberSelect, ...restContext } = context;
|
|
1935
1972
|
const relation = this.transformRelationAccess(expr2.field, fieldDef.type, restContext);
|
|
@@ -1970,7 +2007,7 @@ var ExpressionTransformer = class {
|
|
|
1970
2007
|
]);
|
|
1971
2008
|
}
|
|
1972
2009
|
if (this.isAuthCall(expr2.left) || this.isAuthCall(expr2.right)) {
|
|
1973
|
-
return this.transformAuthBinary(expr2);
|
|
2010
|
+
return this.transformAuthBinary(expr2, context);
|
|
1974
2011
|
}
|
|
1975
2012
|
const op = expr2.op;
|
|
1976
2013
|
if (op === "?" || op === "!" || op === "^") {
|
|
@@ -2023,11 +2060,10 @@ var ExpressionTransformer = class {
|
|
|
2023
2060
|
let predicateFilter = this.transform(expr2.right, {
|
|
2024
2061
|
...context,
|
|
2025
2062
|
model: newContextModel,
|
|
2026
|
-
alias: void 0
|
|
2027
|
-
thisEntity: void 0
|
|
2063
|
+
alias: void 0
|
|
2028
2064
|
});
|
|
2029
2065
|
if (expr2.op === "!") {
|
|
2030
|
-
predicateFilter = logicalNot(predicateFilter);
|
|
2066
|
+
predicateFilter = logicalNot(this.dialect, predicateFilter);
|
|
2031
2067
|
}
|
|
2032
2068
|
const count = import_kysely6.FunctionNode.create("count", [
|
|
2033
2069
|
import_kysely6.ValueNode.createImmediate(1)
|
|
@@ -2039,20 +2075,38 @@ var ExpressionTransformer = class {
|
|
|
2039
2075
|
memberFilter: predicateFilter
|
|
2040
2076
|
});
|
|
2041
2077
|
}
|
|
2042
|
-
transformAuthBinary(expr2) {
|
|
2078
|
+
transformAuthBinary(expr2, context) {
|
|
2043
2079
|
if (expr2.op !== "==" && expr2.op !== "!=") {
|
|
2044
|
-
throw new
|
|
2080
|
+
throw new QueryError(`Unsupported operator for \`auth()\` in policy of model "${context.model}": ${expr2.op}`);
|
|
2045
2081
|
}
|
|
2082
|
+
let authExpr;
|
|
2046
2083
|
let other;
|
|
2047
2084
|
if (this.isAuthCall(expr2.left)) {
|
|
2085
|
+
authExpr = expr2.left;
|
|
2048
2086
|
other = expr2.right;
|
|
2049
2087
|
} else {
|
|
2088
|
+
authExpr = expr2.right;
|
|
2050
2089
|
other = expr2.left;
|
|
2051
2090
|
}
|
|
2052
2091
|
if (ExpressionUtils.isNull(other)) {
|
|
2053
2092
|
return this.transformValue(expr2.op === "==" ? !this.auth : !!this.auth, "Boolean");
|
|
2054
2093
|
} else {
|
|
2055
|
-
|
|
2094
|
+
const authModel = getModel(this.schema, this.authType);
|
|
2095
|
+
if (!authModel) {
|
|
2096
|
+
throw new QueryError(`Unsupported use of \`auth()\` in policy of model "${context.model}", comparing with \`auth()\` is only possible when auth type is a model`);
|
|
2097
|
+
}
|
|
2098
|
+
const idFields = Object.values(authModel.fields).filter((f) => f.id).map((f) => f.name);
|
|
2099
|
+
(0, import_common_helpers5.invariant)(idFields.length > 0, "auth type model must have at least one id field");
|
|
2100
|
+
const conditions = idFields.map((fieldName) => ExpressionUtils.binary(ExpressionUtils.member(authExpr, [
|
|
2101
|
+
fieldName
|
|
2102
|
+
]), "==", ExpressionUtils.member(other, [
|
|
2103
|
+
fieldName
|
|
2104
|
+
])));
|
|
2105
|
+
let result = this.buildAnd(conditions);
|
|
2106
|
+
if (expr2.op === "!=") {
|
|
2107
|
+
result = this.buildLogicalNot(result);
|
|
2108
|
+
}
|
|
2109
|
+
return this.transform(result, context);
|
|
2056
2110
|
}
|
|
2057
2111
|
}
|
|
2058
2112
|
transformValue(value, type) {
|
|
@@ -2060,7 +2114,7 @@ var ExpressionTransformer = class {
|
|
|
2060
2114
|
}
|
|
2061
2115
|
_unary(expr2, context) {
|
|
2062
2116
|
(0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
|
|
2063
|
-
return
|
|
2117
|
+
return logicalNot(this.dialect, this.transform(expr2.operand, context));
|
|
2064
2118
|
}
|
|
2065
2119
|
transformOperator(op) {
|
|
2066
2120
|
const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
|
|
@@ -2087,7 +2141,7 @@ var ExpressionTransformer = class {
|
|
|
2087
2141
|
return eb.val(arg.value);
|
|
2088
2142
|
}
|
|
2089
2143
|
if (ExpressionUtils.isField(arg)) {
|
|
2090
|
-
return
|
|
2144
|
+
return eb.ref(arg.field);
|
|
2091
2145
|
}
|
|
2092
2146
|
if (ExpressionUtils.isCall(arg)) {
|
|
2093
2147
|
return this.transformCall(arg, context);
|
|
@@ -2102,14 +2156,33 @@ var ExpressionTransformer = class {
|
|
|
2102
2156
|
if (this.isAuthCall(expr2.receiver)) {
|
|
2103
2157
|
return this.valueMemberAccess(this.auth, expr2, this.authType);
|
|
2104
2158
|
}
|
|
2105
|
-
(0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver),
|
|
2159
|
+
(0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver) || ExpressionUtils.isThis(expr2.receiver), 'expect receiver to be field expression or "this"');
|
|
2160
|
+
let members = expr2.members;
|
|
2161
|
+
let receiver;
|
|
2106
2162
|
const { memberFilter, memberSelect, ...restContext } = context;
|
|
2107
|
-
|
|
2163
|
+
if (ExpressionUtils.isThis(expr2.receiver)) {
|
|
2164
|
+
if (expr2.members.length === 1) {
|
|
2165
|
+
const fieldDef = requireField(this.schema, context.model, expr2.members[0]);
|
|
2166
|
+
(0, import_common_helpers5.invariant)(!fieldDef.relation, "this.relation access should have been transformed into relation access");
|
|
2167
|
+
return this.createColumnRef(expr2.members[0], restContext);
|
|
2168
|
+
}
|
|
2169
|
+
const firstMemberFieldDef = requireField(this.schema, context.model, expr2.members[0]);
|
|
2170
|
+
receiver = this.transformRelationAccess(expr2.members[0], firstMemberFieldDef.type, restContext);
|
|
2171
|
+
members = expr2.members.slice(1);
|
|
2172
|
+
} else {
|
|
2173
|
+
receiver = this.transform(expr2.receiver, restContext);
|
|
2174
|
+
}
|
|
2108
2175
|
(0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
|
|
2109
|
-
|
|
2176
|
+
let startType;
|
|
2177
|
+
if (ExpressionUtils.isField(expr2.receiver)) {
|
|
2178
|
+
const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
|
|
2179
|
+
startType = receiverField.type;
|
|
2180
|
+
} else {
|
|
2181
|
+
startType = context.model;
|
|
2182
|
+
}
|
|
2110
2183
|
const memberFields = [];
|
|
2111
|
-
let currType =
|
|
2112
|
-
for (const member of
|
|
2184
|
+
let currType = startType;
|
|
2185
|
+
for (const member of members) {
|
|
2113
2186
|
const fieldDef = requireField(this.schema, currType, member);
|
|
2114
2187
|
memberFields.push({
|
|
2115
2188
|
fieldDef,
|
|
@@ -2118,22 +2191,21 @@ var ExpressionTransformer = class {
|
|
|
2118
2191
|
currType = fieldDef.type;
|
|
2119
2192
|
}
|
|
2120
2193
|
let currNode = void 0;
|
|
2121
|
-
for (let i =
|
|
2122
|
-
const member =
|
|
2194
|
+
for (let i = members.length - 1; i >= 0; i--) {
|
|
2195
|
+
const member = members[i];
|
|
2123
2196
|
const { fieldDef, fromModel } = memberFields[i];
|
|
2124
2197
|
if (fieldDef.relation) {
|
|
2125
2198
|
const relation = this.transformRelationAccess(member, fieldDef.type, {
|
|
2126
2199
|
...restContext,
|
|
2127
2200
|
model: fromModel,
|
|
2128
|
-
alias: void 0
|
|
2129
|
-
thisEntity: void 0
|
|
2201
|
+
alias: void 0
|
|
2130
2202
|
});
|
|
2131
2203
|
if (currNode) {
|
|
2132
2204
|
(0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
|
|
2133
2205
|
currNode = {
|
|
2134
2206
|
...relation,
|
|
2135
2207
|
selections: [
|
|
2136
|
-
import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(currNode, import_kysely6.IdentifierNode.create(
|
|
2208
|
+
import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(currNode, import_kysely6.IdentifierNode.create(members[i + 1])))
|
|
2137
2209
|
]
|
|
2138
2210
|
};
|
|
2139
2211
|
} else {
|
|
@@ -2146,7 +2218,7 @@ var ExpressionTransformer = class {
|
|
|
2146
2218
|
};
|
|
2147
2219
|
}
|
|
2148
2220
|
} else {
|
|
2149
|
-
(0, import_common_helpers5.invariant)(i ===
|
|
2221
|
+
(0, import_common_helpers5.invariant)(i === members.length - 1, "plain field access must be the last segment");
|
|
2150
2222
|
(0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
|
|
2151
2223
|
currNode = import_kysely6.ColumnNode.create(member);
|
|
2152
2224
|
}
|
|
@@ -2173,35 +2245,19 @@ var ExpressionTransformer = class {
|
|
|
2173
2245
|
transformRelationAccess(field, relationModel, context) {
|
|
2174
2246
|
const fromModel = context.model;
|
|
2175
2247
|
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, fromModel, field);
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(relationModel)), import_kysely6.OperatorNode.create("="), context.thisEntity[fk])));
|
|
2180
|
-
} else {
|
|
2181
|
-
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(relationModel)), import_kysely6.OperatorNode.create("="), context.thisEntity[pk])));
|
|
2182
|
-
}
|
|
2183
|
-
return {
|
|
2184
|
-
kind: "SelectQueryNode",
|
|
2185
|
-
from: import_kysely6.FromNode.create([
|
|
2186
|
-
import_kysely6.TableNode.create(relationModel)
|
|
2187
|
-
]),
|
|
2188
|
-
where: import_kysely6.WhereNode.create(condition)
|
|
2189
|
-
};
|
|
2248
|
+
let condition;
|
|
2249
|
+
if (ownedByModel) {
|
|
2250
|
+
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(relationModel)))));
|
|
2190
2251
|
} else {
|
|
2191
|
-
|
|
2192
|
-
if (ownedByModel) {
|
|
2193
|
-
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(relationModel)))));
|
|
2194
|
-
} else {
|
|
2195
|
-
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(relationModel)))));
|
|
2196
|
-
}
|
|
2197
|
-
return {
|
|
2198
|
-
kind: "SelectQueryNode",
|
|
2199
|
-
from: import_kysely6.FromNode.create([
|
|
2200
|
-
import_kysely6.TableNode.create(relationModel)
|
|
2201
|
-
]),
|
|
2202
|
-
where: import_kysely6.WhereNode.create(condition)
|
|
2203
|
-
};
|
|
2252
|
+
condition = conjunction(this.dialect, keyPairs.map(({ fk, pk }) => import_kysely6.BinaryOperationNode.create(import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(pk), import_kysely6.TableNode.create(context.alias ?? fromModel)), import_kysely6.OperatorNode.create("="), import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(fk), import_kysely6.TableNode.create(relationModel)))));
|
|
2204
2253
|
}
|
|
2254
|
+
return {
|
|
2255
|
+
kind: "SelectQueryNode",
|
|
2256
|
+
from: import_kysely6.FromNode.create([
|
|
2257
|
+
import_kysely6.TableNode.create(relationModel)
|
|
2258
|
+
]),
|
|
2259
|
+
where: import_kysely6.WhereNode.create(condition)
|
|
2260
|
+
};
|
|
2205
2261
|
}
|
|
2206
2262
|
createColumnRef(column, context) {
|
|
2207
2263
|
return import_kysely6.ReferenceNode.create(import_kysely6.ColumnNode.create(column), import_kysely6.TableNode.create(context.alias ?? context.model));
|
|
@@ -2215,6 +2271,18 @@ var ExpressionTransformer = class {
|
|
|
2215
2271
|
isNullNode(node) {
|
|
2216
2272
|
return import_kysely6.ValueNode.is(node) && node.value === null;
|
|
2217
2273
|
}
|
|
2274
|
+
buildLogicalNot(result) {
|
|
2275
|
+
return ExpressionUtils.unary("!", result);
|
|
2276
|
+
}
|
|
2277
|
+
buildAnd(conditions) {
|
|
2278
|
+
if (conditions.length === 0) {
|
|
2279
|
+
return ExpressionUtils.literal(true);
|
|
2280
|
+
} else if (conditions.length === 1) {
|
|
2281
|
+
return conditions[0];
|
|
2282
|
+
} else {
|
|
2283
|
+
return conditions.reduce((acc, condition) => ExpressionUtils.binary(acc, "&&", condition));
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2218
2286
|
};
|
|
2219
2287
|
_ts_decorate([
|
|
2220
2288
|
expr("literal"),
|
|
@@ -2344,29 +2412,47 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2344
2412
|
return selectedColumns.every((c) => idFields.includes(c));
|
|
2345
2413
|
}
|
|
2346
2414
|
async enforcePreCreatePolicy(node, proceed) {
|
|
2347
|
-
if (!node.columns || !node.values) {
|
|
2348
|
-
return;
|
|
2349
|
-
}
|
|
2350
2415
|
const model = this.getMutationModel(node);
|
|
2351
|
-
const fields = node.columns
|
|
2352
|
-
const valueRows = this.unwrapCreateValueRows(node.values, model, fields)
|
|
2416
|
+
const fields = node.columns?.map((c) => c.column.name) ?? [];
|
|
2417
|
+
const valueRows = node.values ? this.unwrapCreateValueRows(node.values, model, fields) : [
|
|
2418
|
+
[]
|
|
2419
|
+
];
|
|
2353
2420
|
for (const values of valueRows) {
|
|
2354
|
-
await this.enforcePreCreatePolicyForOne(model, fields, values.map((v) => v.node),
|
|
2421
|
+
await this.enforcePreCreatePolicyForOne(model, fields, values.map((v) => v.node), proceed);
|
|
2355
2422
|
}
|
|
2356
2423
|
}
|
|
2357
|
-
async enforcePreCreatePolicyForOne(model, fields, values,
|
|
2358
|
-
const
|
|
2359
|
-
const
|
|
2360
|
-
for (
|
|
2361
|
-
|
|
2362
|
-
|
|
2424
|
+
async enforcePreCreatePolicyForOne(model, fields, values, proceed) {
|
|
2425
|
+
const allFields = Object.keys(requireModel(this.client.$schema, model).fields);
|
|
2426
|
+
const allValues = [];
|
|
2427
|
+
for (const fieldName of allFields) {
|
|
2428
|
+
const index = fields.indexOf(fieldName);
|
|
2429
|
+
if (index >= 0) {
|
|
2430
|
+
allValues.push(values[index]);
|
|
2431
|
+
} else {
|
|
2432
|
+
allValues.push(import_kysely7.ValueNode.createImmediate(null));
|
|
2433
|
+
}
|
|
2363
2434
|
}
|
|
2364
|
-
const
|
|
2435
|
+
const constTable = {
|
|
2436
|
+
kind: "SelectQueryNode",
|
|
2437
|
+
from: import_kysely7.FromNode.create([
|
|
2438
|
+
import_kysely7.AliasNode.create(import_kysely7.ParensNode.create(import_kysely7.ValuesNode.create([
|
|
2439
|
+
import_kysely7.ValueListNode.create(allValues)
|
|
2440
|
+
])), import_kysely7.IdentifierNode.create("$t"))
|
|
2441
|
+
]),
|
|
2442
|
+
selections: allFields.map((field, index) => import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(import_kysely7.ColumnNode.create(`column${index + 1}`), import_kysely7.IdentifierNode.create(field))))
|
|
2443
|
+
};
|
|
2444
|
+
const filter = this.buildPolicyFilter(model, void 0, "create");
|
|
2365
2445
|
const preCreateCheck = {
|
|
2366
2446
|
kind: "SelectQueryNode",
|
|
2447
|
+
from: import_kysely7.FromNode.create([
|
|
2448
|
+
import_kysely7.AliasNode.create(constTable, import_kysely7.IdentifierNode.create(model))
|
|
2449
|
+
]),
|
|
2367
2450
|
selections: [
|
|
2368
|
-
import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(
|
|
2369
|
-
|
|
2451
|
+
import_kysely7.SelectionNode.create(import_kysely7.AliasNode.create(import_kysely7.BinaryOperationNode.create(import_kysely7.FunctionNode.create("COUNT", [
|
|
2452
|
+
import_kysely7.ValueNode.createImmediate(1)
|
|
2453
|
+
]), import_kysely7.OperatorNode.create(">"), import_kysely7.ValueNode.createImmediate(0)), import_kysely7.IdentifierNode.create("$condition")))
|
|
2454
|
+
],
|
|
2455
|
+
where: import_kysely7.WhereNode.create(filter)
|
|
2370
2456
|
};
|
|
2371
2457
|
const result = await proceed(preCreateCheck);
|
|
2372
2458
|
if (!result.rows[0]?.$condition) {
|
|
@@ -2483,13 +2569,13 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2483
2569
|
isMutationQueryNode(node) {
|
|
2484
2570
|
return import_kysely7.InsertQueryNode.is(node) || import_kysely7.UpdateQueryNode.is(node) || import_kysely7.DeleteQueryNode.is(node);
|
|
2485
2571
|
}
|
|
2486
|
-
buildPolicyFilter(model, alias, operation
|
|
2572
|
+
buildPolicyFilter(model, alias, operation) {
|
|
2487
2573
|
const policies = this.getModelPolicies(model, operation);
|
|
2488
2574
|
if (policies.length === 0) {
|
|
2489
2575
|
return falseNode(this.dialect);
|
|
2490
2576
|
}
|
|
2491
|
-
const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.transformPolicyCondition(model, alias, operation, policy
|
|
2492
|
-
const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.transformPolicyCondition(model, alias, operation, policy
|
|
2577
|
+
const allows = policies.filter((policy) => policy.kind === "allow").map((policy) => this.transformPolicyCondition(model, alias, operation, policy));
|
|
2578
|
+
const denies = policies.filter((policy) => policy.kind === "deny").map((policy) => this.transformPolicyCondition(model, alias, operation, policy));
|
|
2493
2579
|
let combinedPolicy;
|
|
2494
2580
|
if (allows.length === 0) {
|
|
2495
2581
|
combinedPolicy = falseNode(this.dialect);
|
|
@@ -2585,13 +2671,11 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2585
2671
|
return void 0;
|
|
2586
2672
|
}
|
|
2587
2673
|
}
|
|
2588
|
-
transformPolicyCondition(model, alias, operation, policy
|
|
2674
|
+
transformPolicyCondition(model, alias, operation, policy) {
|
|
2589
2675
|
return new ExpressionTransformer(this.client.$schema, this.client.$options, this.client.$auth).transform(policy.condition, {
|
|
2590
2676
|
model,
|
|
2591
2677
|
alias,
|
|
2592
2678
|
operation,
|
|
2593
|
-
thisEntity,
|
|
2594
|
-
thisEntityRaw,
|
|
2595
2679
|
auth: this.client.$auth
|
|
2596
2680
|
});
|
|
2597
2681
|
}
|