@sapui5/sap.fe.core 1.102.2 → 1.104.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/package.json +6 -6
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AppComponent.js +73 -30
  4. package/src/sap/fe/core/AppComponent.ts +65 -43
  5. package/src/sap/fe/core/AppStateHandler.js +82 -70
  6. package/src/sap/fe/core/AppStateHandler.ts +32 -37
  7. package/src/sap/fe/core/BaseController.js +11 -9
  8. package/src/sap/fe/core/BaseController.ts +15 -13
  9. package/src/sap/fe/core/CommonUtils.js +227 -126
  10. package/src/sap/fe/core/CommonUtils.ts +240 -163
  11. package/src/sap/fe/core/ExtensionAPI.js +24 -27
  12. package/src/sap/fe/core/ExtensionAPI.ts +36 -38
  13. package/src/sap/fe/core/PageController.js +4 -4
  14. package/src/sap/fe/core/PageController.ts +4 -5
  15. package/src/sap/fe/core/TemplateComponent.js +1 -1
  16. package/src/sap/fe/core/TemplateComponent.ts +6 -6
  17. package/src/sap/fe/core/TemplateModel.js +1 -1
  18. package/src/sap/fe/core/TemplateModel.ts +1 -1
  19. package/src/sap/fe/core/buildingBlocks/AttributeModel.js +1 -1
  20. package/src/sap/fe/core/buildingBlocks/AttributeModel.ts +1 -1
  21. package/src/sap/fe/core/buildingBlocks/BuildingBlock.js +181 -43
  22. package/src/sap/fe/core/buildingBlocks/BuildingBlock.ts +150 -24
  23. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.js +585 -210
  24. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +246 -96
  25. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +30 -30
  26. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +32 -29
  27. package/src/sap/fe/core/controllerextensions/EditFlow.js +379 -330
  28. package/src/sap/fe/core/controllerextensions/EditFlow.ts +253 -245
  29. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.js +9 -9
  30. package/src/sap/fe/core/controllerextensions/IntentBasedNavigation.ts +10 -10
  31. package/src/sap/fe/core/controllerextensions/InternalEditFlow.js +101 -74
  32. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +69 -79
  33. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +67 -67
  34. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +76 -76
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +85 -77
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +103 -99
  37. package/src/sap/fe/core/controllerextensions/KPIManagement.js +66 -68
  38. package/src/sap/fe/core/controllerextensions/KPIManagement.ts +106 -123
  39. package/src/sap/fe/core/controllerextensions/MassEdit.js +9 -9
  40. package/src/sap/fe/core/controllerextensions/MassEdit.ts +20 -27
  41. package/src/sap/fe/core/controllerextensions/MessageHandler.js +20 -12
  42. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +21 -14
  43. package/src/sap/fe/core/controllerextensions/PageReady.js +97 -25
  44. package/src/sap/fe/core/controllerextensions/PageReady.ts +98 -34
  45. package/src/sap/fe/core/controllerextensions/Paginator.js +21 -22
  46. package/src/sap/fe/core/controllerextensions/Paginator.ts +24 -25
  47. package/src/sap/fe/core/controllerextensions/Placeholder.js +4 -6
  48. package/src/sap/fe/core/controllerextensions/Placeholder.ts +12 -14
  49. package/src/sap/fe/core/controllerextensions/Routing.js +10 -11
  50. package/src/sap/fe/core/controllerextensions/Routing.ts +12 -13
  51. package/src/sap/fe/core/controllerextensions/Share.js +170 -139
  52. package/src/sap/fe/core/controllerextensions/Share.ts +117 -118
  53. package/src/sap/fe/core/controllerextensions/SideEffects.js +46 -50
  54. package/src/sap/fe/core/controllerextensions/SideEffects.ts +56 -60
  55. package/src/sap/fe/core/controllerextensions/ViewState.js +200 -131
  56. package/src/sap/fe/core/controllerextensions/ViewState.ts +141 -148
  57. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +5 -5
  58. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +8 -7
  59. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +11 -10
  60. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.ts +17 -20
  61. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.js +2 -2
  62. package/src/sap/fe/core/controllerextensions/collaboration/CollaborationCommon.ts +4 -4
  63. package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +7 -9
  64. package/src/sap/fe/core/controllerextensions/collaboration/Manage.ts +18 -19
  65. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +190 -141
  66. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.ts +258 -210
  67. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +183 -125
  68. package/src/sap/fe/core/controllerextensions/editFlow/draft.ts +213 -156
  69. package/src/sap/fe/core/controllerextensions/editFlow/operations.js +164 -140
  70. package/src/sap/fe/core/controllerextensions/editFlow/operations.ts +180 -150
  71. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +24 -26
  72. package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +35 -33
  73. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +71 -41
  74. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.ts +102 -82
  75. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +61 -71
  76. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.ts +56 -64
  77. package/src/sap/fe/core/controls/Any.js +9 -5
  78. package/src/sap/fe/core/controls/Any.ts +10 -4
  79. package/src/sap/fe/core/controls/CommandExecution.js +11 -25
  80. package/src/sap/fe/core/controls/CommandExecution.ts +11 -25
  81. package/src/sap/fe/core/controls/ConditionalWrapper.js +2 -2
  82. package/src/sap/fe/core/controls/ConditionalWrapper.ts +3 -3
  83. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +22 -22
  84. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +25 -24
  85. package/src/sap/fe/core/controls/CustomQuickViewPage.js +2 -2
  86. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +2 -2
  87. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +3 -3
  88. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +5 -5
  89. package/src/sap/fe/core/controls/FieldWrapper.js +2 -2
  90. package/src/sap/fe/core/controls/FieldWrapper.ts +3 -3
  91. package/src/sap/fe/core/controls/FileWrapper.js +7 -2
  92. package/src/sap/fe/core/controls/FileWrapper.ts +15 -11
  93. package/src/sap/fe/core/controls/FilterBar.js +6 -2
  94. package/src/sap/fe/core/controls/FilterBar.ts +13 -9
  95. package/src/sap/fe/core/controls/FormElementWrapper.js +1 -1
  96. package/src/sap/fe/core/controls/FormElementWrapper.ts +2 -2
  97. package/src/sap/fe/core/controls/MassEditSelect.js +1 -1
  98. package/src/sap/fe/core/controls/MassEditSelect.ts +0 -4
  99. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +3 -3
  100. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +16 -12
  101. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +20 -22
  102. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +3 -3
  103. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +8 -8
  104. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +49 -49
  105. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +54 -54
  106. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +8 -2
  107. package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +22 -35
  108. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +89 -88
  109. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +107 -106
  110. package/src/sap/fe/core/converters/ConverterContext.js +26 -33
  111. package/src/sap/fe/core/converters/ConverterContext.ts +52 -61
  112. package/src/sap/fe/core/converters/ManifestSettings.js +1 -1
  113. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -15
  114. package/src/sap/fe/core/converters/ManifestWrapper.js +59 -45
  115. package/src/sap/fe/core/converters/ManifestWrapper.ts +55 -45
  116. package/src/sap/fe/core/converters/MetaModelConverter.js +64 -35
  117. package/src/sap/fe/core/converters/MetaModelConverter.ts +154 -129
  118. package/src/sap/fe/core/converters/TemplateConverter.js +21 -20
  119. package/src/sap/fe/core/converters/TemplateConverter.ts +27 -24
  120. package/src/sap/fe/core/converters/annotations/DataField.js +58 -35
  121. package/src/sap/fe/core/converters/annotations/DataField.ts +102 -76
  122. package/src/sap/fe/core/converters/common/AnnotationConverter.js +1911 -1495
  123. package/src/sap/fe/core/converters/controls/Common/Action.js +50 -41
  124. package/src/sap/fe/core/converters/controls/Common/Action.ts +56 -46
  125. package/src/sap/fe/core/converters/controls/Common/Chart.js +14 -14
  126. package/src/sap/fe/core/converters/controls/Common/Chart.ts +26 -33
  127. package/src/sap/fe/core/converters/controls/Common/Criticality.js +3 -3
  128. package/src/sap/fe/core/converters/controls/Common/Criticality.ts +4 -4
  129. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +30 -28
  130. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +60 -61
  131. package/src/sap/fe/core/converters/controls/Common/Form.js +27 -28
  132. package/src/sap/fe/core/converters/controls/Common/Form.ts +44 -57
  133. package/src/sap/fe/core/converters/controls/Common/KPI.js +11 -11
  134. package/src/sap/fe/core/converters/controls/Common/KPI.ts +49 -52
  135. package/src/sap/fe/core/converters/controls/Common/Table.js +181 -197
  136. package/src/sap/fe/core/converters/controls/Common/Table.ts +251 -280
  137. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +119 -119
  138. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +144 -141
  139. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +45 -41
  140. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +65 -59
  141. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +28 -26
  142. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +46 -43
  143. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +9 -9
  144. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +14 -13
  145. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +67 -64
  146. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +69 -66
  147. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +77 -73
  148. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +101 -97
  149. package/src/sap/fe/core/converters/helpers/Aggregation.js +2 -4
  150. package/src/sap/fe/core/converters/helpers/Aggregation.ts +12 -15
  151. package/src/sap/fe/core/converters/helpers/BindingHelper.js +31 -31
  152. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +30 -29
  153. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +4 -4
  154. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +9 -9
  155. package/src/sap/fe/core/converters/helpers/ID.js +48 -46
  156. package/src/sap/fe/core/converters/helpers/ID.ts +26 -25
  157. package/src/sap/fe/core/converters/helpers/Key.js +7 -7
  158. package/src/sap/fe/core/converters/helpers/Key.ts +7 -7
  159. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
  160. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +4 -5
  161. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +6 -6
  162. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +10 -10
  163. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +46 -62
  164. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +54 -82
  165. package/src/sap/fe/core/converters/templates/ListReportConverter.js +55 -42
  166. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +81 -66
  167. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +39 -38
  168. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +52 -61
  169. package/src/sap/fe/core/designtime/AppComponent.designtime.js +4 -4
  170. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +4 -4
  171. package/src/sap/fe/core/formatters/CollaborationFormatter.js +2 -2
  172. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +3 -3
  173. package/src/sap/fe/core/formatters/FPMFormatter.js +5 -5
  174. package/src/sap/fe/core/formatters/FPMFormatter.ts +10 -10
  175. package/src/sap/fe/core/formatters/KPIFormatter.js +7 -7
  176. package/src/sap/fe/core/formatters/KPIFormatter.ts +10 -10
  177. package/src/sap/fe/core/formatters/StandardFormatter.js +96 -0
  178. package/src/sap/fe/core/formatters/StandardFormatter.ts +70 -0
  179. package/src/sap/fe/core/formatters/TableFormatter.js +11 -11
  180. package/src/sap/fe/core/formatters/TableFormatter.ts +12 -12
  181. package/src/sap/fe/core/formatters/ValueFormatter.js +8 -8
  182. package/src/sap/fe/core/formatters/ValueFormatter.ts +9 -9
  183. package/src/sap/fe/core/helpers/AppStartupHelper.js +15 -15
  184. package/src/sap/fe/core/helpers/AppStartupHelper.ts +37 -40
  185. package/src/sap/fe/core/helpers/BindingToolkit.js +1832 -0
  186. package/src/sap/fe/core/helpers/{BindingExpression.ts → BindingToolkit.ts} +396 -269
  187. package/src/sap/fe/core/helpers/ClassSupport.js +49 -12
  188. package/src/sap/fe/core/helpers/ClassSupport.ts +37 -10
  189. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +2 -2
  190. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -1
  191. package/src/sap/fe/core/helpers/EditState.js +1 -6
  192. package/src/sap/fe/core/helpers/EditState.ts +5 -10
  193. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +2 -2
  194. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +4 -4
  195. package/src/sap/fe/core/helpers/FPMHelper.js +1 -1
  196. package/src/sap/fe/core/helpers/FPMHelper.ts +2 -2
  197. package/src/sap/fe/core/helpers/KeepAliveHelper.js +31 -31
  198. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +52 -56
  199. package/src/sap/fe/core/helpers/MassEditHelper.js +306 -280
  200. package/src/sap/fe/core/helpers/MassEditHelper.ts +380 -360
  201. package/src/sap/fe/core/helpers/MessageStrip.js +81 -0
  202. package/src/sap/fe/core/helpers/MessageStrip.ts +79 -0
  203. package/src/sap/fe/core/helpers/ModelHelper.js +25 -25
  204. package/src/sap/fe/core/helpers/ModelHelper.ts +34 -32
  205. package/src/sap/fe/core/helpers/PasteHelper.js +3 -10
  206. package/src/sap/fe/core/helpers/PasteHelper.ts +20 -25
  207. package/src/sap/fe/core/helpers/SemanticDateOperators.js +1 -1
  208. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +11 -11
  209. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +3 -3
  210. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +8 -8
  211. package/src/sap/fe/core/helpers/StableIdHelper.js +12 -12
  212. package/src/sap/fe/core/helpers/StableIdHelper.ts +12 -12
  213. package/src/sap/fe/core/helpers/ToES6Promise.js +32 -0
  214. package/src/sap/fe/core/helpers/ToES6Promise.ts +19 -0
  215. package/src/sap/fe/core/jsx-runtime/Fragment.js +16 -0
  216. package/src/sap/fe/core/jsx-runtime/Fragment.ts +3 -0
  217. package/src/sap/fe/core/jsx-runtime/jsx-control.js +99 -0
  218. package/src/sap/fe/core/jsx-runtime/jsx-control.ts +82 -0
  219. package/src/sap/fe/core/jsx-runtime/jsx-xml.js +105 -0
  220. package/src/sap/fe/core/jsx-runtime/jsx-xml.ts +89 -0
  221. package/src/sap/fe/core/jsx-runtime/jsx.js +12 -90
  222. package/src/sap/fe/core/jsx-runtime/jsx.ts +24 -85
  223. package/src/sap/fe/core/library.js +42 -3
  224. package/src/sap/fe/core/library.ts +38 -0
  225. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +3 -3
  226. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +2 -2
  227. package/src/sap/fe/core/messagebundle.properties +39 -63
  228. package/src/sap/fe/core/messagebundle_ar.properties +25 -39
  229. package/src/sap/fe/core/messagebundle_bg.properties +25 -39
  230. package/src/sap/fe/core/messagebundle_ca.properties +25 -39
  231. package/src/sap/fe/core/messagebundle_cs.properties +25 -39
  232. package/src/sap/fe/core/messagebundle_cy.properties +25 -39
  233. package/src/sap/fe/core/messagebundle_da.properties +25 -39
  234. package/src/sap/fe/core/messagebundle_de.properties +25 -39
  235. package/src/sap/fe/core/messagebundle_el.properties +26 -40
  236. package/src/sap/fe/core/messagebundle_en.properties +25 -39
  237. package/src/sap/fe/core/messagebundle_en_GB.properties +25 -39
  238. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +25 -39
  239. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +25 -39
  240. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +26 -18
  241. package/src/sap/fe/core/messagebundle_es.properties +27 -41
  242. package/src/sap/fe/core/messagebundle_es_MX.properties +25 -39
  243. package/src/sap/fe/core/messagebundle_et.properties +25 -39
  244. package/src/sap/fe/core/messagebundle_fi.properties +25 -39
  245. package/src/sap/fe/core/messagebundle_fr.properties +26 -40
  246. package/src/sap/fe/core/messagebundle_fr_CA.properties +25 -39
  247. package/src/sap/fe/core/messagebundle_hi.properties +25 -39
  248. package/src/sap/fe/core/messagebundle_hr.properties +25 -39
  249. package/src/sap/fe/core/messagebundle_hu.properties +25 -39
  250. package/src/sap/fe/core/messagebundle_id.properties +25 -39
  251. package/src/sap/fe/core/messagebundle_it.properties +41 -55
  252. package/src/sap/fe/core/messagebundle_iw.properties +25 -39
  253. package/src/sap/fe/core/messagebundle_ja.properties +25 -39
  254. package/src/sap/fe/core/messagebundle_kk.properties +25 -39
  255. package/src/sap/fe/core/messagebundle_ko.properties +30 -44
  256. package/src/sap/fe/core/messagebundle_lt.properties +25 -39
  257. package/src/sap/fe/core/messagebundle_lv.properties +25 -39
  258. package/src/sap/fe/core/messagebundle_ms.properties +25 -39
  259. package/src/sap/fe/core/messagebundle_nl.properties +27 -41
  260. package/src/sap/fe/core/messagebundle_no.properties +25 -39
  261. package/src/sap/fe/core/messagebundle_pl.properties +26 -40
  262. package/src/sap/fe/core/messagebundle_pt.properties +26 -40
  263. package/src/sap/fe/core/messagebundle_pt_PT.properties +25 -39
  264. package/src/sap/fe/core/messagebundle_ro.properties +25 -39
  265. package/src/sap/fe/core/messagebundle_ru.properties +25 -39
  266. package/src/sap/fe/core/messagebundle_sh.properties +25 -39
  267. package/src/sap/fe/core/messagebundle_sk.properties +25 -39
  268. package/src/sap/fe/core/messagebundle_sl.properties +25 -39
  269. package/src/sap/fe/core/messagebundle_sv.properties +25 -39
  270. package/src/sap/fe/core/messagebundle_th.properties +25 -39
  271. package/src/sap/fe/core/messagebundle_tr.properties +25 -39
  272. package/src/sap/fe/core/messagebundle_uk.properties +25 -39
  273. package/src/sap/fe/core/messagebundle_vi.properties +25 -39
  274. package/src/sap/fe/core/messagebundle_zh_CN.properties +25 -39
  275. package/src/sap/fe/core/messagebundle_zh_TW.properties +25 -39
  276. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +2 -2
  277. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +5 -5
  278. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +97 -69
  279. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +68 -69
  280. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +1 -1
  281. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +3 -2
  282. package/src/sap/fe/core/services/NavigationServiceFactory.js +61 -49
  283. package/src/sap/fe/core/services/NavigationServiceFactory.ts +63 -52
  284. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +2 -2
  285. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +4 -4
  286. package/src/sap/fe/core/services/RoutingServiceFactory.js +55 -55
  287. package/src/sap/fe/core/services/RoutingServiceFactory.ts +67 -65
  288. package/src/sap/fe/core/services/ShellServicesFactory.js +92 -76
  289. package/src/sap/fe/core/services/ShellServicesFactory.ts +95 -82
  290. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +61 -61
  291. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +102 -92
  292. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +224 -198
  293. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +138 -139
  294. package/src/sap/fe/core/support/CommonHelper.js +3 -2
  295. package/src/sap/fe/core/support/CommonHelper.ts +9 -13
  296. package/src/sap/fe/core/support/Diagnostics.js +1 -1
  297. package/src/sap/fe/core/support/Diagnostics.ts +5 -5
  298. package/src/sap/fe/core/templating/CommonFormatters.js +84 -0
  299. package/src/sap/fe/core/templating/CommonFormatters.ts +86 -0
  300. package/src/sap/fe/core/templating/CriticalityFormatters.js +31 -31
  301. package/src/sap/fe/core/templating/CriticalityFormatters.ts +42 -40
  302. package/src/sap/fe/core/templating/DataFieldFormatters.js +8 -8
  303. package/src/sap/fe/core/templating/DataFieldFormatters.ts +13 -10
  304. package/src/sap/fe/core/templating/DataModelPathHelper.js +16 -15
  305. package/src/sap/fe/core/templating/DataModelPathHelper.ts +42 -32
  306. package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
  307. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +2 -3
  308. package/src/sap/fe/core/templating/EntitySetHelper.js +7 -7
  309. package/src/sap/fe/core/templating/EntitySetHelper.ts +6 -8
  310. package/src/sap/fe/core/templating/FieldControlHelper.js +35 -34
  311. package/src/sap/fe/core/templating/FieldControlHelper.ts +29 -46
  312. package/src/sap/fe/core/templating/FilterHelper.js +16 -15
  313. package/src/sap/fe/core/templating/FilterHelper.ts +18 -18
  314. package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
  315. package/src/sap/fe/core/templating/FilterTemplating.ts +3 -3
  316. package/src/sap/fe/core/templating/PropertyFormatters.js +7 -7
  317. package/src/sap/fe/core/templating/PropertyFormatters.ts +21 -19
  318. package/src/sap/fe/core/templating/PropertyHelper.js +25 -25
  319. package/src/sap/fe/core/templating/PropertyHelper.ts +25 -26
  320. package/src/sap/fe/core/templating/UIFormatters.js +152 -95
  321. package/src/sap/fe/core/templating/UIFormatters.ts +202 -128
  322. package/src/sap/fe/core/type/Email.js +2 -2
  323. package/src/sap/fe/core/type/Email.ts +2 -2
  324. package/src/sap/fe/core/helpers/BindingExpression.js +0 -1732
