@constela/compiler 0.2.0 → 0.3.1
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/index.d.ts +15 -2
- package/dist/index.js +91 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -77,6 +77,8 @@ interface CompiledUpdateStep {
|
|
|
77
77
|
target: string;
|
|
78
78
|
operation: string;
|
|
79
79
|
value?: CompiledExpression;
|
|
80
|
+
index?: CompiledExpression;
|
|
81
|
+
deleteCount?: CompiledExpression;
|
|
80
82
|
}
|
|
81
83
|
interface CompiledFetchStep {
|
|
82
84
|
do: 'fetch';
|
|
@@ -112,7 +114,7 @@ interface CompiledEachNode {
|
|
|
112
114
|
key?: CompiledExpression;
|
|
113
115
|
body: CompiledNode;
|
|
114
116
|
}
|
|
115
|
-
type CompiledExpression = CompiledLitExpr | CompiledStateExpr | CompiledVarExpr | CompiledBinExpr | CompiledNotExpr;
|
|
117
|
+
type CompiledExpression = CompiledLitExpr | CompiledStateExpr | CompiledVarExpr | CompiledBinExpr | CompiledNotExpr | CompiledCondExpr | CompiledGetExpr;
|
|
116
118
|
interface CompiledLitExpr {
|
|
117
119
|
expr: 'lit';
|
|
118
120
|
value: string | number | boolean | null | unknown[];
|
|
@@ -136,6 +138,17 @@ interface CompiledNotExpr {
|
|
|
136
138
|
expr: 'not';
|
|
137
139
|
operand: CompiledExpression;
|
|
138
140
|
}
|
|
141
|
+
interface CompiledCondExpr {
|
|
142
|
+
expr: 'cond';
|
|
143
|
+
if: CompiledExpression;
|
|
144
|
+
then: CompiledExpression;
|
|
145
|
+
else: CompiledExpression;
|
|
146
|
+
}
|
|
147
|
+
interface CompiledGetExpr {
|
|
148
|
+
expr: 'get';
|
|
149
|
+
base: CompiledExpression;
|
|
150
|
+
path: string;
|
|
151
|
+
}
|
|
139
152
|
interface CompiledEventHandler {
|
|
140
153
|
event: string;
|
|
141
154
|
action: string;
|
|
@@ -200,4 +213,4 @@ type ValidatePassResult = ValidatePassSuccess | ValidatePassFailure;
|
|
|
200
213
|
*/
|
|
201
214
|
declare function validatePass(input: unknown): ValidatePassResult;
|
|
202
215
|
|
|
203
|
-
export { type AnalysisContext, type AnalyzePassFailure, type AnalyzePassResult, type AnalyzePassSuccess, type CompileFailure, type CompileResult, type CompileSuccess, type CompiledAction, type CompiledActionStep, type CompiledEachNode, type CompiledElementNode, type CompiledEventHandler, type CompiledExpression, type CompiledIfNode, type CompiledNode, type CompiledProgram, type CompiledTextNode, type ValidatePassFailure, type ValidatePassResult, type ValidatePassSuccess, analyzePass, compile, transformPass, validatePass };
|
|
216
|
+
export { type AnalysisContext, type AnalyzePassFailure, type AnalyzePassResult, type AnalyzePassSuccess, type CompileFailure, type CompileResult, type CompileSuccess, type CompiledAction, type CompiledActionStep, type CompiledEachNode, type CompiledElementNode, type CompiledEventHandler, type CompiledExpression, type CompiledFetchStep, type CompiledIfNode, type CompiledNode, type CompiledProgram, type CompiledSetStep, type CompiledTextNode, type CompiledUpdateStep, type ValidatePassFailure, type ValidatePassResult, type ValidatePassSuccess, analyzePass, compile, transformPass, validatePass };
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,8 @@ import {
|
|
|
25
25
|
createComponentCycleError,
|
|
26
26
|
createUndefinedParamError,
|
|
27
27
|
createSchemaError,
|
|
28
|
+
createOperationInvalidForTypeError,
|
|
29
|
+
createOperationMissingFieldError,
|
|
28
30
|
isEventHandler
|
|
29
31
|
} from "@constela/core";
|
|
30
32
|
function buildPath(base, ...segments) {
|
|
@@ -78,6 +80,14 @@ function validateExpression(expr, path, context, scope, paramScope) {
|
|
|
78
80
|
break;
|
|
79
81
|
case "lit":
|
|
80
82
|
break;
|
|
83
|
+
case "cond":
|
|
84
|
+
errors.push(...validateExpression(expr.if, buildPath(path, "if"), context, scope, paramScope));
|
|
85
|
+
errors.push(...validateExpression(expr.then, buildPath(path, "then"), context, scope, paramScope));
|
|
86
|
+
errors.push(...validateExpression(expr.else, buildPath(path, "else"), context, scope, paramScope));
|
|
87
|
+
break;
|
|
88
|
+
case "get":
|
|
89
|
+
errors.push(...validateExpression(expr.base, buildPath(path, "base"), context, scope, paramScope));
|
|
90
|
+
break;
|
|
81
91
|
}
|
|
82
92
|
return errors;
|
|
83
93
|
}
|
|
@@ -92,16 +102,50 @@ function validateActionStep(step, path, context) {
|
|
|
92
102
|
...validateExpressionStateOnly(step.value, buildPath(path, "value"), context)
|
|
93
103
|
);
|
|
94
104
|
break;
|
|
95
|
-
case "update":
|
|
105
|
+
case "update": {
|
|
96
106
|
if (!context.stateNames.has(step.target)) {
|
|
97
107
|
errors.push(createUndefinedStateError(step.target, buildPath(path, "target")));
|
|
108
|
+
} else {
|
|
109
|
+
const stateField = ast.state[step.target];
|
|
110
|
+
if (stateField) {
|
|
111
|
+
const stateType = stateField.type;
|
|
112
|
+
const op = step.operation;
|
|
113
|
+
if (op === "toggle" && stateType !== "boolean") {
|
|
114
|
+
errors.push(createOperationInvalidForTypeError(op, stateType, buildPath(path, "operation")));
|
|
115
|
+
}
|
|
116
|
+
if (op === "merge" && stateType !== "object") {
|
|
117
|
+
errors.push(createOperationInvalidForTypeError(op, stateType, buildPath(path, "operation")));
|
|
118
|
+
}
|
|
119
|
+
if ((op === "increment" || op === "decrement") && stateType !== "number") {
|
|
120
|
+
errors.push(createOperationInvalidForTypeError(op, stateType, buildPath(path, "operation")));
|
|
121
|
+
}
|
|
122
|
+
if ((op === "push" || op === "pop" || op === "remove" || op === "replaceAt" || op === "insertAt" || op === "splice") && stateType !== "list") {
|
|
123
|
+
errors.push(createOperationInvalidForTypeError(op, stateType, buildPath(path, "operation")));
|
|
124
|
+
}
|
|
125
|
+
if (op === "merge" && !step.value) {
|
|
126
|
+
errors.push(createOperationMissingFieldError(op, "value", path));
|
|
127
|
+
}
|
|
128
|
+
if ((op === "replaceAt" || op === "insertAt") && (!step.index || !step.value)) {
|
|
129
|
+
if (!step.index) errors.push(createOperationMissingFieldError(op, "index", path));
|
|
130
|
+
if (!step.value) errors.push(createOperationMissingFieldError(op, "value", path));
|
|
131
|
+
}
|
|
132
|
+
if (op === "splice" && (!step.index || !step.deleteCount)) {
|
|
133
|
+
if (!step.index) errors.push(createOperationMissingFieldError(op, "index", path));
|
|
134
|
+
if (!step.deleteCount) errors.push(createOperationMissingFieldError(op, "deleteCount", path));
|
|
135
|
+
}
|
|
136
|
+
}
|
|
98
137
|
}
|
|
99
138
|
if (step.value) {
|
|
100
|
-
errors.push(
|
|
101
|
-
|
|
102
|
-
|
|
139
|
+
errors.push(...validateExpressionStateOnly(step.value, buildPath(path, "value"), context));
|
|
140
|
+
}
|
|
141
|
+
if (step.index) {
|
|
142
|
+
errors.push(...validateExpressionStateOnly(step.index, buildPath(path, "index"), context));
|
|
143
|
+
}
|
|
144
|
+
if (step.deleteCount) {
|
|
145
|
+
errors.push(...validateExpressionStateOnly(step.deleteCount, buildPath(path, "deleteCount"), context));
|
|
103
146
|
}
|
|
104
147
|
break;
|
|
148
|
+
}
|
|
105
149
|
case "fetch":
|
|
106
150
|
errors.push(
|
|
107
151
|
...validateExpressionStateOnly(step.url, buildPath(path, "url"), context)
|
|
@@ -154,6 +198,14 @@ function validateExpressionStateOnly(expr, path, context) {
|
|
|
154
198
|
break;
|
|
155
199
|
case "lit":
|
|
156
200
|
break;
|
|
201
|
+
case "cond":
|
|
202
|
+
errors.push(...validateExpressionStateOnly(expr.if, buildPath(path, "if"), context));
|
|
203
|
+
errors.push(...validateExpressionStateOnly(expr.then, buildPath(path, "then"), context));
|
|
204
|
+
errors.push(...validateExpressionStateOnly(expr.else, buildPath(path, "else"), context));
|
|
205
|
+
break;
|
|
206
|
+
case "get":
|
|
207
|
+
errors.push(...validateExpressionStateOnly(expr.base, buildPath(path, "base"), context));
|
|
208
|
+
break;
|
|
157
209
|
}
|
|
158
210
|
return errors;
|
|
159
211
|
}
|
|
@@ -187,6 +239,22 @@ function validateExpressionInEventPayload(expr, path, context, scope) {
|
|
|
187
239
|
break;
|
|
188
240
|
case "lit":
|
|
189
241
|
break;
|
|
242
|
+
case "cond":
|
|
243
|
+
errors.push(
|
|
244
|
+
...validateExpressionInEventPayload(expr.if, buildPath(path, "if"), context, scope)
|
|
245
|
+
);
|
|
246
|
+
errors.push(
|
|
247
|
+
...validateExpressionInEventPayload(expr.then, buildPath(path, "then"), context, scope)
|
|
248
|
+
);
|
|
249
|
+
errors.push(
|
|
250
|
+
...validateExpressionInEventPayload(expr.else, buildPath(path, "else"), context, scope)
|
|
251
|
+
);
|
|
252
|
+
break;
|
|
253
|
+
case "get":
|
|
254
|
+
errors.push(
|
|
255
|
+
...validateExpressionInEventPayload(expr.base, buildPath(path, "base"), context, scope)
|
|
256
|
+
);
|
|
257
|
+
break;
|
|
190
258
|
}
|
|
191
259
|
return errors;
|
|
192
260
|
}
|
|
@@ -507,6 +575,19 @@ function transformExpression(expr, ctx) {
|
|
|
507
575
|
}
|
|
508
576
|
return { expr: "lit", value: null };
|
|
509
577
|
}
|
|
578
|
+
case "cond":
|
|
579
|
+
return {
|
|
580
|
+
expr: "cond",
|
|
581
|
+
if: transformExpression(expr.if, ctx),
|
|
582
|
+
then: transformExpression(expr.then, ctx),
|
|
583
|
+
else: transformExpression(expr.else, ctx)
|
|
584
|
+
};
|
|
585
|
+
case "get":
|
|
586
|
+
return {
|
|
587
|
+
expr: "get",
|
|
588
|
+
base: transformExpression(expr.base, ctx),
|
|
589
|
+
path: expr.path
|
|
590
|
+
};
|
|
510
591
|
}
|
|
511
592
|
}
|
|
512
593
|
function transformEventHandler(handler, ctx) {
|
|
@@ -537,6 +618,12 @@ function transformActionStep(step) {
|
|
|
537
618
|
if (step.value) {
|
|
538
619
|
updateStep.value = transformExpression(step.value, emptyContext);
|
|
539
620
|
}
|
|
621
|
+
if (step.index) {
|
|
622
|
+
updateStep.index = transformExpression(step.index, emptyContext);
|
|
623
|
+
}
|
|
624
|
+
if (step.deleteCount) {
|
|
625
|
+
updateStep.deleteCount = transformExpression(step.deleteCount, emptyContext);
|
|
626
|
+
}
|
|
540
627
|
return updateStep;
|
|
541
628
|
}
|
|
542
629
|
case "fetch": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constela/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Compiler for Constela UI framework - AST to Program transformation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"dist"
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@constela/core": "0.
|
|
18
|
+
"@constela/core": "0.3.1"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^20.10.0",
|