@matter/model 0.12.0-alpha.0-20241229-9d9c99934 → 0.12.0-alpha.0-20241231-14ac774ba
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/cjs/aspects/Constraint.d.ts +24 -15
- package/dist/cjs/aspects/Constraint.d.ts.map +1 -1
- package/dist/cjs/aspects/Constraint.js +268 -198
- package/dist/cjs/aspects/Constraint.js.map +2 -2
- package/dist/cjs/common/FieldValue.d.ts +9 -3
- package/dist/cjs/common/FieldValue.d.ts.map +1 -1
- package/dist/cjs/common/FieldValue.js +1 -1
- package/dist/cjs/common/FieldValue.js.map +1 -1
- package/dist/cjs/logic/definition-validation/ValueValidator.js +1 -1
- package/dist/cjs/logic/definition-validation/ValueValidator.js.map +1 -1
- package/dist/cjs/parser/Lexer.d.ts +3 -3
- package/dist/cjs/parser/Lexer.d.ts.map +1 -1
- package/dist/cjs/parser/Lexer.js +35 -31
- package/dist/cjs/parser/Lexer.js.map +1 -1
- package/dist/cjs/parser/Token.d.ts +5 -2
- package/dist/cjs/parser/Token.d.ts.map +1 -1
- package/dist/cjs/parser/TokenStream.js +2 -2
- package/dist/esm/aspects/Constraint.d.ts +24 -15
- package/dist/esm/aspects/Constraint.d.ts.map +1 -1
- package/dist/esm/aspects/Constraint.js +269 -199
- package/dist/esm/aspects/Constraint.js.map +2 -2
- package/dist/esm/common/FieldValue.d.ts +9 -3
- package/dist/esm/common/FieldValue.d.ts.map +1 -1
- package/dist/esm/common/FieldValue.js +1 -1
- package/dist/esm/common/FieldValue.js.map +1 -1
- package/dist/esm/logic/definition-validation/ValueValidator.js +1 -1
- package/dist/esm/logic/definition-validation/ValueValidator.js.map +1 -1
- package/dist/esm/parser/Lexer.d.ts +3 -3
- package/dist/esm/parser/Lexer.d.ts.map +1 -1
- package/dist/esm/parser/Lexer.js +35 -31
- package/dist/esm/parser/Lexer.js.map +1 -1
- package/dist/esm/parser/Token.d.ts +5 -2
- package/dist/esm/parser/Token.d.ts.map +1 -1
- package/dist/esm/parser/TokenStream.js +2 -2
- package/package.json +4 -4
- package/src/aspects/Constraint.ts +340 -215
- package/src/common/FieldValue.ts +9 -4
- package/src/logic/definition-validation/ValueValidator.ts +1 -1
- package/src/parser/Lexer.ts +38 -40
- package/src/parser/Token.ts +11 -1
- package/src/parser/TokenStream.ts +2 -2
|
@@ -9,17 +9,15 @@ import { Aspect } from "./Aspect.js";
|
|
|
9
9
|
* An operational view of constraints as defined by the Matter specification.
|
|
10
10
|
*
|
|
11
11
|
* A "constraint" limits possible data values.
|
|
12
|
-
*
|
|
13
|
-
* Formally a constraint is not considered a quality by the specification. It is handled similarly to qualities, though,
|
|
14
|
-
* so we keep it in the same section.
|
|
15
12
|
*/
|
|
16
13
|
export declare class Constraint extends Aspect<Constraint.Definition> implements Constraint.Ast {
|
|
17
14
|
desc?: boolean;
|
|
18
|
-
value?:
|
|
19
|
-
min?:
|
|
20
|
-
max?:
|
|
15
|
+
value?: Constraint.Expression;
|
|
16
|
+
min?: Constraint.Expression;
|
|
17
|
+
max?: Constraint.Expression;
|
|
21
18
|
in?: FieldValue;
|
|
22
19
|
entry?: Constraint;
|
|
20
|
+
cpMax?: number;
|
|
23
21
|
parts?: Constraint[];
|
|
24
22
|
/**
|
|
25
23
|
* Initialize from a Constraint.Definition or the constraint DSL defined by the Matter Specification.
|
|
@@ -35,7 +33,7 @@ export declare class Constraint extends Aspect<Constraint.Definition> implements
|
|
|
35
33
|
export declare namespace Constraint {
|
|
36
34
|
type NumberOrIdentifier = number | string;
|
|
37
35
|
/**
|
|
38
|
-
* Parsed
|
|
36
|
+
* Parsed constraint.
|
|
39
37
|
*/
|
|
40
38
|
type Ast = {
|
|
41
39
|
/**
|
|
@@ -45,15 +43,15 @@ export declare namespace Constraint {
|
|
|
45
43
|
/**
|
|
46
44
|
* Constant value.
|
|
47
45
|
*/
|
|
48
|
-
value?:
|
|
46
|
+
value?: Expression;
|
|
49
47
|
/**
|
|
50
48
|
* Lower bound on value or sequence length.
|
|
51
49
|
*/
|
|
52
|
-
min?:
|
|
50
|
+
min?: Expression;
|
|
53
51
|
/**
|
|
54
52
|
* Upper bound on value or sequence length.
|
|
55
53
|
*/
|
|
56
|
-
max?:
|
|
54
|
+
max?: Expression;
|
|
57
55
|
/**
|
|
58
56
|
* Require set membership for the value.
|
|
59
57
|
*/
|
|
@@ -62,21 +60,32 @@ export declare namespace Constraint {
|
|
|
62
60
|
* Constraint on list child element.
|
|
63
61
|
*/
|
|
64
62
|
entry?: Ast;
|
|
63
|
+
/**
|
|
64
|
+
* Constraint on codepoints in a string.
|
|
65
|
+
*/
|
|
66
|
+
cpMax?: number;
|
|
65
67
|
/**
|
|
66
68
|
* List of sub-constraints in a sequence.
|
|
67
69
|
*/
|
|
68
70
|
parts?: Ast[];
|
|
69
71
|
};
|
|
72
|
+
/**
|
|
73
|
+
* Parsed binary operator.
|
|
74
|
+
*/
|
|
75
|
+
interface BinaryOperator {
|
|
76
|
+
type: "+" | "-";
|
|
77
|
+
lhs: Expression;
|
|
78
|
+
rhs: Expression;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parsed expression.
|
|
82
|
+
*/
|
|
83
|
+
type Expression = FieldValue | BinaryOperator;
|
|
70
84
|
/**
|
|
71
85
|
* These are all ways to describe a constraint.
|
|
72
86
|
*/
|
|
73
87
|
type Definition = (Ast & {
|
|
74
88
|
definition?: Definition;
|
|
75
89
|
}) | string | number | undefined;
|
|
76
|
-
/**
|
|
77
|
-
* Parse constraint DSL. Extremely lenient.
|
|
78
|
-
*/
|
|
79
|
-
function parse(constraint: Constraint, definition: string): Ast;
|
|
80
|
-
function serialize(ast: Ast): string;
|
|
81
90
|
}
|
|
82
91
|
//# sourceMappingURL=Constraint.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constraint.d.ts","sourceRoot":"","sources":["../../../src/aspects/Constraint.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"Constraint.d.ts","sourceRoot":"","sources":["../../../src/aspects/Constraint.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,MAAM,CAAC,UAAU,CAAC,UAAU,CAAE,YAAW,UAAU,CAAC,GAAG;IAC3E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC;IAC9B,GAAG,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC;IAC5B,GAAG,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC;IAC5B,EAAE,CAAC,EAAE,UAAU,CAAC;IAChB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IAE7B;;OAEG;gBACS,UAAU,EAAE,UAAU,CAAC,UAAU;IA2D7C;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,OAAO;IAoFzD,QAAQ;cAOE,MAAM;CAM5B;AAED,yBAAiB,UAAU,CAAC;IACxB,KAAY,kBAAkB,GAAG,MAAM,GAAG,MAAM,CAAC;IAEjD;;OAEG;IACH,KAAY,GAAG,GAAG;QACd;;WAEG;QACH,IAAI,CAAC,EAAE,OAAO,CAAC;QAEf;;WAEG;QACH,KAAK,CAAC,EAAE,UAAU,CAAC;QAEnB;;WAEG;QACH,GAAG,CAAC,EAAE,UAAU,CAAC;QAEjB;;WAEG;QACH,GAAG,CAAC,EAAE,UAAU,CAAC;QAEjB;;WAEG;QACH,EAAE,CAAC,EAAE,UAAU,CAAC;QAEhB;;WAEG;QACH,KAAK,CAAC,EAAE,GAAG,CAAC;QAEZ;;WAEG;QACH,KAAK,CAAC,EAAE,MAAM,CAAC;QAEf;;WAEG;QACH,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;KACjB,CAAC;IAEF;;OAEG;IACH,UAAiB,cAAc;QAC3B,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;QAEhB,GAAG,EAAE,UAAU,CAAC;QAEhB,GAAG,EAAE,UAAU,CAAC;KACnB;IAED;;OAEG;IACH,KAAY,UAAU,GAAG,UAAU,GAAG,cAAc,CAAC;IAErD;;OAEG;IACH,KAAY,UAAU,GAAG,CAAC,GAAG,GAAG;QAAE,UAAU,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC9F"}
|
|
@@ -21,6 +21,8 @@ __export(Constraint_exports, {
|
|
|
21
21
|
Constraint: () => Constraint
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(Constraint_exports);
|
|
24
|
+
var import_Lexer = require("#parser/Lexer.js");
|
|
25
|
+
var import_TokenStream = require("#parser/TokenStream.js");
|
|
24
26
|
var import_general = require("@matter/general");
|
|
25
27
|
var import_common = require("../common/index.js");
|
|
26
28
|
var import_Aspect = require("./Aspect.js");
|
|
@@ -41,7 +43,7 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
41
43
|
if (definition.match(/(?:0b[0x ]*x[0x ]*)|(?:0x[0x_]*x[0x_]*)|(?:00[0x]*x)/i)) {
|
|
42
44
|
break;
|
|
43
45
|
}
|
|
44
|
-
ast =
|
|
46
|
+
ast = Parser.parse(this, definition);
|
|
45
47
|
break;
|
|
46
48
|
case "number":
|
|
47
49
|
ast = { value: definition };
|
|
@@ -74,6 +76,9 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
74
76
|
if (ast.entry !== void 0) {
|
|
75
77
|
this.entry = new Constraint(ast.entry);
|
|
76
78
|
}
|
|
79
|
+
if (ast.cpMax !== void 0) {
|
|
80
|
+
this.cpMax = ast.cpMax;
|
|
81
|
+
}
|
|
77
82
|
if (ast.parts !== void 0) {
|
|
78
83
|
this.parts = ast.parts.map((p) => new Constraint(p));
|
|
79
84
|
}
|
|
@@ -87,10 +92,34 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
87
92
|
if (!raw && (typeof value2 === "string" || Array.isArray(value2))) {
|
|
88
93
|
return value2.length;
|
|
89
94
|
}
|
|
90
|
-
if (
|
|
91
|
-
const { type
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
if (typeof value2 === "object" && value2 !== null && "type" in value2) {
|
|
96
|
+
const { type } = value2;
|
|
97
|
+
switch (type) {
|
|
98
|
+
case import_common.FieldValue.reference:
|
|
99
|
+
if (typeof value2.name === "string") {
|
|
100
|
+
value2 = valueOf(properties?.[(0, import_general.camelize)(value2.name)], raw);
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case "+":
|
|
104
|
+
{
|
|
105
|
+
const lhs = valueOf(value2.lhs);
|
|
106
|
+
const rhs = valueOf(value2.rhs);
|
|
107
|
+
if (typeof lhs === "number" && typeof rhs === "number") {
|
|
108
|
+
return lhs + rhs;
|
|
109
|
+
}
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
case "-":
|
|
114
|
+
{
|
|
115
|
+
const lhs = valueOf(value2.lhs);
|
|
116
|
+
const rhs = valueOf(value2.rhs);
|
|
117
|
+
if (typeof lhs === "number" && typeof rhs === "number") {
|
|
118
|
+
return lhs - rhs;
|
|
119
|
+
}
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
break;
|
|
94
123
|
}
|
|
95
124
|
}
|
|
96
125
|
return value2;
|
|
@@ -101,7 +130,7 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
101
130
|
if (this.in) {
|
|
102
131
|
let set = valueOf(this.in, true);
|
|
103
132
|
if (!Array.isArray(set)) {
|
|
104
|
-
set = [set];
|
|
133
|
+
set = set === void 0 ? [] : [set];
|
|
105
134
|
}
|
|
106
135
|
return set.indexOf(value) !== -1;
|
|
107
136
|
}
|
|
@@ -133,7 +162,7 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
133
162
|
if (!this.valid && this.definition) {
|
|
134
163
|
return this.definition.toString();
|
|
135
164
|
}
|
|
136
|
-
return
|
|
165
|
+
return Serializer.serialize(this);
|
|
137
166
|
}
|
|
138
167
|
freeze() {
|
|
139
168
|
if (this.parts) {
|
|
@@ -142,221 +171,262 @@ class Constraint extends import_Aspect.Aspect {
|
|
|
142
171
|
super.freeze();
|
|
143
172
|
}
|
|
144
173
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
} else {
|
|
151
|
-
value = Number.parseFloat(numOrName);
|
|
152
|
-
}
|
|
153
|
-
if (typeof numOrName === "string") {
|
|
154
|
-
const lower = numOrName.toLowerCase();
|
|
155
|
-
switch (lower) {
|
|
156
|
-
case "true":
|
|
157
|
-
return true;
|
|
158
|
-
case "false":
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
if (Number.isNaN(value)) {
|
|
163
|
-
return import_common.FieldValue.Reference((0, import_general.camelize)(numOrName));
|
|
174
|
+
var Serializer;
|
|
175
|
+
((Serializer2) => {
|
|
176
|
+
function serialize(ast) {
|
|
177
|
+
if (ast.parts) {
|
|
178
|
+
return ast.parts.map(serialize).join(", ");
|
|
164
179
|
}
|
|
165
|
-
if (
|
|
166
|
-
return
|
|
180
|
+
if (ast.entry) {
|
|
181
|
+
return `${serializeAtom(ast)}[${serialize(ast.entry)}]`;
|
|
167
182
|
}
|
|
168
|
-
if (
|
|
169
|
-
return
|
|
183
|
+
if (ast.cpMax) {
|
|
184
|
+
return `${serializeAtom(ast)}{${ast.cpMax}}`;
|
|
170
185
|
}
|
|
171
|
-
return
|
|
172
|
-
}
|
|
173
|
-
function parseAtom(constraint, words) {
|
|
174
|
-
switch (words.length) {
|
|
175
|
-
case 0:
|
|
176
|
-
return void 0;
|
|
177
|
-
case 1:
|
|
178
|
-
switch (words[0].toLowerCase()) {
|
|
179
|
-
case "desc":
|
|
180
|
-
return { desc: true };
|
|
181
|
-
case "all":
|
|
182
|
-
case "any":
|
|
183
|
-
return {};
|
|
184
|
-
}
|
|
185
|
-
const value = parseValue(words[0]);
|
|
186
|
-
if (value === void 0 || value === null) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
return { value };
|
|
190
|
-
case 2:
|
|
191
|
-
switch (words[0].toLowerCase()) {
|
|
192
|
-
case "min":
|
|
193
|
-
const min = parseValue(words[1]);
|
|
194
|
-
if (min === void 0 || min === null) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
return { min };
|
|
198
|
-
case "max":
|
|
199
|
-
const max = parseValue(words[1]);
|
|
200
|
-
if (max === void 0 || max === null) {
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
return { max };
|
|
204
|
-
case "in":
|
|
205
|
-
const ref = parseValue(words[1]);
|
|
206
|
-
return { in: ref };
|
|
207
|
-
default:
|
|
208
|
-
constraint.error(
|
|
209
|
-
"INVALID_CONSTRAINT",
|
|
210
|
-
`Two word constraint "${words.join(" ")}" does not start with "min" or "max"`
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
return;
|
|
214
|
-
case 3:
|
|
215
|
-
if (words[1].toLowerCase() === "to") {
|
|
216
|
-
let parseBound2 = function(name, pos) {
|
|
217
|
-
if (words[pos].toLowerCase() === name) {
|
|
218
|
-
return void 0;
|
|
219
|
-
}
|
|
220
|
-
return parseValue(words[pos]);
|
|
221
|
-
};
|
|
222
|
-
var parseBound = parseBound2;
|
|
223
|
-
const ast = {};
|
|
224
|
-
const min = parseBound2("min", 0);
|
|
225
|
-
if (min !== void 0 && min !== null) {
|
|
226
|
-
ast.min = min;
|
|
227
|
-
}
|
|
228
|
-
const max = parseBound2("max", 2);
|
|
229
|
-
if (max !== void 0 && max !== null) {
|
|
230
|
-
ast.max = max;
|
|
231
|
-
}
|
|
232
|
-
if (ast.min !== void 0 && ast.min !== null || ast.max !== void 0 && ast.max !== null) {
|
|
233
|
-
return ast;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
constraint.error("INVALID_CONSTRAINT", `Unrecognized value constraint "${words.join(" ")}"`);
|
|
186
|
+
return serializeAtom(ast);
|
|
239
187
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
function scan(depth) {
|
|
254
|
-
const parts = Array();
|
|
255
|
-
let words = Array();
|
|
256
|
-
let word = "";
|
|
257
|
-
function parseWords() {
|
|
258
|
-
if (word) {
|
|
259
|
-
words.push(word);
|
|
260
|
-
word = "";
|
|
188
|
+
Serializer2.serialize = serialize;
|
|
189
|
+
function serializeValue(value, inExpr = false) {
|
|
190
|
+
if (typeof value !== "object" || value === null || Array.isArray(value) || value instanceof Date) {
|
|
191
|
+
return import_common.FieldValue.serialize(value);
|
|
192
|
+
}
|
|
193
|
+
switch (value.type) {
|
|
194
|
+
case "+":
|
|
195
|
+
case "-":
|
|
196
|
+
const sum = `${serializeValue(value.lhs, true)} ${value.type} ${serializeValue(value.rhs, true)}`;
|
|
197
|
+
if (inExpr) {
|
|
198
|
+
return `(${sum})`;
|
|
261
199
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return
|
|
265
|
-
}
|
|
266
|
-
function emit() {
|
|
267
|
-
const atom = parseWords();
|
|
268
|
-
if (atom !== void 0) {
|
|
269
|
-
parts.push(atom);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
while (current !== void 0) {
|
|
273
|
-
switch (current) {
|
|
274
|
-
case " ":
|
|
275
|
-
case " ":
|
|
276
|
-
case "\r":
|
|
277
|
-
case "\n":
|
|
278
|
-
case "\v":
|
|
279
|
-
case "\f":
|
|
280
|
-
if (word) {
|
|
281
|
-
words.push(word);
|
|
282
|
-
word = "";
|
|
283
|
-
}
|
|
284
|
-
break;
|
|
285
|
-
case "[":
|
|
286
|
-
next();
|
|
287
|
-
let ast = parseWords();
|
|
288
|
-
const entry = scan(depth + 1);
|
|
289
|
-
if (entry) {
|
|
290
|
-
if (!ast) {
|
|
291
|
-
ast = {};
|
|
292
|
-
}
|
|
293
|
-
ast.entry = entry;
|
|
294
|
-
}
|
|
295
|
-
if (ast) {
|
|
296
|
-
parts.push(ast);
|
|
297
|
-
}
|
|
298
|
-
break;
|
|
299
|
-
case "]":
|
|
300
|
-
if (!depth) {
|
|
301
|
-
constraint.error("INVALID_CONSTRAINT", 'Unexpected "]"');
|
|
302
|
-
break;
|
|
303
|
-
}
|
|
304
|
-
emit();
|
|
305
|
-
if (parts.length > 1) {
|
|
306
|
-
return { parts };
|
|
307
|
-
}
|
|
308
|
-
return parts[0];
|
|
309
|
-
case ",":
|
|
310
|
-
emit();
|
|
311
|
-
break;
|
|
312
|
-
default:
|
|
313
|
-
word += current;
|
|
314
|
-
break;
|
|
315
|
-
}
|
|
316
|
-
next();
|
|
317
|
-
}
|
|
318
|
-
if (depth) {
|
|
319
|
-
constraint.error("INVALID_CONSTRAINT", "Unterminated sub-constraint");
|
|
320
|
-
}
|
|
321
|
-
emit();
|
|
322
|
-
if (parts.length < 2) {
|
|
323
|
-
return parts[0];
|
|
324
|
-
}
|
|
325
|
-
return { parts };
|
|
200
|
+
return sum;
|
|
201
|
+
default:
|
|
202
|
+
return import_common.FieldValue.serialize(value);
|
|
326
203
|
}
|
|
327
|
-
return scan(0);
|
|
328
204
|
}
|
|
329
|
-
Constraint2.parse = parse;
|
|
330
205
|
function serializeAtom(ast) {
|
|
331
206
|
if (ast.desc) {
|
|
332
207
|
return "desc";
|
|
333
208
|
}
|
|
334
209
|
if (ast.value !== void 0 && ast.value !== null) {
|
|
335
|
-
return `${
|
|
210
|
+
return `${serializeValue(ast.value)}`;
|
|
336
211
|
}
|
|
337
212
|
if (ast.min !== void 0 && ast.min !== null) {
|
|
338
213
|
if (ast.max === void 0 || ast.max === null) {
|
|
339
|
-
return `min ${
|
|
214
|
+
return `min ${serializeValue(ast.min)}`;
|
|
340
215
|
}
|
|
341
|
-
return `${
|
|
216
|
+
return `${serializeValue(ast.min)} to ${serializeValue(ast.max)}`;
|
|
342
217
|
}
|
|
343
218
|
if (ast.max !== void 0 && ast.max !== null) {
|
|
344
|
-
return `max ${
|
|
219
|
+
return `max ${serializeValue(ast.max)}`;
|
|
345
220
|
}
|
|
346
221
|
if (ast.in !== void 0) {
|
|
347
|
-
return `in ${
|
|
222
|
+
return `in ${serializeValue(ast.in)}`;
|
|
348
223
|
}
|
|
349
224
|
return "all";
|
|
350
225
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
226
|
+
})(Serializer || (Serializer = {}));
|
|
227
|
+
var Parser;
|
|
228
|
+
((Parser2) => {
|
|
229
|
+
const lexer = new import_Lexer.Lexer(["in", "min", "max", "to", "all", "desc", "true", "false"]);
|
|
230
|
+
function parse(constraint, definition) {
|
|
231
|
+
const tokens = (0, import_TokenStream.TokenStream)(lexer.lex(definition, (code, message) => constraint.error(code, message)));
|
|
232
|
+
const result = parseParts();
|
|
233
|
+
if (tokens.token && tokens.token?.type !== ",") {
|
|
234
|
+
constraint.error("UNEXPECTED_CONSTRAINT_TOKEN", `Unexpected ${tokens.description}`);
|
|
354
235
|
}
|
|
355
|
-
|
|
356
|
-
|
|
236
|
+
return result;
|
|
237
|
+
function parseParts() {
|
|
238
|
+
const parts = Array();
|
|
239
|
+
while (true) {
|
|
240
|
+
const part = parsePart();
|
|
241
|
+
if (part !== void 0) {
|
|
242
|
+
parts.push(part);
|
|
243
|
+
}
|
|
244
|
+
if (tokens.done) {
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
if (tokens.token?.type !== ",") {
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
tokens.next();
|
|
251
|
+
}
|
|
252
|
+
if (!parts.length) {
|
|
253
|
+
return {};
|
|
254
|
+
}
|
|
255
|
+
if (parts.length === 1) {
|
|
256
|
+
return parts[0];
|
|
257
|
+
}
|
|
258
|
+
return { parts };
|
|
259
|
+
}
|
|
260
|
+
function parsePart() {
|
|
261
|
+
const result2 = parsePartWithoutSubconstraint();
|
|
262
|
+
if (result2 === void 0) {
|
|
263
|
+
return result2;
|
|
264
|
+
}
|
|
265
|
+
switch (tokens.token?.type) {
|
|
266
|
+
case "[":
|
|
267
|
+
{
|
|
268
|
+
tokens.next();
|
|
269
|
+
const entry = parseParts();
|
|
270
|
+
if (tokens.token?.type !== "]") {
|
|
271
|
+
constraint.error("MISSING_ENTRY_END", 'Entry constraint does not end with "]"');
|
|
272
|
+
}
|
|
273
|
+
tokens.next();
|
|
274
|
+
if (entry !== void 0) {
|
|
275
|
+
result2.entry = entry;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
case "{":
|
|
280
|
+
{
|
|
281
|
+
tokens.next();
|
|
282
|
+
if (tokens.token?.type !== "value") {
|
|
283
|
+
constraint.error(
|
|
284
|
+
"MISSING_CODEPOINT_MAX",
|
|
285
|
+
"Codepoint constraint does not specify maximum codepoint length"
|
|
286
|
+
);
|
|
287
|
+
if (tokens.peeked?.type === "}") {
|
|
288
|
+
tokens.next();
|
|
289
|
+
}
|
|
290
|
+
} else {
|
|
291
|
+
result2.cpMax = import_common.FieldValue.numericValue(
|
|
292
|
+
tokens.token.value
|
|
293
|
+
);
|
|
294
|
+
tokens.next();
|
|
295
|
+
}
|
|
296
|
+
if (tokens.token?.type !== "}") {
|
|
297
|
+
constraint.error("MISSING_CODEPOINT_END", 'Codepoint constraint does not end with "}"');
|
|
298
|
+
}
|
|
299
|
+
tokens.next();
|
|
300
|
+
}
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
return result2;
|
|
304
|
+
}
|
|
305
|
+
function parsePartWithoutSubconstraint() {
|
|
306
|
+
const { token } = tokens;
|
|
307
|
+
if (!token) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
switch (token.type) {
|
|
311
|
+
case "desc":
|
|
312
|
+
tokens.next();
|
|
313
|
+
return { desc: true };
|
|
314
|
+
case "all":
|
|
315
|
+
tokens.next();
|
|
316
|
+
return {};
|
|
317
|
+
case "min":
|
|
318
|
+
case "max":
|
|
319
|
+
tokens.next();
|
|
320
|
+
return parseSingleBound(token.type);
|
|
321
|
+
case "in":
|
|
322
|
+
tokens.next();
|
|
323
|
+
if (tokens.token?.type === "word") {
|
|
324
|
+
const name = tokens.token.value;
|
|
325
|
+
tokens.next();
|
|
326
|
+
return { in: import_common.FieldValue.Reference(name) };
|
|
327
|
+
}
|
|
328
|
+
constraint.error("MISSING_IN_FIELD", 'Expected field name to follow "in"');
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
const value = parseExpression();
|
|
332
|
+
if (value === void 0 || tokens.token?.type !== "to") {
|
|
333
|
+
return { value };
|
|
334
|
+
}
|
|
335
|
+
tokens.next();
|
|
336
|
+
const max = parseExpression();
|
|
337
|
+
if (max === void 0) {
|
|
338
|
+
constraint.error("MISSING_UPPER_BOUND", `"to" must be followed by upper boundary value`);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
min: value,
|
|
343
|
+
max
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function parseSingleBound(kind) {
|
|
347
|
+
const bound = parseExpression();
|
|
348
|
+
if (bound === void 0) {
|
|
349
|
+
constraint.error("MISSING_SINGLE_BOUND", `"${kind}" must be followed by boundary value`);
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
return { [kind]: bound };
|
|
353
|
+
}
|
|
354
|
+
function parseExpression() {
|
|
355
|
+
const value = parseValueExpression();
|
|
356
|
+
if (value === void 0) {
|
|
357
|
+
return value;
|
|
358
|
+
}
|
|
359
|
+
switch (tokens.token?.type) {
|
|
360
|
+
case "+":
|
|
361
|
+
case "-":
|
|
362
|
+
const type = tokens.token.type;
|
|
363
|
+
tokens.next();
|
|
364
|
+
const rhs = parseValueExpression();
|
|
365
|
+
if (rhs === void 0) {
|
|
366
|
+
constraint.error("MISSING_RIGHT_OPERAND", `Missing operand after "${type}"`);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
type,
|
|
371
|
+
lhs: value,
|
|
372
|
+
rhs
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return value;
|
|
376
|
+
}
|
|
377
|
+
function parseValueExpression() {
|
|
378
|
+
const { token } = tokens;
|
|
379
|
+
if (token === void 0) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
switch (token.type) {
|
|
383
|
+
case "value":
|
|
384
|
+
tokens.next();
|
|
385
|
+
return token.value;
|
|
386
|
+
case "true":
|
|
387
|
+
tokens.next();
|
|
388
|
+
return true;
|
|
389
|
+
case "false":
|
|
390
|
+
tokens.next();
|
|
391
|
+
return false;
|
|
392
|
+
case "word":
|
|
393
|
+
const ref = import_common.FieldValue.Reference((0, import_general.camelize)(token.value));
|
|
394
|
+
tokens.next();
|
|
395
|
+
return ref;
|
|
396
|
+
case "-":
|
|
397
|
+
case "+": {
|
|
398
|
+
tokens.next();
|
|
399
|
+
let number = tokens.token?.type === "value" ? tokens.token.value : void 0;
|
|
400
|
+
if (number !== void 0) {
|
|
401
|
+
tokens.next();
|
|
402
|
+
if (token.type === "-") {
|
|
403
|
+
if (typeof number === "number") {
|
|
404
|
+
number *= -1;
|
|
405
|
+
} else if (import_common.FieldValue.is(number, import_common.FieldValue.percent) || import_common.FieldValue.is(number, import_common.FieldValue.celsius)) {
|
|
406
|
+
number.value *= -1;
|
|
407
|
+
} else {
|
|
408
|
+
number = void 0;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (number === void 0) {
|
|
413
|
+
constraint.error("MISSING_NUMBER", `Unary "${token.type}" not followed by numeric value`);
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
return number;
|
|
417
|
+
}
|
|
418
|
+
case "(": {
|
|
419
|
+
tokens.next();
|
|
420
|
+
const result2 = parseExpression();
|
|
421
|
+
if (tokens.token?.type !== ")") {
|
|
422
|
+
constraint.error("MISSING_GROUP_END", 'Group does not end with ")"');
|
|
423
|
+
}
|
|
424
|
+
tokens.next();
|
|
425
|
+
return result2;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
357
428
|
}
|
|
358
|
-
return serializeAtom(ast);
|
|
359
429
|
}
|
|
360
|
-
|
|
361
|
-
})(
|
|
430
|
+
Parser2.parse = parse;
|
|
431
|
+
})(Parser || (Parser = {}));
|
|
362
432
|
//# sourceMappingURL=Constraint.js.map
|