@@ -1,7 +1,9 @@
1
- import {
1
+ import type {
2
2
  AndAnnotationExpression,
3
3
  AndConditionalExpression,
4
+ ApplyAnnotationExpression,
4
5
  ConditionalCheckOrValue,
6
+ EntitySet,
5
7
  EntityType,
6
8
  EqAnnotationExpression,
7
9
  EqConditionalExpression,
@@ -21,15 +23,19 @@ import {
21
23
  NotConditionalExpression,
22
24
  OrAnnotationExpression,
23
25
  OrConditionalExpression,
26
+ PathAnnotationExpression,
24
27
  PathConditionExpression,
25
28
  PropertyAnnotationValue
26
29
  } from "@sap-ux/vocabularies-types";
27
- import { EntitySet } from "@sap-ux/vocabularies-types/dist/Converter";
28
- import { ApplyAnnotationExpression, PathAnnotationExpression } from "@sap-ux/vocabularies-types/types/Edm";
29
30
  import { resolveEnumValue } from "./AnnotationEnum";
30
31
 
31
32
  type PrimitiveType = string | number | bigint | boolean | object | null | undefined;
32
-
33
+ type PrimitiveTypeCast<P> =
34
+ | (P extends Boolean ? boolean : never)
35
+ | (P extends Number ? number : never)
36
+ | (P extends String ? string : never)
37
+ | P;
38
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
33
39
  type BaseExpression<T> = {
34
40
  _type: string;
35
41
  };
@@ -43,17 +49,17 @@ type SetOperator = "&&" | "||";
43
49
  export type SetExpression = BaseExpression<boolean> & {
44
50
  _type: "Set";
45
51
  operator: SetOperator;
46
- operands: Expression<boolean>[];
52
+ operands: BindingToolkitExpression<boolean>[];
47
53
  };
48
54
 
49
55
  export type NotExpression = BaseExpression<boolean> & {
50
56
  _type: "Not";
51
- operand: Expression<boolean>;
57
+ operand: BindingToolkitExpression<boolean>;
52
58
  };
53
59
 
54
60
  export type TruthyExpression = BaseExpression<boolean> & {
55
61
  _type: "Truthy";
56
- operand: Expression<string>;
62
+ operand: BindingToolkitExpression<string>;
57
63
  };
58
64
 
59
65
  export type ReferenceExpression = BaseExpression<object> & {
@@ -64,43 +70,43 @@ export type ReferenceExpression = BaseExpression<object> & {
64
70
  export type FormatterExpression<T> = BaseExpression<T> & {
65
71
  _type: "Formatter";
66
72
  fn: string;
67
- parameters: Expression<any>[];
73
+ parameters: BindingToolkitExpression<any>[];
68
74
  };
69
75
 
70
- export type ComplexTypeExpression<T> = BaseExpression<T> & {
76
+ type ComplexTypeExpression<T> = BaseExpression<T> & {
71
77
  _type: "ComplexType";
72
78
  type: string;
73
- formatOptions: object;
79
+ formatOptions: any;
74
80
  parameters: object;
75
- bindingParameters: Expression<any>[];
81
+ bindingParameters: BindingToolkitExpression<any>[];
76
82
  };
77
83
 
78
84
  export type FunctionExpression<T> = BaseExpression<T> & {
79
85
  _type: "Function";
80
- obj?: Expression<object>;
86
+ obj?: BindingToolkitExpression<object>;
81
87
  fn: string;
82
- parameters: Expression<any>[];
88
+ parameters: BindingToolkitExpression<any>[];
83
89
  };
84
90
 
85
91
  export type ConcatExpression = BaseExpression<string> & {
86
92
  _type: "Concat";
87
- expressions: Expression<string>[];
93
+ expressions: BindingToolkitExpression<string>[];
88
94
  };
89
95
 
90
96
  export type LengthExpression = BaseExpression<string> & {
91
97
  _type: "Length";
92
- bindingExpression: BindingExpressionExpression<any>;
98
+ pathInModel: PathInModelExpression<any>;
93
99
  };
94
100
 
95
- export type UnresolveableBindingExpression = BaseExpression<string> & {
101
+ type UnresolveablePathExpression = BaseExpression<string> & {
96
102
  _type: "Unresolvable";
97
103
  };
98
104
 
99
105
  /**
100
- * @typedef BindingExpressionExpression
106
+ * @typedef PathInModelExpression
101
107
  */
102
- export type BindingExpressionExpression<T> = BaseExpression<T> & {
103
- _type: "Binding";
108
+ export type PathInModelExpression<T> = BaseExpression<T> & {
109
+ _type: "PathInModel";
104
110
  modelName?: string;
105
111
  path: string;
106
112
  targetEntitySet?: EntitySet;
@@ -108,26 +114,16 @@ export type BindingExpressionExpression<T> = BaseExpression<T> & {
108
114
  constraints?: any;
109
115
  parameters?: any;
110
116
  targetType?: string;
117
+ mode?: string;
111
118
  formatOptions?: any;
112
119
  };
113
120
 
114
- export type DefaultBindingExpressionExpression<T> = BaseExpression<T> & {
115
- _type: "DefaultBinding";
116
- modelName?: string;
117
- path: string;
118
- type?: string;
119
- constraints?: object;
120
- parameters?: any;
121
- targetType?: string;
122
- formatOptions?: object;
123
- };
124
-
125
- export type EmbeddedBindingExpression<T> = BaseExpression<T> & {
121
+ export type EmbeddedUI5BindingExpression<T> = BaseExpression<T> & {
126
122
  _type: "EmbeddedBinding";
127
123
  value: string;
128
124
  };
129
125
 
130
- export type EmbeddedExpressionBindingExpression<T> = BaseExpression<T> & {
126
+ export type EmbeddedUI5ExpressionBindingExpression<T> = BaseExpression<T> & {
131
127
  _type: "EmbeddedExpressionBinding";
132
128
  value: string;
133
129
  };
@@ -136,34 +132,33 @@ type ComparisonOperator = "===" | "!==" | ">=" | ">" | "<=" | "<";
136
132
  export type ComparisonExpression = BaseExpression<boolean> & {
137
133
  _type: "Comparison";
138
134
  operator: ComparisonOperator;
139
- operand1: Expression<any>;
140
- operand2: Expression<any>;
135
+ operand1: BindingToolkitExpression<any>;
136
+ operand2: BindingToolkitExpression<any>;
141
137
  };
142
138
 
143
139
  export type IfElseExpression<T> = BaseExpression<T> & {
144
140
  _type: "IfElse";
145
- condition: Expression<boolean>;
146
- onTrue: Expression<T>;
147
- onFalse: Expression<T>;
141
+ condition: BindingToolkitExpression<boolean>;
142
+ onTrue: BindingToolkitExpression<T>;
143
+ onFalse: BindingToolkitExpression<T>;
148
144
  };
149
145
 
150
146
  /**
151
147
  * An expression that evaluates to type T.
152
148
  *
153
- * @typedef Expression
149
+ * @typedef BindingToolkitExpression
154
150
  */
155
- export type Expression<T> =
156
- | UnresolveableBindingExpression
151
+ export type BindingToolkitExpression<T> =
152
+ | UnresolveablePathExpression
157
153
  | ConstantExpression<T>
158
154
  | SetExpression
159
155
  | NotExpression
160
156
  | TruthyExpression
161
157
  | ConcatExpression
162
158
  | LengthExpression
163
- | BindingExpressionExpression<T>
164
- | EmbeddedBindingExpression<T>
165
- | EmbeddedExpressionBindingExpression<T>
166
- | DefaultBindingExpressionExpression<T>
159
+ | PathInModelExpression<T>
160
+ | EmbeddedUI5BindingExpression<T>
161
+ | EmbeddedUI5ExpressionBindingExpression<T>
167
162
  | ComparisonExpression
168
163
  | IfElseExpression<T>
169
164
  | FormatterExpression<T>
@@ -174,9 +169,9 @@ export type Expression<T> =
174
169
  /**
175
170
  * An expression that evaluates to type T, or a constant value of type T
176
171
  */
177
- export type ExpressionOrPrimitive<T extends PrimitiveType> = Expression<T> | T;
172
+ type ExpressionOrPrimitive<T extends PrimitiveType> = BindingToolkitExpression<T> | T;
178
173
 
179
- export const unresolveableExpression: UnresolveableBindingExpression = {
174
+ export const unresolveableExpression: UnresolveablePathExpression = {
180
175
  _type: "Unresolvable"
181
176
  };
182
177
 
@@ -184,7 +179,7 @@ function escapeXmlAttribute(inputString: string) {
184
179
  return inputString.replace(/'/g, "\\'");
185
180
  }
186
181
 
187
- export function hasUnresolveableExpression(...expressions: Expression<any>[]): boolean {
182
+ export function hasUnresolveableExpression(...expressions: BindingToolkitExpression<any>[]): boolean {
188
183
  return expressions.find((expr) => expr._type === "Unresolvable") !== undefined;
189
184
  }
190
185
  /**
@@ -192,9 +187,10 @@ export function hasUnresolveableExpression(...expressions: Expression<any>[]): b
192
187
  *
193
188
  * @param a
194
189
  * @param b
195
- * @returns {boolean} `true` if the two expressions are equal
190
+ * @returns `true` if the two expressions are equal
191
+ * @private
196
192
  */
197
- export function _checkExpressionsAreEqual<T>(a: Expression<T>, b: Expression<T>): boolean {
193
+ export function _checkExpressionsAreEqual<T>(a: BindingToolkitExpression<T>, b: BindingToolkitExpression<T>): boolean {
198
194
  if (a._type !== b._type) {
199
195
  return false;
200
196
  }
@@ -245,19 +241,13 @@ export function _checkExpressionsAreEqual<T>(a: Expression<T>, b: Expression<T>)
245
241
  });
246
242
 
247
243
  case "Length":
248
- return _checkExpressionsAreEqual(a.bindingExpression, (b as LengthExpression).bindingExpression);
249
-
250
- case "Binding":
251
- return (
252
- a.modelName === (b as BindingExpressionExpression<T>).modelName &&
253
- a.path === (b as BindingExpressionExpression<T>).path &&
254
- a.targetEntitySet === (b as BindingExpressionExpression<T>).targetEntitySet
255
- );
244
+ return _checkExpressionsAreEqual(a.pathInModel, (b as LengthExpression).pathInModel);
256
245
 
257
- case "DefaultBinding":
246
+ case "PathInModel":
258
247
  return (
259
- a.modelName === (b as DefaultBindingExpressionExpression<T>).modelName &&
260
- a.path === (b as DefaultBindingExpressionExpression<T>).path
248
+ a.modelName === (b as PathInModelExpression<T>).modelName &&
249
+ a.path === (b as PathInModelExpression<T>).path &&
250
+ a.targetEntitySet === (b as PathInModelExpression<T>).targetEntitySet
261
251
  );
262
252
 
263
253
  case "Formatter":
@@ -297,7 +287,7 @@ export function _checkExpressionsAreEqual<T>(a: Expression<T>, b: Expression<T>)
297
287
  * Converts a nested SetExpression by inlining operands of type SetExpression with the same operator.
298
288
  *
299
289
  * @param expression The expression to flatten
300
- * @returns {SetExpression} A new SetExpression with the same operator
290
+ * @returns A new SetExpression with the same operator
301
291
  */
302
292
  function flattenSetExpression(expression: SetExpression): SetExpression {
303
293
  return expression.operands.reduce(
@@ -319,9 +309,9 @@ function flattenSetExpression(expression: SetExpression): SetExpression {
319
309
  * Detects whether an array of boolean expressions contains an expression and its negation.
320
310
  *
321
311
  * @param expressions Array of expressions
322
- * @returns {boolean} `true` if the set of expressions contains an expression and its negation
312
+ * @returns `true` if the set of expressions contains an expression and its negation
323
313
  */
324
- function hasOppositeExpressions(expressions: Expression<boolean>[]): boolean {
314
+ function hasOppositeExpressions(expressions: BindingToolkitExpression<boolean>[]): boolean {
325
315
  const negatedExpressions = expressions.map(not);
326
316
  return expressions.some((expression, index) => {
327
317
  for (let i = index + 1; i < negatedExpressions.length; i++) {
@@ -340,9 +330,9 @@ function hasOppositeExpressions(expressions: Expression<boolean>[]): boolean {
340
330
  * false or if the expression contains an operand and its negation).
341
331
  *
342
332
  * @param operands Expressions to connect by `and`
343
- * @returns {Expression<boolean>} Expression evaluating to boolean
333
+ * @returns Expression evaluating to boolean
344
334
  */
345
- export function and(...operands: ExpressionOrPrimitive<boolean>[]): Expression<boolean> {
335
+ export function and(...operands: ExpressionOrPrimitive<boolean>[]): BindingToolkitExpression<boolean> {
346
336
  const expressions = flattenSetExpression({
347
337
  _type: "Set",
348
338
  operator: "&&",
@@ -385,9 +375,9 @@ export function and(...operands: ExpressionOrPrimitive<boolean>[]): Expression<b
385
375
  * true or if the expression contains an operand and its negation).
386
376
  *
387
377
  * @param operands Expressions to connect by `or`
388
- * @returns {Expression<boolean>} Expression evaluating to boolean
378
+ * @returns Expression evaluating to boolean
389
379
  */
390
- export function or(...operands: ExpressionOrPrimitive<boolean>[]): Expression<boolean> {
380
+ export function or(...operands: ExpressionOrPrimitive<boolean>[]): BindingToolkitExpression<boolean> {
391
381
  const expressions = flattenSetExpression({
392
382
  _type: "Set",
393
383
  operator: "||",
@@ -426,9 +416,9 @@ export function or(...operands: ExpressionOrPrimitive<boolean>[]): Expression<bo
426
416
  * Logical `not` operator.
427
417
  *
428
418
  * @param operand The expression to reverse
429
- * @returns {Expression<boolean>} The resulting expression that evaluates to boolean
419
+ * @returns The resulting expression that evaluates to boolean
430
420
  */
431
- export function not(operand: ExpressionOrPrimitive<boolean>): Expression<boolean> {
421
+ export function not(operand: ExpressionOrPrimitive<boolean>): BindingToolkitExpression<boolean> {
432
422
  operand = wrapPrimitive(operand);
433
423
  if (hasUnresolveableExpression(operand)) {
434
424
  return unresolveableExpression;
@@ -478,9 +468,9 @@ export function not(operand: ExpressionOrPrimitive<boolean>): Expression<boolean
478
468
  * Evaluates whether a binding expression is equal to true with a loose equality.
479
469
  *
480
470
  * @param operand The expression to check
481
- * @returns {Expression<boolean>} The resulting expression that evaluates to boolean
471
+ * @returns The resulting expression that evaluates to boolean
482
472
  */
483
- export function isTruthy(operand: Expression<string>): Expression<boolean> {
473
+ export function isTruthy(operand: BindingToolkitExpression<string>): BindingToolkitExpression<boolean> {
484
474
  if (isConstant(operand)) {
485
475
  return constant(!!operand.value);
486
476
  } else {
@@ -491,6 +481,25 @@ export function isTruthy(operand: Expression<string>): Expression<boolean> {
491
481
  }
492
482
  }
493
483
 
484
+ /**
485
+ * Creates a binding expression that will be evaluated by the corresponding model.
486
+ *
487
+ * @param path
488
+ * @param modelName
489
+ * @param visitedNavigationPaths
490
+ * @param pathVisitor
491
+ * @returns An expression representating that path in the model
492
+ * @deprecated use pathInModel instead
493
+ */
494
+ export function bindingExpression<TargetType extends PrimitiveType>(
495
+ path: any,
496
+ modelName?: string,
497
+ visitedNavigationPaths: string[] = [],
498
+ pathVisitor?: Function
499
+ ): PathInModelExpression<TargetType> | UnresolveablePathExpression {
500
+ return pathInModel(path, modelName, visitedNavigationPaths, pathVisitor);
501
+ }
502
+
494
503
  /**
495
504
  * Creates a binding expression that will be evaluated by the corresponding model.
496
505
  *
@@ -499,14 +508,38 @@ export function isTruthy(operand: Expression<string>): Expression<boolean> {
499
508
  * @param [modelName] The name of the model
500
509
  * @param [visitedNavigationPaths] The paths from the root entitySet
501
510
  * @param [pathVisitor] A function to modify the resulting path
502
- * @returns {BindingExpressionExpression<TargetType>} The default binding expression
511
+ * @returns An expression representating that path in the model
503
512
  */
504
- export function bindingExpression<TargetType extends PrimitiveType>(
513
+ export function pathInModel(
514
+ path: undefined,
515
+ modelName?: string,
516
+ visitedNavigationPaths?: string[],
517
+ pathVisitor?: Function
518
+ ): UnresolveablePathExpression;
519
+ export function pathInModel<TargetType extends PrimitiveType>(
520
+ path: string,
521
+ modelName?: string,
522
+ visitedNavigationPaths?: string[],
523
+ pathVisitor?: undefined
524
+ ): PathInModelExpression<TargetType>;
525
+ export function pathInModel<TargetType extends PrimitiveType>(
526
+ path: string,
527
+ modelName?: string,
528
+ visitedNavigationPaths?: string[],
529
+ pathVisitor?: Function
530
+ ): UnresolveablePathExpression | PathInModelExpression<TargetType>;
531
+ export function pathInModel<TargetType extends PrimitiveType>(
532
+ path: string | undefined,
533
+ modelName?: string,
534
+ visitedNavigationPaths?: string[],
535
+ pathVisitor?: Function
536
+ ): UnresolveablePathExpression | PathInModelExpression<TargetType>;
537
+ export function pathInModel<TargetType extends PrimitiveType>(
505
538
  path: string | undefined,
506
539
  modelName?: string,
507
540
  visitedNavigationPaths: string[] = [],
508
541
  pathVisitor?: Function
509
- ): BindingExpressionExpression<TargetType> | UnresolveableBindingExpression {
542
+ ): UnresolveablePathExpression | PathInModelExpression<TargetType> {
510
543
  if (path === undefined) {
511
544
  return unresolveableExpression;
512
545
  }
@@ -522,20 +555,20 @@ export function bindingExpression<TargetType extends PrimitiveType>(
522
555
  targetPath = localPath.join("/");
523
556
  }
524
557
  return {
525
- _type: "Binding",
558
+ _type: "PathInModel",
526
559
  modelName: modelName,
527
560
  path: targetPath
528
561
  };
529
562
  }
530
563
 
531
- type PlainExpressionObject = { [index: string]: Expression<any> };
564
+ type PlainExpressionObject = { [index: string]: BindingToolkitExpression<any> };
532
565
 
533
566
  /**
534
567
  * Creates a constant expression based on a primitive value.
535
568
  *
536
569
  * @template T
537
570
  * @param value The constant to wrap in an expression
538
- * @returns {ConstantExpression<T>} The constant expression
571
+ * @returns The constant expression
539
572
  */
540
573
  export function constant<T extends PrimitiveType>(value: T): ConstantExpression<T> {
541
574
  let constantValue: T;
@@ -565,7 +598,7 @@ type EvaluationType = "boolean";
565
598
  export function resolveBindingString<T extends PrimitiveType>(
566
599
  value: string | boolean | number,
567
600
  targetType?: EvaluationType
568
- ): ConstantExpression<T> | EmbeddedBindingExpression<T> | EmbeddedExpressionBindingExpression<T> {
601
+ ): ConstantExpression<T> | EmbeddedUI5BindingExpression<T> | EmbeddedUI5ExpressionBindingExpression<T> {
569
602
  if (value !== undefined && typeof value === "string" && value.startsWith("{")) {
570
603
  if (value.startsWith("{=")) {
571
604
  // Expression binding, we can just remove the outer binding things
@@ -590,9 +623,8 @@ export function resolveBindingString<T extends PrimitiveType>(
590
623
  * A named reference.
591
624
  *
592
625
  * @see fn
593
- *
594
626
  * @param reference Reference
595
- * @returns {ReferenceExpression} The object reference binding part
627
+ * @returns The object reference binding part
596
628
  */
597
629
  export function ref(reference: string | null): ReferenceExpression {
598
630
  return { _type: "Ref", ref: reference };
@@ -605,9 +637,9 @@ export function ref(reference: string | null): ReferenceExpression {
605
637
  * no such expression type supported.
606
638
  *
607
639
  * @param something Type to check
608
- * @returns {boolean} `true` if the type is considered to be an expression
640
+ * @returns `true` if the type is considered to be an expression
609
641
  */
610
- function isExpression<T extends PrimitiveType>(something: ExpressionOrPrimitive<T>): something is Expression<T> {
642
+ function isExpression<T extends PrimitiveType>(something: ExpressionOrPrimitive<T>): something is BindingToolkitExpression<T> {
611
643
  return something !== null && typeof something === "object" && (something as BaseExpression<T>)._type !== undefined;
612
644
  }
613
645
 
@@ -616,9 +648,9 @@ function isExpression<T extends PrimitiveType>(something: ExpressionOrPrimitive<
616
648
  *
617
649
  * @template T
618
650
  * @param something The object to wrap in a Constant expression
619
- * @returns {Expression<T>} Either the original object or the wrapped one depending on the case
651
+ * @returns Either the original object or the wrapped one depending on the case
620
652
  */
621
- function wrapPrimitive<T extends PrimitiveType>(something: ExpressionOrPrimitive<T>): Expression<T> {
653
+ function wrapPrimitive<T extends PrimitiveType>(something: ExpressionOrPrimitive<T>): BindingToolkitExpression<T> {
622
654
  if (isExpression(something)) {
623
655
  return something;
624
656
  }
@@ -631,29 +663,44 @@ function wrapPrimitive<T extends PrimitiveType>(something: ExpressionOrPrimitive
631
663
  *
632
664
  * @template T The target type
633
665
  * @param maybeConstant The expression or primitive value that is to be checked
634
- * @returns {boolean} `true` if it is constant
666
+ * @returns `true` if it is constant
635
667
  */
636
668
  export function isConstant<T extends PrimitiveType>(maybeConstant: ExpressionOrPrimitive<T>): maybeConstant is ConstantExpression<T> {
637
669
  return typeof maybeConstant !== "object" || (maybeConstant as BaseExpression<T>)._type === "Constant";
638
670
  }
639
671
 
640
- function isTrue(expression: Expression<PrimitiveType>) {
672
+ function isTrue(expression: BindingToolkitExpression<PrimitiveType>) {
641
673
  return isConstant(expression) && expression.value === true;
642
674
  }
643
675
 
644
- function isFalse(expression: Expression<PrimitiveType>) {
676
+ function isFalse(expression: BindingToolkitExpression<PrimitiveType>) {
645
677
  return isConstant(expression) && expression.value === false;
646
678
  }
647
679
 
648
680
  /**
649
- * Checks if the expression or value provided is binding or not.
681
+ * Checks if the expression or value provided is a path in model expression or not.
682
+ *
683
+ * @template T The target type
684
+ * @param maybeBinding The expression or primitive value that is to be checked
685
+ * @returns `true` if it is a path in model expression
686
+ */
687
+ export function isPathInModelExpression<T extends PrimitiveType>(
688
+ maybeBinding: ExpressionOrPrimitive<T>
689
+ ): maybeBinding is PathInModelExpression<T> {
690
+ return typeof maybeBinding === "object" && (maybeBinding as BaseExpression<T>)._type === "PathInModel";
691
+ }
692
+
693
+ /**
694
+ * Checks if the expression or value provided is a complex type expression.
650
695
  *
651
696
  * @template T The target type
652
697
  * @param maybeBinding The expression or primitive value that is to be checked
653
- * @returns {boolean} `true` if it is binding
698
+ * @returns `true` if it is a path in model expression
654
699
  */
655
- export function isBinding<T extends PrimitiveType>(maybeBinding: ExpressionOrPrimitive<T>): maybeBinding is BindingExpressionExpression<T> {
656
- return typeof maybeBinding === "object" && (maybeBinding as BaseExpression<T>)._type === "Binding";
700
+ export function isComplexTypeExpression<T extends PrimitiveType>(
701
+ maybeBinding: ExpressionOrPrimitive<T>
702
+ ): maybeBinding is ComplexTypeExpression<T> {
703
+ return typeof maybeBinding === "object" && (maybeBinding as BaseExpression<T>)._type === "ComplexType";
657
704
  }
658
705
 
659
706
  /**
@@ -661,9 +708,9 @@ export function isBinding<T extends PrimitiveType>(maybeBinding: ExpressionOrPri
661
708
  *
662
709
  * @template T The target type
663
710
  * @param expression The expression
664
- * @returns {boolean} `true` if the expression is a ComparisonExpression
711
+ * @returns `true` if the expression is a ComparisonExpression
665
712
  */
666
- function isComparison<T extends PrimitiveType>(expression: Expression<T>): expression is ComparisonExpression {
713
+ function isComparison<T extends PrimitiveType>(expression: BindingToolkitExpression<T>): expression is ComparisonExpression {
667
714
  return expression._type === "Comparison";
668
715
  }
669
716
 
@@ -696,7 +743,7 @@ function isPrimitiveObject(objectType: object): boolean {
696
743
  *
697
744
  * @template T The target type
698
745
  * @param annotationValue The annotation annotationValue to evaluate
699
- * @returns {boolean} `true` if the object is a {ComplexAnnotationExpression}
746
+ * @returns `true` if the object is a {ComplexAnnotationExpression}
700
747
  */
701
748
  function isComplexAnnotationExpression<T>(annotationValue: PropertyAnnotationValue<T>): annotationValue is ComplexAnnotationExpression<T> {
702
749
  return typeof annotationValue === "object" && !isPrimitiveObject(annotationValue as object);
@@ -710,14 +757,33 @@ function isComplexAnnotationExpression<T>(annotationValue: PropertyAnnotationVal
710
757
  * @param visitedNavigationPaths The path from the root entity set
711
758
  * @param defaultValue Default value if the annotationValue is undefined
712
759
  * @param pathVisitor A function to modify the resulting path
713
- * @returns {Expression<T>} The annotationValue equivalent to that annotation annotationValue
760
+ * @returns The annotationValue equivalent to that annotation annotationValue
761
+ * @deprecated use getExpressionFromAnnotation instead
714
762
  */
715
763
  export function annotationExpression<T extends PrimitiveType>(
716
764
  annotationValue: PropertyAnnotationValue<T>,
717
765
  visitedNavigationPaths: string[] = [],
718
766
  defaultValue?: ExpressionOrPrimitive<T>,
719
767
  pathVisitor?: Function
720
- ): Expression<T> {
768
+ ): BindingToolkitExpression<PrimitiveTypeCast<T>> {
769
+ return getExpressionFromAnnotation(annotationValue, visitedNavigationPaths, defaultValue, pathVisitor);
770
+ }
771
+ /**
772
+ * Generate the corresponding annotationValue for a given annotation annotationValue.
773
+ *
774
+ * @template T The target type
775
+ * @param annotationValue The source annotation annotationValue
776
+ * @param visitedNavigationPaths The path from the root entity set
777
+ * @param defaultValue Default value if the annotationValue is undefined
778
+ * @param pathVisitor A function to modify the resulting path
779
+ * @returns The annotationValue equivalent to that annotation annotationValue
780
+ */
781
+ export function getExpressionFromAnnotation<T extends PrimitiveType>(
782
+ annotationValue: PropertyAnnotationValue<T>,
783
+ visitedNavigationPaths: string[] = [],
784
+ defaultValue?: ExpressionOrPrimitive<T>,
785
+ pathVisitor?: Function
786
+ ): BindingToolkitExpression<PrimitiveTypeCast<T>> {
721
787
  if (annotationValue === undefined) {
722
788
  return wrapPrimitive(defaultValue as T);
723
789
  }
@@ -728,59 +794,59 @@ export function annotationExpression<T extends PrimitiveType>(
728
794
 
729
795
  switch (annotationValue.type) {
730
796
  case "Path":
731
- return bindingExpression(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
797
+ return pathInModel(annotationValue.path, undefined, visitedNavigationPaths, pathVisitor);
732
798
  case "If":
733
799
  return annotationIfExpression(annotationValue.If, visitedNavigationPaths, pathVisitor);
734
800
  case "Not":
735
- return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor)) as Expression<T>;
801
+ return not(parseAnnotationCondition(annotationValue.Not, visitedNavigationPaths, pathVisitor)) as BindingToolkitExpression<T>;
736
802
  case "Eq":
737
803
  return equal(
738
804
  parseAnnotationCondition(annotationValue.Eq[0], visitedNavigationPaths, pathVisitor),
739
805
  parseAnnotationCondition(annotationValue.Eq[1], visitedNavigationPaths, pathVisitor)
740
- ) as Expression<T>;
806
+ ) as BindingToolkitExpression<T>;
741
807
  case "Ne":
742
808
  return notEqual(
743
809
  parseAnnotationCondition(annotationValue.Ne[0], visitedNavigationPaths, pathVisitor),
744
810
  parseAnnotationCondition(annotationValue.Ne[1], visitedNavigationPaths, pathVisitor)
745
- ) as Expression<T>;
811
+ ) as BindingToolkitExpression<T>;
746
812
  case "Gt":
747
813
  return greaterThan(
748
814
  parseAnnotationCondition(annotationValue.Gt[0], visitedNavigationPaths, pathVisitor),
749
815
  parseAnnotationCondition(annotationValue.Gt[1], visitedNavigationPaths, pathVisitor)
750
- ) as Expression<T>;
816
+ ) as BindingToolkitExpression<T>;
751
817
  case "Ge":
752
818
  return greaterOrEqual(
753
819
  parseAnnotationCondition(annotationValue.Ge[0], visitedNavigationPaths, pathVisitor),
754
820
  parseAnnotationCondition(annotationValue.Ge[1], visitedNavigationPaths, pathVisitor)
755
- ) as Expression<T>;
821
+ ) as BindingToolkitExpression<T>;
756
822
  case "Lt":
757
823
  return lessThan(
758
824
  parseAnnotationCondition(annotationValue.Lt[0], visitedNavigationPaths, pathVisitor),
759
825
  parseAnnotationCondition(annotationValue.Lt[1], visitedNavigationPaths, pathVisitor)
760
- ) as Expression<T>;
826
+ ) as BindingToolkitExpression<T>;
761
827
  case "Le":
762
828
  return lessOrEqual(
763
829
  parseAnnotationCondition(annotationValue.Le[0], visitedNavigationPaths, pathVisitor),
764
830
  parseAnnotationCondition(annotationValue.Le[1], visitedNavigationPaths, pathVisitor)
765
- ) as Expression<T>;
831
+ ) as BindingToolkitExpression<T>;
766
832
  case "Or":
767
833
  return or(
768
- ...(annotationValue.Or.map(function (orCondition) {
769
- return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
770
- }) as Expression<boolean>[])
771
- ) as Expression<T>;
834
+ ...annotationValue.Or.map(function (orCondition) {
835
+ return parseAnnotationCondition<boolean>(orCondition, visitedNavigationPaths, pathVisitor);
836
+ })
837
+ ) as BindingToolkitExpression<T>;
772
838
  case "And":
773
839
  return and(
774
- ...(annotationValue.And.map(function (andCondition) {
775
- return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
776
- }) as Expression<boolean>[])
777
- ) as Expression<T>;
840
+ ...annotationValue.And.map(function (andCondition) {
841
+ return parseAnnotationCondition<boolean>(andCondition, visitedNavigationPaths, pathVisitor);
842
+ })
843
+ ) as BindingToolkitExpression<T>;
778
844
  case "Apply":
779
845
  return annotationApplyExpression(
780
846
  annotationValue as ApplyAnnotationExpression<string>,
781
847
  visitedNavigationPaths,
782
848
  pathVisitor
783
- ) as Expression<T>;
849
+ ) as BindingToolkitExpression<T>;
784
850
  }
785
851
  return unresolveableExpression;
786
852
  }
@@ -792,65 +858,65 @@ export function annotationExpression<T extends PrimitiveType>(
792
858
  * @param annotationValue The condition or value from the annotation
793
859
  * @param visitedNavigationPaths The path from the root entity set
794
860
  * @param pathVisitor A function to modify the resulting path
795
- * @returns {Expression<T>} An equivalent expression
861
+ * @returns An equivalent expression
796
862
  */
797
863
  function parseAnnotationCondition<T extends PrimitiveType>(
798
864
  annotationValue: ConditionalCheckOrValue,
799
865
  visitedNavigationPaths: string[] = [],
800
866
  pathVisitor?: Function
801
- ): Expression<T> {
867
+ ): BindingToolkitExpression<T> {
802
868
  if (annotationValue === null || typeof annotationValue !== "object") {
803
869
  return constant(annotationValue as T);
804
870
  } else if (annotationValue.hasOwnProperty("$Or")) {
805
871
  return or(
806
872
  ...((annotationValue as OrConditionalExpression).$Or.map(function (orCondition) {
807
873
  return parseAnnotationCondition(orCondition, visitedNavigationPaths, pathVisitor);
808
- }) as unknown as Expression<boolean>[])
809
- ) as Expression<T>;
874
+ }) as unknown as BindingToolkitExpression<boolean>[])
875
+ ) as BindingToolkitExpression<T>;
810
876
  } else if (annotationValue.hasOwnProperty("$And")) {
811
877
  return and(
812
878
  ...((annotationValue as AndConditionalExpression).$And.map(function (andCondition) {
813
879
  return parseAnnotationCondition(andCondition, visitedNavigationPaths, pathVisitor);
814
- }) as unknown as Expression<boolean>[])
815
- ) as Expression<T>;
880
+ }) as unknown as BindingToolkitExpression<boolean>[])
881
+ ) as BindingToolkitExpression<T>;
816
882
  } else if (annotationValue.hasOwnProperty("$Not")) {
817
883
  return not(
818
- parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not[0], visitedNavigationPaths, pathVisitor)
819
- ) as Expression<T>;
884
+ parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not, visitedNavigationPaths, pathVisitor)
885
+ ) as BindingToolkitExpression<T>;
820
886
  } else if (annotationValue.hasOwnProperty("$Eq")) {
821
887
  return equal(
822
888
  parseAnnotationCondition((annotationValue as EqConditionalExpression).$Eq[0], visitedNavigationPaths, pathVisitor),
823
889
  parseAnnotationCondition((annotationValue as EqConditionalExpression).$Eq[1], visitedNavigationPaths, pathVisitor)
824
- ) as Expression<T>;
890
+ ) as BindingToolkitExpression<T>;
825
891
  } else if (annotationValue.hasOwnProperty("$Ne")) {
826
892
  return notEqual(
827
893
  parseAnnotationCondition((annotationValue as NeConditionalExpression).$Ne[0], visitedNavigationPaths, pathVisitor),
828
894
  parseAnnotationCondition((annotationValue as NeConditionalExpression).$Ne[1], visitedNavigationPaths, pathVisitor)
829
- ) as Expression<T>;
895
+ ) as BindingToolkitExpression<T>;
830
896
  } else if (annotationValue.hasOwnProperty("$Gt")) {
831
897
  return greaterThan(
832
898
  parseAnnotationCondition((annotationValue as GtConditionalExpression).$Gt[0], visitedNavigationPaths, pathVisitor),
833
899
  parseAnnotationCondition((annotationValue as GtConditionalExpression).$Gt[1], visitedNavigationPaths, pathVisitor)
834
- ) as Expression<T>;
900
+ ) as BindingToolkitExpression<T>;
835
901
  } else if (annotationValue.hasOwnProperty("$Ge")) {
836
902
  return greaterOrEqual(
837
903
  parseAnnotationCondition((annotationValue as GeConditionalExpression).$Ge[0], visitedNavigationPaths, pathVisitor),
838
904
  parseAnnotationCondition((annotationValue as GeConditionalExpression).$Ge[1], visitedNavigationPaths, pathVisitor)
839
- ) as Expression<T>;
905
+ ) as BindingToolkitExpression<T>;
840
906
  } else if (annotationValue.hasOwnProperty("$Lt")) {
841
907
  return lessThan(
842
908
  parseAnnotationCondition((annotationValue as LtConditionalExpression).$Lt[0], visitedNavigationPaths, pathVisitor),
843
909
  parseAnnotationCondition((annotationValue as LtConditionalExpression).$Lt[1], visitedNavigationPaths, pathVisitor)
844
- ) as Expression<T>;
910
+ ) as BindingToolkitExpression<T>;
845
911
  } else if (annotationValue.hasOwnProperty("$Le")) {
846
912
  return lessOrEqual(
847
913
  parseAnnotationCondition((annotationValue as LeConditionalExpression).$Le[0], visitedNavigationPaths, pathVisitor),
848
914
  parseAnnotationCondition((annotationValue as LeConditionalExpression).$Le[1], visitedNavigationPaths, pathVisitor)
849
- ) as Expression<T>;
915
+ ) as BindingToolkitExpression<T>;
850
916
  } else if (annotationValue.hasOwnProperty("$Path")) {
851
- return bindingExpression((annotationValue as PathConditionExpression<T>).$Path, undefined, visitedNavigationPaths, pathVisitor);
917
+ return pathInModel((annotationValue as PathConditionExpression<T>).$Path, undefined, visitedNavigationPaths, pathVisitor);
852
918
  } else if (annotationValue.hasOwnProperty("$Apply")) {
853
- return annotationExpression(
919
+ return getExpressionFromAnnotation(
854
920
  {
855
921
  type: "Apply",
856
922
  Function: (annotationValue as any).$Function,
@@ -859,9 +925,9 @@ function parseAnnotationCondition<T extends PrimitiveType>(
859
925
  visitedNavigationPaths,
860
926
  undefined,
861
927
  pathVisitor
862
- );
928
+ ) as BindingToolkitExpression<T>;
863
929
  } else if (annotationValue.hasOwnProperty("$If")) {
864
- return annotationExpression(
930
+ return getExpressionFromAnnotation(
865
931
  {
866
932
  type: "If",
867
933
  If: (annotationValue as any).$If
@@ -869,7 +935,7 @@ function parseAnnotationCondition<T extends PrimitiveType>(
869
935
  visitedNavigationPaths,
870
936
  undefined,
871
937
  pathVisitor
872
- );
938
+ ) as BindingToolkitExpression<T>;
873
939
  } else if (annotationValue.hasOwnProperty("$EnumMember")) {
874
940
  return constant(resolveEnumValue((annotationValue as any).$EnumMember) as T);
875
941
  }
@@ -883,13 +949,13 @@ function parseAnnotationCondition<T extends PrimitiveType>(
883
949
  * @param annotationValue An If expression returning the type T
884
950
  * @param visitedNavigationPaths The path from the root entity set
885
951
  * @param pathVisitor A function to modify the resulting path
886
- * @returns {Expression<T>} The equivalent ifElse expression
952
+ * @returns The equivalent ifElse expression
887
953
  */
888
954
  export function annotationIfExpression<T extends PrimitiveType>(
889
955
  annotationValue: IfAnnotationExpressionValue<T>,
890
956
  visitedNavigationPaths: string[] = [],
891
957
  pathVisitor?: Function
892
- ): Expression<T> {
958
+ ): BindingToolkitExpression<T> {
893
959
  return ifElse(
894
960
  parseAnnotationCondition(annotationValue[0], visitedNavigationPaths, pathVisitor),
895
961
  parseAnnotationCondition(annotationValue[1] as any, visitedNavigationPaths, pathVisitor),
@@ -901,7 +967,7 @@ export function annotationApplyExpression(
901
967
  applyExpression: ApplyAnnotationExpression<string>,
902
968
  visitedNavigationPaths: string[] = [],
903
969
  pathVisitor?: Function
904
- ): Expression<string> {
970
+ ): BindingToolkitExpression<string> {
905
971
  switch (applyExpression.Function) {
906
972
  case "odata.concat":
907
973
  return concat(
@@ -924,7 +990,7 @@ export function annotationApplyExpression(
924
990
  Apply: applyParam.$Apply
925
991
  };
926
992
  }
927
- return annotationExpression(applyParamConverted, visitedNavigationPaths, undefined, pathVisitor);
993
+ return getExpressionFromAnnotation(applyParamConverted, visitedNavigationPaths, undefined, pathVisitor);
928
994
  })
929
995
  );
930
996
  }
@@ -938,13 +1004,13 @@ export function annotationApplyExpression(
938
1004
  * @param operator The operator to apply
939
1005
  * @param leftOperand The operand on the left side of the operator
940
1006
  * @param rightOperand The operand on the right side of the operator
941
- * @returns {Expression<boolean>} An expression representing the comparison
1007
+ * @returns An expression representing the comparison
942
1008
  */
943
1009
  function comparison<T extends PrimitiveType>(
944
1010
  operator: ComparisonOperator,
945
1011
  leftOperand: ExpressionOrPrimitive<T>,
946
1012
  rightOperand: ExpressionOrPrimitive<T>
947
- ): Expression<boolean> {
1013
+ ): BindingToolkitExpression<boolean> {
948
1014
  const leftExpression = wrapPrimitive(leftOperand);
949
1015
  const rightExpression = wrapPrimitive(rightOperand);
950
1016
  if (hasUnresolveableExpression(leftExpression, rightExpression)) {
@@ -975,13 +1041,13 @@ function comparison<T extends PrimitiveType>(
975
1041
  }
976
1042
  }
977
1043
 
978
- export function length(expression: BindingExpressionExpression<any> | UnresolveableBindingExpression): Expression<number> {
1044
+ export function length(expression: PathInModelExpression<any> | UnresolveablePathExpression): BindingToolkitExpression<number> {
979
1045
  if (expression._type === "Unresolvable") {
980
1046
  return expression;
981
1047
  }
982
1048
  return {
983
1049
  _type: "Length",
984
- bindingExpression: expression
1050
+ pathInModel: expression
985
1051
  };
986
1052
  }
987
1053
 
@@ -991,12 +1057,12 @@ export function length(expression: BindingExpressionExpression<any> | Unresolvea
991
1057
  * @template T The target type
992
1058
  * @param leftOperand The operand on the left side
993
1059
  * @param rightOperand The operand on the right side of the comparison
994
- * @returns {Expression<boolean>} An expression representing the comparison
1060
+ * @returns An expression representing the comparison
995
1061
  */
996
1062
  export function equal<T extends PrimitiveType>(
997
1063
  leftOperand: ExpressionOrPrimitive<T>,
998
1064
  rightOperand: ExpressionOrPrimitive<T>
999
- ): Expression<boolean> {
1065
+ ): BindingToolkitExpression<boolean> {
1000
1066
  const leftExpression = wrapPrimitive(leftOperand);
1001
1067
  const rightExpression = wrapPrimitive(rightOperand);
1002
1068
  if (hasUnresolveableExpression(leftExpression, rightExpression)) {
@@ -1006,7 +1072,7 @@ export function equal<T extends PrimitiveType>(
1006
1072
  return constant(true);
1007
1073
  }
1008
1074
 
1009
- function reduce(left: Expression<T>, right: Expression<T>) {
1075
+ function reduce(left: BindingToolkitExpression<T>, right: BindingToolkitExpression<T>) {
1010
1076
  if (left._type === "Comparison" && isTrue(right)) {
1011
1077
  // compare(a, b) === true ~~> compare(a, b)
1012
1078
  return left;
@@ -1043,12 +1109,12 @@ export function equal<T extends PrimitiveType>(
1043
1109
  * @template T The target type
1044
1110
  * @param leftOperand The operand on the left side
1045
1111
  * @param rightOperand The operand on the right side of the comparison
1046
- * @returns {Expression<boolean>} An expression representing the comparison
1112
+ * @returns An expression representing the comparison
1047
1113
  */
1048
1114
  export function notEqual<T extends PrimitiveType>(
1049
1115
  leftOperand: ExpressionOrPrimitive<T>,
1050
1116
  rightOperand: ExpressionOrPrimitive<T>
1051
- ): Expression<boolean> {
1117
+ ): BindingToolkitExpression<boolean> {
1052
1118
  return not(equal(leftOperand, rightOperand));
1053
1119
  }
1054
1120
 
@@ -1058,12 +1124,12 @@ export function notEqual<T extends PrimitiveType>(
1058
1124
  * @template T The target type
1059
1125
  * @param leftOperand The operand on the left side
1060
1126
  * @param rightOperand The operand on the right side of the comparison
1061
- * @returns {Expression<boolean>} An expression representing the comparison
1127
+ * @returns An expression representing the comparison
1062
1128
  */
1063
1129
  export function greaterOrEqual<T extends PrimitiveType>(
1064
1130
  leftOperand: ExpressionOrPrimitive<T>,
1065
1131
  rightOperand: ExpressionOrPrimitive<T>
1066
- ): Expression<boolean> {
1132
+ ): BindingToolkitExpression<boolean> {
1067
1133
  return comparison(">=", leftOperand, rightOperand);
1068
1134
  }
1069
1135
 
@@ -1073,12 +1139,12 @@ export function greaterOrEqual<T extends PrimitiveType>(
1073
1139
  * @template T The target type
1074
1140
  * @param leftOperand The operand on the left side
1075
1141
  * @param rightOperand The operand on the right side of the comparison
1076
- * @returns {Expression<boolean>} An expression representing the comparison
1142
+ * @returns An expression representing the comparison
1077
1143
  */
1078
1144
  export function greaterThan<T extends PrimitiveType>(
1079
1145
  leftOperand: ExpressionOrPrimitive<T>,
1080
1146
  rightOperand: ExpressionOrPrimitive<T>
1081
- ): Expression<boolean> {
1147
+ ): BindingToolkitExpression<boolean> {
1082
1148
  return comparison(">", leftOperand, rightOperand);
1083
1149
  }
1084
1150
 
@@ -1088,12 +1154,12 @@ export function greaterThan<T extends PrimitiveType>(
1088
1154
  * @template T The target type
1089
1155
  * @param leftOperand The operand on the left side
1090
1156
  * @param rightOperand The operand on the right side of the comparison
1091
- * @returns {Expression<boolean>} An expression representing the comparison
1157
+ * @returns An expression representing the comparison
1092
1158
  */
1093
1159
  export function lessOrEqual<T extends PrimitiveType>(
1094
1160
  leftOperand: ExpressionOrPrimitive<T>,
1095
1161
  rightOperand: ExpressionOrPrimitive<T>
1096
- ): Expression<boolean> {
1162
+ ): BindingToolkitExpression<boolean> {
1097
1163
  return comparison("<=", leftOperand, rightOperand);
1098
1164
  }
1099
1165
 
@@ -1103,12 +1169,12 @@ export function lessOrEqual<T extends PrimitiveType>(
1103
1169
  * @template T The target type
1104
1170
  * @param leftOperand The operand on the left side
1105
1171
  * @param rightOperand The operand on the right side of the comparison
1106
- * @returns {Expression<boolean>} An expression representing the comparison
1172
+ * @returns An expression representing the comparison
1107
1173
  */
1108
1174
  export function lessThan<T extends PrimitiveType>(
1109
1175
  leftOperand: ExpressionOrPrimitive<T>,
1110
1176
  rightOperand: ExpressionOrPrimitive<T>
1111
- ): Expression<boolean> {
1177
+ ): BindingToolkitExpression<boolean> {
1112
1178
  return comparison("<", leftOperand, rightOperand);
1113
1179
  }
1114
1180
 
@@ -1121,13 +1187,13 @@ export function lessThan<T extends PrimitiveType>(
1121
1187
  * @param condition The condition to evaluate
1122
1188
  * @param onTrue Expression result if the condition evaluates to true
1123
1189
  * @param onFalse Expression result if the condition evaluates to false
1124
- * @returns {Expression<T>} The expression that represents this conditional check
1190
+ * @returns The expression that represents this conditional check
1125
1191
  */
1126
1192
  export function ifElse<T extends PrimitiveType>(
1127
1193
  condition: ExpressionOrPrimitive<boolean>,
1128
1194
  onTrue: ExpressionOrPrimitive<T>,
1129
1195
  onFalse: ExpressionOrPrimitive<T>
1130
- ): Expression<T> {
1196
+ ): BindingToolkitExpression<T> {
1131
1197
  let conditionExpression = wrapPrimitive(condition);
1132
1198
  let onTrueExpression = wrapPrimitive(onTrue);
1133
1199
  let onFalseExpression = wrapPrimitive(onFalse);
@@ -1170,24 +1236,39 @@ export function ifElse<T extends PrimitiveType>(
1170
1236
 
1171
1237
  // if X then a else false ~~> X && a
1172
1238
  if (isFalse(onFalseExpression)) {
1173
- return and(conditionExpression, onTrueExpression as Expression<boolean>) as Expression<T>;
1239
+ return and(conditionExpression, onTrueExpression as BindingToolkitExpression<boolean>) as BindingToolkitExpression<T>;
1174
1240
  }
1175
1241
 
1176
1242
  // if X then a else true ~~> !X || a
1177
1243
  if (isTrue(onFalseExpression)) {
1178
- return or(not(conditionExpression), onTrueExpression as Expression<boolean>) as Expression<T>;
1244
+ return or(not(conditionExpression), onTrueExpression as BindingToolkitExpression<boolean>) as BindingToolkitExpression<T>;
1179
1245
  }
1180
1246
 
1181
1247
  // if X then false else a ~~> !X && a
1182
1248
  if (isFalse(onTrueExpression)) {
1183
- return and(not(conditionExpression), onFalseExpression as Expression<boolean>) as Expression<T>;
1249
+ return and(not(conditionExpression), onFalseExpression as BindingToolkitExpression<boolean>) as BindingToolkitExpression<T>;
1184
1250
  }
1185
1251
 
1186
1252
  // if X then true else a ~~> X || a
1187
1253
  if (isTrue(onTrueExpression)) {
1188
- return or(conditionExpression, onFalseExpression as Expression<boolean>) as Expression<T>;
1254
+ return or(conditionExpression, onFalseExpression as BindingToolkitExpression<boolean>) as BindingToolkitExpression<T>;
1255
+ }
1256
+ if (isComplexTypeExpression(condition) || isComplexTypeExpression(onTrue) || isComplexTypeExpression(onFalse)) {
1257
+ let pathIdx = 0;
1258
+ const myIfElseExpression = formatResult([condition, onTrue, onFalse], "sap.fe.core.formatters.StandardFormatter#ifElse");
1259
+ const allParts = [];
1260
+ transformRecursively(
1261
+ myIfElseExpression,
1262
+ "PathInModel",
1263
+ (constantPath: PathInModelExpression<any>) => {
1264
+ allParts.push(constantPath);
1265
+ return pathInModel(`\$${pathIdx++}`, "$");
1266
+ },
1267
+ true
1268
+ );
1269
+ allParts.unshift(constant(JSON.stringify(myIfElseExpression)));
1270
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression");
1189
1271
  }
1190
-
1191
1272
  return {
1192
1273
  _type: "IfElse",
1193
1274
  condition: conditionExpression,
@@ -1200,9 +1281,9 @@ export function ifElse<T extends PrimitiveType>(
1200
1281
  * Checks whether the current expression has a reference to the default model (undefined).
1201
1282
  *
1202
1283
  * @param expression The expression to evaluate
1203
- * @returns {boolean} `true` if there is a reference to the default context
1284
+ * @returns `true` if there is a reference to the default context
1204
1285
  */
1205
- function hasReferenceToDefaultContext(expression: Expression<any>): boolean {
1286
+ function hasReferenceToDefaultContext(expression: BindingToolkitExpression<any>): boolean {
1206
1287
  switch (expression._type) {
1207
1288
  case "Constant":
1208
1289
  case "Formatter":
@@ -1210,12 +1291,10 @@ function hasReferenceToDefaultContext(expression: Expression<any>): boolean {
1210
1291
  return false;
1211
1292
  case "Set":
1212
1293
  return expression.operands.some(hasReferenceToDefaultContext);
1213
- case "Binding":
1294
+ case "PathInModel":
1214
1295
  return expression.modelName === undefined;
1215
1296
  case "Comparison":
1216
1297
  return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
1217
- case "DefaultBinding":
1218
- return true;
1219
1298
  case "IfElse":
1220
1299
  return (
1221
1300
  hasReferenceToDefaultContext(expression.condition) ||
@@ -1262,27 +1341,32 @@ type FunctionParameters<T, F extends FunctionOrName<T>> = F extends Fn<T> ? Para
1262
1341
  * @param parameters The list of parameter that should match the type and number of the formatter function
1263
1342
  * @param formatterFunction The function to call
1264
1343
  * @param [contextEntityType] The context entity type to consider
1265
- * @returns {Expression<T>} The corresponding expression
1344
+ * @returns The corresponding expression
1266
1345
  */
1267
1346
  export function formatResult<T, U extends Fn<T>>(
1268
1347
  parameters: WrappedTuple<Parameters<U>>,
1269
- formatterFunction: U,
1348
+ formatterFunction: U | string,
1270
1349
  contextEntityType?: EntityType
1271
- ): Expression<T> {
1350
+ ): BindingToolkitExpression<T> {
1272
1351
  const parameterExpressions = (parameters as any[]).map(wrapPrimitive);
1273
1352
 
1274
1353
  if (hasUnresolveableExpression(...parameterExpressions)) {
1275
1354
  return unresolveableExpression;
1276
1355
  }
1277
- if (!!contextEntityType) {
1356
+ if (contextEntityType) {
1278
1357
  // Otherwise, if the context is required and no context is provided make sure to add the default binding
1279
1358
  if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1280
- contextEntityType.keys.forEach((key) => parameterExpressions.push(bindingExpression(key.name, "")));
1359
+ contextEntityType.keys.forEach((key) => parameterExpressions.push(pathInModel(key.name, "")));
1281
1360
  }
1282
1361
  }
1283
-
1362
+ let functionName = "";
1363
+ if (typeof formatterFunction === "string") {
1364
+ functionName = formatterFunction;
1365
+ } else {
1366
+ functionName = formatterFunction.__functionName;
1367
+ }
1284
1368
  // FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
1285
- const [formatterClass, formatterName] = formatterFunction.__functionName.split("#");
1369
+ const [formatterClass, formatterName] = functionName.split("#");
1286
1370
 
1287
1371
  if (!!formatterName && formatterName.length > 0) {
1288
1372
  parameterExpressions.unshift(constant(formatterName));
@@ -1296,22 +1380,23 @@ export function formatResult<T, U extends Fn<T>>(
1296
1380
  }
1297
1381
 
1298
1382
  /**
1299
- * Calls a complex type to process the parameters.
1300
- * If requireContext is set to true and no context is passed a default context will be added automatically.
1383
+ * Calls a complex type to process the parameters.
1384
+ * If requireContext is set to true and no context is passed, a default context will be added automatically.
1301
1385
  *
1302
1386
  * @template T
1303
1387
  * @template U
1304
- * @param parameters The list of parameter that should match the type for the compplex type
1388
+ * @param parameters The list of parameters that should match the type for the complex type=
1305
1389
  * @param type The complex type to use
1306
1390
  * @param [contextEntityType] The context entity type to consider
1307
- * @returns {Expression<T>} The corresponding expression
1391
+ * @param oFormatOptions
1392
+ * @returns The corresponding expression
1308
1393
  */
1309
1394
  export function addTypeInformation<T, U extends Fn<T>>(
1310
1395
  parameters: WrappedTuple<Parameters<U>>,
1311
1396
  type: string,
1312
1397
  contextEntityType?: EntityType,
1313
1398
  oFormatOptions?: any
1314
- ): Expression<T> {
1399
+ ): UnresolveablePathExpression | ComplexTypeExpression<T> | ConstantExpression<T> {
1315
1400
  const parameterExpressions = (parameters as any[]).map(wrapPrimitive);
1316
1401
  if (hasUnresolveableExpression(...parameterExpressions)) {
1317
1402
  return unresolveableExpression;
@@ -1319,14 +1404,43 @@ export function addTypeInformation<T, U extends Fn<T>>(
1319
1404
  // If there is only one parameter and it is a constant and we don't expect the context then return the constant
1320
1405
  if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
1321
1406
  return parameterExpressions[0];
1322
- } else if (!!contextEntityType) {
1407
+ } else if (contextEntityType) {
1323
1408
  // Otherwise, if the context is required and no context is provided make sure to add the default binding
1324
1409
  if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1325
- contextEntityType.keys.forEach((key) => parameterExpressions.push(bindingExpression(key.name, "")));
1410
+ contextEntityType.keys.forEach((key) => parameterExpressions.push(pathInModel(key.name, "")));
1326
1411
  }
1327
1412
  }
1328
- if (!oFormatOptions && (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Int") === 0) {
1329
- oFormatOptions = { parseAsString: false, emptyString: "" };
1413
+ // if showMeasure is set to false we want to not parse as string to see the 0
1414
+ // we do that also for all bindings because otherwise the mdc Field isn't editable
1415
+ if (
1416
+ !(oFormatOptions && oFormatOptions.showNumber === false) &&
1417
+ ((parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Int") === 0 ||
1418
+ (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Decimal") === 0 ||
1419
+ (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Double") === 0)
1420
+ ) {
1421
+ if (
1422
+ (parameters[0] as any)?.type === "sap.ui.model.odata.type.Int64" ||
1423
+ (parameters[0] as any)?.type === "sap.ui.model.odata.type.Decimal"
1424
+ ) {
1425
+ //sap.ui.model.odata.type.Int64 do not support parseAsString false
1426
+ oFormatOptions = oFormatOptions?.showMeasure === false ? { emptyString: "", showMeasure: false } : { emptyString: "" };
1427
+ } else {
1428
+ oFormatOptions =
1429
+ oFormatOptions?.showMeasure === false
1430
+ ? { parseAsString: false, emptyString: "", showMeasure: false }
1431
+ : { parseAsString: false, emptyString: "" };
1432
+ }
1433
+ }
1434
+ if (type === "sap.ui.model.odata.type.Unit") {
1435
+ const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
1436
+ uomPath.targetType = "any";
1437
+ uomPath.mode = "OneTime";
1438
+ parameterExpressions.push(uomPath);
1439
+ } else if (type === "sap.ui.model.odata.type.Currency") {
1440
+ const currencyPath = pathInModel("/##@@requestCurrencyCodes");
1441
+ currencyPath.targetType = "any";
1442
+ currencyPath.mode = "OneTime";
1443
+ parameterExpressions.push(currencyPath);
1330
1444
  }
1331
1445
 
1332
1446
  return {
@@ -1343,14 +1457,14 @@ export function addTypeInformation<T, U extends Fn<T>>(
1343
1457
  * @param func Function name or reference to function
1344
1458
  * @param parameters Arguments
1345
1459
  * @param on Object to call the function on
1346
- * @returns {FunctionExpression<T>} Expression representing the function call (not the result of the function call!)
1460
+ * @returns Expression representing the function call (not the result of the function call!)
1347
1461
  */
1348
1462
  export function fn<T, U extends FunctionOrName<T>>(
1349
1463
  func: U,
1350
1464
  parameters: WrappedTuple<FunctionParameters<T, U>>,
1351
1465
  on?: ExpressionOrPrimitive<object>
1352
1466
  ): FunctionExpression<T> {
1353
- const functionName = typeof func === "string" ? func : (func as Fn<T>).__functionName;
1467
+ const functionName = typeof func === "string" ? func : func.__functionName;
1354
1468
  return {
1355
1469
  _type: "Function",
1356
1470
  obj: on !== undefined ? wrapPrimitive(on) : undefined,
@@ -1365,14 +1479,14 @@ export function fn<T, U extends FunctionOrName<T>>(
1365
1479
  * @param expression
1366
1480
  * @returns A boolean expression evaluating the fact that the current element is empty
1367
1481
  */
1368
- export function isEmpty(expression: Expression<string>): Expression<boolean> {
1482
+ export function isEmpty(expression: BindingToolkitExpression<string>): BindingToolkitExpression<boolean> {
1369
1483
  if (expression._type === "Concat") {
1370
1484
  return or(...expression.expressions.map(isEmpty));
1371
1485
  }
1372
1486
  return or(equal(expression, ""), equal(expression, undefined), equal(expression, null));
1373
1487
  }
1374
1488
 
1375
- export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expression<string> {
1489
+ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): BindingToolkitExpression<string> {
1376
1490
  const expressions = inExpressions.map(wrapPrimitive);
1377
1491
  if (hasUnresolveableExpression(...expressions)) {
1378
1492
  return unresolveableExpression;
@@ -1383,6 +1497,16 @@ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expre
1383
1497
  return concatenated + (value as ConstantExpression<any>).value.toString();
1384
1498
  }, "")
1385
1499
  );
1500
+ } else if (expressions.some(isComplexTypeExpression)) {
1501
+ let pathIdx = 0;
1502
+ const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat");
1503
+ const allParts = [];
1504
+ transformRecursively(myConcatExpression, "PathInModel", (constantPath: PathInModelExpression<any>) => {
1505
+ allParts.push(constantPath);
1506
+ return pathInModel(`\$${pathIdx++}`, "$");
1507
+ });
1508
+ allParts.unshift(constant(JSON.stringify(myConcatExpression)));
1509
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression");
1386
1510
  }
1387
1511
  return {
1388
1512
  _type: "Concat",
@@ -1390,14 +1514,14 @@ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expre
1390
1514
  };
1391
1515
  }
1392
1516
 
1393
- export type TransformFunction = <T extends PrimitiveType | unknown>(expressionPart: any) => Expression<T>;
1394
- export type ExpressionType = Pick<Expression<any>, "_type">["_type"];
1517
+ export type TransformFunction = <T extends PrimitiveType | unknown>(expressionPart: any) => BindingToolkitExpression<T>;
1518
+ export type ExpressionType = Pick<BindingToolkitExpression<any>, "_type">["_type"];
1395
1519
  export function transformRecursively<T extends PrimitiveType | unknown>(
1396
- inExpression: Expression<T>,
1520
+ inExpression: BindingToolkitExpression<T>,
1397
1521
  expressionType: ExpressionType,
1398
1522
  transformFunction: TransformFunction,
1399
1523
  includeAllExpression = false
1400
- ): Expression<T> {
1524
+ ): BindingToolkitExpression<T> {
1401
1525
  let expression = inExpression;
1402
1526
  switch (expression._type) {
1403
1527
  case "Function":
@@ -1423,35 +1547,41 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1423
1547
  if (includeAllExpression) {
1424
1548
  condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
1425
1549
  }
1426
- expression = ifElse(condition, onTrue, onFalse) as Expression<T>;
1550
+ expression = ifElse(condition, onTrue, onFalse) as BindingToolkitExpression<T>;
1427
1551
  break;
1428
1552
  case "Not":
1429
1553
  if (includeAllExpression) {
1430
1554
  const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
1431
- expression = not(operand) as Expression<T>;
1555
+ expression = not(operand) as BindingToolkitExpression<T>;
1432
1556
  }
1433
1557
  break;
1434
1558
  case "Truthy":
1435
1559
  break;
1436
1560
  case "Set":
1437
1561
  if (includeAllExpression) {
1438
- expression.operands = expression.operands.map((operand) =>
1562
+ const operands = expression.operands.map((operand) =>
1439
1563
  transformRecursively(operand, expressionType, transformFunction, includeAllExpression)
1440
1564
  );
1565
+ expression =
1566
+ expression.operator === "||"
1567
+ ? (or(...operands) as BindingToolkitExpression<T>)
1568
+ : (and(...operands) as BindingToolkitExpression<T>);
1441
1569
  }
1442
1570
  break;
1443
1571
  case "Comparison":
1444
1572
  if (includeAllExpression) {
1445
1573
  const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
1446
1574
  const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
1447
- expression = comparison(expression.operator, operand1, operand2) as Expression<T>;
1575
+ expression = comparison(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
1448
1576
  }
1449
1577
  break;
1450
- case "DefaultBinding":
1451
1578
  case "Ref":
1452
1579
  case "Length":
1453
- case "Binding":
1580
+ case "PathInModel":
1454
1581
  case "Constant":
1582
+ case "EmbeddedBinding":
1583
+ case "EmbeddedExpressionBinding":
1584
+ case "Unresolvable":
1455
1585
  // Do nothing
1456
1586
  break;
1457
1587
  }
@@ -1461,19 +1591,22 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1461
1591
  return expression;
1462
1592
  }
1463
1593
 
1464
- export type BindingExpression<T> = T | string | undefined;
1594
+ export type CompiledBindingToolkitExpression = string | undefined;
1465
1595
 
1466
1596
  const needParenthesis = function <T extends PrimitiveType>(expr: ExpressionOrPrimitive<T>): boolean {
1467
- return !isConstant(expr) && !isBinding(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
1597
+ return (
1598
+ !isConstant(expr) && !isPathInModelExpression(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function"
1599
+ );
1468
1600
  };
1469
1601
 
1470
1602
  /**
1471
1603
  * Compiles a constant object to a string.
1604
+ *
1472
1605
  * @param expr
1473
1606
  * @param isNullable
1474
- * @returns {string} The compiled string
1607
+ * @returns The compiled string
1475
1608
  */
1476
- function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable = false) {
1609
+ function compileConstantObject(expr: ConstantExpression<object>, isNullable = false) {
1477
1610
  if (isNullable && Object.keys(expr.value).length === 0) {
1478
1611
  return "";
1479
1612
  }
@@ -1482,7 +1615,7 @@ function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable =
1482
1615
  const properties: string[] = [];
1483
1616
  Object.keys(o).forEach((key) => {
1484
1617
  const value = o[key];
1485
- const childResult = compileBinding(value, true, false, true);
1618
+ const childResult = compileExpression(value, true, false, true);
1486
1619
  if (childResult && childResult.length > 0) {
1487
1620
  properties.push(`${key}: ${childResult}`);
1488
1621
  }
@@ -1492,10 +1625,11 @@ function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable =
1492
1625
 
1493
1626
  /**
1494
1627
  * Compiles a Constant Binding Expression.
1628
+ *
1495
1629
  * @param expr
1496
1630
  * @param embeddedInBinding
1497
1631
  * @param isNullable
1498
- * @returns {string} The compiled string
1632
+ * @returns The compiled string
1499
1633
  */
1500
1634
  function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, embeddedInBinding: boolean, isNullable = false) {
1501
1635
  if (expr.value === null) {
@@ -1506,7 +1640,7 @@ function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, e
1506
1640
  }
1507
1641
  if (typeof expr.value === "object") {
1508
1642
  if (Array.isArray(expr.value)) {
1509
- const entries = expr.value.map((expression) => compileBinding(expression, true));
1643
+ const entries = expr.value.map((expression) => compileExpression(expression, true));
1510
1644
  return `[${entries.join(", ")}]`;
1511
1645
  } else {
1512
1646
  return compileConstantObject(expr as ConstantExpression<object>, isNullable);
@@ -1535,10 +1669,10 @@ function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, e
1535
1669
  * @param expressionForBinding The expression to compile
1536
1670
  * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1537
1671
  * @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
1538
- * @returns {BindingExpression<T>} The corresponding expression binding
1672
+ * @returns The corresponding expression binding
1539
1673
  */
1540
- function compileBindingForBinding<T extends PrimitiveType>(
1541
- expressionForBinding: BindingExpressionExpression<T> | DefaultBindingExpressionExpression<T>,
1674
+ function compilePathInModelExpression<T extends PrimitiveType>(
1675
+ expressionForBinding: PathInModelExpression<T>,
1542
1676
  embeddedInBinding: boolean,
1543
1677
  embeddedSeparator: string
1544
1678
  ) {
@@ -1551,22 +1685,22 @@ function compileBindingForBinding<T extends PrimitiveType>(
1551
1685
  ) {
1552
1686
  // This is now a complex binding definition, let's prepare for it
1553
1687
  const complexBindingDefinition = {
1554
- path: compileBindingPath(expressionForBinding),
1688
+ path: compilePathInModel(expressionForBinding),
1555
1689
  type: expressionForBinding.type,
1556
1690
  targetType: expressionForBinding.targetType,
1557
1691
  parameters: expressionForBinding.parameters,
1558
1692
  formatOptions: expressionForBinding.formatOptions,
1559
1693
  constraints: expressionForBinding.constraints
1560
1694
  };
1561
- let outBinding = compileBinding(complexBindingDefinition);
1695
+ let outBinding = compileExpression(complexBindingDefinition);
1562
1696
  if (embeddedInBinding) {
1563
- outBinding = `${embeddedSeparator}` + outBinding;
1697
+ outBinding = `${embeddedSeparator}${outBinding}`;
1564
1698
  }
1565
1699
  return outBinding;
1566
1700
  } else if (embeddedInBinding) {
1567
- return `${embeddedSeparator}{${compileBindingPath(expressionForBinding)}}`;
1701
+ return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
1568
1702
  } else {
1569
- return `{${compileBindingPath(expressionForBinding)}}`;
1703
+ return `{${compilePathInModel(expressionForBinding)}}`;
1570
1704
  }
1571
1705
  }
1572
1706
 
@@ -1575,23 +1709,12 @@ function compileComplexTypeExpression<T extends PrimitiveType>(expression: Compl
1575
1709
  return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
1576
1710
  }
1577
1711
 
1578
- let outputEnd;
1579
- // this code is based on sap.ui.model.odata.v4._AnnotationHelperExpression.fetchCurrencyOrUnit
1580
- switch (expression.type) {
1581
- case "sap.ui.model.odata.type.Unit":
1582
- outputEnd = `,{mode:'OneTime',path:'/##@@requestUnitsOfMeasure',targetType:'any'}],type:'sap.ui.model.odata.type.Unit'`;
1583
- break;
1584
- case "sap.ui.model.odata.type.Currency":
1585
- outputEnd = `,{mode:'OneTime',path:'/##@@requestCurrencyCodes',targetType:'any'}],type:'sap.ui.model.odata.type.Currency'`;
1586
- break;
1587
- default:
1588
- outputEnd = `], type: '${expression.type}'`;
1589
- }
1712
+ let outputEnd = `], type: '${expression.type}'`;
1590
1713
  if (hasElements(expression.formatOptions)) {
1591
- outputEnd += `, formatOptions: ${compileBinding(expression.formatOptions)}`;
1714
+ outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1592
1715
  }
1593
1716
  if (hasElements(expression.parameters)) {
1594
- outputEnd += `, parameters: ${compileBinding(expression.parameters)}`;
1717
+ outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
1595
1718
  }
1596
1719
  outputEnd += "}";
1597
1720
 
@@ -1604,9 +1727,13 @@ function compileComplexTypeExpression<T extends PrimitiveType>(expression: Compl
1604
1727
  * @param expression The compiled expression
1605
1728
  * @param embeddedInBinding True if the compiled expression is to be embedded in a binding
1606
1729
  * @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
1607
- * @returns {BindingExpression<string>} Finalized compiled expression
1730
+ * @returns Finalized compiled expression
1608
1731
  */
1609
- function wrapBindingExpression(expression: string, embeddedInBinding: boolean, parenthesisRequired = false): BindingExpression<string> {
1732
+ function wrapBindingExpression(
1733
+ expression: string,
1734
+ embeddedInBinding: boolean,
1735
+ parenthesisRequired = false
1736
+ ): CompiledBindingToolkitExpression {
1610
1737
  if (embeddedInBinding) {
1611
1738
  if (parenthesisRequired) {
1612
1739
  return `(${expression})`;
@@ -1626,14 +1753,14 @@ function wrapBindingExpression(expression: string, embeddedInBinding: boolean, p
1626
1753
  * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1627
1754
  * @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
1628
1755
  * @param isNullable Whether binding expression can resolve to empty string or not
1629
- * @returns {BindingExpression<T>} The corresponding expression binding
1756
+ * @returns The corresponding expression binding
1630
1757
  */
1631
- export function compileBinding<T extends PrimitiveType>(
1758
+ export function compileExpression<T extends PrimitiveType>(
1632
1759
  expression: ExpressionOrPrimitive<T>,
1633
1760
  embeddedInBinding = false,
1634
1761
  keepTargetType = false,
1635
1762
  isNullable = false
1636
- ): BindingExpression<string> {
1763
+ ): CompiledBindingToolkitExpression {
1637
1764
  const expr = wrapPrimitive(expression);
1638
1765
  const embeddedSeparator = keepTargetType ? "$" : "%";
1639
1766
 
@@ -1648,10 +1775,10 @@ export function compileBinding<T extends PrimitiveType>(
1648
1775
  return expr.ref || "null";
1649
1776
 
1650
1777
  case "Function":
1651
- const argumentString = `${expr.parameters.map((arg) => compileBinding(arg, true)).join(", ")}`;
1778
+ const argumentString = `${expr.parameters.map((arg) => compileExpression(arg, true)).join(", ")}`;
1652
1779
  return expr.obj === undefined
1653
1780
  ? `${expr.fn}(${argumentString})`
1654
- : `${compileBinding(expr.obj, true)}.${expr.fn}(${argumentString})`;
1781
+ : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
1655
1782
 
1656
1783
  case "EmbeddedExpressionBinding":
1657
1784
  return embeddedInBinding ? `(${expr.value.substr(2, expr.value.length - 3)})` : `${expr.value}`;
@@ -1659,39 +1786,40 @@ export function compileBinding<T extends PrimitiveType>(
1659
1786
  case "EmbeddedBinding":
1660
1787
  return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
1661
1788
 
1662
- case "DefaultBinding":
1663
- case "Binding":
1664
- return compileBindingForBinding(expr, embeddedInBinding, embeddedSeparator);
1789
+ case "PathInModel":
1790
+ return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
1665
1791
 
1666
1792
  case "Comparison":
1667
1793
  const comparisonExpression = compileComparisonExpression(expr);
1668
1794
  return wrapBindingExpression(comparisonExpression, embeddedInBinding);
1669
1795
 
1670
1796
  case "IfElse":
1671
- const ifElseExpression = `${compileBinding(expr.condition, true)} ? ${compileBinding(expr.onTrue, true)} : ${compileBinding(
1672
- expr.onFalse,
1797
+ const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(
1798
+ expr.onTrue,
1673
1799
  true
1674
- )}`;
1800
+ )} : ${compileExpression(expr.onFalse, true)}`;
1675
1801
  return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
1676
1802
 
1677
1803
  case "Set":
1678
- const setExpression = expr.operands.map((operand) => compileBinding(operand, true)).join(` ${expr.operator} `);
1804
+ const setExpression = expr.operands.map((operand) => compileExpression(operand, true)).join(` ${expr.operator} `);
1679
1805
  return wrapBindingExpression(setExpression, embeddedInBinding, true);
1680
1806
 
1681
1807
  case "Concat":
1682
- const concatExpression = expr.expressions.map((nestedExpression) => compileBinding(nestedExpression, true, true)).join(" + ");
1808
+ const concatExpression = expr.expressions
1809
+ .map((nestedExpression) => compileExpression(nestedExpression, true, true))
1810
+ .join(" + ");
1683
1811
  return wrapBindingExpression(concatExpression, embeddedInBinding);
1684
1812
 
1685
1813
  case "Length":
1686
- const lengthExpression = `${compileBinding(expr.bindingExpression, true)}.length`;
1814
+ const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
1687
1815
  return wrapBindingExpression(lengthExpression, embeddedInBinding);
1688
1816
 
1689
1817
  case "Not":
1690
- const notExpression = `!${compileBinding(expr.operand, true)}`;
1818
+ const notExpression = `!${compileExpression(expr.operand, true)}`;
1691
1819
  return wrapBindingExpression(notExpression, embeddedInBinding);
1692
1820
 
1693
1821
  case "Truthy":
1694
- const truthyExpression = `!!${compileBinding(expr.operand, true)}`;
1822
+ const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
1695
1823
  return wrapBindingExpression(truthyExpression, embeddedInBinding);
1696
1824
 
1697
1825
  case "Formatter":
@@ -1714,8 +1842,8 @@ export function compileBinding<T extends PrimitiveType>(
1714
1842
  * @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
1715
1843
  */
1716
1844
  function compileComparisonExpression(expression: ComparisonExpression) {
1717
- function compileOperand(operand: Expression<any>) {
1718
- const compiledOperand = compileBinding(operand, true) ?? "undefined";
1845
+ function compileOperand(operand: BindingToolkitExpression<any>) {
1846
+ const compiledOperand = compileExpression(operand, true) ?? "undefined";
1719
1847
  return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
1720
1848
  }
1721
1849
 
@@ -1732,7 +1860,13 @@ function compileFormatterExpression<T extends PrimitiveType>(expression: Formatt
1732
1860
  if (expression.parameters.length === 1) {
1733
1861
  return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
1734
1862
  } else {
1735
- const parts = expression.parameters.map((param) => compilePathParameter(param));
1863
+ const parts = expression.parameters.map((param) => {
1864
+ if (param._type === "ComplexType") {
1865
+ return compileComplexTypeExpression(param);
1866
+ } else {
1867
+ return compilePathParameter(param);
1868
+ }
1869
+ });
1736
1870
  return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
1737
1871
  }
1738
1872
  }
@@ -1742,39 +1876,32 @@ function compileFormatterExpression<T extends PrimitiveType>(expression: Formatt
1742
1876
  *
1743
1877
  * @param expression The binding part to evaluate
1744
1878
  * @param singlePath Whether there is one or multiple path to consider
1745
- * @returns {string} The string snippet to include in the overall binding definition
1879
+ * @returns The string snippet to include in the overall binding definition
1746
1880
  */
1747
- function compilePathParameter(expression: Expression<any>, singlePath = false): string {
1881
+ function compilePathParameter(expression: BindingToolkitExpression<any>, singlePath = false): string {
1748
1882
  let outValue = "";
1749
1883
  if (expression._type === "Constant") {
1750
- switch (typeof expression.value) {
1751
- case "number":
1752
- case "bigint":
1753
- outValue = `value: ${expression.value.toString()}`;
1754
- break;
1755
- case "string":
1756
- outValue = `value: '${escapeXmlAttribute(expression.value.toString())}'`;
1757
- break;
1758
- case "boolean":
1759
- outValue = `value: '${expression.value.toString()}'`;
1760
- break;
1761
- default:
1762
- outValue = "value: ''";
1763
- break;
1884
+ if (expression.value === undefined) {
1885
+ // Special case otherwise the JSTokenizer complains about incorrect content
1886
+ outValue = `value: 'undefined'`;
1887
+ } else {
1888
+ outValue = `value: ${compileConstant(expression, true)}`;
1764
1889
  }
1765
- } else if (expression._type === "DefaultBinding" || expression._type === "Binding") {
1766
- outValue = `path: '${compileBindingPath(expression)}'`;
1890
+ } else if (expression._type === "PathInModel") {
1891
+ outValue = `path: '${compilePathInModel(expression)}'`;
1767
1892
 
1768
1893
  outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
1769
-
1894
+ if (hasElements(expression.mode)) {
1895
+ outValue += `, mode: '${compileExpression(expression.mode)}'`;
1896
+ }
1770
1897
  if (hasElements(expression.constraints)) {
1771
- outValue += `, constraints: ${compileBinding(expression.constraints)}`;
1898
+ outValue += `, constraints: ${compileExpression(expression.constraints)}`;
1772
1899
  }
1773
1900
  if (hasElements(expression.formatOptions)) {
1774
- outValue += `, formatOptions: ${compileBinding(expression.formatOptions)}`;
1901
+ outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1775
1902
  }
1776
1903
  if (hasElements(expression.parameters)) {
1777
- outValue += `, parameters: ${compileBinding(expression.parameters)}`;
1904
+ outValue += `, parameters: ${compileExpression(expression.parameters)}`;
1778
1905
  }
1779
1906
  } else {
1780
1907
  return "";
@@ -1792,6 +1919,6 @@ function hasElements(obj: any) {
1792
1919
  * @param expression The expression to compile.
1793
1920
  * @returns The compiled path.
1794
1921
  */
1795
- function compileBindingPath<T extends PrimitiveType>(expression: BindingExpressionExpression<T> | DefaultBindingExpressionExpression<T>) {
1796
- return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
1922
+ function compilePathInModel<T extends PrimitiveType>(expression: PathInModelExpression<T>) {
1923
+ return `${expression.modelName ? `${expression.modelName}>` : ""}${expression.path}`;
1797
1924
  }