zenstack 1.0.0-beta.1 → 1.0.0-beta.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/README.md +12 -4
- package/cli/cli-util.js +1 -1
- package/cli/cli-util.js.map +1 -1
- package/cli/plugin-runner.d.ts +2 -1
- package/cli/plugin-runner.js +101 -47
- package/cli/plugin-runner.js.map +1 -1
- package/language-server/constants.d.ts +0 -4
- package/language-server/constants.js +1 -14
- package/language-server/constants.js.map +1 -1
- package/language-server/validator/datamodel-validator.js +8 -3
- package/language-server/validator/datamodel-validator.js.map +1 -1
- package/language-server/validator/expression-validator.js +38 -1
- package/language-server/validator/expression-validator.js.map +1 -1
- package/language-server/validator/function-decl-validator.d.ts +9 -0
- package/language-server/validator/function-decl-validator.js +15 -0
- package/language-server/validator/function-decl-validator.js.map +1 -0
- package/language-server/validator/function-invocation-validator.js +31 -5
- package/language-server/validator/function-invocation-validator.js.map +1 -1
- package/language-server/validator/utils.d.ts +3 -3
- package/language-server/validator/utils.js.map +1 -1
- package/language-server/validator/zmodel-validator.d.ts +2 -1
- package/language-server/validator/zmodel-validator.js +8 -3
- package/language-server/validator/zmodel-validator.js.map +1 -1
- package/language-server/zmodel-linker.d.ts +1 -0
- package/language-server/zmodel-linker.js +43 -1
- package/language-server/zmodel-linker.js.map +1 -1
- package/package.json +8 -15
- package/plugins/access-policy/expression-writer.js +33 -12
- package/plugins/access-policy/expression-writer.js.map +1 -1
- package/plugins/access-policy/policy-guard-generator.js +33 -22
- package/plugins/access-policy/policy-guard-generator.js.map +1 -1
- package/plugins/model-meta/index.js +18 -3
- package/plugins/model-meta/index.js.map +1 -1
- package/plugins/plugin-utils.d.ts +4 -0
- package/plugins/plugin-utils.js +16 -1
- package/plugins/plugin-utils.js.map +1 -1
- package/plugins/prisma/prisma-builder.d.ts +3 -1
- package/plugins/prisma/prisma-builder.js +9 -3
- package/plugins/prisma/prisma-builder.js.map +1 -1
- package/plugins/prisma/schema-generator.js +34 -5
- package/plugins/prisma/schema-generator.js.map +1 -1
- package/plugins/zod/generator.js +157 -18
- package/plugins/zod/generator.js.map +1 -1
- package/plugins/zod/index.d.ts +1 -1
- package/plugins/zod/transformer.d.ts +4 -4
- package/plugins/zod/transformer.js +134 -82
- package/plugins/zod/transformer.js.map +1 -1
- package/plugins/zod/types.d.ts +2 -0
- package/plugins/zod/utils/schema-gen.d.ts +3 -0
- package/plugins/zod/utils/schema-gen.js +178 -0
- package/plugins/zod/utils/schema-gen.js.map +1 -0
- package/res/stdlib.zmodel +102 -29
- package/telemetry.d.ts +1 -0
- package/telemetry.js +3 -1
- package/telemetry.js.map +1 -1
- package/utils/ast-utils.d.ts +1 -14
- package/utils/ast-utils.js +3 -71
- package/utils/ast-utils.js.map +1 -1
- package/utils/pkg-utils.js +1 -1
- package/utils/pkg-utils.js.map +1 -1
- package/utils/typescript-expression-transformer.d.ts +53 -0
- package/utils/typescript-expression-transformer.js +295 -0
- package/utils/typescript-expression-transformer.js.map +1 -0
- package/plugins/access-policy/typescript-expression-transformer.d.ts +0 -28
- package/plugins/access-policy/typescript-expression-transformer.js +0 -180
- package/plugins/access-policy/typescript-expression-transformer.js.map +0 -1
- package/plugins/access-policy/zod-schema-generator.d.ts +0 -12
- package/plugins/access-policy/zod-schema-generator.js +0 -160
- package/plugins/access-policy/zod-schema-generator.js.map +0 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeValidationRefinements = exports.makeFieldSchema = void 0;
|
|
4
|
+
const sdk_1 = require("@zenstackhq/sdk");
|
|
5
|
+
const ast_1 = require("@zenstackhq/sdk/ast");
|
|
6
|
+
const upper_case_first_1 = require("upper-case-first");
|
|
7
|
+
const __1 = require("..");
|
|
8
|
+
const typescript_expression_transformer_1 = require("../../../utils/typescript-expression-transformer");
|
|
9
|
+
function makeFieldSchema(field) {
|
|
10
|
+
var _a;
|
|
11
|
+
let schema = makeZodSchema(field);
|
|
12
|
+
for (const attr of field.attributes) {
|
|
13
|
+
const message = getAttrLiteralArg(attr, 'message');
|
|
14
|
+
const messageArg = message ? `, { message: ${JSON.stringify(message)} }` : '';
|
|
15
|
+
const messageArgFirst = message ? `{ message: ${JSON.stringify(message)} }` : '';
|
|
16
|
+
switch ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) {
|
|
17
|
+
case '@length': {
|
|
18
|
+
const min = getAttrLiteralArg(attr, 'min');
|
|
19
|
+
if (min) {
|
|
20
|
+
schema += `.min(${min}${messageArg})`;
|
|
21
|
+
}
|
|
22
|
+
const max = getAttrLiteralArg(attr, 'max');
|
|
23
|
+
if (max) {
|
|
24
|
+
schema += `.max(${max}${messageArg})`;
|
|
25
|
+
}
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
case '@contains': {
|
|
29
|
+
const expr = getAttrLiteralArg(attr, 'text');
|
|
30
|
+
if (expr) {
|
|
31
|
+
schema += `.includes(${JSON.stringify(expr)}${messageArg})`;
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case '@regex': {
|
|
36
|
+
const expr = getAttrLiteralArg(attr, 'regex');
|
|
37
|
+
if (expr) {
|
|
38
|
+
schema += `.regex(new RegExp(${JSON.stringify(expr)})${messageArg})`;
|
|
39
|
+
}
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case '@startsWith': {
|
|
43
|
+
const text = getAttrLiteralArg(attr, 'text');
|
|
44
|
+
if (text) {
|
|
45
|
+
schema += `.startsWith(${JSON.stringify(text)}${messageArg})`;
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case '@endsWith': {
|
|
50
|
+
const text = getAttrLiteralArg(attr, 'text');
|
|
51
|
+
if (text) {
|
|
52
|
+
schema += `.endsWith(${JSON.stringify(text)}${messageArg})`;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
case '@email': {
|
|
57
|
+
schema += `.email(${messageArgFirst})`;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case '@url': {
|
|
61
|
+
schema += `.url(${messageArgFirst})`;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
case '@datetime': {
|
|
65
|
+
schema += `.datetime({ offset: true${message ? ', message: ' + JSON.stringify(message) : ''} })`;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case '@gt': {
|
|
69
|
+
const value = getAttrLiteralArg(attr, 'value');
|
|
70
|
+
if (value !== undefined) {
|
|
71
|
+
schema += `.gt(${value}${messageArg})`;
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case '@gte': {
|
|
76
|
+
const value = getAttrLiteralArg(attr, 'value');
|
|
77
|
+
if (value !== undefined) {
|
|
78
|
+
schema += `.gte(${value}${messageArg})`;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
case '@lt': {
|
|
83
|
+
const value = getAttrLiteralArg(attr, 'value');
|
|
84
|
+
if (value !== undefined) {
|
|
85
|
+
schema += `.lt(${value}${messageArg})`;
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case '@lte': {
|
|
90
|
+
const value = getAttrLiteralArg(attr, 'value');
|
|
91
|
+
if (value !== undefined) {
|
|
92
|
+
schema += `.lte(${value}${messageArg})`;
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (field.type.optional) {
|
|
99
|
+
schema += '.nullish()';
|
|
100
|
+
}
|
|
101
|
+
return schema;
|
|
102
|
+
}
|
|
103
|
+
exports.makeFieldSchema = makeFieldSchema;
|
|
104
|
+
function makeZodSchema(field) {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
let schema;
|
|
107
|
+
if (((_a = field.type.reference) === null || _a === void 0 ? void 0 : _a.ref) && (0, ast_1.isEnum)((_b = field.type.reference) === null || _b === void 0 ? void 0 : _b.ref)) {
|
|
108
|
+
schema = `${(0, upper_case_first_1.upperCaseFirst)(field.type.reference.ref.name)}Schema`;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
switch (field.type.type) {
|
|
112
|
+
case 'Int':
|
|
113
|
+
case 'Float':
|
|
114
|
+
schema = 'z.number()';
|
|
115
|
+
break;
|
|
116
|
+
case 'Decimal':
|
|
117
|
+
schema = 'DecimalSchema';
|
|
118
|
+
break;
|
|
119
|
+
case 'BigInt':
|
|
120
|
+
schema = 'z.bigint()';
|
|
121
|
+
break;
|
|
122
|
+
case 'String':
|
|
123
|
+
schema = 'z.string()';
|
|
124
|
+
break;
|
|
125
|
+
case 'Boolean':
|
|
126
|
+
schema = 'z.boolean()';
|
|
127
|
+
break;
|
|
128
|
+
case 'DateTime':
|
|
129
|
+
schema = 'z.date()';
|
|
130
|
+
break;
|
|
131
|
+
case 'Bytes':
|
|
132
|
+
schema = 'z.union([z.string(), z.instanceof(Uint8Array)])';
|
|
133
|
+
break;
|
|
134
|
+
default:
|
|
135
|
+
schema = 'z.any()';
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (field.type.array) {
|
|
140
|
+
schema = `z.array(${schema})`;
|
|
141
|
+
}
|
|
142
|
+
return schema;
|
|
143
|
+
}
|
|
144
|
+
function makeValidationRefinements(model) {
|
|
145
|
+
const attrs = model.attributes.filter((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@validate'; });
|
|
146
|
+
const refinements = attrs
|
|
147
|
+
.map((attr) => {
|
|
148
|
+
const valueArg = (0, sdk_1.getAttributeArg)(attr, 'value');
|
|
149
|
+
if (!valueArg) {
|
|
150
|
+
return undefined;
|
|
151
|
+
}
|
|
152
|
+
const messageArg = (0, sdk_1.getAttributeArgLiteral)(attr, 'message');
|
|
153
|
+
const message = messageArg ? `, { message: ${JSON.stringify(messageArg)} }` : '';
|
|
154
|
+
try {
|
|
155
|
+
const expr = new typescript_expression_transformer_1.TypeScriptExpressionTransformer({
|
|
156
|
+
context: sdk_1.ExpressionContext.ValidationRule,
|
|
157
|
+
fieldReferenceContext: 'value',
|
|
158
|
+
}).transform(valueArg);
|
|
159
|
+
return `.refine((value: any) => ${expr}${message})`;
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
if (err instanceof typescript_expression_transformer_1.TypeScriptExpressionTransformerError) {
|
|
163
|
+
throw new sdk_1.PluginError(__1.name, err.message);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
throw err;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
})
|
|
170
|
+
.filter((r) => !!r);
|
|
171
|
+
return refinements;
|
|
172
|
+
}
|
|
173
|
+
exports.makeValidationRefinements = makeValidationRefinements;
|
|
174
|
+
function getAttrLiteralArg(attr, paramName) {
|
|
175
|
+
const arg = attr.args.find((arg) => { var _a; return ((_a = arg.$resolvedParam) === null || _a === void 0 ? void 0 : _a.name) === paramName; });
|
|
176
|
+
return arg && (0, sdk_1.getLiteral)(arg.value);
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=schema-gen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-gen.js","sourceRoot":"","sources":["../../../../src/plugins/zod/utils/schema-gen.ts"],"names":[],"mappings":"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"}
|
package/res/stdlib.zmodel
CHANGED
|
@@ -49,6 +49,20 @@ enum AttributeTargetField {
|
|
|
49
49
|
ModelField
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Indicates the expression context a function can be used.
|
|
54
|
+
*/
|
|
55
|
+
enum ExpressionContext {
|
|
56
|
+
// used in @default
|
|
57
|
+
DefaultValue
|
|
58
|
+
|
|
59
|
+
// used in @@allow and @@deny
|
|
60
|
+
AccessPolicy
|
|
61
|
+
|
|
62
|
+
// used in @@validate
|
|
63
|
+
ValidationRule
|
|
64
|
+
}
|
|
65
|
+
|
|
52
66
|
/**
|
|
53
67
|
* Reads value from an environment variable.
|
|
54
68
|
*/
|
|
@@ -59,99 +73,109 @@ function env(name: String): String {
|
|
|
59
73
|
* Gets the current login user.
|
|
60
74
|
*/
|
|
61
75
|
function auth(): Any {
|
|
62
|
-
}
|
|
76
|
+
} @@@expressionContext([AccessPolicy])
|
|
63
77
|
|
|
64
78
|
/**
|
|
65
79
|
* Gets current date-time (as DateTime type).
|
|
66
80
|
*/
|
|
67
81
|
function now(): DateTime {
|
|
68
|
-
}
|
|
82
|
+
} @@@expressionContext([DefaultValue, AccessPolicy, ValidationRule])
|
|
69
83
|
|
|
70
84
|
/**
|
|
71
85
|
* Generates a globally unique identifier based on the UUID specs.
|
|
72
86
|
*/
|
|
73
87
|
function uuid(): String {
|
|
74
|
-
}
|
|
88
|
+
} @@@expressionContext([DefaultValue])
|
|
75
89
|
|
|
76
90
|
/**
|
|
77
91
|
* Generates a globally unique identifier based on the CUID spec.
|
|
78
92
|
*/
|
|
79
93
|
function cuid(): String {
|
|
80
|
-
}
|
|
94
|
+
} @@@expressionContext([DefaultValue])
|
|
81
95
|
|
|
82
96
|
/**
|
|
83
97
|
* Creates a sequence of integers in the underlying database and assign the incremented
|
|
84
98
|
* values to the ID values of the created records based on the sequence.
|
|
85
99
|
*/
|
|
86
100
|
function autoincrement(): Int {
|
|
87
|
-
}
|
|
101
|
+
} @@@expressionContext([DefaultValue])
|
|
88
102
|
|
|
89
103
|
/**
|
|
90
104
|
* Represents default values that cannot be expressed in the Prisma schema (such as random()).
|
|
91
105
|
*/
|
|
92
106
|
function dbgenerated(expr: String): Any {
|
|
93
|
-
}
|
|
107
|
+
} @@@expressionContext([DefaultValue])
|
|
94
108
|
|
|
95
109
|
/**
|
|
96
110
|
* Gets entities value before an update. Only valid when used in a "update" policy rule.
|
|
97
111
|
*/
|
|
98
112
|
function future(): Any {
|
|
99
|
-
}
|
|
113
|
+
} @@@expressionContext([AccessPolicy])
|
|
100
114
|
|
|
101
115
|
/**
|
|
102
116
|
* If the field value contains the search string. By default, the search is case-sensitive,
|
|
103
117
|
* but you can override the behavior with the "caseInSensitive" argument.
|
|
104
118
|
*/
|
|
105
119
|
function contains(field: String, search: String, caseInSensitive: Boolean?): Boolean {
|
|
106
|
-
}
|
|
120
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
107
121
|
|
|
108
122
|
/**
|
|
109
123
|
* If the field value matches the search condition with [full-text-search](https://www.prisma.io/docs/concepts/components/prisma-client/full-text-search). Need to enable "fullTextSearch" preview feature to use.
|
|
110
124
|
*/
|
|
111
125
|
function search(field: String, search: String): Boolean {
|
|
112
|
-
}
|
|
126
|
+
} @@@expressionContext([AccessPolicy])
|
|
113
127
|
|
|
114
128
|
/**
|
|
115
129
|
* If the field value starts with the search string
|
|
116
130
|
*/
|
|
117
131
|
function startsWith(field: String, search: String): Boolean {
|
|
118
|
-
}
|
|
132
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
119
133
|
|
|
120
134
|
/**
|
|
121
135
|
* If the field value ends with the search string
|
|
122
136
|
*/
|
|
123
137
|
function endsWith(field: String, search: String): Boolean {
|
|
124
|
-
}
|
|
138
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
125
139
|
|
|
126
140
|
/**
|
|
127
141
|
* If the field value (a list) has the given search value
|
|
128
142
|
*/
|
|
129
143
|
function has(field: Any[], search: Any): Boolean {
|
|
130
|
-
}
|
|
144
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
131
145
|
|
|
132
146
|
/**
|
|
133
147
|
* If the field value (a list) has every element of the search list
|
|
134
148
|
*/
|
|
135
149
|
function hasEvery(field: Any[], search: Any[]): Boolean {
|
|
136
|
-
}
|
|
150
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
137
151
|
|
|
138
152
|
/**
|
|
139
153
|
* If the field value (a list) has at least one element of the search list
|
|
140
154
|
*/
|
|
141
155
|
function hasSome(field: Any[], search: Any[]): Boolean {
|
|
142
|
-
}
|
|
156
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
143
157
|
|
|
144
158
|
/**
|
|
145
159
|
* If the field value (a list) is empty
|
|
146
160
|
*/
|
|
147
161
|
function isEmpty(field: Any[]): Boolean {
|
|
148
|
-
}
|
|
162
|
+
} @@@expressionContext([AccessPolicy, ValidationRule])
|
|
149
163
|
|
|
150
164
|
/**
|
|
151
165
|
* Marks an attribute to be only applicable to certain field types.
|
|
152
166
|
*/
|
|
153
167
|
attribute @@@targetField(targetField: AttributeTargetField[])
|
|
154
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Marks an attribute to be used for data validation.
|
|
171
|
+
*/
|
|
172
|
+
attribute @@@validation()
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Indicates the expression context a function can be used.
|
|
176
|
+
*/
|
|
177
|
+
attribute @@@expressionContext(_ context: ExpressionContext[])
|
|
178
|
+
|
|
155
179
|
/**
|
|
156
180
|
* Indicates an attribute is directly supported by the Prisma schema.
|
|
157
181
|
*/
|
|
@@ -351,60 +375,109 @@ attribute @password(saltLength: Int?, salt: String?) @@@targetField([StringField
|
|
|
351
375
|
*/
|
|
352
376
|
attribute @omit()
|
|
353
377
|
|
|
378
|
+
//////////////////////////////////////////////
|
|
379
|
+
// Begin validation attributes and functions
|
|
380
|
+
//////////////////////////////////////////////
|
|
381
|
+
|
|
354
382
|
/**
|
|
355
383
|
* Validates length of a string field.
|
|
356
384
|
*/
|
|
357
|
-
attribute @length(_ min: Int?, _ max: Int?) @@@targetField([StringField])
|
|
385
|
+
attribute @length(_ min: Int?, _ max: Int?, _ message: String?) @@@targetField([StringField]) @@@validation
|
|
358
386
|
|
|
359
387
|
/**
|
|
360
|
-
* Validates a string field value
|
|
388
|
+
* Validates a string field value starts with the given text.
|
|
361
389
|
*/
|
|
362
|
-
attribute @
|
|
390
|
+
attribute @startsWith(_ text: String, _ message: String?) @@@targetField([StringField]) @@@validation
|
|
363
391
|
|
|
364
392
|
/**
|
|
365
|
-
* Validates a string field value
|
|
393
|
+
* Validates a string field value ends with the given text.
|
|
366
394
|
*/
|
|
367
|
-
attribute @
|
|
395
|
+
attribute @endsWith(_ text: String, _ message: String?) @@@targetField([StringField]) @@@validation
|
|
368
396
|
|
|
369
397
|
/**
|
|
370
|
-
* Validates a string field value
|
|
398
|
+
* Validates a string field value contains the given text.
|
|
399
|
+
*/
|
|
400
|
+
attribute @contains(_ text: String, _ message: String?) @@@targetField([StringField]) @@@validation
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Validates a string field value matches a regex.
|
|
371
404
|
*/
|
|
372
|
-
attribute @
|
|
405
|
+
attribute @regex(_ regex: String, _ message: String?) @@@targetField([StringField]) @@@validation
|
|
373
406
|
|
|
374
407
|
/**
|
|
375
408
|
* Validates a string field value is a valid email address.
|
|
376
409
|
*/
|
|
377
|
-
attribute @email() @@@targetField([StringField])
|
|
410
|
+
attribute @email(_ message: String?) @@@targetField([StringField]) @@@validation
|
|
378
411
|
|
|
379
412
|
/**
|
|
380
413
|
* Validates a string field value is a valid ISO datetime.
|
|
381
414
|
*/
|
|
382
|
-
attribute @datetime() @@@targetField([StringField])
|
|
415
|
+
attribute @datetime(_ message: String?) @@@targetField([StringField]) @@@validation
|
|
383
416
|
|
|
384
417
|
/**
|
|
385
418
|
* Validates a string field value is a valid url.
|
|
386
419
|
*/
|
|
387
|
-
attribute @url() @@@targetField([StringField])
|
|
420
|
+
attribute @url(_ message: String?) @@@targetField([StringField]) @@@validation
|
|
388
421
|
|
|
389
422
|
/**
|
|
390
423
|
* Validates a number field is greater than the given value.
|
|
391
424
|
*/
|
|
392
|
-
attribute @gt(_ value: Int) @@@targetField([IntField, FloatField, DecimalField])
|
|
425
|
+
attribute @gt(_ value: Int, _ message: String?) @@@targetField([IntField, FloatField, DecimalField]) @@@validation
|
|
393
426
|
|
|
394
427
|
/**
|
|
395
428
|
* Validates a number field is greater than or equal to the given value.
|
|
396
429
|
*/
|
|
397
|
-
attribute @gte(_ value: Int) @@@targetField([IntField, FloatField, DecimalField])
|
|
430
|
+
attribute @gte(_ value: Int, _ message: String?) @@@targetField([IntField, FloatField, DecimalField]) @@@validation
|
|
398
431
|
|
|
399
432
|
/**
|
|
400
433
|
* Validates a number field is less than the given value.
|
|
401
434
|
*/
|
|
402
|
-
attribute @lt(_ value: Int) @@@targetField([IntField, FloatField, DecimalField])
|
|
435
|
+
attribute @lt(_ value: Int, _ message: String?) @@@targetField([IntField, FloatField, DecimalField]) @@@validation
|
|
403
436
|
|
|
404
437
|
/**
|
|
405
438
|
* Validates a number field is less than or equal to the given value.
|
|
406
439
|
*/
|
|
407
|
-
attribute @lte(_ value: Int) @@@targetField([IntField, FloatField, DecimalField])
|
|
440
|
+
attribute @lte(_ value: Int, _ message: String?) @@@targetField([IntField, FloatField, DecimalField]) @@@validation
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Validates the entity with a complex condition.
|
|
444
|
+
*/
|
|
445
|
+
attribute @@validate(_ value: Boolean, _ message: String?) @@@validation
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Validates length of a string field.
|
|
449
|
+
*/
|
|
450
|
+
function length(field: String, min: Int, max: Int?): Boolean {
|
|
451
|
+
} @@@expressionContext([ValidationRule])
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Validates a string field value matches a regex.
|
|
456
|
+
*/
|
|
457
|
+
function regex(field: String, regex: String): Boolean {
|
|
458
|
+
} @@@expressionContext([ValidationRule])
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Validates a string field value is a valid email address.
|
|
462
|
+
*/
|
|
463
|
+
function email(field: String): Boolean {
|
|
464
|
+
} @@@expressionContext([ValidationRule])
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Validates a string field value is a valid ISO datetime.
|
|
468
|
+
*/
|
|
469
|
+
function datetime(field: String): Boolean {
|
|
470
|
+
} @@@expressionContext([ValidationRule])
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Validates a string field value is a valid url.
|
|
474
|
+
*/
|
|
475
|
+
function url(field: String): Boolean {
|
|
476
|
+
} @@@expressionContext([ValidationRule])
|
|
477
|
+
|
|
478
|
+
//////////////////////////////////////////////
|
|
479
|
+
// End validation attributes and functions
|
|
480
|
+
//////////////////////////////////////////////
|
|
408
481
|
|
|
409
482
|
/**
|
|
410
483
|
* A utility attribute to allow passthrough of arbitrary attribute text to the generated Prisma schema.
|
package/telemetry.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export declare class Telemetry {
|
|
|
11
11
|
private readonly sessionid;
|
|
12
12
|
private readonly _os;
|
|
13
13
|
private readonly version;
|
|
14
|
+
private readonly prismaVersion;
|
|
14
15
|
private exitWait;
|
|
15
16
|
constructor();
|
|
16
17
|
track(event: TelemetryEvents, properties?: Record<string, unknown>): void;
|
package/telemetry.js
CHANGED
|
@@ -46,6 +46,7 @@ const sleep_promise_1 = __importDefault(require("sleep-promise"));
|
|
|
46
46
|
const cli_error_1 = require("./cli/cli-error");
|
|
47
47
|
const constants_1 = require("./constants");
|
|
48
48
|
const version_utils_1 = require("./utils/version-utils");
|
|
49
|
+
const sdk_1 = require("@zenstackhq/sdk");
|
|
49
50
|
/**
|
|
50
51
|
* Utility class for sending telemetry
|
|
51
52
|
*/
|
|
@@ -55,6 +56,7 @@ class Telemetry {
|
|
|
55
56
|
this.sessionid = (0, cuid2_1.createId)();
|
|
56
57
|
this._os = os.platform();
|
|
57
58
|
this.version = (0, version_utils_1.getVersion)();
|
|
59
|
+
this.prismaVersion = (0, sdk_1.getPrismaVersion)();
|
|
58
60
|
this.exitWait = 200;
|
|
59
61
|
if (process.env.DO_NOT_TRACK !== '1' && constants_1.TELEMETRY_TRACKING_TOKEN) {
|
|
60
62
|
this.mixpanel = (0, mixpanel_1.init)(constants_1.TELEMETRY_TRACKING_TOKEN, {
|
|
@@ -98,7 +100,7 @@ class Telemetry {
|
|
|
98
100
|
}
|
|
99
101
|
track(event, properties = {}) {
|
|
100
102
|
if (this.mixpanel) {
|
|
101
|
-
const payload = Object.assign({ distinct_id: this.hostId, session: this.sessionid, time: new Date(), $os: this._os, nodeVersion: process.version, version: this.version }, properties);
|
|
103
|
+
const payload = Object.assign({ distinct_id: this.hostId, session: this.sessionid, time: new Date(), $os: this._os, nodeVersion: process.version, version: this.version, prismaVersion: this.prismaVersion }, properties);
|
|
102
104
|
this.mixpanel.track(event, payload);
|
|
103
105
|
}
|
|
104
106
|
}
|
package/telemetry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAgD;AAChD,sEAAuC;AACvC,yCAA2C;AAC3C,uCAA0C;AAC1C,qDAAgD;AAChD,uCAAyB;AACzB,kEAAkC;AAClC,+CAA2C;AAC3C,2CAAuD;AACvD,yDAAmD;AAkBnD;;GAEG;AACH,MAAa,SAAS;
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
package/utils/ast-utils.d.ts
CHANGED
|
@@ -1,23 +1,10 @@
|
|
|
1
|
-
import { DataModel,
|
|
1
|
+
import { DataModel, DataModelField, Expression, Model, ModelImport } from '@zenstackhq/language/ast';
|
|
2
2
|
import { AstNode, LangiumDocuments } from 'langium';
|
|
3
3
|
import { URI } from 'vscode-uri';
|
|
4
4
|
export declare function extractDataModelsWithAllowRules(model: Model): DataModel[];
|
|
5
|
-
export declare function analyzePolicies(dataModel: DataModel): {
|
|
6
|
-
allows: DataModelAttribute[];
|
|
7
|
-
denies: DataModelAttribute[];
|
|
8
|
-
create: boolean | undefined;
|
|
9
|
-
read: boolean | undefined;
|
|
10
|
-
update: boolean | undefined;
|
|
11
|
-
delete: boolean | undefined;
|
|
12
|
-
allowAll: boolean;
|
|
13
|
-
denyAll: boolean;
|
|
14
|
-
hasFieldValidation: boolean;
|
|
15
|
-
};
|
|
16
5
|
export declare function mergeBaseModel(model: Model): void;
|
|
17
|
-
export declare const VALIDATION_ATTRIBUTES: string[];
|
|
18
6
|
export declare function getIdFields(dataModel: DataModel): DataModelField[];
|
|
19
7
|
export declare function isAuthInvocation(node: AstNode): boolean;
|
|
20
|
-
export declare function isEnumFieldReference(expr: Expression): boolean;
|
|
21
8
|
export declare function getDataModelFieldReference(expr: Expression): DataModelField | undefined;
|
|
22
9
|
export declare function resolveImportUri(imp: ModelImport): URI | undefined;
|
|
23
10
|
export declare function resolveTransitiveImports(documents: LangiumDocuments, model: Model): Model[];
|
package/utils/ast-utils.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAllDeclarationsFromImports = exports.resolveImport = exports.resolveTransitiveImports = exports.resolveImportUri = exports.getDataModelFieldReference = exports.
|
|
3
|
+
exports.getAllDeclarationsFromImports = exports.resolveImport = exports.resolveTransitiveImports = exports.resolveImportUri = exports.getDataModelFieldReference = exports.isAuthInvocation = exports.getIdFields = exports.mergeBaseModel = exports.extractDataModelsWithAllowRules = void 0;
|
|
4
4
|
const ast_1 = require("@zenstackhq/language/ast");
|
|
5
|
-
const sdk_1 = require("@zenstackhq/sdk");
|
|
6
5
|
const langium_1 = require("langium");
|
|
7
6
|
const vscode_uri_1 = require("vscode-uri");
|
|
8
7
|
const utils_1 = require("../language-server/utils");
|
|
@@ -10,36 +9,17 @@ function extractDataModelsWithAllowRules(model) {
|
|
|
10
9
|
return model.declarations.filter((d) => (0, ast_1.isDataModel)(d) && d.attributes.some((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@allow'; }));
|
|
11
10
|
}
|
|
12
11
|
exports.extractDataModelsWithAllowRules = extractDataModelsWithAllowRules;
|
|
13
|
-
function analyzePolicies(dataModel) {
|
|
14
|
-
const allows = dataModel.attributes.filter((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@allow'; });
|
|
15
|
-
const denies = dataModel.attributes.filter((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@deny'; });
|
|
16
|
-
const create = toStaticPolicy('create', allows, denies);
|
|
17
|
-
const read = toStaticPolicy('read', allows, denies);
|
|
18
|
-
const update = toStaticPolicy('update', allows, denies);
|
|
19
|
-
const del = toStaticPolicy('delete', allows, denies);
|
|
20
|
-
const hasFieldValidation = dataModel.$resolvedFields.some((field) => field.attributes.some((attr) => exports.VALIDATION_ATTRIBUTES.includes(attr.decl.$refText)));
|
|
21
|
-
return {
|
|
22
|
-
allows,
|
|
23
|
-
denies,
|
|
24
|
-
create,
|
|
25
|
-
read,
|
|
26
|
-
update,
|
|
27
|
-
delete: del,
|
|
28
|
-
allowAll: create === true && read === true && update === true && del === true,
|
|
29
|
-
denyAll: create === false && read === false && update === false && del === false,
|
|
30
|
-
hasFieldValidation,
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
exports.analyzePolicies = analyzePolicies;
|
|
34
12
|
function mergeBaseModel(model) {
|
|
35
13
|
model.declarations
|
|
36
14
|
.filter((x) => x.$type === 'DataModel')
|
|
37
15
|
.forEach((decl) => {
|
|
38
16
|
const dataModel = decl;
|
|
39
17
|
dataModel.fields = dataModel.superTypes
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
40
19
|
.flatMap((superType) => updateContainer(superType.ref.fields, dataModel))
|
|
41
20
|
.concat(dataModel.fields);
|
|
42
21
|
dataModel.attributes = dataModel.superTypes
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
43
23
|
.flatMap((superType) => updateContainer(superType.ref.attributes, dataModel))
|
|
44
24
|
.concat(dataModel.attributes);
|
|
45
25
|
});
|
|
@@ -56,50 +36,6 @@ function updateContainer(nodes, container) {
|
|
|
56
36
|
return mutable;
|
|
57
37
|
});
|
|
58
38
|
}
|
|
59
|
-
function toStaticPolicy(operation, allows, denies) {
|
|
60
|
-
const filteredDenies = forOperation(operation, denies);
|
|
61
|
-
if (filteredDenies.some((rule) => (0, sdk_1.getLiteral)(rule.args[1].value) === true)) {
|
|
62
|
-
// any constant true deny rule
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
const filteredAllows = forOperation(operation, allows);
|
|
66
|
-
if (filteredAllows.length === 0) {
|
|
67
|
-
// no allow rule
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
if (filteredDenies.length === 0 &&
|
|
71
|
-
filteredAllows.some((rule) => (0, sdk_1.getLiteral)(rule.args[1].value) === true)) {
|
|
72
|
-
// any constant true allow rule
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
return undefined;
|
|
76
|
-
}
|
|
77
|
-
function forOperation(operation, rules) {
|
|
78
|
-
return rules.filter((rule) => {
|
|
79
|
-
const ops = (0, sdk_1.getLiteral)(rule.args[0].value);
|
|
80
|
-
if (!ops) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
if (ops === 'all') {
|
|
84
|
-
return true;
|
|
85
|
-
}
|
|
86
|
-
const splitOps = ops.split(',').map((p) => p.trim());
|
|
87
|
-
return splitOps.includes(operation);
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
exports.VALIDATION_ATTRIBUTES = [
|
|
91
|
-
'@length',
|
|
92
|
-
'@regex',
|
|
93
|
-
'@startsWith',
|
|
94
|
-
'@endsWith',
|
|
95
|
-
'@email',
|
|
96
|
-
'@url',
|
|
97
|
-
'@datetime',
|
|
98
|
-
'@gt',
|
|
99
|
-
'@gte',
|
|
100
|
-
'@lt',
|
|
101
|
-
'@lte',
|
|
102
|
-
];
|
|
103
39
|
function getIdFields(dataModel) {
|
|
104
40
|
const fieldLevelId = dataModel.$resolvedFields.find((f) => f.attributes.some((attr) => attr.decl.$refText === '@id'));
|
|
105
41
|
if (fieldLevelId) {
|
|
@@ -127,10 +63,6 @@ function isAuthInvocation(node) {
|
|
|
127
63
|
return (0, ast_1.isInvocationExpr)(node) && ((_a = node.function.ref) === null || _a === void 0 ? void 0 : _a.name) === 'auth' && (0, utils_1.isFromStdlib)(node.function.ref);
|
|
128
64
|
}
|
|
129
65
|
exports.isAuthInvocation = isAuthInvocation;
|
|
130
|
-
function isEnumFieldReference(expr) {
|
|
131
|
-
return (0, ast_1.isReferenceExpr)(expr) && (0, ast_1.isEnumField)(expr.target.ref);
|
|
132
|
-
}
|
|
133
|
-
exports.isEnumFieldReference = isEnumFieldReference;
|
|
134
66
|
function getDataModelFieldReference(expr) {
|
|
135
67
|
if ((0, ast_1.isReferenceExpr)(expr) && (0, ast_1.isDataModelField)(expr.target.ref)) {
|
|
136
68
|
return expr.target.ref;
|