@sapui5/sap.fe.base 1.142.1 → 1.142.2
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/package.json +1 -1
- package/src/sap/fe/base/.library +1 -1
- package/src/sap/fe/base/AnnotationEnum.js +5 -3
- package/src/sap/fe/base/AnnotationEnum.ts +5 -2
- package/src/sap/fe/base/BindingToolkit.js +287 -28
- package/src/sap/fe/base/BindingToolkit.ts +607 -49
- package/src/sap/fe/base/library.js +1 -1
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ActionParameter,
|
|
3
|
+
AddAnnotationExpression,
|
|
4
|
+
AddConditionalExpression,
|
|
3
5
|
AndAnnotationExpression,
|
|
4
6
|
AndConditionalExpression,
|
|
5
7
|
ApplyAnnotationExpression,
|
|
6
8
|
Boolean,
|
|
7
9
|
ConditionalCheckOrValue,
|
|
10
|
+
ConvertedMetadata,
|
|
11
|
+
DivAnnotationExpression,
|
|
12
|
+
DivByAnnotationExpression,
|
|
13
|
+
DivByConditionalExpression,
|
|
14
|
+
DivConditionalExpression,
|
|
8
15
|
EntitySet,
|
|
9
16
|
EntityType,
|
|
10
17
|
EqAnnotationExpression,
|
|
@@ -13,14 +20,24 @@ import type {
|
|
|
13
20
|
GeConditionalExpression,
|
|
14
21
|
GtAnnotationExpression,
|
|
15
22
|
GtConditionalExpression,
|
|
23
|
+
HasAnnotationExpression,
|
|
24
|
+
HasConditionalExpression,
|
|
16
25
|
IfAnnotationExpression,
|
|
17
26
|
IfAnnotationExpressionValue,
|
|
27
|
+
InAnnotationExpression,
|
|
28
|
+
InConditionalExpression,
|
|
18
29
|
LeAnnotationExpression,
|
|
19
30
|
LeConditionalExpression,
|
|
20
31
|
LtAnnotationExpression,
|
|
21
32
|
LtConditionalExpression,
|
|
33
|
+
ModAnnotationExpression,
|
|
34
|
+
ModConditionalExpression,
|
|
35
|
+
MulAnnotationExpression,
|
|
36
|
+
MulConditionalExpression,
|
|
22
37
|
NeAnnotationExpression,
|
|
23
38
|
NeConditionalExpression,
|
|
39
|
+
NegAnnotationExpression,
|
|
40
|
+
NegConditionalExpression,
|
|
24
41
|
NotAnnotationExpression,
|
|
25
42
|
NotConditionalExpression,
|
|
26
43
|
OrAnnotationExpression,
|
|
@@ -29,6 +46,8 @@ import type {
|
|
|
29
46
|
PathConditionExpression,
|
|
30
47
|
Property,
|
|
31
48
|
PropertyAnnotationValue,
|
|
49
|
+
SubAnnotationExpression,
|
|
50
|
+
SubConditionalExpression,
|
|
32
51
|
ConstantExpression as VocabConstantExpression
|
|
33
52
|
} from "@sap-ux/vocabularies-types";
|
|
34
53
|
import { CommonAnnotationTerms } from "@sap-ux/vocabularies-types/vocabularies/Common";
|
|
@@ -157,7 +176,7 @@ export type EmbeddedUI5ExpressionBindingExpression<T> = BaseExpression<T> & {
|
|
|
157
176
|
value: string;
|
|
158
177
|
};
|
|
159
178
|
|
|
160
|
-
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<";
|
|
179
|
+
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<" | "Has" | "In";
|
|
161
180
|
export type ComparisonExpression = BaseExpression<boolean> & {
|
|
162
181
|
_type: "Comparison";
|
|
163
182
|
operator: ComparisonOperator;
|
|
@@ -165,6 +184,13 @@ export type ComparisonExpression = BaseExpression<boolean> & {
|
|
|
165
184
|
operand2: BindingToolkitExpression<unknown>;
|
|
166
185
|
};
|
|
167
186
|
|
|
187
|
+
export type ArithmeticOperator = "+" | "-" | "*" | "/" | "%" | "Neg" | "Floor";
|
|
188
|
+
export type ArithmeticExpression = BaseExpression<number> & {
|
|
189
|
+
_type: "Arithmetic";
|
|
190
|
+
operator: ArithmeticOperator;
|
|
191
|
+
operand1: BindingToolkitExpression<unknown>;
|
|
192
|
+
operand2: BindingToolkitExpression<unknown>;
|
|
193
|
+
};
|
|
168
194
|
export type IfElseExpression<T> = BaseExpression<T> & {
|
|
169
195
|
_type: "IfElse";
|
|
170
196
|
condition: BindingToolkitExpression<boolean>;
|
|
@@ -198,7 +224,8 @@ export type BindingToolkitExpression<T> =
|
|
|
198
224
|
| FormatterExpression<T>
|
|
199
225
|
| ComplexTypeExpression<T>
|
|
200
226
|
| ReferenceExpression
|
|
201
|
-
| FunctionExpression<T
|
|
227
|
+
| FunctionExpression<T>
|
|
228
|
+
| ArithmeticExpression;
|
|
202
229
|
|
|
203
230
|
type TypeMappingDefinition = {
|
|
204
231
|
type: string;
|
|
@@ -296,7 +323,12 @@ export function _checkExpressionsAreEqual<T>(a: BindingToolkitExpression<T>, b:
|
|
|
296
323
|
case "EmbeddedBinding":
|
|
297
324
|
case "EmbeddedExpressionBinding":
|
|
298
325
|
return a.value === (b as ConstantExpression<T>).value;
|
|
299
|
-
|
|
326
|
+
case "Arithmetic":
|
|
327
|
+
return (
|
|
328
|
+
a.operator === (b as ArithmeticExpression).operator &&
|
|
329
|
+
_checkExpressionsAreEqual(a.operand1, (b as ArithmeticExpression).operand1) &&
|
|
330
|
+
_checkExpressionsAreEqual(a.operand2, (b as ArithmeticExpression).operand2)
|
|
331
|
+
);
|
|
300
332
|
case "Not":
|
|
301
333
|
return _checkExpressionsAreEqual(a.operand, (b as NotExpression).operand);
|
|
302
334
|
case "Truthy":
|
|
@@ -502,6 +534,138 @@ export function or(...operands: ExpressionOrPrimitive<boolean>[]): BindingToolki
|
|
|
502
534
|
}
|
|
503
535
|
}
|
|
504
536
|
|
|
537
|
+
export function add<T extends PrimitiveType>(
|
|
538
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
539
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
540
|
+
): BindingToolkitExpression<number> {
|
|
541
|
+
return arithmetic("+", leftOperand, rightOperand);
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
export function subtract<T extends PrimitiveType>(
|
|
545
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
546
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
547
|
+
): BindingToolkitExpression<number> {
|
|
548
|
+
return arithmetic("-", leftOperand, rightOperand);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
export function multiply<T extends PrimitiveType>(
|
|
552
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
553
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
554
|
+
): BindingToolkitExpression<number> {
|
|
555
|
+
return arithmetic("*", leftOperand, rightOperand);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
export function divide<T extends PrimitiveType>(
|
|
559
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
560
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
561
|
+
): BindingToolkitExpression<number> {
|
|
562
|
+
return arithmetic("/", leftOperand, rightOperand);
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
export function modulo<T extends PrimitiveType>(
|
|
566
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
567
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
568
|
+
): BindingToolkitExpression<number> {
|
|
569
|
+
return arithmetic("%", leftOperand, rightOperand);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function negate<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
573
|
+
return arithmetic("Neg", operand, null);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export function floor<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
577
|
+
return arithmetic("Floor", operand, null);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Arithmetic expression.
|
|
582
|
+
* @param operator
|
|
583
|
+
* @param leftOperand
|
|
584
|
+
* @param rightOperand
|
|
585
|
+
* @returns Expression evaluating to number
|
|
586
|
+
*/
|
|
587
|
+
export function arithmetic<T extends PrimitiveType>(
|
|
588
|
+
operator: ArithmeticOperator,
|
|
589
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
590
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
591
|
+
): BindingToolkitExpression<number> {
|
|
592
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
593
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
594
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
595
|
+
return unresolvableExpression;
|
|
596
|
+
}
|
|
597
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
598
|
+
switch (operator) {
|
|
599
|
+
case "+":
|
|
600
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
601
|
+
return constant(rightExpression.value as number);
|
|
602
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
603
|
+
return constant(leftExpression.value as number);
|
|
604
|
+
}
|
|
605
|
+
const sum = (leftExpression.value as number) + (rightExpression.value as number);
|
|
606
|
+
return constant(sum);
|
|
607
|
+
case "-":
|
|
608
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
609
|
+
return constant(rightExpression.value as number);
|
|
610
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
611
|
+
return constant(leftExpression.value as number);
|
|
612
|
+
}
|
|
613
|
+
const diff = (leftExpression.value as number) - (rightExpression.value as number);
|
|
614
|
+
return constant(diff);
|
|
615
|
+
case "/":
|
|
616
|
+
if (
|
|
617
|
+
leftExpression.value === null ||
|
|
618
|
+
leftExpression.value === undefined ||
|
|
619
|
+
rightExpression.value === null ||
|
|
620
|
+
rightExpression.value === undefined
|
|
621
|
+
) {
|
|
622
|
+
return constant(0);
|
|
623
|
+
}
|
|
624
|
+
const div = (leftExpression.value as number) / (rightExpression.value as number);
|
|
625
|
+
return constant(div);
|
|
626
|
+
case "Neg":
|
|
627
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
628
|
+
return constant(0);
|
|
629
|
+
}
|
|
630
|
+
return constant(-leftExpression.value);
|
|
631
|
+
case "%":
|
|
632
|
+
if (
|
|
633
|
+
leftExpression.value === null ||
|
|
634
|
+
leftExpression.value === undefined ||
|
|
635
|
+
rightExpression.value === null ||
|
|
636
|
+
rightExpression.value === undefined
|
|
637
|
+
) {
|
|
638
|
+
return constant(0);
|
|
639
|
+
}
|
|
640
|
+
const mod = (leftExpression.value as number) % (rightExpression.value as number);
|
|
641
|
+
return constant(mod);
|
|
642
|
+
case "Floor":
|
|
643
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
644
|
+
return constant(0);
|
|
645
|
+
}
|
|
646
|
+
return constant(Math.floor(leftExpression.value as number));
|
|
647
|
+
case "*":
|
|
648
|
+
if (
|
|
649
|
+
leftExpression.value === null ||
|
|
650
|
+
leftExpression.value === undefined ||
|
|
651
|
+
rightExpression.value === null ||
|
|
652
|
+
rightExpression.value === undefined
|
|
653
|
+
) {
|
|
654
|
+
return constant(0);
|
|
655
|
+
}
|
|
656
|
+
const mult = (leftExpression.value as number) * (rightExpression.value as number);
|
|
657
|
+
return constant(mult);
|
|
658
|
+
}
|
|
659
|
+
} else {
|
|
660
|
+
return {
|
|
661
|
+
_type: "Arithmetic",
|
|
662
|
+
operator: operator,
|
|
663
|
+
operand1: leftExpression,
|
|
664
|
+
operand2: rightExpression
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
|
|
505
669
|
/**
|
|
506
670
|
* Logical `not` operator.
|
|
507
671
|
* @param operand The expression to reverse
|
|
@@ -542,6 +706,11 @@ export function not(operand: ExpressionOrPrimitive<boolean>): BindingToolkitExpr
|
|
|
542
706
|
return { ...operand, operator: "<=" };
|
|
543
707
|
case ">=":
|
|
544
708
|
return { ...operand, operator: "<" };
|
|
709
|
+
default:
|
|
710
|
+
return {
|
|
711
|
+
_type: "Not",
|
|
712
|
+
operand: operand
|
|
713
|
+
};
|
|
545
714
|
}
|
|
546
715
|
} else if (operand._type === "Not") {
|
|
547
716
|
return operand.operand;
|
|
@@ -852,6 +1021,15 @@ type ComplexAnnotationExpression<P> =
|
|
|
852
1021
|
| GeAnnotationExpression<P>
|
|
853
1022
|
| LeAnnotationExpression<P>
|
|
854
1023
|
| LtAnnotationExpression<P>
|
|
1024
|
+
| HasAnnotationExpression<P>
|
|
1025
|
+
| InAnnotationExpression<P>
|
|
1026
|
+
| AddAnnotationExpression<P>
|
|
1027
|
+
| SubAnnotationExpression<P>
|
|
1028
|
+
| MulAnnotationExpression<P>
|
|
1029
|
+
| DivAnnotationExpression<P>
|
|
1030
|
+
| ModAnnotationExpression<P>
|
|
1031
|
+
| DivByAnnotationExpression<P>
|
|
1032
|
+
| NegAnnotationExpression<P>
|
|
855
1033
|
| VocabConstantExpression<P>;
|
|
856
1034
|
|
|
857
1035
|
function isPrimitiveObject(objectType: object): boolean {
|
|
@@ -874,6 +1052,11 @@ function isComplexAnnotationExpression<T>(annotationValue: PropertyAnnotationVal
|
|
|
874
1052
|
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue as object);
|
|
875
1053
|
}
|
|
876
1054
|
|
|
1055
|
+
let CONVERTER_ROOT_SYMBOL: symbol | undefined;
|
|
1056
|
+
export function setConverterRootSymbol(converterRootSymbol: symbol): void {
|
|
1057
|
+
CONVERTER_ROOT_SYMBOL = converterRootSymbol;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
877
1060
|
/**
|
|
878
1061
|
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
879
1062
|
* @template T The target type
|
|
@@ -889,6 +1072,11 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
889
1072
|
defaultValue?: ExpressionOrPrimitive<T>,
|
|
890
1073
|
pathVisitor?: Function
|
|
891
1074
|
): BindingToolkitExpression<PrimitiveTypeCast<T>> {
|
|
1075
|
+
let converterRoot: ConvertedMetadata | undefined;
|
|
1076
|
+
if (CONVERTER_ROOT_SYMBOL) {
|
|
1077
|
+
converterRoot = (annotationValue?.[CONVERTER_ROOT_SYMBOL as never] as unknown as Function)?.() as ConvertedMetadata | undefined;
|
|
1078
|
+
}
|
|
1079
|
+
|
|
892
1080
|
if (annotationValue === undefined) {
|
|
893
1081
|
return wrapPrimitive(defaultValue as PrimitiveTypeCast<T>);
|
|
894
1082
|
}
|
|
@@ -901,55 +1089,106 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
901
1089
|
case "Path":
|
|
902
1090
|
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
903
1091
|
case "If":
|
|
904
|
-
return annotationIfExpression(
|
|
905
|
-
|
|
906
|
-
|
|
1092
|
+
return annotationIfExpression(
|
|
1093
|
+
annotationValue.$If,
|
|
1094
|
+
visitedNavigationPaths,
|
|
1095
|
+
pathVisitor,
|
|
1096
|
+
converterRoot
|
|
1097
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
907
1098
|
case "Not":
|
|
908
|
-
return not(
|
|
909
|
-
|
|
910
|
-
|
|
1099
|
+
return not(
|
|
1100
|
+
parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1101
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
911
1102
|
case "Eq":
|
|
912
1103
|
return equal(
|
|
913
|
-
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor),
|
|
914
|
-
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor)
|
|
1104
|
+
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1105
|
+
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
915
1106
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
916
1107
|
case "Ne":
|
|
917
1108
|
return notEqual(
|
|
918
|
-
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor),
|
|
919
|
-
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor)
|
|
1109
|
+
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1110
|
+
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
920
1111
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
921
1112
|
case "Gt":
|
|
922
1113
|
return greaterThan(
|
|
923
|
-
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor),
|
|
924
|
-
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor)
|
|
1114
|
+
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1115
|
+
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
925
1116
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
926
1117
|
case "Ge":
|
|
927
1118
|
return greaterOrEqual(
|
|
928
|
-
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor),
|
|
929
|
-
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor)
|
|
1119
|
+
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1120
|
+
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
930
1121
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
931
1122
|
case "Lt":
|
|
932
1123
|
return lessThan(
|
|
933
|
-
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor),
|
|
934
|
-
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor)
|
|
1124
|
+
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1125
|
+
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
935
1126
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
936
1127
|
case "Le":
|
|
937
1128
|
return lessOrEqual(
|
|
938
|
-
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor),
|
|
939
|
-
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor)
|
|
1129
|
+
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1130
|
+
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
940
1131
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
941
1132
|
case "Or":
|
|
942
1133
|
return or(
|
|
943
1134
|
...annotationValue.$Or.map(function (orCondition) {
|
|
944
|
-
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1135
|
+
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
945
1136
|
})
|
|
946
1137
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
947
1138
|
case "And":
|
|
948
1139
|
return and(
|
|
949
1140
|
...annotationValue.$And.map(function (andCondition) {
|
|
950
|
-
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1141
|
+
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
951
1142
|
})
|
|
952
1143
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1144
|
+
case "In":
|
|
1145
|
+
return comparison(
|
|
1146
|
+
"In",
|
|
1147
|
+
parseAnnotationCondition(annotationValue.$In[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1148
|
+
parseAnnotationCondition(annotationValue.$In[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1149
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1150
|
+
case "Has":
|
|
1151
|
+
return comparison(
|
|
1152
|
+
"Has",
|
|
1153
|
+
parseAnnotationCondition(annotationValue.$Has[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1154
|
+
parseAnnotationCondition(annotationValue.$Has[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1155
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1156
|
+
case "Add":
|
|
1157
|
+
return add(
|
|
1158
|
+
parseAnnotationCondition(annotationValue.$Add[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1159
|
+
parseAnnotationCondition(annotationValue.$Add[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1160
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1161
|
+
case "Sub":
|
|
1162
|
+
return subtract(
|
|
1163
|
+
parseAnnotationCondition(annotationValue.$Sub[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1164
|
+
parseAnnotationCondition(annotationValue.$Sub[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1165
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1166
|
+
case "Mul":
|
|
1167
|
+
return multiply(
|
|
1168
|
+
parseAnnotationCondition(annotationValue.$Mul[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1169
|
+
parseAnnotationCondition(annotationValue.$Mul[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1170
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1171
|
+
case "Div":
|
|
1172
|
+
return floor(
|
|
1173
|
+
divide(
|
|
1174
|
+
parseAnnotationCondition(annotationValue.$Div[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1175
|
+
parseAnnotationCondition(annotationValue.$Div[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1176
|
+
)
|
|
1177
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1178
|
+
case "DivBy":
|
|
1179
|
+
return divide(
|
|
1180
|
+
parseAnnotationCondition(annotationValue.$DivBy[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1181
|
+
parseAnnotationCondition(annotationValue.$DivBy[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1182
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1183
|
+
case "Mod":
|
|
1184
|
+
return modulo(
|
|
1185
|
+
parseAnnotationCondition(annotationValue.$Mod[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1186
|
+
parseAnnotationCondition(annotationValue.$Mod[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1187
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1188
|
+
case "Neg":
|
|
1189
|
+
return negate(
|
|
1190
|
+
parseAnnotationCondition(annotationValue.$Neg[0], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1191
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
953
1192
|
case "Apply":
|
|
954
1193
|
return annotationApplyExpression(
|
|
955
1194
|
annotationValue as ApplyAnnotationExpression<string>,
|
|
@@ -969,60 +1208,122 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
969
1208
|
* @param annotationValue The condition or value from the annotation
|
|
970
1209
|
* @param visitedNavigationPaths The path from the root entity set
|
|
971
1210
|
* @param pathVisitor A function to modify the resulting path
|
|
1211
|
+
* @param converterRoot The root converted metadata
|
|
972
1212
|
* @returns An equivalent expression
|
|
973
1213
|
*/
|
|
974
1214
|
function parseAnnotationCondition<T extends PrimitiveType>(
|
|
975
1215
|
annotationValue: ConditionalCheckOrValue,
|
|
976
1216
|
visitedNavigationPaths: string[] = [],
|
|
977
|
-
pathVisitor?: Function
|
|
1217
|
+
pathVisitor?: Function,
|
|
1218
|
+
converterRoot?: ConvertedMetadata
|
|
978
1219
|
): BindingToolkitExpression<T> {
|
|
979
1220
|
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
980
1221
|
return constant(annotationValue as T);
|
|
981
1222
|
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
982
1223
|
return or(
|
|
983
1224
|
...((annotationValue as OrConditionalExpression).$Or.map(function (orCondition) {
|
|
984
|
-
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1225
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
985
1226
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
986
1227
|
) as BindingToolkitExpression<T>;
|
|
987
1228
|
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
988
1229
|
return and(
|
|
989
1230
|
...((annotationValue as AndConditionalExpression).$And.map(function (andCondition) {
|
|
990
|
-
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1231
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
991
1232
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
992
1233
|
) as BindingToolkitExpression<T>;
|
|
993
1234
|
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
994
1235
|
return not(
|
|
995
|
-
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor)
|
|
1236
|
+
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
996
1237
|
) as BindingToolkitExpression<T>;
|
|
997
1238
|
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
998
1239
|
return equal(
|
|
999
|
-
parseAnnotationCondition(
|
|
1000
|
-
|
|
1240
|
+
parseAnnotationCondition(
|
|
1241
|
+
(annotationValue as EqConditionalExpression).$Eq[0],
|
|
1242
|
+
visitedNavigationPaths,
|
|
1243
|
+
pathVisitor,
|
|
1244
|
+
converterRoot
|
|
1245
|
+
),
|
|
1246
|
+
parseAnnotationCondition(
|
|
1247
|
+
(annotationValue as EqConditionalExpression).$Eq[1],
|
|
1248
|
+
visitedNavigationPaths,
|
|
1249
|
+
pathVisitor,
|
|
1250
|
+
converterRoot
|
|
1251
|
+
)
|
|
1001
1252
|
) as BindingToolkitExpression<T>;
|
|
1002
1253
|
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
1003
1254
|
return notEqual(
|
|
1004
|
-
parseAnnotationCondition(
|
|
1005
|
-
|
|
1255
|
+
parseAnnotationCondition(
|
|
1256
|
+
(annotationValue as NeConditionalExpression).$Ne[0],
|
|
1257
|
+
visitedNavigationPaths,
|
|
1258
|
+
pathVisitor,
|
|
1259
|
+
converterRoot
|
|
1260
|
+
),
|
|
1261
|
+
parseAnnotationCondition(
|
|
1262
|
+
(annotationValue as NeConditionalExpression).$Ne[1],
|
|
1263
|
+
visitedNavigationPaths,
|
|
1264
|
+
pathVisitor,
|
|
1265
|
+
converterRoot
|
|
1266
|
+
)
|
|
1006
1267
|
) as BindingToolkitExpression<T>;
|
|
1007
1268
|
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
1008
1269
|
return greaterThan(
|
|
1009
|
-
parseAnnotationCondition(
|
|
1010
|
-
|
|
1270
|
+
parseAnnotationCondition(
|
|
1271
|
+
(annotationValue as GtConditionalExpression).$Gt[0],
|
|
1272
|
+
visitedNavigationPaths,
|
|
1273
|
+
pathVisitor,
|
|
1274
|
+
converterRoot
|
|
1275
|
+
),
|
|
1276
|
+
parseAnnotationCondition(
|
|
1277
|
+
(annotationValue as GtConditionalExpression).$Gt[1],
|
|
1278
|
+
visitedNavigationPaths,
|
|
1279
|
+
pathVisitor,
|
|
1280
|
+
converterRoot
|
|
1281
|
+
)
|
|
1011
1282
|
) as BindingToolkitExpression<T>;
|
|
1012
1283
|
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
1013
1284
|
return greaterOrEqual(
|
|
1014
|
-
parseAnnotationCondition(
|
|
1015
|
-
|
|
1285
|
+
parseAnnotationCondition(
|
|
1286
|
+
(annotationValue as GeConditionalExpression).$Ge[0],
|
|
1287
|
+
visitedNavigationPaths,
|
|
1288
|
+
pathVisitor,
|
|
1289
|
+
converterRoot
|
|
1290
|
+
),
|
|
1291
|
+
parseAnnotationCondition(
|
|
1292
|
+
(annotationValue as GeConditionalExpression).$Ge[1],
|
|
1293
|
+
visitedNavigationPaths,
|
|
1294
|
+
pathVisitor,
|
|
1295
|
+
converterRoot
|
|
1296
|
+
)
|
|
1016
1297
|
) as BindingToolkitExpression<T>;
|
|
1017
1298
|
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
1018
1299
|
return lessThan(
|
|
1019
|
-
parseAnnotationCondition(
|
|
1020
|
-
|
|
1300
|
+
parseAnnotationCondition(
|
|
1301
|
+
(annotationValue as LtConditionalExpression).$Lt[0],
|
|
1302
|
+
visitedNavigationPaths,
|
|
1303
|
+
pathVisitor,
|
|
1304
|
+
converterRoot
|
|
1305
|
+
),
|
|
1306
|
+
parseAnnotationCondition(
|
|
1307
|
+
(annotationValue as LtConditionalExpression).$Lt[1],
|
|
1308
|
+
visitedNavigationPaths,
|
|
1309
|
+
pathVisitor,
|
|
1310
|
+
converterRoot
|
|
1311
|
+
)
|
|
1021
1312
|
) as BindingToolkitExpression<T>;
|
|
1022
1313
|
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
1023
1314
|
return lessOrEqual(
|
|
1024
|
-
parseAnnotationCondition(
|
|
1025
|
-
|
|
1315
|
+
parseAnnotationCondition(
|
|
1316
|
+
(annotationValue as LeConditionalExpression).$Le[0],
|
|
1317
|
+
visitedNavigationPaths,
|
|
1318
|
+
pathVisitor,
|
|
1319
|
+
converterRoot
|
|
1320
|
+
),
|
|
1321
|
+
parseAnnotationCondition(
|
|
1322
|
+
(annotationValue as LeConditionalExpression).$Le[1],
|
|
1323
|
+
visitedNavigationPaths,
|
|
1324
|
+
pathVisitor,
|
|
1325
|
+
converterRoot
|
|
1326
|
+
)
|
|
1026
1327
|
) as BindingToolkitExpression<T>;
|
|
1027
1328
|
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
1028
1329
|
return pathInModel((annotationValue as PathConditionExpression<T>).$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
@@ -1048,9 +1349,137 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1048
1349
|
pathVisitor
|
|
1049
1350
|
) as BindingToolkitExpression<T>;
|
|
1050
1351
|
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
1051
|
-
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember) as T);
|
|
1352
|
+
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember, converterRoot) as T);
|
|
1353
|
+
} else if (annotationValue.hasOwnProperty("$In")) {
|
|
1354
|
+
return comparison(
|
|
1355
|
+
"In",
|
|
1356
|
+
parseAnnotationCondition(
|
|
1357
|
+
(annotationValue as InConditionalExpression).$In[0],
|
|
1358
|
+
visitedNavigationPaths,
|
|
1359
|
+
pathVisitor,
|
|
1360
|
+
converterRoot
|
|
1361
|
+
),
|
|
1362
|
+
parseAnnotationCondition(
|
|
1363
|
+
(annotationValue as InConditionalExpression).$In[1],
|
|
1364
|
+
visitedNavigationPaths,
|
|
1365
|
+
pathVisitor,
|
|
1366
|
+
converterRoot
|
|
1367
|
+
)
|
|
1368
|
+
) as BindingToolkitExpression<T>;
|
|
1369
|
+
} else if (annotationValue.hasOwnProperty("$Has")) {
|
|
1370
|
+
return comparison(
|
|
1371
|
+
"Has",
|
|
1372
|
+
parseAnnotationCondition(
|
|
1373
|
+
(annotationValue as HasConditionalExpression).$Has[0],
|
|
1374
|
+
visitedNavigationPaths,
|
|
1375
|
+
pathVisitor,
|
|
1376
|
+
converterRoot
|
|
1377
|
+
),
|
|
1378
|
+
parseAnnotationCondition(
|
|
1379
|
+
(annotationValue as HasConditionalExpression).$Has[1],
|
|
1380
|
+
visitedNavigationPaths,
|
|
1381
|
+
pathVisitor,
|
|
1382
|
+
converterRoot
|
|
1383
|
+
)
|
|
1384
|
+
) as BindingToolkitExpression<T>;
|
|
1385
|
+
} else if (annotationValue.hasOwnProperty("$Add")) {
|
|
1386
|
+
return add(
|
|
1387
|
+
parseAnnotationCondition(
|
|
1388
|
+
(annotationValue as AddConditionalExpression).$Add[0],
|
|
1389
|
+
visitedNavigationPaths,
|
|
1390
|
+
pathVisitor,
|
|
1391
|
+
converterRoot
|
|
1392
|
+
),
|
|
1393
|
+
parseAnnotationCondition(
|
|
1394
|
+
(annotationValue as AddConditionalExpression).$Add[1],
|
|
1395
|
+
visitedNavigationPaths,
|
|
1396
|
+
pathVisitor,
|
|
1397
|
+
converterRoot
|
|
1398
|
+
)
|
|
1399
|
+
) as BindingToolkitExpression<T>;
|
|
1400
|
+
} else if (annotationValue.hasOwnProperty("$Sub")) {
|
|
1401
|
+
return subtract(
|
|
1402
|
+
parseAnnotationCondition(
|
|
1403
|
+
(annotationValue as SubConditionalExpression).$Sub[0],
|
|
1404
|
+
visitedNavigationPaths,
|
|
1405
|
+
pathVisitor,
|
|
1406
|
+
converterRoot
|
|
1407
|
+
),
|
|
1408
|
+
parseAnnotationCondition(
|
|
1409
|
+
(annotationValue as SubConditionalExpression).$Sub[1],
|
|
1410
|
+
visitedNavigationPaths,
|
|
1411
|
+
pathVisitor,
|
|
1412
|
+
converterRoot
|
|
1413
|
+
)
|
|
1414
|
+
) as BindingToolkitExpression<T>;
|
|
1415
|
+
} else if (annotationValue.hasOwnProperty("$Mul")) {
|
|
1416
|
+
return multiply(
|
|
1417
|
+
parseAnnotationCondition(
|
|
1418
|
+
(annotationValue as MulConditionalExpression).$Mul[0],
|
|
1419
|
+
visitedNavigationPaths,
|
|
1420
|
+
pathVisitor,
|
|
1421
|
+
converterRoot
|
|
1422
|
+
),
|
|
1423
|
+
parseAnnotationCondition(
|
|
1424
|
+
(annotationValue as MulConditionalExpression).$Mul[1],
|
|
1425
|
+
visitedNavigationPaths,
|
|
1426
|
+
pathVisitor,
|
|
1427
|
+
converterRoot
|
|
1428
|
+
)
|
|
1429
|
+
) as BindingToolkitExpression<T>;
|
|
1430
|
+
} else if (annotationValue.hasOwnProperty("$Div")) {
|
|
1431
|
+
return floor(
|
|
1432
|
+
divide(
|
|
1433
|
+
parseAnnotationCondition(
|
|
1434
|
+
(annotationValue as DivConditionalExpression).$Div[0],
|
|
1435
|
+
visitedNavigationPaths,
|
|
1436
|
+
pathVisitor,
|
|
1437
|
+
converterRoot
|
|
1438
|
+
),
|
|
1439
|
+
parseAnnotationCondition(
|
|
1440
|
+
(annotationValue as DivConditionalExpression).$Div[1],
|
|
1441
|
+
visitedNavigationPaths,
|
|
1442
|
+
pathVisitor,
|
|
1443
|
+
converterRoot
|
|
1444
|
+
)
|
|
1445
|
+
)
|
|
1446
|
+
) as BindingToolkitExpression<T>;
|
|
1447
|
+
} else if (annotationValue.hasOwnProperty("$DivBy")) {
|
|
1448
|
+
return divide(
|
|
1449
|
+
parseAnnotationCondition(
|
|
1450
|
+
(annotationValue as DivByConditionalExpression).$DivBy[0],
|
|
1451
|
+
visitedNavigationPaths,
|
|
1452
|
+
pathVisitor,
|
|
1453
|
+
converterRoot
|
|
1454
|
+
),
|
|
1455
|
+
parseAnnotationCondition(
|
|
1456
|
+
(annotationValue as DivByConditionalExpression).$DivBy[1],
|
|
1457
|
+
visitedNavigationPaths,
|
|
1458
|
+
pathVisitor,
|
|
1459
|
+
converterRoot
|
|
1460
|
+
)
|
|
1461
|
+
) as BindingToolkitExpression<T>;
|
|
1462
|
+
} else if (annotationValue.hasOwnProperty("$Mod")) {
|
|
1463
|
+
return modulo(
|
|
1464
|
+
parseAnnotationCondition(
|
|
1465
|
+
(annotationValue as ModConditionalExpression).$Mod[0],
|
|
1466
|
+
visitedNavigationPaths,
|
|
1467
|
+
pathVisitor,
|
|
1468
|
+
converterRoot
|
|
1469
|
+
),
|
|
1470
|
+
parseAnnotationCondition(
|
|
1471
|
+
(annotationValue as ModConditionalExpression).$Mod[1],
|
|
1472
|
+
visitedNavigationPaths,
|
|
1473
|
+
pathVisitor,
|
|
1474
|
+
converterRoot
|
|
1475
|
+
)
|
|
1476
|
+
) as BindingToolkitExpression<T>;
|
|
1477
|
+
} else if (annotationValue.hasOwnProperty("$Neg")) {
|
|
1478
|
+
return negate(
|
|
1479
|
+
parseAnnotationCondition((annotationValue as NegConditionalExpression).$Neg, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1480
|
+
) as BindingToolkitExpression<T>;
|
|
1052
1481
|
}
|
|
1053
|
-
return constant(
|
|
1482
|
+
return constant(annotationValue as T);
|
|
1054
1483
|
}
|
|
1055
1484
|
|
|
1056
1485
|
/**
|
|
@@ -1059,17 +1488,19 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1059
1488
|
* @param annotationValue An If expression returning the type T
|
|
1060
1489
|
* @param visitedNavigationPaths The path from the root entity set
|
|
1061
1490
|
* @param pathVisitor A function to modify the resulting path
|
|
1491
|
+
* @param converterRoot The root converted metadata
|
|
1062
1492
|
* @returns The equivalent ifElse expression
|
|
1063
1493
|
*/
|
|
1064
1494
|
export function annotationIfExpression<T extends PrimitiveType>(
|
|
1065
1495
|
annotationValue: IfAnnotationExpressionValue<T>,
|
|
1066
1496
|
visitedNavigationPaths: string[] = [],
|
|
1067
|
-
pathVisitor?: Function
|
|
1497
|
+
pathVisitor?: Function,
|
|
1498
|
+
converterRoot?: ConvertedMetadata
|
|
1068
1499
|
): BindingToolkitExpression<T> {
|
|
1069
1500
|
return ifElse(
|
|
1070
|
-
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor),
|
|
1071
|
-
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor),
|
|
1072
|
-
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor)
|
|
1501
|
+
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1502
|
+
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1503
|
+
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1073
1504
|
);
|
|
1074
1505
|
}
|
|
1075
1506
|
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
@@ -1208,6 +1639,43 @@ function comparison<T extends PrimitiveType>(
|
|
|
1208
1639
|
return constant(false);
|
|
1209
1640
|
}
|
|
1210
1641
|
return constant(leftExpression.value >= rightExpression.value);
|
|
1642
|
+
|
|
1643
|
+
case "Has": {
|
|
1644
|
+
if (
|
|
1645
|
+
leftExpression.value === null ||
|
|
1646
|
+
leftExpression.value === undefined ||
|
|
1647
|
+
rightExpression.value === null ||
|
|
1648
|
+
rightExpression.value === undefined
|
|
1649
|
+
) {
|
|
1650
|
+
return constant(false);
|
|
1651
|
+
}
|
|
1652
|
+
const leftValueInt = leftExpression.value as number;
|
|
1653
|
+
const rightValueInt = rightExpression.value as number;
|
|
1654
|
+
return constant(!!(leftValueInt & rightValueInt));
|
|
1655
|
+
}
|
|
1656
|
+
case "In": {
|
|
1657
|
+
if (
|
|
1658
|
+
leftExpression.value === null ||
|
|
1659
|
+
leftExpression.value === undefined ||
|
|
1660
|
+
rightExpression.value === null ||
|
|
1661
|
+
rightExpression.value === undefined
|
|
1662
|
+
) {
|
|
1663
|
+
return constant(false);
|
|
1664
|
+
}
|
|
1665
|
+
// Check all the children of the right expression are constants
|
|
1666
|
+
const allChildrenConstants = (rightExpression.value as T[]).every((item) => isConstant(item));
|
|
1667
|
+
if (allChildrenConstants) {
|
|
1668
|
+
const rightValues = (rightExpression.value as ConstantExpression<T>[]).map((item) => item.value);
|
|
1669
|
+
return constant(rightValues.includes(leftExpression.value));
|
|
1670
|
+
} else {
|
|
1671
|
+
return {
|
|
1672
|
+
_type: "Comparison",
|
|
1673
|
+
operator: operator,
|
|
1674
|
+
operand1: leftExpression,
|
|
1675
|
+
operand2: rightExpression
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1211
1679
|
}
|
|
1212
1680
|
} else {
|
|
1213
1681
|
return {
|
|
@@ -1362,6 +1830,20 @@ export function lessThan<T extends DefinedPrimitiveType>(
|
|
|
1362
1830
|
return comparison("<", leftOperand, rightOperand);
|
|
1363
1831
|
}
|
|
1364
1832
|
|
|
1833
|
+
/**
|
|
1834
|
+
* Comparison: "Include" (In).
|
|
1835
|
+
* @template T The target type
|
|
1836
|
+
* @param leftOperand The operand on the left side
|
|
1837
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1838
|
+
* @returns An expression representing the comparison
|
|
1839
|
+
*/
|
|
1840
|
+
export function includes<T extends DefinedPrimitiveType>(
|
|
1841
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
1842
|
+
rightOperand: ExpressionOrPrimitive<T[]>
|
|
1843
|
+
): BindingToolkitExpression<boolean> {
|
|
1844
|
+
return comparison("In", leftOperand, rightOperand as ExpressionOrPrimitive<T>);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1365
1847
|
/**
|
|
1366
1848
|
* If-then-else expression.
|
|
1367
1849
|
*
|
|
@@ -1587,7 +2069,7 @@ export function formatResult<T, U extends Fn<T>>(
|
|
|
1587
2069
|
}
|
|
1588
2070
|
|
|
1589
2071
|
type BindingConstraints = {
|
|
1590
|
-
scale?: number;
|
|
2072
|
+
scale?: number | string;
|
|
1591
2073
|
precision?: number;
|
|
1592
2074
|
maxLength?: number;
|
|
1593
2075
|
nullable?: boolean;
|
|
@@ -1909,7 +2391,7 @@ export function isEmpty(expression: BindingToolkitExpression<string>): BindingTo
|
|
|
1909
2391
|
* @param exp The expression to evaluate
|
|
1910
2392
|
* @returns A Boolean evaluating if there is no relative path dependent on the current context
|
|
1911
2393
|
*/
|
|
1912
|
-
export function isExpressionStaticallyResolvable(exp: BindingToolkitExpression<
|
|
2394
|
+
export function isExpressionStaticallyResolvable<T extends PrimitiveType>(exp: BindingToolkitExpression<T>): boolean {
|
|
1913
2395
|
const referencedPaths: string[] = [];
|
|
1914
2396
|
transformRecursively(
|
|
1915
2397
|
exp,
|
|
@@ -1928,6 +2410,28 @@ export function isExpressionStaticallyResolvable(exp: BindingToolkitExpression<b
|
|
|
1928
2410
|
return referencedPaths.every((p) => p.startsWith("/"));
|
|
1929
2411
|
}
|
|
1930
2412
|
|
|
2413
|
+
export function getStaticallyResolvableExpression<T extends PrimitiveType>(
|
|
2414
|
+
exp: BindingToolkitExpression<T>,
|
|
2415
|
+
defaultValue: BindingToolkitExpression<T>
|
|
2416
|
+
): BindingToolkitExpression<T> {
|
|
2417
|
+
if (exp._type === "Set") {
|
|
2418
|
+
const newOperands = exp.operands.map((operand: BindingToolkitExpression<boolean>) => {
|
|
2419
|
+
if (isExpressionStaticallyResolvable(operand) || isConstant(operand)) {
|
|
2420
|
+
return operand;
|
|
2421
|
+
} else {
|
|
2422
|
+
return defaultValue;
|
|
2423
|
+
}
|
|
2424
|
+
});
|
|
2425
|
+
|
|
2426
|
+
if (exp.operator === "||") {
|
|
2427
|
+
return or(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2428
|
+
} else {
|
|
2429
|
+
return and(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
return isExpressionStaticallyResolvable(exp) ? exp : defaultValue;
|
|
2433
|
+
}
|
|
2434
|
+
|
|
1931
2435
|
export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): BindingToolkitExpression<string> {
|
|
1932
2436
|
const expressions = inExpressions.map(wrapPrimitive);
|
|
1933
2437
|
if (hasUnresolvableExpression(...expressions)) {
|
|
@@ -2076,6 +2580,21 @@ export function transformRecursively<T extends PrimitiveType | unknown, ET exten
|
|
|
2076
2580
|
expression = comparison(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2077
2581
|
}
|
|
2078
2582
|
break;
|
|
2583
|
+
case "Arithmetic":
|
|
2584
|
+
const operand1 = transformRecursively(
|
|
2585
|
+
expression.operand1 as BindingToolkitExpression<T>,
|
|
2586
|
+
expressionType,
|
|
2587
|
+
transformFunction,
|
|
2588
|
+
includeAllExpression
|
|
2589
|
+
);
|
|
2590
|
+
const operand2 = transformRecursively(
|
|
2591
|
+
expression.operand2 as BindingToolkitExpression<T>,
|
|
2592
|
+
expressionType,
|
|
2593
|
+
transformFunction,
|
|
2594
|
+
includeAllExpression
|
|
2595
|
+
);
|
|
2596
|
+
expression = arithmetic(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2597
|
+
break;
|
|
2079
2598
|
case "Constant":
|
|
2080
2599
|
const constantValue: Record<string, BindingToolkitExpression<unknown>> = expression.value as Record<
|
|
2081
2600
|
string,
|
|
@@ -2392,6 +2911,9 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2392
2911
|
case "Not":
|
|
2393
2912
|
const notExpression = `!${compileExpression(expr.operand, true)}`;
|
|
2394
2913
|
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
2914
|
+
case "Arithmetic":
|
|
2915
|
+
const arithmeticExpression = compileArithmeticExpression(expr);
|
|
2916
|
+
return wrapBindingExpression(arithmeticExpression, embeddedInBinding);
|
|
2395
2917
|
|
|
2396
2918
|
case "Truthy":
|
|
2397
2919
|
const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
|
|
@@ -2410,6 +2932,25 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2410
2932
|
}
|
|
2411
2933
|
}
|
|
2412
2934
|
|
|
2935
|
+
function compileArithmeticExpression(expression: ArithmeticExpression): string {
|
|
2936
|
+
function compileOperand(operand: BindingToolkitExpression<unknown>): CompiledBindingToolkitExpression {
|
|
2937
|
+
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2938
|
+
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2939
|
+
}
|
|
2940
|
+
switch (expression.operator) {
|
|
2941
|
+
case "Neg":
|
|
2942
|
+
return `-(${compileOperand(expression.operand1)})`;
|
|
2943
|
+
case "Floor":
|
|
2944
|
+
return `Math.floor(${compileOperand(expression.operand1)})`;
|
|
2945
|
+
case "%":
|
|
2946
|
+
case "/":
|
|
2947
|
+
case "*":
|
|
2948
|
+
case "+":
|
|
2949
|
+
case "-":
|
|
2950
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2413
2954
|
/**
|
|
2414
2955
|
* Compile a comparison expression.
|
|
2415
2956
|
* @param expression The comparison expression.
|
|
@@ -2420,8 +2961,25 @@ function compileComparisonExpression(expression: ComparisonExpression): string {
|
|
|
2420
2961
|
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2421
2962
|
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2422
2963
|
}
|
|
2423
|
-
|
|
2424
|
-
|
|
2964
|
+
switch (expression.operator) {
|
|
2965
|
+
case "In": {
|
|
2966
|
+
const path = compileOperand(expression.operand1);
|
|
2967
|
+
const collection = compileOperand(expression.operand2) ?? [];
|
|
2968
|
+
return `${collection}.includes(${path})`;
|
|
2969
|
+
}
|
|
2970
|
+
case "Has": {
|
|
2971
|
+
const path = compileOperand(expression.operand1);
|
|
2972
|
+
const flags = compileOperand(expression.operand2) ?? [];
|
|
2973
|
+
return `(${path} & ${flags}) > 0`;
|
|
2974
|
+
}
|
|
2975
|
+
case "===":
|
|
2976
|
+
case "!==":
|
|
2977
|
+
case ">=":
|
|
2978
|
+
case ">":
|
|
2979
|
+
case "<=":
|
|
2980
|
+
case "<":
|
|
2981
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
2982
|
+
}
|
|
2425
2983
|
}
|
|
2426
2984
|
|
|
2427
2985
|
/**
|