@sapui5/sap.fe.base 1.143.0 → 1.145.0
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 +345 -37
- package/src/sap/fe/base/BindingToolkit.ts +663 -55
- package/src/sap/fe/base/BuildingBlockBase.js +52 -6
- package/src/sap/fe/base/BuildingBlockBase.ts +55 -7
- package/src/sap/fe/base/ClassSupport.js +95 -18
- package/src/sap/fe/base/ClassSupport.ts +91 -21
- package/src/sap/fe/base/jsx-runtime/jsx-control.js +5 -5
- package/src/sap/fe/base/jsx-runtime/jsx-control.ts +5 -4
- package/src/sap/fe/base/jsx-runtime/jsx-xml.js +4 -2
- package/src/sap/fe/base/jsx-runtime/jsx-xml.ts +3 -1
- package/src/sap/fe/base/jsx-runtime/jsx.js +13 -1
- package/src/sap/fe/base/jsx-runtime/jsx.ts +11 -0
- package/src/sap/fe/base/library.js +1 -1
- package/src/sap/fe/base/types/sap.fe.base-auto-ext.d.js +10 -0
- package/src/sap/fe/base/types/sap.fe.base-auto-ext.d.ts +315 -0
- package/src/sap/fe/base/types/sap.fe.base-manual-ext.d.js +9 -0
- package/src/sap/fe/base/types/sap.fe.base-manual-ext.d.ts +33 -0
|
@@ -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";
|
|
@@ -37,11 +56,22 @@ import type { BindingInfoHolder } from "sap/fe/base/ClassSupport";
|
|
|
37
56
|
|
|
38
57
|
export type PrimitiveType = string | number | bigint | boolean | object | null | undefined;
|
|
39
58
|
type DefinedPrimitiveType = string | number | bigint | boolean | object;
|
|
59
|
+
/**
|
|
60
|
+
* Returns either the value of the object or the object itself if it is not a primitive object.
|
|
61
|
+
*/
|
|
40
62
|
type PrimitiveTypeCast<P> = P extends String ? string : P extends Boolean ? boolean : P extends Number ? number : P;
|
|
41
63
|
type BaseExpression<_T> = {
|
|
42
64
|
_type: string;
|
|
43
65
|
};
|
|
44
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Collection of functions to support the manipulation of UI5 bindings
|
|
69
|
+
* @public
|
|
70
|
+
* @namespace
|
|
71
|
+
* @ui5-experimental-since 1.145.0
|
|
72
|
+
*/
|
|
73
|
+
export const bindingToolkitNamespace = "sap.fe.base.BindingToolkit";
|
|
74
|
+
|
|
45
75
|
export type FormatOptions = Partial<{
|
|
46
76
|
customUnits: Record<string, object>;
|
|
47
77
|
customCurrencies: Record<string, object>;
|
|
@@ -157,7 +187,7 @@ export type EmbeddedUI5ExpressionBindingExpression<T> = BaseExpression<T> & {
|
|
|
157
187
|
value: string;
|
|
158
188
|
};
|
|
159
189
|
|
|
160
|
-
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<";
|
|
190
|
+
export type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<" | "Has" | "In";
|
|
161
191
|
export type ComparisonExpression = BaseExpression<boolean> & {
|
|
162
192
|
_type: "Comparison";
|
|
163
193
|
operator: ComparisonOperator;
|
|
@@ -165,6 +195,13 @@ export type ComparisonExpression = BaseExpression<boolean> & {
|
|
|
165
195
|
operand2: BindingToolkitExpression<unknown>;
|
|
166
196
|
};
|
|
167
197
|
|
|
198
|
+
export type ArithmeticOperator = "+" | "-" | "*" | "/" | "%" | "Neg" | "Floor";
|
|
199
|
+
export type ArithmeticExpression = BaseExpression<number> & {
|
|
200
|
+
_type: "Arithmetic";
|
|
201
|
+
operator: ArithmeticOperator;
|
|
202
|
+
operand1: BindingToolkitExpression<unknown>;
|
|
203
|
+
operand2: BindingToolkitExpression<unknown>;
|
|
204
|
+
};
|
|
168
205
|
export type IfElseExpression<T> = BaseExpression<T> & {
|
|
169
206
|
_type: "IfElse";
|
|
170
207
|
condition: BindingToolkitExpression<boolean>;
|
|
@@ -174,10 +211,14 @@ export type IfElseExpression<T> = BaseExpression<T> & {
|
|
|
174
211
|
export function isProperty(serviceObject: unknown): serviceObject is Property {
|
|
175
212
|
return (serviceObject as Property)?._type === "Property";
|
|
176
213
|
}
|
|
214
|
+
function isActionParameter(serviceObject: unknown): serviceObject is ActionParameter {
|
|
215
|
+
return (serviceObject as ActionParameter)?._type === "ActionParameter";
|
|
216
|
+
}
|
|
177
217
|
|
|
178
218
|
/**
|
|
179
|
-
*
|
|
180
|
-
* @
|
|
219
|
+
* A binding expression that evaluates to type T.
|
|
220
|
+
* @public
|
|
221
|
+
* @ui5-experimental-since 1.145.0
|
|
181
222
|
*/
|
|
182
223
|
export type BindingToolkitExpression<T> =
|
|
183
224
|
| UnresolvablePathExpression
|
|
@@ -195,7 +236,8 @@ export type BindingToolkitExpression<T> =
|
|
|
195
236
|
| FormatterExpression<T>
|
|
196
237
|
| ComplexTypeExpression<T>
|
|
197
238
|
| ReferenceExpression
|
|
198
|
-
| FunctionExpression<T
|
|
239
|
+
| FunctionExpression<T>
|
|
240
|
+
| ArithmeticExpression;
|
|
199
241
|
|
|
200
242
|
type TypeMappingDefinition = {
|
|
201
243
|
type: string;
|
|
@@ -293,7 +335,12 @@ export function _checkExpressionsAreEqual<T>(a: BindingToolkitExpression<T>, b:
|
|
|
293
335
|
case "EmbeddedBinding":
|
|
294
336
|
case "EmbeddedExpressionBinding":
|
|
295
337
|
return a.value === (b as ConstantExpression<T>).value;
|
|
296
|
-
|
|
338
|
+
case "Arithmetic":
|
|
339
|
+
return (
|
|
340
|
+
a.operator === (b as ArithmeticExpression).operator &&
|
|
341
|
+
_checkExpressionsAreEqual(a.operand1, (b as ArithmeticExpression).operand1) &&
|
|
342
|
+
_checkExpressionsAreEqual(a.operand2, (b as ArithmeticExpression).operand2)
|
|
343
|
+
);
|
|
297
344
|
case "Not":
|
|
298
345
|
return _checkExpressionsAreEqual(a.operand, (b as NotExpression).operand);
|
|
299
346
|
case "Truthy":
|
|
@@ -499,6 +546,138 @@ export function or(...operands: ExpressionOrPrimitive<boolean>[]): BindingToolki
|
|
|
499
546
|
}
|
|
500
547
|
}
|
|
501
548
|
|
|
549
|
+
export function add<T extends PrimitiveType>(
|
|
550
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
551
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
552
|
+
): BindingToolkitExpression<number> {
|
|
553
|
+
return arithmetic("+", leftOperand, rightOperand);
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
export function subtract<T extends PrimitiveType>(
|
|
557
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
558
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
559
|
+
): BindingToolkitExpression<number> {
|
|
560
|
+
return arithmetic("-", leftOperand, rightOperand);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
export function multiply<T extends PrimitiveType>(
|
|
564
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
565
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
566
|
+
): BindingToolkitExpression<number> {
|
|
567
|
+
return arithmetic("*", leftOperand, rightOperand);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
export function divide<T extends PrimitiveType>(
|
|
571
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
572
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
573
|
+
): BindingToolkitExpression<number> {
|
|
574
|
+
return arithmetic("/", leftOperand, rightOperand);
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export function modulo<T extends PrimitiveType>(
|
|
578
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
579
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
580
|
+
): BindingToolkitExpression<number> {
|
|
581
|
+
return arithmetic("%", leftOperand, rightOperand);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
export function negate<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
585
|
+
return arithmetic("Neg", operand, null);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export function floor<T extends PrimitiveType>(operand: ExpressionOrPrimitive<T>): BindingToolkitExpression<number> {
|
|
589
|
+
return arithmetic("Floor", operand, null);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Arithmetic expression.
|
|
594
|
+
* @param operator
|
|
595
|
+
* @param leftOperand
|
|
596
|
+
* @param rightOperand
|
|
597
|
+
* @returns Expression evaluating to number
|
|
598
|
+
*/
|
|
599
|
+
export function arithmetic<T extends PrimitiveType>(
|
|
600
|
+
operator: ArithmeticOperator,
|
|
601
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
602
|
+
rightOperand: ExpressionOrPrimitive<T>
|
|
603
|
+
): BindingToolkitExpression<number> {
|
|
604
|
+
const leftExpression = wrapPrimitive(leftOperand);
|
|
605
|
+
const rightExpression = wrapPrimitive(rightOperand);
|
|
606
|
+
if (hasUnresolvableExpression(leftExpression, rightExpression)) {
|
|
607
|
+
return unresolvableExpression;
|
|
608
|
+
}
|
|
609
|
+
if (isConstant(leftExpression) && isConstant(rightExpression)) {
|
|
610
|
+
switch (operator) {
|
|
611
|
+
case "+":
|
|
612
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
613
|
+
return constant(rightExpression.value as number);
|
|
614
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
615
|
+
return constant(leftExpression.value as number);
|
|
616
|
+
}
|
|
617
|
+
const sum = (leftExpression.value as number) + (rightExpression.value as number);
|
|
618
|
+
return constant(sum);
|
|
619
|
+
case "-":
|
|
620
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
621
|
+
return constant(rightExpression.value as number);
|
|
622
|
+
} else if (rightExpression.value === null || rightExpression.value === undefined) {
|
|
623
|
+
return constant(leftExpression.value as number);
|
|
624
|
+
}
|
|
625
|
+
const diff = (leftExpression.value as number) - (rightExpression.value as number);
|
|
626
|
+
return constant(diff);
|
|
627
|
+
case "/":
|
|
628
|
+
if (
|
|
629
|
+
leftExpression.value === null ||
|
|
630
|
+
leftExpression.value === undefined ||
|
|
631
|
+
rightExpression.value === null ||
|
|
632
|
+
rightExpression.value === undefined
|
|
633
|
+
) {
|
|
634
|
+
return constant(0);
|
|
635
|
+
}
|
|
636
|
+
const div = (leftExpression.value as number) / (rightExpression.value as number);
|
|
637
|
+
return constant(div);
|
|
638
|
+
case "Neg":
|
|
639
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
640
|
+
return constant(0);
|
|
641
|
+
}
|
|
642
|
+
return constant(-leftExpression.value);
|
|
643
|
+
case "%":
|
|
644
|
+
if (
|
|
645
|
+
leftExpression.value === null ||
|
|
646
|
+
leftExpression.value === undefined ||
|
|
647
|
+
rightExpression.value === null ||
|
|
648
|
+
rightExpression.value === undefined
|
|
649
|
+
) {
|
|
650
|
+
return constant(0);
|
|
651
|
+
}
|
|
652
|
+
const mod = (leftExpression.value as number) % (rightExpression.value as number);
|
|
653
|
+
return constant(mod);
|
|
654
|
+
case "Floor":
|
|
655
|
+
if (leftExpression.value === null || leftExpression.value === undefined) {
|
|
656
|
+
return constant(0);
|
|
657
|
+
}
|
|
658
|
+
return constant(Math.floor(leftExpression.value as number));
|
|
659
|
+
case "*":
|
|
660
|
+
if (
|
|
661
|
+
leftExpression.value === null ||
|
|
662
|
+
leftExpression.value === undefined ||
|
|
663
|
+
rightExpression.value === null ||
|
|
664
|
+
rightExpression.value === undefined
|
|
665
|
+
) {
|
|
666
|
+
return constant(0);
|
|
667
|
+
}
|
|
668
|
+
const mult = (leftExpression.value as number) * (rightExpression.value as number);
|
|
669
|
+
return constant(mult);
|
|
670
|
+
}
|
|
671
|
+
} else {
|
|
672
|
+
return {
|
|
673
|
+
_type: "Arithmetic",
|
|
674
|
+
operator: operator,
|
|
675
|
+
operand1: leftExpression,
|
|
676
|
+
operand2: rightExpression
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
502
681
|
/**
|
|
503
682
|
* Logical `not` operator.
|
|
504
683
|
* @param operand The expression to reverse
|
|
@@ -539,6 +718,11 @@ export function not(operand: ExpressionOrPrimitive<boolean>): BindingToolkitExpr
|
|
|
539
718
|
return { ...operand, operator: "<=" };
|
|
540
719
|
case ">=":
|
|
541
720
|
return { ...operand, operator: "<" };
|
|
721
|
+
default:
|
|
722
|
+
return {
|
|
723
|
+
_type: "Not",
|
|
724
|
+
operand: operand
|
|
725
|
+
};
|
|
542
726
|
}
|
|
543
727
|
} else if (operand._type === "Not") {
|
|
544
728
|
return operand.operand;
|
|
@@ -849,6 +1033,15 @@ type ComplexAnnotationExpression<P> =
|
|
|
849
1033
|
| GeAnnotationExpression<P>
|
|
850
1034
|
| LeAnnotationExpression<P>
|
|
851
1035
|
| LtAnnotationExpression<P>
|
|
1036
|
+
| HasAnnotationExpression<P>
|
|
1037
|
+
| InAnnotationExpression<P>
|
|
1038
|
+
| AddAnnotationExpression<P>
|
|
1039
|
+
| SubAnnotationExpression<P>
|
|
1040
|
+
| MulAnnotationExpression<P>
|
|
1041
|
+
| DivAnnotationExpression<P>
|
|
1042
|
+
| ModAnnotationExpression<P>
|
|
1043
|
+
| DivByAnnotationExpression<P>
|
|
1044
|
+
| NegAnnotationExpression<P>
|
|
852
1045
|
| VocabConstantExpression<P>;
|
|
853
1046
|
|
|
854
1047
|
function isPrimitiveObject(objectType: object): boolean {
|
|
@@ -871,6 +1064,11 @@ function isComplexAnnotationExpression<T>(annotationValue: PropertyAnnotationVal
|
|
|
871
1064
|
return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue as object);
|
|
872
1065
|
}
|
|
873
1066
|
|
|
1067
|
+
let CONVERTER_ROOT_SYMBOL: symbol | undefined;
|
|
1068
|
+
export function setConverterRootSymbol(converterRootSymbol: symbol): void {
|
|
1069
|
+
CONVERTER_ROOT_SYMBOL = converterRootSymbol;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
874
1072
|
/**
|
|
875
1073
|
* Generate the corresponding annotationValue for a given annotation annotationValue.
|
|
876
1074
|
* @template T The target type
|
|
@@ -886,6 +1084,11 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
886
1084
|
defaultValue?: ExpressionOrPrimitive<T>,
|
|
887
1085
|
pathVisitor?: Function
|
|
888
1086
|
): BindingToolkitExpression<PrimitiveTypeCast<T>> {
|
|
1087
|
+
let converterRoot: ConvertedMetadata | undefined;
|
|
1088
|
+
if (CONVERTER_ROOT_SYMBOL) {
|
|
1089
|
+
converterRoot = (annotationValue?.[CONVERTER_ROOT_SYMBOL as never] as unknown as Function)?.() as ConvertedMetadata | undefined;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
889
1092
|
if (annotationValue === undefined) {
|
|
890
1093
|
return wrapPrimitive(defaultValue as PrimitiveTypeCast<T>);
|
|
891
1094
|
}
|
|
@@ -898,55 +1101,106 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
898
1101
|
case "Path":
|
|
899
1102
|
return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
|
|
900
1103
|
case "If":
|
|
901
|
-
return annotationIfExpression(
|
|
902
|
-
|
|
903
|
-
|
|
1104
|
+
return annotationIfExpression(
|
|
1105
|
+
annotationValue.$If,
|
|
1106
|
+
visitedNavigationPaths,
|
|
1107
|
+
pathVisitor,
|
|
1108
|
+
converterRoot
|
|
1109
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
904
1110
|
case "Not":
|
|
905
|
-
return not(
|
|
906
|
-
|
|
907
|
-
|
|
1111
|
+
return not(
|
|
1112
|
+
parseAnnotationCondition(annotationValue.$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1113
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
908
1114
|
case "Eq":
|
|
909
1115
|
return equal(
|
|
910
|
-
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor),
|
|
911
|
-
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor)
|
|
1116
|
+
parseAnnotationCondition(annotationValue.$Eq[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1117
|
+
parseAnnotationCondition(annotationValue.$Eq[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
912
1118
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
913
1119
|
case "Ne":
|
|
914
1120
|
return notEqual(
|
|
915
|
-
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor),
|
|
916
|
-
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor)
|
|
1121
|
+
parseAnnotationCondition(annotationValue.$Ne[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1122
|
+
parseAnnotationCondition(annotationValue.$Ne[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
917
1123
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
918
1124
|
case "Gt":
|
|
919
1125
|
return greaterThan(
|
|
920
|
-
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor),
|
|
921
|
-
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor)
|
|
1126
|
+
parseAnnotationCondition(annotationValue.$Gt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1127
|
+
parseAnnotationCondition(annotationValue.$Gt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
922
1128
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
923
1129
|
case "Ge":
|
|
924
1130
|
return greaterOrEqual(
|
|
925
|
-
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor),
|
|
926
|
-
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor)
|
|
1131
|
+
parseAnnotationCondition(annotationValue.$Ge[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1132
|
+
parseAnnotationCondition(annotationValue.$Ge[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
927
1133
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
928
1134
|
case "Lt":
|
|
929
1135
|
return lessThan(
|
|
930
|
-
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor),
|
|
931
|
-
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor)
|
|
1136
|
+
parseAnnotationCondition(annotationValue.$Lt[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1137
|
+
parseAnnotationCondition(annotationValue.$Lt[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
932
1138
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
933
1139
|
case "Le":
|
|
934
1140
|
return lessOrEqual(
|
|
935
|
-
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor),
|
|
936
|
-
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor)
|
|
1141
|
+
parseAnnotationCondition(annotationValue.$Le[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1142
|
+
parseAnnotationCondition(annotationValue.$Le[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
937
1143
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
938
1144
|
case "Or":
|
|
939
1145
|
return or(
|
|
940
1146
|
...annotationValue.$Or.map(function (orCondition) {
|
|
941
|
-
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1147
|
+
return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
942
1148
|
})
|
|
943
1149
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
944
1150
|
case "And":
|
|
945
1151
|
return and(
|
|
946
1152
|
...annotationValue.$And.map(function (andCondition) {
|
|
947
|
-
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1153
|
+
return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
948
1154
|
})
|
|
949
1155
|
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1156
|
+
case "In":
|
|
1157
|
+
return comparison(
|
|
1158
|
+
"In",
|
|
1159
|
+
parseAnnotationCondition(annotationValue.$In[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1160
|
+
parseAnnotationCondition(annotationValue.$In[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1161
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1162
|
+
case "Has":
|
|
1163
|
+
return comparison(
|
|
1164
|
+
"Has",
|
|
1165
|
+
parseAnnotationCondition(annotationValue.$Has[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1166
|
+
parseAnnotationCondition(annotationValue.$Has[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1167
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1168
|
+
case "Add":
|
|
1169
|
+
return add(
|
|
1170
|
+
parseAnnotationCondition(annotationValue.$Add[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1171
|
+
parseAnnotationCondition(annotationValue.$Add[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1172
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1173
|
+
case "Sub":
|
|
1174
|
+
return subtract(
|
|
1175
|
+
parseAnnotationCondition(annotationValue.$Sub[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1176
|
+
parseAnnotationCondition(annotationValue.$Sub[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1177
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1178
|
+
case "Mul":
|
|
1179
|
+
return multiply(
|
|
1180
|
+
parseAnnotationCondition(annotationValue.$Mul[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1181
|
+
parseAnnotationCondition(annotationValue.$Mul[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1182
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1183
|
+
case "Div":
|
|
1184
|
+
return floor(
|
|
1185
|
+
divide(
|
|
1186
|
+
parseAnnotationCondition(annotationValue.$Div[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1187
|
+
parseAnnotationCondition(annotationValue.$Div[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1188
|
+
)
|
|
1189
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1190
|
+
case "DivBy":
|
|
1191
|
+
return divide(
|
|
1192
|
+
parseAnnotationCondition(annotationValue.$DivBy[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1193
|
+
parseAnnotationCondition(annotationValue.$DivBy[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1194
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1195
|
+
case "Mod":
|
|
1196
|
+
return modulo(
|
|
1197
|
+
parseAnnotationCondition(annotationValue.$Mod[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1198
|
+
parseAnnotationCondition(annotationValue.$Mod[1], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1199
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
1200
|
+
case "Neg":
|
|
1201
|
+
return negate(
|
|
1202
|
+
parseAnnotationCondition(annotationValue.$Neg[0], visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1203
|
+
) as BindingToolkitExpression<PrimitiveTypeCast<T>>;
|
|
950
1204
|
case "Apply":
|
|
951
1205
|
return annotationApplyExpression(
|
|
952
1206
|
annotationValue as ApplyAnnotationExpression<string>,
|
|
@@ -966,60 +1220,122 @@ export function getExpressionFromAnnotation<T extends PrimitiveType>(
|
|
|
966
1220
|
* @param annotationValue The condition or value from the annotation
|
|
967
1221
|
* @param visitedNavigationPaths The path from the root entity set
|
|
968
1222
|
* @param pathVisitor A function to modify the resulting path
|
|
1223
|
+
* @param converterRoot The root converted metadata
|
|
969
1224
|
* @returns An equivalent expression
|
|
970
1225
|
*/
|
|
971
1226
|
function parseAnnotationCondition<T extends PrimitiveType>(
|
|
972
1227
|
annotationValue: ConditionalCheckOrValue,
|
|
973
1228
|
visitedNavigationPaths: string[] = [],
|
|
974
|
-
pathVisitor?: Function
|
|
1229
|
+
pathVisitor?: Function,
|
|
1230
|
+
converterRoot?: ConvertedMetadata
|
|
975
1231
|
): BindingToolkitExpression<T> {
|
|
976
1232
|
if (annotationValue === null || typeof annotationValue !== "object") {
|
|
977
1233
|
return constant(annotationValue as T);
|
|
978
1234
|
} else if (annotationValue.hasOwnProperty("$Or")) {
|
|
979
1235
|
return or(
|
|
980
1236
|
...((annotationValue as OrConditionalExpression).$Or.map(function (orCondition) {
|
|
981
|
-
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
|
|
1237
|
+
return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
982
1238
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
983
1239
|
) as BindingToolkitExpression<T>;
|
|
984
1240
|
} else if (annotationValue.hasOwnProperty("$And")) {
|
|
985
1241
|
return and(
|
|
986
1242
|
...((annotationValue as AndConditionalExpression).$And.map(function (andCondition) {
|
|
987
|
-
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
|
|
1243
|
+
return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor, converterRoot);
|
|
988
1244
|
}) as unknown as BindingToolkitExpression<boolean>[])
|
|
989
1245
|
) as BindingToolkitExpression<T>;
|
|
990
1246
|
} else if (annotationValue.hasOwnProperty("$Not")) {
|
|
991
1247
|
return not(
|
|
992
|
-
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor)
|
|
1248
|
+
parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
993
1249
|
) as BindingToolkitExpression<T>;
|
|
994
1250
|
} else if (annotationValue.hasOwnProperty("$Eq")) {
|
|
995
1251
|
return equal(
|
|
996
|
-
parseAnnotationCondition(
|
|
997
|
-
|
|
1252
|
+
parseAnnotationCondition(
|
|
1253
|
+
(annotationValue as EqConditionalExpression).$Eq[0],
|
|
1254
|
+
visitedNavigationPaths,
|
|
1255
|
+
pathVisitor,
|
|
1256
|
+
converterRoot
|
|
1257
|
+
),
|
|
1258
|
+
parseAnnotationCondition(
|
|
1259
|
+
(annotationValue as EqConditionalExpression).$Eq[1],
|
|
1260
|
+
visitedNavigationPaths,
|
|
1261
|
+
pathVisitor,
|
|
1262
|
+
converterRoot
|
|
1263
|
+
)
|
|
998
1264
|
) as BindingToolkitExpression<T>;
|
|
999
1265
|
} else if (annotationValue.hasOwnProperty("$Ne")) {
|
|
1000
1266
|
return notEqual(
|
|
1001
|
-
parseAnnotationCondition(
|
|
1002
|
-
|
|
1267
|
+
parseAnnotationCondition(
|
|
1268
|
+
(annotationValue as NeConditionalExpression).$Ne[0],
|
|
1269
|
+
visitedNavigationPaths,
|
|
1270
|
+
pathVisitor,
|
|
1271
|
+
converterRoot
|
|
1272
|
+
),
|
|
1273
|
+
parseAnnotationCondition(
|
|
1274
|
+
(annotationValue as NeConditionalExpression).$Ne[1],
|
|
1275
|
+
visitedNavigationPaths,
|
|
1276
|
+
pathVisitor,
|
|
1277
|
+
converterRoot
|
|
1278
|
+
)
|
|
1003
1279
|
) as BindingToolkitExpression<T>;
|
|
1004
1280
|
} else if (annotationValue.hasOwnProperty("$Gt")) {
|
|
1005
1281
|
return greaterThan(
|
|
1006
|
-
parseAnnotationCondition(
|
|
1007
|
-
|
|
1282
|
+
parseAnnotationCondition(
|
|
1283
|
+
(annotationValue as GtConditionalExpression).$Gt[0],
|
|
1284
|
+
visitedNavigationPaths,
|
|
1285
|
+
pathVisitor,
|
|
1286
|
+
converterRoot
|
|
1287
|
+
),
|
|
1288
|
+
parseAnnotationCondition(
|
|
1289
|
+
(annotationValue as GtConditionalExpression).$Gt[1],
|
|
1290
|
+
visitedNavigationPaths,
|
|
1291
|
+
pathVisitor,
|
|
1292
|
+
converterRoot
|
|
1293
|
+
)
|
|
1008
1294
|
) as BindingToolkitExpression<T>;
|
|
1009
1295
|
} else if (annotationValue.hasOwnProperty("$Ge")) {
|
|
1010
1296
|
return greaterOrEqual(
|
|
1011
|
-
parseAnnotationCondition(
|
|
1012
|
-
|
|
1297
|
+
parseAnnotationCondition(
|
|
1298
|
+
(annotationValue as GeConditionalExpression).$Ge[0],
|
|
1299
|
+
visitedNavigationPaths,
|
|
1300
|
+
pathVisitor,
|
|
1301
|
+
converterRoot
|
|
1302
|
+
),
|
|
1303
|
+
parseAnnotationCondition(
|
|
1304
|
+
(annotationValue as GeConditionalExpression).$Ge[1],
|
|
1305
|
+
visitedNavigationPaths,
|
|
1306
|
+
pathVisitor,
|
|
1307
|
+
converterRoot
|
|
1308
|
+
)
|
|
1013
1309
|
) as BindingToolkitExpression<T>;
|
|
1014
1310
|
} else if (annotationValue.hasOwnProperty("$Lt")) {
|
|
1015
1311
|
return lessThan(
|
|
1016
|
-
parseAnnotationCondition(
|
|
1017
|
-
|
|
1312
|
+
parseAnnotationCondition(
|
|
1313
|
+
(annotationValue as LtConditionalExpression).$Lt[0],
|
|
1314
|
+
visitedNavigationPaths,
|
|
1315
|
+
pathVisitor,
|
|
1316
|
+
converterRoot
|
|
1317
|
+
),
|
|
1318
|
+
parseAnnotationCondition(
|
|
1319
|
+
(annotationValue as LtConditionalExpression).$Lt[1],
|
|
1320
|
+
visitedNavigationPaths,
|
|
1321
|
+
pathVisitor,
|
|
1322
|
+
converterRoot
|
|
1323
|
+
)
|
|
1018
1324
|
) as BindingToolkitExpression<T>;
|
|
1019
1325
|
} else if (annotationValue.hasOwnProperty("$Le")) {
|
|
1020
1326
|
return lessOrEqual(
|
|
1021
|
-
parseAnnotationCondition(
|
|
1022
|
-
|
|
1327
|
+
parseAnnotationCondition(
|
|
1328
|
+
(annotationValue as LeConditionalExpression).$Le[0],
|
|
1329
|
+
visitedNavigationPaths,
|
|
1330
|
+
pathVisitor,
|
|
1331
|
+
converterRoot
|
|
1332
|
+
),
|
|
1333
|
+
parseAnnotationCondition(
|
|
1334
|
+
(annotationValue as LeConditionalExpression).$Le[1],
|
|
1335
|
+
visitedNavigationPaths,
|
|
1336
|
+
pathVisitor,
|
|
1337
|
+
converterRoot
|
|
1338
|
+
)
|
|
1023
1339
|
) as BindingToolkitExpression<T>;
|
|
1024
1340
|
} else if (annotationValue.hasOwnProperty("$Path")) {
|
|
1025
1341
|
return pathInModel((annotationValue as PathConditionExpression<T>).$Path, undefined, visitedNavigationPaths, pathVisitor);
|
|
@@ -1045,9 +1361,137 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1045
1361
|
pathVisitor
|
|
1046
1362
|
) as BindingToolkitExpression<T>;
|
|
1047
1363
|
} else if (annotationValue.hasOwnProperty("$EnumMember")) {
|
|
1048
|
-
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember) as T);
|
|
1364
|
+
return constant(resolveEnumValue((annotationValue as { $EnumMember?: string }).$EnumMember, converterRoot) as T);
|
|
1365
|
+
} else if (annotationValue.hasOwnProperty("$In")) {
|
|
1366
|
+
return comparison(
|
|
1367
|
+
"In",
|
|
1368
|
+
parseAnnotationCondition(
|
|
1369
|
+
(annotationValue as InConditionalExpression).$In[0],
|
|
1370
|
+
visitedNavigationPaths,
|
|
1371
|
+
pathVisitor,
|
|
1372
|
+
converterRoot
|
|
1373
|
+
),
|
|
1374
|
+
parseAnnotationCondition(
|
|
1375
|
+
(annotationValue as InConditionalExpression).$In[1],
|
|
1376
|
+
visitedNavigationPaths,
|
|
1377
|
+
pathVisitor,
|
|
1378
|
+
converterRoot
|
|
1379
|
+
)
|
|
1380
|
+
) as BindingToolkitExpression<T>;
|
|
1381
|
+
} else if (annotationValue.hasOwnProperty("$Has")) {
|
|
1382
|
+
return comparison(
|
|
1383
|
+
"Has",
|
|
1384
|
+
parseAnnotationCondition(
|
|
1385
|
+
(annotationValue as HasConditionalExpression).$Has[0],
|
|
1386
|
+
visitedNavigationPaths,
|
|
1387
|
+
pathVisitor,
|
|
1388
|
+
converterRoot
|
|
1389
|
+
),
|
|
1390
|
+
parseAnnotationCondition(
|
|
1391
|
+
(annotationValue as HasConditionalExpression).$Has[1],
|
|
1392
|
+
visitedNavigationPaths,
|
|
1393
|
+
pathVisitor,
|
|
1394
|
+
converterRoot
|
|
1395
|
+
)
|
|
1396
|
+
) as BindingToolkitExpression<T>;
|
|
1397
|
+
} else if (annotationValue.hasOwnProperty("$Add")) {
|
|
1398
|
+
return add(
|
|
1399
|
+
parseAnnotationCondition(
|
|
1400
|
+
(annotationValue as AddConditionalExpression).$Add[0],
|
|
1401
|
+
visitedNavigationPaths,
|
|
1402
|
+
pathVisitor,
|
|
1403
|
+
converterRoot
|
|
1404
|
+
),
|
|
1405
|
+
parseAnnotationCondition(
|
|
1406
|
+
(annotationValue as AddConditionalExpression).$Add[1],
|
|
1407
|
+
visitedNavigationPaths,
|
|
1408
|
+
pathVisitor,
|
|
1409
|
+
converterRoot
|
|
1410
|
+
)
|
|
1411
|
+
) as BindingToolkitExpression<T>;
|
|
1412
|
+
} else if (annotationValue.hasOwnProperty("$Sub")) {
|
|
1413
|
+
return subtract(
|
|
1414
|
+
parseAnnotationCondition(
|
|
1415
|
+
(annotationValue as SubConditionalExpression).$Sub[0],
|
|
1416
|
+
visitedNavigationPaths,
|
|
1417
|
+
pathVisitor,
|
|
1418
|
+
converterRoot
|
|
1419
|
+
),
|
|
1420
|
+
parseAnnotationCondition(
|
|
1421
|
+
(annotationValue as SubConditionalExpression).$Sub[1],
|
|
1422
|
+
visitedNavigationPaths,
|
|
1423
|
+
pathVisitor,
|
|
1424
|
+
converterRoot
|
|
1425
|
+
)
|
|
1426
|
+
) as BindingToolkitExpression<T>;
|
|
1427
|
+
} else if (annotationValue.hasOwnProperty("$Mul")) {
|
|
1428
|
+
return multiply(
|
|
1429
|
+
parseAnnotationCondition(
|
|
1430
|
+
(annotationValue as MulConditionalExpression).$Mul[0],
|
|
1431
|
+
visitedNavigationPaths,
|
|
1432
|
+
pathVisitor,
|
|
1433
|
+
converterRoot
|
|
1434
|
+
),
|
|
1435
|
+
parseAnnotationCondition(
|
|
1436
|
+
(annotationValue as MulConditionalExpression).$Mul[1],
|
|
1437
|
+
visitedNavigationPaths,
|
|
1438
|
+
pathVisitor,
|
|
1439
|
+
converterRoot
|
|
1440
|
+
)
|
|
1441
|
+
) as BindingToolkitExpression<T>;
|
|
1442
|
+
} else if (annotationValue.hasOwnProperty("$Div")) {
|
|
1443
|
+
return floor(
|
|
1444
|
+
divide(
|
|
1445
|
+
parseAnnotationCondition(
|
|
1446
|
+
(annotationValue as DivConditionalExpression).$Div[0],
|
|
1447
|
+
visitedNavigationPaths,
|
|
1448
|
+
pathVisitor,
|
|
1449
|
+
converterRoot
|
|
1450
|
+
),
|
|
1451
|
+
parseAnnotationCondition(
|
|
1452
|
+
(annotationValue as DivConditionalExpression).$Div[1],
|
|
1453
|
+
visitedNavigationPaths,
|
|
1454
|
+
pathVisitor,
|
|
1455
|
+
converterRoot
|
|
1456
|
+
)
|
|
1457
|
+
)
|
|
1458
|
+
) as BindingToolkitExpression<T>;
|
|
1459
|
+
} else if (annotationValue.hasOwnProperty("$DivBy")) {
|
|
1460
|
+
return divide(
|
|
1461
|
+
parseAnnotationCondition(
|
|
1462
|
+
(annotationValue as DivByConditionalExpression).$DivBy[0],
|
|
1463
|
+
visitedNavigationPaths,
|
|
1464
|
+
pathVisitor,
|
|
1465
|
+
converterRoot
|
|
1466
|
+
),
|
|
1467
|
+
parseAnnotationCondition(
|
|
1468
|
+
(annotationValue as DivByConditionalExpression).$DivBy[1],
|
|
1469
|
+
visitedNavigationPaths,
|
|
1470
|
+
pathVisitor,
|
|
1471
|
+
converterRoot
|
|
1472
|
+
)
|
|
1473
|
+
) as BindingToolkitExpression<T>;
|
|
1474
|
+
} else if (annotationValue.hasOwnProperty("$Mod")) {
|
|
1475
|
+
return modulo(
|
|
1476
|
+
parseAnnotationCondition(
|
|
1477
|
+
(annotationValue as ModConditionalExpression).$Mod[0],
|
|
1478
|
+
visitedNavigationPaths,
|
|
1479
|
+
pathVisitor,
|
|
1480
|
+
converterRoot
|
|
1481
|
+
),
|
|
1482
|
+
parseAnnotationCondition(
|
|
1483
|
+
(annotationValue as ModConditionalExpression).$Mod[1],
|
|
1484
|
+
visitedNavigationPaths,
|
|
1485
|
+
pathVisitor,
|
|
1486
|
+
converterRoot
|
|
1487
|
+
)
|
|
1488
|
+
) as BindingToolkitExpression<T>;
|
|
1489
|
+
} else if (annotationValue.hasOwnProperty("$Neg")) {
|
|
1490
|
+
return negate(
|
|
1491
|
+
parseAnnotationCondition((annotationValue as NegConditionalExpression).$Neg, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1492
|
+
) as BindingToolkitExpression<T>;
|
|
1049
1493
|
}
|
|
1050
|
-
return constant(
|
|
1494
|
+
return constant(annotationValue as T);
|
|
1051
1495
|
}
|
|
1052
1496
|
|
|
1053
1497
|
/**
|
|
@@ -1056,17 +1500,19 @@ function parseAnnotationCondition<T extends PrimitiveType>(
|
|
|
1056
1500
|
* @param annotationValue An If expression returning the type T
|
|
1057
1501
|
* @param visitedNavigationPaths The path from the root entity set
|
|
1058
1502
|
* @param pathVisitor A function to modify the resulting path
|
|
1503
|
+
* @param converterRoot The root converted metadata
|
|
1059
1504
|
* @returns The equivalent ifElse expression
|
|
1060
1505
|
*/
|
|
1061
1506
|
export function annotationIfExpression<T extends PrimitiveType>(
|
|
1062
1507
|
annotationValue: IfAnnotationExpressionValue<T>,
|
|
1063
1508
|
visitedNavigationPaths: string[] = [],
|
|
1064
|
-
pathVisitor?: Function
|
|
1509
|
+
pathVisitor?: Function,
|
|
1510
|
+
converterRoot?: ConvertedMetadata
|
|
1065
1511
|
): BindingToolkitExpression<T> {
|
|
1066
1512
|
return ifElse(
|
|
1067
|
-
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor),
|
|
1068
|
-
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor),
|
|
1069
|
-
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor)
|
|
1513
|
+
parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1514
|
+
parseAnnotationCondition(annotationValue[1] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot),
|
|
1515
|
+
parseAnnotationCondition(annotationValue[2] as ConditionalCheckOrValue, visitedNavigationPaths, pathVisitor, converterRoot)
|
|
1070
1516
|
);
|
|
1071
1517
|
}
|
|
1072
1518
|
// This type is not recursively transformed from the metamodel content, as such we have some ugly things there
|
|
@@ -1205,6 +1651,43 @@ function comparison<T extends PrimitiveType>(
|
|
|
1205
1651
|
return constant(false);
|
|
1206
1652
|
}
|
|
1207
1653
|
return constant(leftExpression.value >= rightExpression.value);
|
|
1654
|
+
|
|
1655
|
+
case "Has": {
|
|
1656
|
+
if (
|
|
1657
|
+
leftExpression.value === null ||
|
|
1658
|
+
leftExpression.value === undefined ||
|
|
1659
|
+
rightExpression.value === null ||
|
|
1660
|
+
rightExpression.value === undefined
|
|
1661
|
+
) {
|
|
1662
|
+
return constant(false);
|
|
1663
|
+
}
|
|
1664
|
+
const leftValueInt = leftExpression.value as number;
|
|
1665
|
+
const rightValueInt = rightExpression.value as number;
|
|
1666
|
+
return constant(!!(leftValueInt & rightValueInt));
|
|
1667
|
+
}
|
|
1668
|
+
case "In": {
|
|
1669
|
+
if (
|
|
1670
|
+
leftExpression.value === null ||
|
|
1671
|
+
leftExpression.value === undefined ||
|
|
1672
|
+
rightExpression.value === null ||
|
|
1673
|
+
rightExpression.value === undefined
|
|
1674
|
+
) {
|
|
1675
|
+
return constant(false);
|
|
1676
|
+
}
|
|
1677
|
+
// Check all the children of the right expression are constants
|
|
1678
|
+
const allChildrenConstants = (rightExpression.value as T[]).every((item) => isConstant(item));
|
|
1679
|
+
if (allChildrenConstants) {
|
|
1680
|
+
const rightValues = (rightExpression.value as ConstantExpression<T>[]).map((item) => item.value);
|
|
1681
|
+
return constant(rightValues.includes(leftExpression.value));
|
|
1682
|
+
} else {
|
|
1683
|
+
return {
|
|
1684
|
+
_type: "Comparison",
|
|
1685
|
+
operator: operator,
|
|
1686
|
+
operand1: leftExpression,
|
|
1687
|
+
operand2: rightExpression
|
|
1688
|
+
};
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1208
1691
|
}
|
|
1209
1692
|
} else {
|
|
1210
1693
|
return {
|
|
@@ -1359,6 +1842,20 @@ export function lessThan<T extends DefinedPrimitiveType>(
|
|
|
1359
1842
|
return comparison("<", leftOperand, rightOperand);
|
|
1360
1843
|
}
|
|
1361
1844
|
|
|
1845
|
+
/**
|
|
1846
|
+
* Comparison: "Include" (In).
|
|
1847
|
+
* @template T The target type
|
|
1848
|
+
* @param leftOperand The operand on the left side
|
|
1849
|
+
* @param rightOperand The operand on the right side of the comparison
|
|
1850
|
+
* @returns An expression representing the comparison
|
|
1851
|
+
*/
|
|
1852
|
+
export function includes<T extends DefinedPrimitiveType>(
|
|
1853
|
+
leftOperand: ExpressionOrPrimitive<T>,
|
|
1854
|
+
rightOperand: ExpressionOrPrimitive<T[]>
|
|
1855
|
+
): BindingToolkitExpression<boolean> {
|
|
1856
|
+
return comparison("In", leftOperand, rightOperand as ExpressionOrPrimitive<T>);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1362
1859
|
/**
|
|
1363
1860
|
* If-then-else expression.
|
|
1364
1861
|
*
|
|
@@ -1584,7 +2081,7 @@ export function formatResult<T, U extends Fn<T>>(
|
|
|
1584
2081
|
}
|
|
1585
2082
|
|
|
1586
2083
|
type BindingConstraints = {
|
|
1587
|
-
scale?: number;
|
|
2084
|
+
scale?: number | string;
|
|
1588
2085
|
precision?: number;
|
|
1589
2086
|
maxLength?: number;
|
|
1590
2087
|
nullable?: boolean;
|
|
@@ -1664,16 +2161,18 @@ export function formatWithTypeInformation<T>(
|
|
|
1664
2161
|
parseAsString: false
|
|
1665
2162
|
});
|
|
1666
2163
|
}
|
|
1667
|
-
if (outExpression.type === "sap.ui.model.odata.type.String" && isProperty(property)) {
|
|
2164
|
+
if (outExpression.type === "sap.ui.model.odata.type.String" && (isProperty(property) || isActionParameter(property))) {
|
|
1668
2165
|
if (outExpression.constraints?.isDigitSequence || (outExpression.constraints?.nullable !== false && property.nullable === true)) {
|
|
1669
2166
|
outExpression.formatOptions.parseKeepsEmptyString = false;
|
|
1670
2167
|
} else {
|
|
1671
2168
|
outExpression.formatOptions.parseKeepsEmptyString = true;
|
|
1672
2169
|
}
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
2170
|
+
if (isProperty(property)) {
|
|
2171
|
+
const fiscalType = getFiscalType(property);
|
|
2172
|
+
if (fiscalType) {
|
|
2173
|
+
outExpression.formatOptions.fiscalType = fiscalType;
|
|
2174
|
+
outExpression.type = "sap.fe.core.type.FiscalDate";
|
|
2175
|
+
}
|
|
1677
2176
|
}
|
|
1678
2177
|
}
|
|
1679
2178
|
const typesSupportingParseEmptyValueToZero = [
|
|
@@ -1899,7 +2398,57 @@ export function isEmpty(expression: BindingToolkitExpression<string>): BindingTo
|
|
|
1899
2398
|
});
|
|
1900
2399
|
return and(...aBindings);
|
|
1901
2400
|
}
|
|
2401
|
+
/**
|
|
2402
|
+
* Shortcut function to determine if a binding can be statically resolvable.
|
|
2403
|
+
* @param exp The expression to evaluate
|
|
2404
|
+
* @returns A Boolean evaluating if there is no relative path dependent on the current context
|
|
2405
|
+
*/
|
|
2406
|
+
export function isExpressionStaticallyResolvable<T extends PrimitiveType>(exp: BindingToolkitExpression<T>): boolean {
|
|
2407
|
+
const referencedPaths: string[] = [];
|
|
2408
|
+
transformRecursively(
|
|
2409
|
+
exp,
|
|
2410
|
+
"PathInModel",
|
|
2411
|
+
(pathExp) => {
|
|
2412
|
+
if (pathExp.modelName === undefined && typeof pathExp.path === "string") {
|
|
2413
|
+
referencedPaths.push(pathExp.path);
|
|
2414
|
+
}
|
|
2415
|
+
return pathExp;
|
|
2416
|
+
},
|
|
2417
|
+
true
|
|
2418
|
+
);
|
|
2419
|
+
if (referencedPaths.length === 0) {
|
|
2420
|
+
return true;
|
|
2421
|
+
}
|
|
2422
|
+
return referencedPaths.every((p) => p.startsWith("/"));
|
|
2423
|
+
}
|
|
2424
|
+
|
|
2425
|
+
export function getStaticallyResolvableExpression<T extends PrimitiveType>(
|
|
2426
|
+
exp: BindingToolkitExpression<T>,
|
|
2427
|
+
defaultValue: BindingToolkitExpression<T>
|
|
2428
|
+
): BindingToolkitExpression<T> {
|
|
2429
|
+
if (exp._type === "Set") {
|
|
2430
|
+
const newOperands = exp.operands.map((operand: BindingToolkitExpression<boolean>) => {
|
|
2431
|
+
if (isExpressionStaticallyResolvable(operand) || isConstant(operand)) {
|
|
2432
|
+
return operand;
|
|
2433
|
+
} else {
|
|
2434
|
+
return defaultValue;
|
|
2435
|
+
}
|
|
2436
|
+
});
|
|
2437
|
+
|
|
2438
|
+
if (exp.operator === "||") {
|
|
2439
|
+
return or(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2440
|
+
} else {
|
|
2441
|
+
return and(...(newOperands as unknown as BindingToolkitExpression<boolean>[])) as unknown as BindingToolkitExpression<T>;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
return isExpressionStaticallyResolvable(exp) ? exp : defaultValue;
|
|
2445
|
+
}
|
|
1902
2446
|
|
|
2447
|
+
/**
|
|
2448
|
+
* Function used to concatenate multiple expressions.
|
|
2449
|
+
* @param inExpressions The expressions to concatenate
|
|
2450
|
+
* @returns The concatenated expression
|
|
2451
|
+
*/
|
|
1903
2452
|
export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): BindingToolkitExpression<string> {
|
|
1904
2453
|
const expressions = inExpressions.map(wrapPrimitive);
|
|
1905
2454
|
if (hasUnresolvableExpression(...expressions)) {
|
|
@@ -1943,6 +2492,7 @@ type ExpressionTypeToExpression<T extends ExpressionType, V> = T extends "Consta
|
|
|
1943
2492
|
|
|
1944
2493
|
export type TransformFunction<T, V> = (expressionPart: T) => BindingToolkitExpression<V>;
|
|
1945
2494
|
export type ExpressionType = Pick<BindingToolkitExpression<unknown>, "_type">["_type"];
|
|
2495
|
+
|
|
1946
2496
|
export function transformRecursively<T extends PrimitiveType | unknown, ET extends ExpressionType>(
|
|
1947
2497
|
inExpression: BindingToolkitExpression<T>,
|
|
1948
2498
|
expressionType: ET,
|
|
@@ -2048,6 +2598,21 @@ export function transformRecursively<T extends PrimitiveType | unknown, ET exten
|
|
|
2048
2598
|
expression = comparison(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2049
2599
|
}
|
|
2050
2600
|
break;
|
|
2601
|
+
case "Arithmetic":
|
|
2602
|
+
const operand1 = transformRecursively(
|
|
2603
|
+
expression.operand1 as BindingToolkitExpression<T>,
|
|
2604
|
+
expressionType,
|
|
2605
|
+
transformFunction,
|
|
2606
|
+
includeAllExpression
|
|
2607
|
+
);
|
|
2608
|
+
const operand2 = transformRecursively(
|
|
2609
|
+
expression.operand2 as BindingToolkitExpression<T>,
|
|
2610
|
+
expressionType,
|
|
2611
|
+
transformFunction,
|
|
2612
|
+
includeAllExpression
|
|
2613
|
+
);
|
|
2614
|
+
expression = arithmetic(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
|
|
2615
|
+
break;
|
|
2051
2616
|
case "Constant":
|
|
2052
2617
|
const constantValue: Record<string, BindingToolkitExpression<unknown>> = expression.value as Record<
|
|
2053
2618
|
string,
|
|
@@ -2079,6 +2644,10 @@ export function transformRecursively<T extends PrimitiveType | unknown, ET exten
|
|
|
2079
2644
|
return expression;
|
|
2080
2645
|
}
|
|
2081
2646
|
|
|
2647
|
+
/**
|
|
2648
|
+
* Compiled Binding Toolkit Expression
|
|
2649
|
+
* This is a type representing the compiled form of a Binding Toolkit expression as a binding string.
|
|
2650
|
+
*/
|
|
2082
2651
|
export type CompiledBindingToolkitExpression = string | undefined;
|
|
2083
2652
|
|
|
2084
2653
|
const needParenthesis = function <T extends PrimitiveType>(expr: ExpressionOrPrimitive<T>): boolean {
|
|
@@ -2364,6 +2933,9 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2364
2933
|
case "Not":
|
|
2365
2934
|
const notExpression = `!${compileExpression(expr.operand, true)}`;
|
|
2366
2935
|
return wrapBindingExpression(notExpression, embeddedInBinding);
|
|
2936
|
+
case "Arithmetic":
|
|
2937
|
+
const arithmeticExpression = compileArithmeticExpression(expr);
|
|
2938
|
+
return wrapBindingExpression(arithmeticExpression, embeddedInBinding);
|
|
2367
2939
|
|
|
2368
2940
|
case "Truthy":
|
|
2369
2941
|
const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
|
|
@@ -2382,6 +2954,25 @@ export function compileExpression<T extends PrimitiveType>(
|
|
|
2382
2954
|
}
|
|
2383
2955
|
}
|
|
2384
2956
|
|
|
2957
|
+
function compileArithmeticExpression(expression: ArithmeticExpression): string {
|
|
2958
|
+
function compileOperand(operand: BindingToolkitExpression<unknown>): CompiledBindingToolkitExpression {
|
|
2959
|
+
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2960
|
+
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2961
|
+
}
|
|
2962
|
+
switch (expression.operator) {
|
|
2963
|
+
case "Neg":
|
|
2964
|
+
return `-(${compileOperand(expression.operand1)})`;
|
|
2965
|
+
case "Floor":
|
|
2966
|
+
return `Math.floor(${compileOperand(expression.operand1)})`;
|
|
2967
|
+
case "%":
|
|
2968
|
+
case "/":
|
|
2969
|
+
case "*":
|
|
2970
|
+
case "+":
|
|
2971
|
+
case "-":
|
|
2972
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
2973
|
+
}
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2385
2976
|
/**
|
|
2386
2977
|
* Compile a comparison expression.
|
|
2387
2978
|
* @param expression The comparison expression.
|
|
@@ -2392,8 +2983,25 @@ function compileComparisonExpression(expression: ComparisonExpression): string {
|
|
|
2392
2983
|
const compiledOperand = compileExpression(operand, true) ?? "undefined";
|
|
2393
2984
|
return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
|
|
2394
2985
|
}
|
|
2395
|
-
|
|
2396
|
-
|
|
2986
|
+
switch (expression.operator) {
|
|
2987
|
+
case "In": {
|
|
2988
|
+
const path = compileOperand(expression.operand1);
|
|
2989
|
+
const collection = compileOperand(expression.operand2) ?? [];
|
|
2990
|
+
return `${collection}.includes(${path})`;
|
|
2991
|
+
}
|
|
2992
|
+
case "Has": {
|
|
2993
|
+
const path = compileOperand(expression.operand1);
|
|
2994
|
+
const flags = compileOperand(expression.operand2) ?? [];
|
|
2995
|
+
return `(${path} & ${flags}) > 0`;
|
|
2996
|
+
}
|
|
2997
|
+
case "===":
|
|
2998
|
+
case "!==":
|
|
2999
|
+
case ">=":
|
|
3000
|
+
case ">":
|
|
3001
|
+
case "<=":
|
|
3002
|
+
case "<":
|
|
3003
|
+
return `${compileOperand(expression.operand1)} ${expression.operator} ${compileOperand(expression.operand2)}`;
|
|
3004
|
+
}
|
|
2397
3005
|
}
|
|
2398
3006
|
|
|
2399
3007
|
/**
|