@sapui5/sap.fe.core 1.101.0 → 1.103.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (339) hide show
  1. package/package.json +5 -5
  2. package/src/sap/fe/core/.library +1 -1
  3. package/src/sap/fe/core/AppComponent.js +66 -30
  4. package/src/sap/fe/core/AppComponent.ts +68 -51
  5. package/src/sap/fe/core/AppStateHandler.js +13 -13
  6. package/src/sap/fe/core/AppStateHandler.ts +18 -18
  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 +279 -188
  10. package/src/sap/fe/core/CommonUtils.ts +306 -215
  11. package/src/sap/fe/core/ExtensionAPI.js +25 -30
  12. package/src/sap/fe/core/ExtensionAPI.ts +37 -41
  13. package/src/sap/fe/core/PageController.js +12 -7
  14. package/src/sap/fe/core/PageController.ts +10 -5
  15. package/src/sap/fe/core/TemplateComponent.js +6 -6
  16. package/src/sap/fe/core/TemplateComponent.ts +11 -11
  17. package/src/sap/fe/core/TemplateModel.js +2 -2
  18. package/src/sap/fe/core/TemplateModel.ts +3 -3
  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/BuildingBlockRuntime.js +306 -78
  22. package/src/sap/fe/core/buildingBlocks/BuildingBlockRuntime.ts +280 -70
  23. package/src/sap/fe/core/buildingBlocks/TraceInfo.js +27 -27
  24. package/src/sap/fe/core/buildingBlocks/TraceInfo.ts +28 -26
  25. package/src/sap/fe/core/{BusyLocker.js → controllerextensions/BusyLocker.js} +1 -1
  26. package/src/sap/fe/core/{BusyLocker.ts → controllerextensions/BusyLocker.ts} +7 -7
  27. package/src/sap/fe/core/controllerextensions/EditFlow.js +351 -229
  28. package/src/sap/fe/core/controllerextensions/EditFlow.ts +321 -246
  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 +59 -34
  32. package/src/sap/fe/core/controllerextensions/InternalEditFlow.ts +71 -45
  33. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.js +72 -72
  34. package/src/sap/fe/core/controllerextensions/InternalIntentBasedNavigation.ts +82 -80
  35. package/src/sap/fe/core/controllerextensions/InternalRouting.js +152 -131
  36. package/src/sap/fe/core/controllerextensions/InternalRouting.ts +171 -152
  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 +11 -10
  40. package/src/sap/fe/core/controllerextensions/MassEdit.ts +31 -37
  41. package/src/sap/fe/core/controllerextensions/MessageHandler.js +21 -13
  42. package/src/sap/fe/core/controllerextensions/MessageHandler.ts +30 -15
  43. package/src/sap/fe/core/controllerextensions/PageReady.js +97 -25
  44. package/src/sap/fe/core/controllerextensions/PageReady.ts +94 -34
  45. package/src/sap/fe/core/controllerextensions/Paginator.js +19 -11
  46. package/src/sap/fe/core/controllerextensions/Paginator.ts +22 -14
  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 +39 -21
  52. package/src/sap/fe/core/controllerextensions/Share.ts +45 -26
  53. package/src/sap/fe/core/controllerextensions/SideEffects.js +47 -51
  54. package/src/sap/fe/core/controllerextensions/SideEffects.ts +58 -62
  55. package/src/sap/fe/core/controllerextensions/ViewState.js +75 -62
  56. package/src/sap/fe/core/controllerextensions/ViewState.ts +78 -63
  57. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.js +105 -0
  58. package/src/sap/fe/core/controllerextensions/collaboration/ActivityBase.ts +99 -0
  59. package/src/sap/fe/core/controllerextensions/collaboration/ActivitySync.js +360 -0
  60. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ActivitySync.ts +58 -112
  61. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.js +2 -2
  62. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/CollaborationCommon.ts +7 -7
  63. package/src/sap/fe/core/controllerextensions/collaboration/Manage.js +262 -0
  64. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/Manage.ts +20 -21
  65. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/ManageDialog.fragment.xml +0 -0
  66. package/src/sap/fe/core/{actions → controllerextensions}/collaboration/UserDetails.fragment.xml +5 -7
  67. package/src/sap/fe/core/controllerextensions/editFlow/TransactionHelper.js +1631 -0
  68. package/src/sap/fe/core/{TransactionHelper.ts → controllerextensions/editFlow/TransactionHelper.ts} +270 -211
  69. package/src/sap/fe/core/controllerextensions/editFlow/draft.js +772 -0
  70. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/draft.ts +240 -100
  71. package/src/sap/fe/core/controllerextensions/editFlow/operations.js +1199 -0
  72. package/src/sap/fe/core/{actions → controllerextensions/editFlow}/operations.ts +364 -229
  73. package/src/sap/fe/core/controllerextensions/editFlow/sticky.js +188 -0
  74. package/src/sap/fe/core/controllerextensions/editFlow/sticky.ts +185 -0
  75. package/src/sap/fe/core/controllerextensions/messageHandler/messageHandling.js +626 -0
  76. package/src/sap/fe/core/{actions → controllerextensions/messageHandler}/messageHandling.ts +112 -69
  77. package/src/sap/fe/core/controllerextensions/routing/RouterProxy.js +937 -0
  78. package/src/sap/fe/core/{RouterProxy.ts → controllerextensions/routing/RouterProxy.ts} +72 -73
  79. package/src/sap/fe/core/controls/ActionParameterDialog.fragment.xml +21 -18
  80. package/src/sap/fe/core/controls/Any.js +9 -5
  81. package/src/sap/fe/core/controls/Any.ts +10 -4
  82. package/src/sap/fe/core/controls/CommandExecution.js +21 -24
  83. package/src/sap/fe/core/controls/CommandExecution.ts +19 -24
  84. package/src/sap/fe/core/controls/ConditionalWrapper.js +2 -2
  85. package/src/sap/fe/core/controls/ConditionalWrapper.ts +3 -3
  86. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.js +48 -43
  87. package/src/sap/fe/core/controls/CustomFilterFieldContentWrapper.ts +51 -46
  88. package/src/sap/fe/core/controls/CustomQuickViewPage.js +3 -2
  89. package/src/sap/fe/core/controls/CustomQuickViewPage.ts +3 -2
  90. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossDraft.fragment.xml +11 -3
  91. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.js +19 -9
  92. package/src/sap/fe/core/controls/DataLossOrDraftDiscard/DataLossOrDraftDiscardHandler.ts +14 -8
  93. package/src/sap/fe/core/controls/FieldWrapper.js +2 -2
  94. package/src/sap/fe/core/controls/FieldWrapper.ts +3 -3
  95. package/src/sap/fe/core/controls/FileWrapper.js +50 -3
  96. package/src/sap/fe/core/controls/FileWrapper.ts +45 -12
  97. package/src/sap/fe/core/controls/FilterBar.js +6 -2
  98. package/src/sap/fe/core/controls/FilterBar.ts +13 -9
  99. package/src/sap/fe/core/controls/FormElementWrapper.js +12 -2
  100. package/src/sap/fe/core/controls/FormElementWrapper.ts +14 -3
  101. package/src/sap/fe/core/controls/MassEditSelect.js +33 -0
  102. package/src/sap/fe/core/controls/MassEditSelect.ts +41 -0
  103. package/src/sap/fe/core/controls/NonComputedVisibleKeyFieldsDialog.fragment.xml +3 -3
  104. package/src/sap/fe/core/controls/filterbar/VisualFilter.js +16 -12
  105. package/src/sap/fe/core/controls/filterbar/VisualFilter.ts +20 -22
  106. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.js +3 -3
  107. package/src/sap/fe/core/controls/filterbar/VisualFilterContainer.ts +8 -8
  108. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.js +48 -48
  109. package/src/sap/fe/core/controls/filterbar/utils/VisualFilterUtils.ts +71 -76
  110. package/src/sap/fe/core/controls/massEdit/MassEditDialog.fragment.xml +36 -65
  111. package/src/sap/fe/core/controls/massEdit/MassEditField.fragment.xml +107 -0
  112. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.js +551 -36
  113. package/src/sap/fe/core/controls/massEdit/MassEditHandlers.ts +605 -36
  114. package/src/sap/fe/core/converters/ConverterContext.js +26 -33
  115. package/src/sap/fe/core/converters/ConverterContext.ts +51 -60
  116. package/src/sap/fe/core/converters/ManifestSettings.js +2 -1
  117. package/src/sap/fe/core/converters/ManifestSettings.ts +17 -14
  118. package/src/sap/fe/core/converters/ManifestWrapper.js +59 -45
  119. package/src/sap/fe/core/converters/ManifestWrapper.ts +55 -45
  120. package/src/sap/fe/core/converters/MetaModelConverter.js +56 -67
  121. package/src/sap/fe/core/converters/MetaModelConverter.ts +183 -193
  122. package/src/sap/fe/core/converters/TemplateConverter.js +21 -20
  123. package/src/sap/fe/core/converters/TemplateConverter.ts +27 -24
  124. package/src/sap/fe/core/converters/annotations/DataField.js +73 -37
  125. package/src/sap/fe/core/converters/annotations/DataField.ts +121 -77
  126. package/src/sap/fe/core/converters/common/AnnotationConverter.js +1911 -1495
  127. package/src/sap/fe/core/converters/controls/Common/Action.js +51 -49
  128. package/src/sap/fe/core/converters/controls/Common/Action.ts +58 -54
  129. package/src/sap/fe/core/converters/controls/Common/Chart.js +22 -15
  130. package/src/sap/fe/core/converters/controls/Common/Chart.ts +29 -27
  131. package/src/sap/fe/core/converters/controls/Common/Criticality.js +3 -3
  132. package/src/sap/fe/core/converters/controls/Common/Criticality.ts +4 -4
  133. package/src/sap/fe/core/converters/controls/Common/DataVisualization.js +28 -28
  134. package/src/sap/fe/core/converters/controls/Common/DataVisualization.ts +40 -36
  135. package/src/sap/fe/core/converters/controls/Common/Form.js +30 -34
  136. package/src/sap/fe/core/converters/controls/Common/Form.ts +48 -58
  137. package/src/sap/fe/core/converters/controls/Common/KPI.js +11 -11
  138. package/src/sap/fe/core/converters/controls/Common/KPI.ts +35 -39
  139. package/src/sap/fe/core/converters/controls/Common/Table.js +318 -244
  140. package/src/sap/fe/core/converters/controls/Common/Table.ts +368 -297
  141. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.js +135 -125
  142. package/src/sap/fe/core/converters/controls/Common/table/StandardActions.ts +162 -148
  143. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +51 -45
  144. package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +79 -67
  145. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.js +28 -26
  146. package/src/sap/fe/core/converters/controls/ListReport/VisualFilters.ts +46 -43
  147. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.js +9 -9
  148. package/src/sap/fe/core/converters/controls/ObjectPage/Avatar.ts +14 -13
  149. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.js +67 -64
  150. package/src/sap/fe/core/converters/controls/ObjectPage/HeaderFacet.ts +69 -66
  151. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.js +92 -89
  152. package/src/sap/fe/core/converters/controls/ObjectPage/SubSection.ts +124 -120
  153. package/src/sap/fe/core/converters/helpers/Aggregation.js +11 -5
  154. package/src/sap/fe/core/converters/helpers/Aggregation.ts +25 -23
  155. package/src/sap/fe/core/converters/helpers/BindingHelper.js +31 -30
  156. package/src/sap/fe/core/converters/helpers/BindingHelper.ts +31 -29
  157. package/src/sap/fe/core/converters/helpers/ConfigurableObject.js +4 -4
  158. package/src/sap/fe/core/converters/helpers/ConfigurableObject.ts +9 -9
  159. package/src/sap/fe/core/converters/helpers/ID.js +46 -46
  160. package/src/sap/fe/core/converters/helpers/ID.ts +25 -25
  161. package/src/sap/fe/core/converters/helpers/Key.js +7 -7
  162. package/src/sap/fe/core/converters/helpers/Key.ts +7 -7
  163. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.js +1 -1
  164. package/src/sap/fe/core/converters/helpers/SelectionVariantHelper.ts +4 -4
  165. package/src/sap/fe/core/converters/objectPage/FormMenuActions.js +6 -6
  166. package/src/sap/fe/core/converters/objectPage/FormMenuActions.ts +10 -10
  167. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.js +46 -62
  168. package/src/sap/fe/core/converters/objectPage/HeaderAndFooterAction.ts +54 -82
  169. package/src/sap/fe/core/converters/templates/ListReportConverter.js +30 -29
  170. package/src/sap/fe/core/converters/templates/ListReportConverter.ts +40 -40
  171. package/src/sap/fe/core/converters/templates/ObjectPageConverter.js +56 -55
  172. package/src/sap/fe/core/converters/templates/ObjectPageConverter.ts +65 -77
  173. package/src/sap/fe/core/designtime/AppComponent.designtime.js +6 -6
  174. package/src/sap/fe/core/designtime/AppComponent.designtime.ts +10 -8
  175. package/src/sap/fe/core/formatters/CollaborationFormatter.js +2 -2
  176. package/src/sap/fe/core/formatters/CollaborationFormatter.ts +3 -3
  177. package/src/sap/fe/core/formatters/FPMFormatter.js +5 -5
  178. package/src/sap/fe/core/formatters/FPMFormatter.ts +10 -10
  179. package/src/sap/fe/core/formatters/KPIFormatter.js +7 -7
  180. package/src/sap/fe/core/formatters/KPIFormatter.ts +10 -10
  181. package/src/sap/fe/core/formatters/StandardFormatter.js +89 -0
  182. package/src/sap/fe/core/formatters/StandardFormatter.ts +64 -0
  183. package/src/sap/fe/core/formatters/TableFormatter.js +83 -22
  184. package/src/sap/fe/core/formatters/TableFormatter.ts +80 -25
  185. package/src/sap/fe/core/formatters/ValueFormatter.js +8 -8
  186. package/src/sap/fe/core/formatters/ValueFormatter.ts +9 -9
  187. package/src/sap/fe/core/fpm/Component.js +2 -2
  188. package/src/sap/fe/core/fpm/Component.ts +1 -1
  189. package/src/sap/fe/core/helpers/AppStartupHelper.js +15 -15
  190. package/src/sap/fe/core/helpers/AppStartupHelper.ts +37 -40
  191. package/src/sap/fe/core/helpers/BindingToolkit.js +1809 -0
  192. package/src/sap/fe/core/helpers/{BindingExpression.ts → BindingToolkit.ts} +388 -285
  193. package/src/sap/fe/core/helpers/ClassSupport.js +20 -11
  194. package/src/sap/fe/core/helpers/ClassSupport.ts +15 -10
  195. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.js +2 -2
  196. package/src/sap/fe/core/helpers/DynamicAnnotationPathHelper.ts +1 -1
  197. package/src/sap/fe/core/helpers/EditState.js +1 -6
  198. package/src/sap/fe/core/helpers/EditState.ts +5 -10
  199. package/src/sap/fe/core/helpers/ExcelFormatHelper.js +2 -2
  200. package/src/sap/fe/core/helpers/ExcelFormatHelper.ts +4 -4
  201. package/src/sap/fe/core/helpers/FPMHelper.js +3 -2
  202. package/src/sap/fe/core/helpers/FPMHelper.ts +10 -9
  203. package/src/sap/fe/core/helpers/KeepAliveHelper.js +31 -31
  204. package/src/sap/fe/core/helpers/KeepAliveHelper.ts +52 -56
  205. package/src/sap/fe/core/helpers/MassEditHelper.js +532 -264
  206. package/src/sap/fe/core/helpers/MassEditHelper.ts +560 -289
  207. package/src/sap/fe/core/helpers/ModelHelper.js +25 -25
  208. package/src/sap/fe/core/helpers/ModelHelper.ts +50 -58
  209. package/src/sap/fe/core/helpers/PasteHelper.js +3 -10
  210. package/src/sap/fe/core/helpers/PasteHelper.ts +20 -25
  211. package/src/sap/fe/core/helpers/SemanticDateOperators.js +1 -1
  212. package/src/sap/fe/core/helpers/SemanticDateOperators.ts +11 -11
  213. package/src/sap/fe/core/helpers/SemanticKeyHelper.js +3 -3
  214. package/src/sap/fe/core/helpers/SemanticKeyHelper.ts +8 -8
  215. package/src/sap/fe/core/helpers/StableIdHelper.js +16 -12
  216. package/src/sap/fe/core/helpers/StableIdHelper.ts +20 -16
  217. package/src/sap/fe/core/{Synchronization.js → helpers/Synchronization.js} +1 -1
  218. package/src/sap/fe/core/{Synchronization.ts → helpers/Synchronization.ts} +1 -1
  219. package/src/sap/fe/core/jsx-runtime/jsx.js +1 -1
  220. package/src/sap/fe/core/jsx-runtime/jsx.ts +8 -8
  221. package/src/sap/fe/core/library.js +51 -3
  222. package/src/sap/fe/core/library.ts +47 -0
  223. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.js +3 -3
  224. package/src/sap/fe/core/manifestMerger/ChangePageConfiguration.ts +2 -2
  225. package/src/sap/fe/core/messagebundle.properties +151 -197
  226. package/src/sap/fe/core/messagebundle_ar.properties +36 -63
  227. package/src/sap/fe/core/messagebundle_bg.properties +36 -63
  228. package/src/sap/fe/core/messagebundle_ca.properties +36 -63
  229. package/src/sap/fe/core/messagebundle_cs.properties +36 -63
  230. package/src/sap/fe/core/messagebundle_cy.properties +36 -63
  231. package/src/sap/fe/core/messagebundle_da.properties +37 -64
  232. package/src/sap/fe/core/messagebundle_de.properties +36 -63
  233. package/src/sap/fe/core/messagebundle_el.properties +38 -65
  234. package/src/sap/fe/core/messagebundle_en.properties +37 -64
  235. package/src/sap/fe/core/messagebundle_en_GB.properties +37 -64
  236. package/src/sap/fe/core/messagebundle_en_US_sappsd.properties +44 -73
  237. package/src/sap/fe/core/messagebundle_en_US_saprigi.properties +37 -64
  238. package/src/sap/fe/core/messagebundle_en_US_saptrc.properties +52 -81
  239. package/src/sap/fe/core/messagebundle_es.properties +36 -63
  240. package/src/sap/fe/core/messagebundle_es_MX.properties +36 -63
  241. package/src/sap/fe/core/messagebundle_et.properties +36 -63
  242. package/src/sap/fe/core/messagebundle_fi.properties +36 -63
  243. package/src/sap/fe/core/messagebundle_fr.properties +39 -66
  244. package/src/sap/fe/core/messagebundle_fr_CA.properties +36 -63
  245. package/src/sap/fe/core/messagebundle_hi.properties +36 -63
  246. package/src/sap/fe/core/messagebundle_hr.properties +36 -63
  247. package/src/sap/fe/core/messagebundle_hu.properties +35 -62
  248. package/src/sap/fe/core/messagebundle_id.properties +37 -64
  249. package/src/sap/fe/core/messagebundle_it.properties +54 -81
  250. package/src/sap/fe/core/messagebundle_iw.properties +36 -63
  251. package/src/sap/fe/core/messagebundle_ja.properties +36 -63
  252. package/src/sap/fe/core/messagebundle_kk.properties +36 -63
  253. package/src/sap/fe/core/messagebundle_ko.properties +36 -63
  254. package/src/sap/fe/core/messagebundle_lt.properties +36 -63
  255. package/src/sap/fe/core/messagebundle_lv.properties +36 -63
  256. package/src/sap/fe/core/messagebundle_ms.properties +37 -64
  257. package/src/sap/fe/core/messagebundle_nl.properties +37 -64
  258. package/src/sap/fe/core/messagebundle_no.properties +36 -63
  259. package/src/sap/fe/core/messagebundle_pl.properties +37 -64
  260. package/src/sap/fe/core/messagebundle_pt.properties +37 -64
  261. package/src/sap/fe/core/messagebundle_pt_PT.properties +36 -63
  262. package/src/sap/fe/core/messagebundle_ro.properties +36 -63
  263. package/src/sap/fe/core/messagebundle_ru.properties +36 -63
  264. package/src/sap/fe/core/messagebundle_sh.properties +36 -63
  265. package/src/sap/fe/core/messagebundle_sk.properties +36 -63
  266. package/src/sap/fe/core/messagebundle_sl.properties +38 -65
  267. package/src/sap/fe/core/messagebundle_sv.properties +36 -63
  268. package/src/sap/fe/core/messagebundle_th.properties +36 -63
  269. package/src/sap/fe/core/messagebundle_tr.properties +36 -63
  270. package/src/sap/fe/core/messagebundle_uk.properties +37 -64
  271. package/src/sap/fe/core/messagebundle_vi.properties +37 -64
  272. package/src/sap/fe/core/messagebundle_zh_CN.properties +36 -63
  273. package/src/sap/fe/core/messagebundle_zh_TW.properties +37 -64
  274. package/src/sap/fe/core/services/AsyncComponentServiceFactory.js +2 -2
  275. package/src/sap/fe/core/services/AsyncComponentServiceFactory.ts +5 -5
  276. package/src/sap/fe/core/services/CacheHandlerServiceFactory.js +2 -2
  277. package/src/sap/fe/core/services/CacheHandlerServiceFactory.ts +14 -14
  278. package/src/sap/fe/core/services/EnvironmentServiceFactory.js +6 -3
  279. package/src/sap/fe/core/services/EnvironmentServiceFactory.ts +12 -10
  280. package/src/sap/fe/core/services/NavigationServiceFactory.js +54 -45
  281. package/src/sap/fe/core/services/NavigationServiceFactory.ts +61 -49
  282. package/src/sap/fe/core/services/ResourceModelServiceFactory.js +2 -2
  283. package/src/sap/fe/core/services/ResourceModelServiceFactory.ts +4 -4
  284. package/src/sap/fe/core/services/RoutingServiceFactory.js +63 -60
  285. package/src/sap/fe/core/services/RoutingServiceFactory.ts +76 -73
  286. package/src/sap/fe/core/services/ShellServicesFactory.js +102 -71
  287. package/src/sap/fe/core/services/ShellServicesFactory.ts +109 -78
  288. package/src/sap/fe/core/services/SideEffectsServiceFactory.js +61 -61
  289. package/src/sap/fe/core/services/SideEffectsServiceFactory.ts +102 -92
  290. package/src/sap/fe/core/services/TemplatedViewServiceFactory.js +24 -18
  291. package/src/sap/fe/core/services/TemplatedViewServiceFactory.ts +53 -50
  292. package/src/sap/fe/core/support/CommonHelper.js +3 -2
  293. package/src/sap/fe/core/support/CommonHelper.ts +9 -13
  294. package/src/sap/fe/core/support/Diagnostics.js +1 -1
  295. package/src/sap/fe/core/support/Diagnostics.ts +5 -5
  296. package/src/sap/fe/core/templating/CommonFormatters.js +84 -0
  297. package/src/sap/fe/core/templating/CommonFormatters.ts +86 -0
  298. package/src/sap/fe/core/templating/CriticalityFormatters.js +31 -31
  299. package/src/sap/fe/core/templating/CriticalityFormatters.ts +42 -40
  300. package/src/sap/fe/core/templating/DataFieldFormatters.js +8 -8
  301. package/src/sap/fe/core/templating/DataFieldFormatters.ts +13 -10
  302. package/src/sap/fe/core/templating/DataModelPathHelper.js +16 -15
  303. package/src/sap/fe/core/templating/DataModelPathHelper.ts +42 -32
  304. package/src/sap/fe/core/templating/DisplayModeFormatter.js +1 -1
  305. package/src/sap/fe/core/templating/DisplayModeFormatter.ts +3 -4
  306. package/src/sap/fe/core/templating/EntitySetHelper.js +7 -15
  307. package/src/sap/fe/core/templating/EntitySetHelper.ts +14 -18
  308. package/src/sap/fe/core/templating/FieldControlHelper.js +35 -34
  309. package/src/sap/fe/core/templating/FieldControlHelper.ts +29 -46
  310. package/src/sap/fe/core/templating/FilterHelper.js +12 -11
  311. package/src/sap/fe/core/templating/FilterHelper.ts +17 -16
  312. package/src/sap/fe/core/templating/FilterTemplating.js +1 -1
  313. package/src/sap/fe/core/templating/FilterTemplating.ts +3 -3
  314. package/src/sap/fe/core/templating/PropertyFormatters.js +7 -7
  315. package/src/sap/fe/core/templating/PropertyFormatters.ts +21 -19
  316. package/src/sap/fe/core/templating/PropertyHelper.js +79 -56
  317. package/src/sap/fe/core/templating/PropertyHelper.ts +41 -27
  318. package/src/sap/fe/core/templating/UIFormatters.js +163 -97
  319. package/src/sap/fe/core/templating/UIFormatters.ts +210 -129
  320. package/src/sap/fe/core/type/DateTimeWithTimezone.js +47 -0
  321. package/src/sap/fe/core/type/DateTimeWithTimezone.ts +23 -0
  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/AnnotationHelper.js +0 -331
  325. package/src/sap/fe/core/AnnotationHelper.ts +0 -321
  326. package/src/sap/fe/core/RouterProxy.js +0 -938
  327. package/src/sap/fe/core/TransactionHelper.js +0 -1577
  328. package/src/sap/fe/core/actions/collaboration/ActivitySync.js +0 -406
  329. package/src/sap/fe/core/actions/collaboration/Manage.js +0 -264
  330. package/src/sap/fe/core/actions/draft.js +0 -665
  331. package/src/sap/fe/core/actions/messageHandling.js +0 -579
  332. package/src/sap/fe/core/actions/nonDraft.js +0 -20
  333. package/src/sap/fe/core/actions/nonDraft.ts +0 -12
  334. package/src/sap/fe/core/actions/operations.js +0 -1096
  335. package/src/sap/fe/core/actions/sticky.js +0 -130
  336. package/src/sap/fe/core/actions/sticky.ts +0 -119
  337. package/src/sap/fe/core/formatters/CriticalityFormatter.js +0 -77
  338. package/src/sap/fe/core/formatters/CriticalityFormatter.ts +0 -58
  339. package/src/sap/fe/core/helpers/BindingExpression.js +0 -1729
