@zenstackhq/runtime 3.0.0-alpha.0 → 3.0.0-alpha.10
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-DguafRNB.d.cts → contract-BiU0iYAh.d.cts} +813 -709
- package/dist/{contract-DguafRNB.d.ts → contract-BiU0iYAh.d.ts} +813 -709
- package/dist/{utils/pg-utils.cjs → helpers.cjs} +8 -16
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +1 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +6 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +517 -328
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +466 -282
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy.cjs +115 -104
- package/dist/plugins/policy.cjs.map +1 -1
- package/dist/plugins/policy.d.cts +2 -4
- package/dist/plugins/policy.d.ts +2 -4
- package/dist/plugins/policy.js +87 -66
- package/dist/plugins/policy.js.map +1 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js.map +1 -1
- package/package.json +23 -46
- package/dist/client.cjs +0 -6094
- package/dist/client.cjs.map +0 -1
- package/dist/client.d.cts +0 -19
- package/dist/client.d.ts +0 -19
- package/dist/client.js +0 -6060
- package/dist/client.js.map +0 -1
- package/dist/utils/pg-utils.cjs.map +0 -1
- package/dist/utils/pg-utils.d.cts +0 -8
- package/dist/utils/pg-utils.d.ts +0 -8
- package/dist/utils/pg-utils.js +0 -16
- package/dist/utils/pg-utils.js.map +0 -1
- package/dist/utils/sqlite-utils.cjs +0 -55
- package/dist/utils/sqlite-utils.cjs.map +0 -1
- package/dist/utils/sqlite-utils.d.cts +0 -8
- package/dist/utils/sqlite-utils.d.ts +0 -8
- package/dist/utils/sqlite-utils.js +0 -22
- package/dist/utils/sqlite-utils.js.map +0 -1
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { V as RuntimePlugin, X as OnKyselyQueryArgs } from '../contract-
|
|
2
|
+
import { V as RuntimePlugin, X as OnKyselyQueryArgs } from '../contract-BiU0iYAh.cjs';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
|
-
import 'utility-types';
|
|
6
|
-
import '@zenstackhq/language/ast';
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* Error thrown when an operation is rejected by access policy.
|
|
@@ -18,7 +16,7 @@ declare class PolicyPlugin<Schema extends SchemaDef> implements RuntimePlugin<Sc
|
|
|
18
16
|
get id(): string;
|
|
19
17
|
get name(): string;
|
|
20
18
|
get description(): string;
|
|
21
|
-
onKyselyQuery({ query, client, proceed
|
|
19
|
+
onKyselyQuery({ query, client, proceed }: OnKyselyQueryArgs<Schema>): Promise<kysely.QueryResult<any>>;
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
export { PolicyPlugin, RejectedByPolicyError };
|
package/dist/plugins/policy.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { V as RuntimePlugin, X as OnKyselyQueryArgs } from '../contract-
|
|
2
|
+
import { V as RuntimePlugin, X as OnKyselyQueryArgs } from '../contract-BiU0iYAh.js';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
|
-
import 'utility-types';
|
|
6
|
-
import '@zenstackhq/language/ast';
|
|
7
5
|
|
|
8
6
|
/**
|
|
9
7
|
* Error thrown when an operation is rejected by access policy.
|
|
@@ -18,7 +16,7 @@ declare class PolicyPlugin<Schema extends SchemaDef> implements RuntimePlugin<Sc
|
|
|
18
16
|
get id(): string;
|
|
19
17
|
get name(): string;
|
|
20
18
|
get description(): string;
|
|
21
|
-
onKyselyQuery({ query, client, proceed
|
|
19
|
+
onKyselyQuery({ query, client, proceed }: OnKyselyQueryArgs<Schema>): Promise<kysely.QueryResult<any>>;
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
export { PolicyPlugin, RejectedByPolicyError };
|
package/dist/plugins/policy.js
CHANGED
|
@@ -14,16 +14,16 @@ var RejectedByPolicyError = class extends Error {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// src/plugins/policy/policy-handler.ts
|
|
17
|
+
import { invariant as invariant6 } from "@zenstackhq/common-helpers";
|
|
17
18
|
import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode2, DeleteQueryNode, FromNode as FromNode2, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, TableNode as TableNode3, UpdateQueryNode, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
|
|
18
|
-
import invariant6 from "tiny-invariant";
|
|
19
19
|
import { match as match7 } from "ts-pattern";
|
|
20
20
|
|
|
21
21
|
// src/client/crud/dialects/index.ts
|
|
22
22
|
import { match as match4 } from "ts-pattern";
|
|
23
23
|
|
|
24
24
|
// src/client/crud/dialects/postgresql.ts
|
|
25
|
+
import { invariant as invariant2 } from "@zenstackhq/common-helpers";
|
|
25
26
|
import { sql as sql2 } from "kysely";
|
|
26
|
-
import invariant2 from "tiny-invariant";
|
|
27
27
|
import { match as match2 } from "ts-pattern";
|
|
28
28
|
|
|
29
29
|
// src/client/errors.ts
|
|
@@ -31,17 +31,16 @@ var QueryError = class extends Error {
|
|
|
31
31
|
static {
|
|
32
32
|
__name(this, "QueryError");
|
|
33
33
|
}
|
|
34
|
-
constructor(message) {
|
|
35
|
-
super(message
|
|
34
|
+
constructor(message, cause) {
|
|
35
|
+
super(message, {
|
|
36
|
+
cause
|
|
37
|
+
});
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
40
|
var InternalError = class extends Error {
|
|
39
41
|
static {
|
|
40
42
|
__name(this, "InternalError");
|
|
41
43
|
}
|
|
42
|
-
constructor(message) {
|
|
43
|
-
super(message);
|
|
44
|
-
}
|
|
45
44
|
};
|
|
46
45
|
|
|
47
46
|
// src/client/query-utils.ts
|
|
@@ -52,7 +51,7 @@ __name(getModel, "getModel");
|
|
|
52
51
|
function requireModel(schema, model) {
|
|
53
52
|
const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
|
|
54
53
|
if (!matchedName) {
|
|
55
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
54
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
56
55
|
}
|
|
57
56
|
return schema.models[matchedName];
|
|
58
57
|
}
|
|
@@ -115,6 +114,11 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
|
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
__name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
|
|
117
|
+
function isRelationField(schema, model, field) {
|
|
118
|
+
const fieldDef = requireField(schema, model, field);
|
|
119
|
+
return !!fieldDef.relation;
|
|
120
|
+
}
|
|
121
|
+
__name(isRelationField, "isRelationField");
|
|
118
122
|
function getUniqueFields(schema, model) {
|
|
119
123
|
const modelDef = requireModel(schema, model);
|
|
120
124
|
const result = [];
|
|
@@ -151,7 +155,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
|
|
|
151
155
|
computer = computedFields?.[model]?.[field];
|
|
152
156
|
}
|
|
153
157
|
if (!computer) {
|
|
154
|
-
throw new QueryError(`Computed field "${field}" implementation not provided`);
|
|
158
|
+
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
155
159
|
}
|
|
156
160
|
return computer(eb);
|
|
157
161
|
}
|
|
@@ -230,8 +234,8 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
|
|
|
230
234
|
__name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
|
|
231
235
|
|
|
232
236
|
// src/client/crud/dialects/base.ts
|
|
237
|
+
import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
|
|
233
238
|
import { sql } from "kysely";
|
|
234
|
-
import invariant from "tiny-invariant";
|
|
235
239
|
import { match, P } from "ts-pattern";
|
|
236
240
|
|
|
237
241
|
// src/utils/enumerate.ts
|
|
@@ -249,7 +253,6 @@ function enumerate(x) {
|
|
|
249
253
|
__name(enumerate, "enumerate");
|
|
250
254
|
|
|
251
255
|
// src/client/crud/dialects/base.ts
|
|
252
|
-
import { isPlainObject } from "is-plain-object";
|
|
253
256
|
var BaseCrudDialect = class {
|
|
254
257
|
static {
|
|
255
258
|
__name(this, "BaseCrudDialect");
|
|
@@ -260,7 +263,7 @@ var BaseCrudDialect = class {
|
|
|
260
263
|
this.schema = schema;
|
|
261
264
|
this.options = options;
|
|
262
265
|
}
|
|
263
|
-
transformPrimitive(value, _type) {
|
|
266
|
+
transformPrimitive(value, _type, _forArrayField) {
|
|
264
267
|
return value;
|
|
265
268
|
}
|
|
266
269
|
buildFilter(eb, model, modelAlias, where) {
|
|
@@ -403,7 +406,7 @@ var BaseCrudDialect = class {
|
|
|
403
406
|
if (_value === void 0) {
|
|
404
407
|
continue;
|
|
405
408
|
}
|
|
406
|
-
const value = this.transformPrimitive(_value, fieldType);
|
|
409
|
+
const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
|
|
407
410
|
switch (key) {
|
|
408
411
|
case "equals": {
|
|
409
412
|
clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
|
|
@@ -441,10 +444,14 @@ var BaseCrudDialect = class {
|
|
|
441
444
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
442
445
|
return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
|
|
443
446
|
}
|
|
444
|
-
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).
|
|
447
|
+
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).with("Json", () => {
|
|
448
|
+
throw new InternalError("JSON filters are not supported yet");
|
|
449
|
+
}).with("Unsupported", () => {
|
|
450
|
+
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
451
|
+
}).exhaustive();
|
|
445
452
|
}
|
|
446
453
|
buildLiteralFilter(eb, lhs, type, rhs) {
|
|
447
|
-
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
|
|
454
|
+
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
|
|
448
455
|
}
|
|
449
456
|
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
|
|
450
457
|
if (payload === null || !isPlainObject(payload)) {
|
|
@@ -531,22 +538,22 @@ var BaseCrudDialect = class {
|
|
|
531
538
|
}
|
|
532
539
|
}
|
|
533
540
|
buildNumberFilter(eb, model, table, field, type, payload) {
|
|
534
|
-
const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
|
|
541
|
+
const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
|
|
535
542
|
return this.and(eb, ...conditions);
|
|
536
543
|
}
|
|
537
544
|
buildBooleanFilter(eb, table, field, payload) {
|
|
538
|
-
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean"), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
|
|
545
|
+
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
|
|
539
546
|
"equals",
|
|
540
547
|
"not"
|
|
541
548
|
]);
|
|
542
549
|
return this.and(eb, ...conditions);
|
|
543
550
|
}
|
|
544
551
|
buildDateTimeFilter(eb, table, field, payload) {
|
|
545
|
-
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime"), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
|
|
552
|
+
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
|
|
546
553
|
return this.and(eb, ...conditions);
|
|
547
554
|
}
|
|
548
555
|
buildBytesFilter(eb, table, field, payload) {
|
|
549
|
-
const conditions = this.buildStandardFilter(eb, "Bytes", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes"), (value) => this.buildBytesFilter(eb, table, field, value), true, [
|
|
556
|
+
const conditions = this.buildStandardFilter(eb, "Bytes", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
|
|
550
557
|
"equals",
|
|
551
558
|
"in",
|
|
552
559
|
"notIn",
|
|
@@ -645,10 +652,10 @@ var BaseCrudDialect = class {
|
|
|
645
652
|
return negated ? sort === "asc" ? "desc" : "asc" : sort;
|
|
646
653
|
}
|
|
647
654
|
true(eb) {
|
|
648
|
-
return eb.lit(this.transformPrimitive(true, "Boolean"));
|
|
655
|
+
return eb.lit(this.transformPrimitive(true, "Boolean", false));
|
|
649
656
|
}
|
|
650
657
|
false(eb) {
|
|
651
|
-
return eb.lit(this.transformPrimitive(false, "Boolean"));
|
|
658
|
+
return eb.lit(this.transformPrimitive(false, "Boolean", false));
|
|
652
659
|
}
|
|
653
660
|
isTrue(expression) {
|
|
654
661
|
const node = expression.toOperationNode();
|
|
@@ -697,14 +704,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
697
704
|
get provider() {
|
|
698
705
|
return "postgresql";
|
|
699
706
|
}
|
|
700
|
-
transformPrimitive(value, type) {
|
|
707
|
+
transformPrimitive(value, type, forArrayField) {
|
|
701
708
|
if (value === void 0) {
|
|
702
709
|
return value;
|
|
703
710
|
}
|
|
704
711
|
if (Array.isArray(value)) {
|
|
705
|
-
|
|
712
|
+
if (type === "Json" && !forArrayField) {
|
|
713
|
+
return JSON.stringify(value);
|
|
714
|
+
} else {
|
|
715
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
716
|
+
}
|
|
706
717
|
} else {
|
|
707
|
-
return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
|
|
718
|
+
return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
|
|
708
719
|
}
|
|
709
720
|
}
|
|
710
721
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -771,25 +782,33 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
771
782
|
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
772
783
|
]).flatMap((v) => v));
|
|
773
784
|
} else if (payload.select) {
|
|
774
|
-
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) =>
|
|
775
|
-
|
|
776
|
-
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
777
|
-
|
|
785
|
+
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => {
|
|
786
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
787
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentName}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
|
|
788
|
+
return [
|
|
789
|
+
sql2.lit(field),
|
|
790
|
+
fieldValue
|
|
791
|
+
];
|
|
792
|
+
}).flatMap((v) => v));
|
|
778
793
|
}
|
|
779
794
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
780
795
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
781
796
|
sql2.lit(field),
|
|
797
|
+
// reference the synthesized JSON field
|
|
782
798
|
eb.ref(`${parentName}$${relationField}$${field}.$j`)
|
|
783
799
|
]).flatMap((v) => v));
|
|
784
800
|
}
|
|
785
801
|
return objArgs;
|
|
786
802
|
}
|
|
787
|
-
buildRelationJoins(
|
|
803
|
+
buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
|
|
788
804
|
let result = qb;
|
|
789
|
-
if (typeof payload === "object"
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
805
|
+
if (typeof payload === "object") {
|
|
806
|
+
const selectInclude = payload.include ?? payload.select;
|
|
807
|
+
if (selectInclude && typeof selectInclude === "object") {
|
|
808
|
+
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
809
|
+
result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
|
|
810
|
+
});
|
|
811
|
+
}
|
|
793
812
|
}
|
|
794
813
|
return result;
|
|
795
814
|
}
|
|
@@ -832,8 +851,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
832
851
|
};
|
|
833
852
|
|
|
834
853
|
// src/client/crud/dialects/sqlite.ts
|
|
854
|
+
import { invariant as invariant3 } from "@zenstackhq/common-helpers";
|
|
835
855
|
import { sql as sql3 } from "kysely";
|
|
836
|
-
import invariant3 from "tiny-invariant";
|
|
837
856
|
import { match as match3 } from "ts-pattern";
|
|
838
857
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
839
858
|
static {
|
|
@@ -842,14 +861,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
842
861
|
get provider() {
|
|
843
862
|
return "sqlite";
|
|
844
863
|
}
|
|
845
|
-
transformPrimitive(value, type) {
|
|
864
|
+
transformPrimitive(value, type, _forArrayField) {
|
|
846
865
|
if (value === void 0) {
|
|
847
866
|
return value;
|
|
848
867
|
}
|
|
849
868
|
if (Array.isArray(value)) {
|
|
850
|
-
return value.map((v) => this.transformPrimitive(v, type));
|
|
869
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
851
870
|
} else {
|
|
852
|
-
return match3(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).otherwise(() => value);
|
|
871
|
+
return match3(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
|
|
853
872
|
}
|
|
854
873
|
}
|
|
855
874
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -1377,12 +1396,12 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
|
|
|
1377
1396
|
};
|
|
1378
1397
|
|
|
1379
1398
|
// src/plugins/policy/expression-transformer.ts
|
|
1399
|
+
import { invariant as invariant5 } from "@zenstackhq/common-helpers";
|
|
1380
1400
|
import { AliasNode as AliasNode2, BinaryOperationNode as BinaryOperationNode2, ColumnNode, expressionBuilder, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode2, SelectionNode, SelectQueryNode, TableNode as TableNode2, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
|
|
1381
|
-
import invariant5 from "tiny-invariant";
|
|
1382
1401
|
import { match as match6 } from "ts-pattern";
|
|
1383
1402
|
|
|
1384
1403
|
// src/plugins/policy/expression-evaluator.ts
|
|
1385
|
-
import invariant4 from "
|
|
1404
|
+
import { invariant as invariant4 } from "@zenstackhq/common-helpers";
|
|
1386
1405
|
import { match as match5 } from "ts-pattern";
|
|
1387
1406
|
var ExpressionEvaluator = class {
|
|
1388
1407
|
static {
|
|
@@ -1454,11 +1473,11 @@ var ExpressionEvaluator = class {
|
|
|
1454
1473
|
// src/plugins/policy/utils.ts
|
|
1455
1474
|
import { AliasNode, AndNode, BinaryOperationNode, FunctionNode, OperatorNode, OrNode, ParensNode, ReferenceNode, TableNode, UnaryOperationNode, ValueNode } from "kysely";
|
|
1456
1475
|
function trueNode(dialect) {
|
|
1457
|
-
return ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
|
|
1476
|
+
return ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
|
|
1458
1477
|
}
|
|
1459
1478
|
__name(trueNode, "trueNode");
|
|
1460
1479
|
function falseNode(dialect) {
|
|
1461
|
-
return ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
|
|
1480
|
+
return ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
|
|
1462
1481
|
}
|
|
1463
1482
|
__name(falseNode, "falseNode");
|
|
1464
1483
|
function isTrueNode(node) {
|
|
@@ -1716,7 +1735,7 @@ var ExpressionTransformer = class {
|
|
|
1716
1735
|
}
|
|
1717
1736
|
}
|
|
1718
1737
|
transformValue(value, type) {
|
|
1719
|
-
return ValueNode2.create(this.dialect.transformPrimitive(value, type) ?? null);
|
|
1738
|
+
return ValueNode2.create(this.dialect.transformPrimitive(value, type, false) ?? null);
|
|
1720
1739
|
}
|
|
1721
1740
|
_unary(expr2, context) {
|
|
1722
1741
|
invariant5(expr2.op === "!", 'only "!" operator is supported');
|
|
@@ -1959,7 +1978,7 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
1959
1978
|
get kysely() {
|
|
1960
1979
|
return this.client.$qb;
|
|
1961
1980
|
}
|
|
1962
|
-
async handle(node, proceed
|
|
1981
|
+
async handle(node, proceed) {
|
|
1963
1982
|
if (!this.isCrudQueryNode(node)) {
|
|
1964
1983
|
throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
|
|
1965
1984
|
}
|
|
@@ -1979,27 +1998,20 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
1979
1998
|
if (!mutationRequiresTransaction && !node.returning) {
|
|
1980
1999
|
return proceed(this.transformNode(node));
|
|
1981
2000
|
}
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
const
|
|
1989
|
-
if (
|
|
1990
|
-
|
|
1991
|
-
if (readBackResult.rows.length !== result2.rows.length) {
|
|
1992
|
-
readBackError = true;
|
|
1993
|
-
}
|
|
1994
|
-
return readBackResult;
|
|
1995
|
-
} else {
|
|
1996
|
-
return result2;
|
|
2001
|
+
if (InsertQueryNode.is(node)) {
|
|
2002
|
+
await this.enforcePreCreatePolicy(node, proceed);
|
|
2003
|
+
}
|
|
2004
|
+
const transformedNode = this.transformNode(node);
|
|
2005
|
+
const result = await proceed(transformedNode);
|
|
2006
|
+
if (!this.onlyReturningId(node)) {
|
|
2007
|
+
const readBackResult = await this.processReadBack(node, result, proceed);
|
|
2008
|
+
if (readBackResult.rows.length !== result.rows.length) {
|
|
2009
|
+
throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
|
|
1997
2010
|
}
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2011
|
+
return readBackResult;
|
|
2012
|
+
} else {
|
|
2013
|
+
return result;
|
|
2001
2014
|
}
|
|
2002
|
-
return result;
|
|
2003
2015
|
}
|
|
2004
2016
|
onlyReturningId(node) {
|
|
2005
2017
|
if (!node.returning) {
|
|
@@ -2060,11 +2072,11 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
2060
2072
|
if (typeof item === "object" && item && "kind" in item) {
|
|
2061
2073
|
invariant6(item.kind === "ValueNode", "expecting a ValueNode");
|
|
2062
2074
|
result.push({
|
|
2063
|
-
node: ValueNode3.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
|
|
2075
|
+
node: ValueNode3.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
|
|
2064
2076
|
raw: item.value
|
|
2065
2077
|
});
|
|
2066
2078
|
} else {
|
|
2067
|
-
const value = this.dialect.transformPrimitive(item, fieldDef.type);
|
|
2079
|
+
const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
|
|
2068
2080
|
if (Array.isArray(value)) {
|
|
2069
2081
|
result.push({
|
|
2070
2082
|
node: RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
|
|
@@ -2295,9 +2307,18 @@ var PolicyPlugin = class {
|
|
|
2295
2307
|
get description() {
|
|
2296
2308
|
return "Enforces access policies defined in the schema.";
|
|
2297
2309
|
}
|
|
2298
|
-
onKyselyQuery({
|
|
2310
|
+
onKyselyQuery({
|
|
2311
|
+
query,
|
|
2312
|
+
client,
|
|
2313
|
+
proceed
|
|
2314
|
+
/*, transaction*/
|
|
2315
|
+
}) {
|
|
2299
2316
|
const handler = new PolicyHandler(client);
|
|
2300
|
-
return handler.handle(
|
|
2317
|
+
return handler.handle(
|
|
2318
|
+
query,
|
|
2319
|
+
proceed
|
|
2320
|
+
/*, transaction*/
|
|
2321
|
+
);
|
|
2301
2322
|
}
|
|
2302
2323
|
};
|
|
2303
2324
|
export {
|