@@ -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 { ApplyAnnotationExpression, PathAnnotationExpression } from "@sap-ux/vocabularies-types/types/Edm";
28
- import { EntitySet } from "@sap-ux/vocabularies-types/dist/Converter";
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,17 +179,18 @@ function escapeXmlAttribute(inputString: string) {
184
179
  return inputString.replace(/'/g, "\\'");
185
180
  }
186
181
 
187
- export function hasUnresolveableExpression(...expressions: Expression<any>[]): boolean {
188
- return expressions.find(expr => expr._type === "Unresolvable") !== undefined;
182
+ export function hasUnresolveableExpression(...expressions: BindingToolkitExpression<any>[]): boolean {
183
+ return expressions.find((expr) => expr._type === "Unresolvable") !== undefined;
189
184
  }
190
185
  /**
191
186
  * Check two expressions for (deep) equality.
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
  }
@@ -215,8 +211,8 @@ export function _checkExpressionsAreEqual<T>(a: Expression<T>, b: Expression<T>)
215
211
  return (
216
212
  a.operator === (b as SetExpression).operator &&
217
213
  a.operands.length === (b as SetExpression).operands.length &&
218
- a.operands.every(expression =>
219
- (b as SetExpression).operands.some(otherExpression => _checkExpressionsAreEqual(expression, otherExpression))
214
+ a.operands.every((expression) =>
215
+ (b as SetExpression).operands.some((otherExpression) => _checkExpressionsAreEqual(expression, otherExpression))
220
216
  )
221
217
  );
222
218
 
@@ -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,15 +287,15 @@ 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(
304
294
  (result: SetExpression, operand) => {
305
295
  const candidatesForFlattening =
306
296
  operand._type === "Set" && operand.operator === expression.operator ? operand.operands : [operand];
307
- candidatesForFlattening.forEach(candidate => {
308
- if (result.operands.every(e => !_checkExpressionsAreEqual(e, candidate))) {
297
+ candidatesForFlattening.forEach((candidate) => {
298
+ if (result.operands.every((e) => !_checkExpressionsAreEqual(e, candidate))) {
309
299
  result.operands.push(candidate);
310
300
  }
311
301
  });
@@ -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: "&&",
@@ -353,7 +343,7 @@ export function and(...operands: ExpressionOrPrimitive<boolean>[]): Expression<b
353
343
  return unresolveableExpression;
354
344
  }
355
345
  let isStaticFalse = false;
356
- const nonTrivialExpression = expressions.filter(expression => {
346
+ const nonTrivialExpression = expressions.filter((expression) => {
357
347
  if (isFalse(expression)) {
358
348
  isStaticFalse = true;
359
349
  }
@@ -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: "||",
@@ -397,7 +387,7 @@ export function or(...operands: ExpressionOrPrimitive<boolean>[]): Expression<bo
397
387
  return unresolveableExpression;
398
388
  }
399
389
  let isStaticTrue = false;
400
- const nonTrivialExpression = expressions.filter(expression => {
390
+ const nonTrivialExpression = expressions.filter((expression) => {
401
391
  if (isTrue(expression)) {
402
392
  isStaticTrue = true;
403
393
  }
@@ -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;
@@ -438,16 +428,16 @@ export function not(operand: ExpressionOrPrimitive<boolean>): Expression<boolean
438
428
  typeof operand === "object" &&
439
429
  operand._type === "Set" &&
440
430
  operand.operator === "||" &&
441
- operand.operands.every(expression => isConstant(expression) || isComparison(expression))
431
+ operand.operands.every((expression) => isConstant(expression) || isComparison(expression))
442
432
  ) {
443
- return and(...operand.operands.map(expression => not(expression)));
433
+ return and(...operand.operands.map((expression) => not(expression)));
444
434
  } else if (
445
435
  typeof operand === "object" &&
446
436
  operand._type === "Set" &&
447
437
  operand.operator === "&&" &&
448
- operand.operands.every(expression => isConstant(expression) || isComparison(expression))
438
+ operand.operands.every((expression) => isConstant(expression) || isComparison(expression))
449
439
  ) {
450
- return or(...operand.operands.map(expression => not(expression)));
440
+ return or(...operand.operands.map((expression) => not(expression)));
451
441
  } else if (isComparison(operand)) {
452
442
  // Create the reverse comparison
453
443
  switch (operand.operator) {
@@ -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
- ...(((annotationValue as OrConditionalExpression).$Or.map(function(orCondition) {
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
- ...(((annotationValue as AndConditionalExpression).$And.map(function(andCondition) {
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
884
  parseAnnotationCondition((annotationValue as NotConditionalExpression).$Not[0], visitedNavigationPaths, pathVisitor)
819
- ) as Expression<T>;
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,22 +1236,22 @@ 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>;
1189
1255
  }
1190
1256
 
1191
1257
  return {
@@ -1200,9 +1266,9 @@ export function ifElse<T extends PrimitiveType>(
1200
1266
  * Checks whether the current expression has a reference to the default model (undefined).
1201
1267
  *
1202
1268
  * @param expression The expression to evaluate
1203
- * @returns {boolean} `true` if there is a reference to the default context
1269
+ * @returns `true` if there is a reference to the default context
1204
1270
  */
1205
- function hasReferenceToDefaultContext(expression: Expression<any>): boolean {
1271
+ function hasReferenceToDefaultContext(expression: BindingToolkitExpression<any>): boolean {
1206
1272
  switch (expression._type) {
1207
1273
  case "Constant":
1208
1274
  case "Formatter":
@@ -1210,12 +1276,10 @@ function hasReferenceToDefaultContext(expression: Expression<any>): boolean {
1210
1276
  return false;
1211
1277
  case "Set":
1212
1278
  return expression.operands.some(hasReferenceToDefaultContext);
1213
- case "Binding":
1279
+ case "PathInModel":
1214
1280
  return expression.modelName === undefined;
1215
1281
  case "Comparison":
1216
1282
  return hasReferenceToDefaultContext(expression.operand1) || hasReferenceToDefaultContext(expression.operand2);
1217
- case "DefaultBinding":
1218
- return true;
1219
1283
  case "IfElse":
1220
1284
  return (
1221
1285
  hasReferenceToDefaultContext(expression.condition) ||
@@ -1262,27 +1326,32 @@ type FunctionParameters<T, F extends FunctionOrName<T>> = F extends Fn<T> ? Para
1262
1326
  * @param parameters The list of parameter that should match the type and number of the formatter function
1263
1327
  * @param formatterFunction The function to call
1264
1328
  * @param [contextEntityType] The context entity type to consider
1265
- * @returns {Expression<T>} The corresponding expression
1329
+ * @returns The corresponding expression
1266
1330
  */
1267
1331
  export function formatResult<T, U extends Fn<T>>(
1268
1332
  parameters: WrappedTuple<Parameters<U>>,
1269
- formatterFunction: U,
1333
+ formatterFunction: U | string,
1270
1334
  contextEntityType?: EntityType
1271
- ): Expression<T> {
1335
+ ): BindingToolkitExpression<T> {
1272
1336
  const parameterExpressions = (parameters as any[]).map(wrapPrimitive);
1273
1337
 
1274
1338
  if (hasUnresolveableExpression(...parameterExpressions)) {
1275
1339
  return unresolveableExpression;
1276
1340
  }
1277
- if (!!contextEntityType) {
1341
+ if (contextEntityType) {
1278
1342
  // Otherwise, if the context is required and no context is provided make sure to add the default binding
1279
1343
  if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1280
- contextEntityType.keys.forEach(key => parameterExpressions.push(bindingExpression(key.name, "")));
1344
+ contextEntityType.keys.forEach((key) => parameterExpressions.push(pathInModel(key.name, "")));
1281
1345
  }
1282
1346
  }
1283
-
1347
+ let functionName = "";
1348
+ if (typeof formatterFunction === "string") {
1349
+ functionName = formatterFunction;
1350
+ } else {
1351
+ functionName = formatterFunction.__functionName;
1352
+ }
1284
1353
  // FormatterName can be of format sap.fe.core.xxx#methodName to have multiple formatter in one class
1285
- const [formatterClass, formatterName] = formatterFunction.__functionName.split("#");
1354
+ const [formatterClass, formatterName] = functionName.split("#");
1286
1355
 
1287
1356
  if (!!formatterName && formatterName.length > 0) {
1288
1357
  parameterExpressions.unshift(constant(formatterName));
@@ -1301,16 +1370,18 @@ export function formatResult<T, U extends Fn<T>>(
1301
1370
  *
1302
1371
  * @template T
1303
1372
  * @template U
1304
- * @param parameters The list of parameter that should match the type for the compplex type
1373
+ * @param parameters The list of parameter that should match the type for the compplex type=
1305
1374
  * @param type The complex type to use
1306
1375
  * @param [contextEntityType] The context entity type to consider
1307
- * @returns {Expression<T>} The corresponding expression
1376
+ * @param oFormatOptions
1377
+ * @returns The corresponding expression
1308
1378
  */
1309
1379
  export function addTypeInformation<T, U extends Fn<T>>(
1310
1380
  parameters: WrappedTuple<Parameters<U>>,
1311
1381
  type: string,
1312
- contextEntityType?: EntityType
1313
- ): Expression<T> {
1382
+ contextEntityType?: EntityType,
1383
+ oFormatOptions?: any
1384
+ ): UnresolveablePathExpression | ComplexTypeExpression<T> | ConstantExpression<T> {
1314
1385
  const parameterExpressions = (parameters as any[]).map(wrapPrimitive);
1315
1386
  if (hasUnresolveableExpression(...parameterExpressions)) {
1316
1387
  return unresolveableExpression;
@@ -1318,19 +1389,42 @@ export function addTypeInformation<T, U extends Fn<T>>(
1318
1389
  // If there is only one parameter and it is a constant and we don't expect the context then return the constant
1319
1390
  if (parameterExpressions.length === 1 && isConstant(parameterExpressions[0]) && !contextEntityType) {
1320
1391
  return parameterExpressions[0];
1321
- } else if (!!contextEntityType) {
1392
+ } else if (contextEntityType) {
1322
1393
  // Otherwise, if the context is required and no context is provided make sure to add the default binding
1323
1394
  if (!parameterExpressions.some(hasReferenceToDefaultContext)) {
1324
- contextEntityType.keys.forEach(key => parameterExpressions.push(bindingExpression(key.name, "")));
1395
+ contextEntityType.keys.forEach((key) => parameterExpressions.push(pathInModel(key.name, "")));
1396
+ }
1397
+ }
1398
+ // if showMeasure is set to false we want to not parse as string to see the 0
1399
+ if (
1400
+ oFormatOptions?.showMeasure === false &&
1401
+ ((parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Int") === 0 ||
1402
+ (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Decimal") === 0 ||
1403
+ (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Double") === 0)
1404
+ ) {
1405
+ if ((parameters[0] as any)?.type === "sap.ui.model.odata.type.Int64") {
1406
+ //sap.ui.model.odata.type.Int64 do not support parseAsString false
1407
+ oFormatOptions = { emptyString: "", showMeasure: false };
1408
+ } else {
1409
+ oFormatOptions = { parseAsString: false, emptyString: "", showMeasure: false };
1325
1410
  }
1326
1411
  }
1412
+ if (type === "sap.ui.model.odata.type.Unit") {
1413
+ const uomPath = pathInModel("/##@@requestUnitsOfMeasure");
1414
+ uomPath.targetType = "any";
1415
+ uomPath.mode = "OneTime";
1416
+ parameterExpressions.push(uomPath);
1417
+ } else if (type === "sap.ui.model.odata.type.Currency") {
1418
+ const currencyPath = pathInModel("/##@@requestCurrencyCodes");
1419
+ currencyPath.targetType = "any";
1420
+ currencyPath.mode = "OneTime";
1421
+ parameterExpressions.push(currencyPath);
1422
+ }
1327
1423
 
1328
- const oFormatOptions =
1329
- (parameters[0] as any)?.type?.indexOf("sap.ui.model.odata.type.Int") === 0 ? { parseAsString: false, emptyString: "" } : {};
1330
1424
  return {
1331
1425
  _type: "ComplexType",
1332
1426
  type: type,
1333
- formatOptions: oFormatOptions,
1427
+ formatOptions: oFormatOptions || {},
1334
1428
  parameters: {},
1335
1429
  bindingParameters: parameterExpressions
1336
1430
  };
@@ -1341,14 +1435,14 @@ export function addTypeInformation<T, U extends Fn<T>>(
1341
1435
  * @param func Function name or reference to function
1342
1436
  * @param parameters Arguments
1343
1437
  * @param on Object to call the function on
1344
- * @returns {FunctionExpression<T>} Expression representing the function call (not the result of the function call!)
1438
+ * @returns Expression representing the function call (not the result of the function call!)
1345
1439
  */
1346
1440
  export function fn<T, U extends FunctionOrName<T>>(
1347
1441
  func: U,
1348
1442
  parameters: WrappedTuple<FunctionParameters<T, U>>,
1349
1443
  on?: ExpressionOrPrimitive<object>
1350
1444
  ): FunctionExpression<T> {
1351
- const functionName = typeof func === "string" ? func : (func as Fn<T>).__functionName;
1445
+ const functionName = typeof func === "string" ? func : func.__functionName;
1352
1446
  return {
1353
1447
  _type: "Function",
1354
1448
  obj: on !== undefined ? wrapPrimitive(on) : undefined,
@@ -1363,14 +1457,14 @@ export function fn<T, U extends FunctionOrName<T>>(
1363
1457
  * @param expression
1364
1458
  * @returns A boolean expression evaluating the fact that the current element is empty
1365
1459
  */
1366
- export function isEmpty(expression: Expression<string>): Expression<boolean> {
1460
+ export function isEmpty(expression: BindingToolkitExpression<string>): BindingToolkitExpression<boolean> {
1367
1461
  if (expression._type === "Concat") {
1368
1462
  return or(...expression.expressions.map(isEmpty));
1369
1463
  }
1370
1464
  return or(equal(expression, ""), equal(expression, undefined), equal(expression, null));
1371
1465
  }
1372
1466
 
1373
- export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expression<string> {
1467
+ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): BindingToolkitExpression<string> {
1374
1468
  const expressions = inExpressions.map(wrapPrimitive);
1375
1469
  if (hasUnresolveableExpression(...expressions)) {
1376
1470
  return unresolveableExpression;
@@ -1381,6 +1475,16 @@ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expre
1381
1475
  return concatenated + (value as ConstantExpression<any>).value.toString();
1382
1476
  }, "")
1383
1477
  );
1478
+ } else if (expressions.some(isComplexTypeExpression)) {
1479
+ let pathIdx = 0;
1480
+ const myConcatExpression = formatResult(expressions, "sap.fe.core.formatters.StandardFormatter#concat");
1481
+ const allParts = [];
1482
+ transformRecursively(myConcatExpression, "PathInModel", (constantPath: PathInModelExpression<any>) => {
1483
+ allParts.push(constantPath);
1484
+ return constant(`\$${pathIdx++}`) as ConstantExpression<any>;
1485
+ });
1486
+ allParts.unshift(constant(JSON.stringify(myConcatExpression)));
1487
+ return formatResult(allParts, "sap.fe.core.formatters.StandardFormatter#evaluateComplexExpression");
1384
1488
  }
1385
1489
  return {
1386
1490
  _type: "Concat",
@@ -1388,29 +1492,29 @@ export function concat(...inExpressions: ExpressionOrPrimitive<string>[]): Expre
1388
1492
  };
1389
1493
  }
1390
1494
 
1391
- export type TransformFunction = <T extends PrimitiveType | unknown>(expressionPart: any) => Expression<T>;
1392
- export type ExpressionType = Pick<Expression<any>, "_type">["_type"];
1495
+ export type TransformFunction = <T extends PrimitiveType | unknown>(expressionPart: any) => BindingToolkitExpression<T>;
1496
+ export type ExpressionType = Pick<BindingToolkitExpression<any>, "_type">["_type"];
1393
1497
  export function transformRecursively<T extends PrimitiveType | unknown>(
1394
- inExpression: Expression<T>,
1498
+ inExpression: BindingToolkitExpression<T>,
1395
1499
  expressionType: ExpressionType,
1396
1500
  transformFunction: TransformFunction,
1397
1501
  includeAllExpression = false
1398
- ): Expression<T> {
1502
+ ): BindingToolkitExpression<T> {
1399
1503
  let expression = inExpression;
1400
1504
  switch (expression._type) {
1401
1505
  case "Function":
1402
1506
  case "Formatter":
1403
- expression.parameters = expression.parameters.map(parameter =>
1507
+ expression.parameters = expression.parameters.map((parameter) =>
1404
1508
  transformRecursively(parameter, expressionType, transformFunction, includeAllExpression)
1405
1509
  );
1406
1510
  break;
1407
1511
  case "Concat":
1408
- expression.expressions = expression.expressions.map(subExpression =>
1512
+ expression.expressions = expression.expressions.map((subExpression) =>
1409
1513
  transformRecursively(subExpression, expressionType, transformFunction, includeAllExpression)
1410
1514
  );
1411
1515
  break;
1412
1516
  case "ComplexType":
1413
- expression.bindingParameters = expression.bindingParameters.map(bindingParameter =>
1517
+ expression.bindingParameters = expression.bindingParameters.map((bindingParameter) =>
1414
1518
  transformRecursively(bindingParameter, expressionType, transformFunction, includeAllExpression)
1415
1519
  );
1416
1520
  break;
@@ -1421,19 +1525,19 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1421
1525
  if (includeAllExpression) {
1422
1526
  condition = transformRecursively(expression.condition, expressionType, transformFunction, includeAllExpression);
1423
1527
  }
1424
- expression = ifElse(condition, onTrue, onFalse) as Expression<T>;
1528
+ expression = ifElse(condition, onTrue, onFalse) as BindingToolkitExpression<T>;
1425
1529
  break;
1426
1530
  case "Not":
1427
1531
  if (includeAllExpression) {
1428
1532
  const operand = transformRecursively(expression.operand, expressionType, transformFunction, includeAllExpression);
1429
- expression = not(operand) as Expression<T>;
1533
+ expression = not(operand) as BindingToolkitExpression<T>;
1430
1534
  }
1431
1535
  break;
1432
1536
  case "Truthy":
1433
1537
  break;
1434
1538
  case "Set":
1435
1539
  if (includeAllExpression) {
1436
- expression.operands = expression.operands.map(operand =>
1540
+ expression.operands = expression.operands.map((operand) =>
1437
1541
  transformRecursively(operand, expressionType, transformFunction, includeAllExpression)
1438
1542
  );
1439
1543
  }
@@ -1442,14 +1546,16 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1442
1546
  if (includeAllExpression) {
1443
1547
  const operand1 = transformRecursively(expression.operand1, expressionType, transformFunction, includeAllExpression);
1444
1548
  const operand2 = transformRecursively(expression.operand2, expressionType, transformFunction, includeAllExpression);
1445
- expression = comparison(expression.operator, operand1, operand2) as Expression<T>;
1549
+ expression = comparison(expression.operator, operand1, operand2) as BindingToolkitExpression<T>;
1446
1550
  }
1447
1551
  break;
1448
- case "DefaultBinding":
1449
1552
  case "Ref":
1450
1553
  case "Length":
1451
- case "Binding":
1554
+ case "PathInModel":
1452
1555
  case "Constant":
1556
+ case "EmbeddedBinding":
1557
+ case "EmbeddedExpressionBinding":
1558
+ case "Unresolvable":
1453
1559
  // Do nothing
1454
1560
  break;
1455
1561
  }
@@ -1459,28 +1565,31 @@ export function transformRecursively<T extends PrimitiveType | unknown>(
1459
1565
  return expression;
1460
1566
  }
1461
1567
 
1462
- export type BindingExpression<T> = T | string | undefined;
1568
+ export type CompiledBindingToolkitExpression = string | undefined;
1463
1569
 
1464
- const needParenthesis = function<T extends PrimitiveType>(expr: ExpressionOrPrimitive<T>): boolean {
1465
- return !isConstant(expr) && !isBinding(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function";
1570
+ const needParenthesis = function <T extends PrimitiveType>(expr: ExpressionOrPrimitive<T>): boolean {
1571
+ return (
1572
+ !isConstant(expr) && !isPathInModelExpression(expr) && isExpression(expr) && expr._type !== "IfElse" && expr._type !== "Function"
1573
+ );
1466
1574
  };
1467
1575
 
1468
1576
  /**
1469
1577
  * Compiles a constant object to a string.
1578
+ *
1470
1579
  * @param expr
1471
1580
  * @param isNullable
1472
- * @returns {string} The compiled string
1581
+ * @returns The compiled string
1473
1582
  */
1474
- function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable = false) {
1583
+ function compileConstantObject(expr: ConstantExpression<object>, isNullable = false) {
1475
1584
  if (isNullable && Object.keys(expr.value).length === 0) {
1476
1585
  return "";
1477
1586
  }
1478
1587
  // Objects
1479
1588
  const o = expr.value as PlainExpressionObject;
1480
1589
  const properties: string[] = [];
1481
- Object.keys(o).forEach(key => {
1590
+ Object.keys(o).forEach((key) => {
1482
1591
  const value = o[key];
1483
- const childResult = compileBinding(value, true, false, true);
1592
+ const childResult = compileExpression(value, true, false, true);
1484
1593
  if (childResult && childResult.length > 0) {
1485
1594
  properties.push(`${key}: ${childResult}`);
1486
1595
  }
@@ -1490,10 +1599,11 @@ function compileConstantObject<T>(expr: ConstantExpression<object>, isNullable =
1490
1599
 
1491
1600
  /**
1492
1601
  * Compiles a Constant Binding Expression.
1602
+ *
1493
1603
  * @param expr
1494
1604
  * @param embeddedInBinding
1495
1605
  * @param isNullable
1496
- * @returns {string} The compiled string
1606
+ * @returns The compiled string
1497
1607
  */
1498
1608
  function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, embeddedInBinding: boolean, isNullable = false) {
1499
1609
  if (expr.value === null) {
@@ -1504,7 +1614,7 @@ function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, e
1504
1614
  }
1505
1615
  if (typeof expr.value === "object") {
1506
1616
  if (Array.isArray(expr.value)) {
1507
- const entries = expr.value.map(expression => compileBinding(expression, true));
1617
+ const entries = expr.value.map((expression) => compileExpression(expression, true));
1508
1618
  return `[${entries.join(", ")}]`;
1509
1619
  } else {
1510
1620
  return compileConstantObject(expr as ConstantExpression<object>, isNullable);
@@ -1533,10 +1643,10 @@ function compileConstant<T extends PrimitiveType>(expr: ConstantExpression<T>, e
1533
1643
  * @param expressionForBinding The expression to compile
1534
1644
  * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1535
1645
  * @param embeddedSeparator The binding value evaluator ($ or % depending on whether we want to force the type or not)
1536
- * @returns {BindingExpression<T>} The corresponding expression binding
1646
+ * @returns The corresponding expression binding
1537
1647
  */
1538
- function compileBindingForBinding<T extends PrimitiveType>(
1539
- expressionForBinding: BindingExpressionExpression<T> | DefaultBindingExpressionExpression<T>,
1648
+ function compilePathInModelExpression<T extends PrimitiveType>(
1649
+ expressionForBinding: PathInModelExpression<T>,
1540
1650
  embeddedInBinding: boolean,
1541
1651
  embeddedSeparator: string
1542
1652
  ) {
@@ -1549,22 +1659,22 @@ function compileBindingForBinding<T extends PrimitiveType>(
1549
1659
  ) {
1550
1660
  // This is now a complex binding definition, let's prepare for it
1551
1661
  const complexBindingDefinition = {
1552
- path: compileBindingPath(expressionForBinding),
1662
+ path: compilePathInModel(expressionForBinding),
1553
1663
  type: expressionForBinding.type,
1554
1664
  targetType: expressionForBinding.targetType,
1555
1665
  parameters: expressionForBinding.parameters,
1556
1666
  formatOptions: expressionForBinding.formatOptions,
1557
1667
  constraints: expressionForBinding.constraints
1558
1668
  };
1559
- let outBinding = compileBinding(complexBindingDefinition);
1669
+ let outBinding = compileExpression(complexBindingDefinition);
1560
1670
  if (embeddedInBinding) {
1561
- outBinding = `${embeddedSeparator}` + outBinding;
1671
+ outBinding = `${embeddedSeparator}${outBinding}`;
1562
1672
  }
1563
1673
  return outBinding;
1564
1674
  } else if (embeddedInBinding) {
1565
- return `${embeddedSeparator}{${compileBindingPath(expressionForBinding)}}`;
1675
+ return `${embeddedSeparator}{${compilePathInModel(expressionForBinding)}}`;
1566
1676
  } else {
1567
- return `{${compileBindingPath(expressionForBinding)}}`;
1677
+ return `{${compilePathInModel(expressionForBinding)}}`;
1568
1678
  }
1569
1679
  }
1570
1680
 
@@ -1573,23 +1683,12 @@ function compileComplexTypeExpression<T extends PrimitiveType>(expression: Compl
1573
1683
  return `{${compilePathParameter(expression.bindingParameters[0], true)}, type: '${expression.type}'}`;
1574
1684
  }
1575
1685
 
1576
- let outputEnd;
1577
- // this code is based on sap.ui.model.odata.v4._AnnotationHelperExpression.fetchCurrencyOrUnit
1578
- switch (expression.type) {
1579
- case "sap.ui.model.odata.type.Unit":
1580
- outputEnd = `,{mode:'OneTime',path:'/##@@requestUnitsOfMeasure',targetType:'any'}],type:'sap.ui.model.odata.type.Unit'`;
1581
- break;
1582
- case "sap.ui.model.odata.type.Currency":
1583
- outputEnd = `,{mode:'OneTime',path:'/##@@requestCurrencyCodes',targetType:'any'}],type:'sap.ui.model.odata.type.Currency'`;
1584
- break;
1585
- default:
1586
- outputEnd = `], type: '${expression.type}'`;
1587
- }
1686
+ let outputEnd = `], type: '${expression.type}'`;
1588
1687
  if (hasElements(expression.formatOptions)) {
1589
- outputEnd += `, formatOptions: ${compileBinding(expression.formatOptions)}`;
1688
+ outputEnd += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1590
1689
  }
1591
1690
  if (hasElements(expression.parameters)) {
1592
- outputEnd += `, parameters: ${compileBinding(expression.parameters)}`;
1691
+ outputEnd += `, parameters: ${compileExpression(expression.parameters)}`;
1593
1692
  }
1594
1693
  outputEnd += "}";
1595
1694
 
@@ -1602,9 +1701,13 @@ function compileComplexTypeExpression<T extends PrimitiveType>(expression: Compl
1602
1701
  * @param expression The compiled expression
1603
1702
  * @param embeddedInBinding True if the compiled expression is to be embedded in a binding
1604
1703
  * @param parenthesisRequired True if the embedded binding needs to be wrapped in parethesis so that it is evaluated as one
1605
- * @returns {BindingExpression<string>} Finalized compiled expression
1704
+ * @returns Finalized compiled expression
1606
1705
  */
1607
- function wrapBindingExpression(expression: string, embeddedInBinding: boolean, parenthesisRequired = false): BindingExpression<string> {
1706
+ function wrapBindingExpression(
1707
+ expression: string,
1708
+ embeddedInBinding: boolean,
1709
+ parenthesisRequired = false
1710
+ ): CompiledBindingToolkitExpression {
1608
1711
  if (embeddedInBinding) {
1609
1712
  if (parenthesisRequired) {
1610
1713
  return `(${expression})`;
@@ -1624,14 +1727,14 @@ function wrapBindingExpression(expression: string, embeddedInBinding: boolean, p
1624
1727
  * @param embeddedInBinding Whether the expression to compile is embedded into another expression
1625
1728
  * @param keepTargetType Keep the target type of the embedded bindings instead of casting them to any
1626
1729
  * @param isNullable Whether binding expression can resolve to empty string or not
1627
- * @returns {BindingExpression<T>} The corresponding expression binding
1730
+ * @returns The corresponding expression binding
1628
1731
  */
1629
- export function compileBinding<T extends PrimitiveType>(
1732
+ export function compileExpression<T extends PrimitiveType>(
1630
1733
  expression: ExpressionOrPrimitive<T>,
1631
1734
  embeddedInBinding = false,
1632
1735
  keepTargetType = false,
1633
1736
  isNullable = false
1634
- ): BindingExpression<string> {
1737
+ ): CompiledBindingToolkitExpression {
1635
1738
  const expr = wrapPrimitive(expression);
1636
1739
  const embeddedSeparator = keepTargetType ? "$" : "%";
1637
1740
 
@@ -1646,10 +1749,10 @@ export function compileBinding<T extends PrimitiveType>(
1646
1749
  return expr.ref || "null";
1647
1750
 
1648
1751
  case "Function":
1649
- const argumentString = `${expr.parameters.map(arg => compileBinding(arg, true)).join(", ")}`;
1752
+ const argumentString = `${expr.parameters.map((arg) => compileExpression(arg, true)).join(", ")}`;
1650
1753
  return expr.obj === undefined
1651
1754
  ? `${expr.fn}(${argumentString})`
1652
- : `${compileBinding(expr.obj, true)}.${expr.fn}(${argumentString})`;
1755
+ : `${compileExpression(expr.obj, true)}.${expr.fn}(${argumentString})`;
1653
1756
 
1654
1757
  case "EmbeddedExpressionBinding":
1655
1758
  return embeddedInBinding ? `(${expr.value.substr(2, expr.value.length - 3)})` : `${expr.value}`;
@@ -1657,39 +1760,40 @@ export function compileBinding<T extends PrimitiveType>(
1657
1760
  case "EmbeddedBinding":
1658
1761
  return embeddedInBinding ? `${embeddedSeparator}${expr.value}` : `${expr.value}`;
1659
1762
 
1660
- case "DefaultBinding":
1661
- case "Binding":
1662
- return compileBindingForBinding(expr, embeddedInBinding, embeddedSeparator);
1763
+ case "PathInModel":
1764
+ return compilePathInModelExpression(expr, embeddedInBinding, embeddedSeparator);
1663
1765
 
1664
1766
  case "Comparison":
1665
1767
  const comparisonExpression = compileComparisonExpression(expr);
1666
1768
  return wrapBindingExpression(comparisonExpression, embeddedInBinding);
1667
1769
 
1668
1770
  case "IfElse":
1669
- const ifElseExpression = `${compileBinding(expr.condition, true)} ? ${compileBinding(expr.onTrue, true)} : ${compileBinding(
1670
- expr.onFalse,
1771
+ const ifElseExpression = `${compileExpression(expr.condition, true)} ? ${compileExpression(
1772
+ expr.onTrue,
1671
1773
  true
1672
- )}`;
1774
+ )} : ${compileExpression(expr.onFalse, true)}`;
1673
1775
  return wrapBindingExpression(ifElseExpression, embeddedInBinding, true);
1674
1776
 
1675
1777
  case "Set":
1676
- const setExpression = expr.operands.map(operand => compileBinding(operand, true)).join(` ${expr.operator} `);
1778
+ const setExpression = expr.operands.map((operand) => compileExpression(operand, true)).join(` ${expr.operator} `);
1677
1779
  return wrapBindingExpression(setExpression, embeddedInBinding, true);
1678
1780
 
1679
1781
  case "Concat":
1680
- const concatExpression = expr.expressions.map(nestedExpression => compileBinding(nestedExpression, true, true)).join(" + ");
1782
+ const concatExpression = expr.expressions
1783
+ .map((nestedExpression) => compileExpression(nestedExpression, true, true))
1784
+ .join(" + ");
1681
1785
  return wrapBindingExpression(concatExpression, embeddedInBinding);
1682
1786
 
1683
1787
  case "Length":
1684
- const lengthExpression = `${compileBinding(expr.bindingExpression, true)}.length`;
1788
+ const lengthExpression = `${compileExpression(expr.pathInModel, true)}.length`;
1685
1789
  return wrapBindingExpression(lengthExpression, embeddedInBinding);
1686
1790
 
1687
1791
  case "Not":
1688
- const notExpression = `!${compileBinding(expr.operand, true)}`;
1792
+ const notExpression = `!${compileExpression(expr.operand, true)}`;
1689
1793
  return wrapBindingExpression(notExpression, embeddedInBinding);
1690
1794
 
1691
1795
  case "Truthy":
1692
- const truthyExpression = `!!${compileBinding(expr.operand, true)}`;
1796
+ const truthyExpression = `!!${compileExpression(expr.operand, true)}`;
1693
1797
  return wrapBindingExpression(truthyExpression, embeddedInBinding);
1694
1798
 
1695
1799
  case "Formatter":
@@ -1712,8 +1816,8 @@ export function compileBinding<T extends PrimitiveType>(
1712
1816
  * @returns The compiled expression. Needs wrapping before it can be used as an expression binding.
1713
1817
  */
1714
1818
  function compileComparisonExpression(expression: ComparisonExpression) {
1715
- function compileOperand(operand: Expression<any>) {
1716
- const compiledOperand = compileBinding(operand, true) ?? "undefined";
1819
+ function compileOperand(operand: BindingToolkitExpression<any>) {
1820
+ const compiledOperand = compileExpression(operand, true) ?? "undefined";
1717
1821
  return wrapBindingExpression(compiledOperand, true, needParenthesis(operand));
1718
1822
  }
1719
1823
 
@@ -1730,7 +1834,13 @@ function compileFormatterExpression<T extends PrimitiveType>(expression: Formatt
1730
1834
  if (expression.parameters.length === 1) {
1731
1835
  return `{${compilePathParameter(expression.parameters[0], true)}, formatter: '${expression.fn}'}`;
1732
1836
  } else {
1733
- const parts = expression.parameters.map(param => compilePathParameter(param));
1837
+ const parts = expression.parameters.map((param) => {
1838
+ if (param._type === "ComplexType") {
1839
+ return compileComplexTypeExpression(param);
1840
+ } else {
1841
+ return compilePathParameter(param);
1842
+ }
1843
+ });
1734
1844
  return `{parts: [${parts.join(", ")}], formatter: '${expression.fn}'}`;
1735
1845
  }
1736
1846
  }
@@ -1740,39 +1850,32 @@ function compileFormatterExpression<T extends PrimitiveType>(expression: Formatt
1740
1850
  *
1741
1851
  * @param expression The binding part to evaluate
1742
1852
  * @param singlePath Whether there is one or multiple path to consider
1743
- * @returns {string} The string snippet to include in the overall binding definition
1853
+ * @returns The string snippet to include in the overall binding definition
1744
1854
  */
1745
- function compilePathParameter(expression: Expression<any>, singlePath = false): string {
1855
+ function compilePathParameter(expression: BindingToolkitExpression<any>, singlePath = false): string {
1746
1856
  let outValue = "";
1747
1857
  if (expression._type === "Constant") {
1748
- switch (typeof expression.value) {
1749
- case "number":
1750
- case "bigint":
1751
- outValue = `value: ${expression.value.toString()}`;
1752
- break;
1753
- case "string":
1754
- outValue = `value: '${escapeXmlAttribute(expression.value.toString())}'`;
1755
- break;
1756
- case "boolean":
1757
- outValue = `value: '${expression.value.toString()}'`;
1758
- break;
1759
- default:
1760
- outValue = "value: ''";
1761
- break;
1858
+ if (expression.value === undefined) {
1859
+ // Special case otherwise the JSTokenizer complains about incorrect content
1860
+ outValue = `value: 'undefined'`;
1861
+ } else {
1862
+ outValue = `value: ${compileConstant(expression, true)}`;
1762
1863
  }
1763
- } else if (expression._type === "DefaultBinding" || expression._type === "Binding") {
1764
- outValue = `path: '${compileBindingPath(expression)}'`;
1864
+ } else if (expression._type === "PathInModel") {
1865
+ outValue = `path: '${compilePathInModel(expression)}'`;
1765
1866
 
1766
1867
  outValue += expression.type ? `, type: '${expression.type}'` : `, targetType: 'any'`;
1767
-
1868
+ if (hasElements(expression.mode)) {
1869
+ outValue += `, mode: '${compileExpression(expression.mode)}'`;
1870
+ }
1768
1871
  if (hasElements(expression.constraints)) {
1769
- outValue += `, constraints: ${compileBinding(expression.constraints)}`;
1872
+ outValue += `, constraints: ${compileExpression(expression.constraints)}`;
1770
1873
  }
1771
1874
  if (hasElements(expression.formatOptions)) {
1772
- outValue += `, formatOptions: ${compileBinding(expression.formatOptions)}`;
1875
+ outValue += `, formatOptions: ${compileExpression(expression.formatOptions)}`;
1773
1876
  }
1774
1877
  if (hasElements(expression.parameters)) {
1775
- outValue += `, parameters: ${compileBinding(expression.parameters)}`;
1878
+ outValue += `, parameters: ${compileExpression(expression.parameters)}`;
1776
1879
  }
1777
1880
  } else {
1778
1881
  return "";
@@ -1790,6 +1893,6 @@ function hasElements(obj: any) {
1790
1893
  * @param expression The expression to compile.
1791
1894
  * @returns The compiled path.
1792
1895
  */
1793
- function compileBindingPath<T extends PrimitiveType>(expression: BindingExpressionExpression<T> | DefaultBindingExpressionExpression<T>) {
1794
- return `${expression.modelName ? expression.modelName + ">" : ""}${expression.path}`;
1896
+ function compilePathInModel<T extends PrimitiveType>(expression: PathInModelExpression<T>) {
1897
+ return `${expression.modelName ? `${expression.modelName}>` : ""}${expression.path}`;
1795
1898
  }