@siliconst/metaui 1.4.9 → 1.4.13

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 (307) hide show
  1. package/README.md +4 -178
  2. package/package.json +1 -1
  3. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +56 -8
  4. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js.map +1 -1
  5. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts +27 -3
  6. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
  7. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
  8. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
  9. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +52 -9
  10. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js +132 -18
  11. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js.map +1 -1
  12. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts +14 -9
  13. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts.map +1 -1
  14. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js +1 -1
  15. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js.map +1 -1
  16. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.ts +117 -18
  17. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate-dbg.js +1 -3
  18. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate-dbg.js.map +1 -1
  19. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.d.ts.map +1 -1
  20. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.js +1 -1
  21. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.js.map +1 -1
  22. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.ts +1 -3
  23. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js +9 -6
  24. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js.map +1 -1
  25. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts +1 -1
  26. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts.map +1 -1
  27. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js +1 -1
  28. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js.map +1 -1
  29. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.ts +9 -6
  30. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate-dbg.js +56 -49
  31. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate-dbg.js.map +1 -1
  32. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.d.ts +9 -4
  33. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.d.ts.map +1 -1
  34. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.js +1 -1
  35. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.js.map +1 -1
  36. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.ts +67 -50
  37. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine-dbg.js +0 -2
  38. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine-dbg.js.map +1 -1
  39. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.d.ts +0 -2
  40. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.d.ts.map +1 -1
  41. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.js.map +1 -1
  42. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.ts +0 -3
  43. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js +4 -6
  44. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator-dbg.js.map +1 -1
  45. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js +1 -1
  46. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.js.map +1 -1
  47. package/src/nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator.ts +4 -4
  48. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js +36 -9
  49. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js.map +1 -1
  50. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts +18 -2
  51. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts.map +1 -1
  52. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js +1 -1
  53. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js.map +1 -1
  54. package/src/nz/co/siliconst/ui5/metaui/core/Engine.ts +39 -5
  55. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry-dbg.js +19 -2
  56. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry-dbg.js.map +1 -1
  57. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.d.ts +9 -0
  58. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.d.ts.map +1 -1
  59. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.js +1 -1
  60. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.js.map +1 -1
  61. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.ts +21 -7
  62. package/src/nz/co/siliconst/ui5/metaui/core/Registry-dbg.js +3 -1
  63. package/src/nz/co/siliconst/ui5/metaui/core/Registry-dbg.js.map +1 -1
  64. package/src/nz/co/siliconst/ui5/metaui/core/Registry.d.ts.map +1 -1
  65. package/src/nz/co/siliconst/ui5/metaui/core/Registry.js +1 -1
  66. package/src/nz/co/siliconst/ui5/metaui/core/Registry.js.map +1 -1
  67. package/src/nz/co/siliconst/ui5/metaui/core/Registry.ts +3 -1
  68. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +54 -34
  69. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
  70. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts +3 -1
  71. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
  72. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
  73. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
  74. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +55 -34
  75. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator-dbg.js +7 -6
  76. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator-dbg.js.map +1 -1
  77. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.d.ts.map +1 -1
  78. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.js +1 -1
  79. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.js.map +1 -1
  80. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.ts +7 -6
  81. package/src/nz/co/siliconst/ui5/metaui/core/StateManager-dbg.js +40 -11
  82. package/src/nz/co/siliconst/ui5/metaui/core/StateManager-dbg.js.map +1 -1
  83. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.d.ts +6 -1
  84. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.d.ts.map +1 -1
  85. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.js +1 -1
  86. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.js.map +1 -1
  87. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.ts +39 -13
  88. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin-dbg.js.map +1 -1
  89. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts +13 -0
  90. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts.map +1 -1
  91. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.ts +15 -0
  92. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema-dbg.js.map +1 -1
  93. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts +1 -0
  94. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts.map +1 -1
  95. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.ts +1 -0
  96. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +10 -0
  97. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
  98. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
  99. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
  100. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
  101. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +10 -0
  102. package/src/nz/co/siliconst/ui5/metaui/library-dbg.js +1 -1
  103. package/src/nz/co/siliconst/ui5/metaui/library-dbg.js.map +1 -1
  104. package/src/nz/co/siliconst/ui5/metaui/library-preload.js +44 -43
  105. package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
  106. package/src/nz/co/siliconst/ui5/metaui/library.d.ts +1 -0
  107. package/src/nz/co/siliconst/ui5/metaui/library.d.ts.map +1 -1
  108. package/src/nz/co/siliconst/ui5/metaui/library.js +1 -1
  109. package/src/nz/co/siliconst/ui5/metaui/library.js.map +1 -1
  110. package/src/nz/co/siliconst/ui5/metaui/library.ts +1 -0
  111. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js +6 -0
  112. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js.map +1 -1
  113. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.d.ts.map +1 -1
  114. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js +1 -1
  115. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js.map +1 -1
  116. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.ts +6 -0
  117. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js +2 -2
  118. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js.map +1 -1
  119. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js +1 -1
  120. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js.map +1 -1
  121. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.ts +2 -2
  122. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js +77 -1
  123. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js.map +1 -1
  124. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts +17 -0
  125. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts.map +1 -1
  126. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js +1 -1
  127. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js.map +1 -1
  128. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.ts +67 -7
  129. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js +1 -1
  130. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js.map +1 -1
  131. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js +1 -1
  132. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js.map +1 -1
  133. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.ts +1 -1
  134. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js +1 -1
  135. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js.map +1 -1
  136. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js +1 -1
  137. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js.map +1 -1
  138. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.ts +1 -1
  139. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js +10 -3
  140. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js.map +1 -1
  141. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.d.ts.map +1 -1
  142. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js +1 -1
  143. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js.map +1 -1
  144. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.ts +10 -3
  145. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js +1 -1
  146. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js.map +1 -1
  147. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js +1 -1
  148. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js.map +1 -1
  149. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.ts +1 -1
  150. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js +1 -1
  151. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js.map +1 -1
  152. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js +1 -1
  153. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js.map +1 -1
  154. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.ts +1 -1
  155. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js +1 -1
  156. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js.map +1 -1
  157. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js +1 -1
  158. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js.map +1 -1
  159. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.ts +1 -1
  160. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js +1 -1
  161. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js.map +1 -1
  162. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js +1 -1
  163. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js.map +1 -1
  164. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.ts +1 -1
  165. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js +1 -1
  166. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js.map +1 -1
  167. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js +1 -1
  168. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js.map +1 -1
  169. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.ts +1 -1
  170. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js +130 -0
  171. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js.map +1 -0
  172. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.d.ts +39 -0
  173. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.d.ts.map +1 -0
  174. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js +2 -0
  175. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js.map +1 -0
  176. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.ts +127 -0
  177. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js +1 -1
  178. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js.map +1 -1
  179. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js +1 -1
  180. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js.map +1 -1
  181. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.ts +1 -1
  182. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js +2 -2
  183. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js.map +1 -1
  184. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js +1 -1
  185. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js.map +1 -1
  186. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.ts +2 -2
  187. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js +6 -0
  188. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js.map +1 -1
  189. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.d.ts.map +1 -1
  190. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js +1 -1
  191. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js.map +1 -1
  192. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.ts +6 -0
  193. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js +1 -1
  194. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js.map +1 -1
  195. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js +1 -1
  196. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js.map +1 -1
  197. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.ts +1 -1
  198. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js +1 -1
  199. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js.map +1 -1
  200. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js +1 -1
  201. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js.map +1 -1
  202. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.ts +1 -1
  203. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js +1 -1
  204. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js.map +1 -1
  205. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js +1 -1
  206. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js.map +1 -1
  207. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.ts +1 -1
  208. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js +1 -1
  209. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js.map +1 -1
  210. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js +1 -1
  211. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js.map +1 -1
  212. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.ts +1 -1
  213. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js +1 -1
  214. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js.map +1 -1
  215. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js +1 -1
  216. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js.map +1 -1
  217. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.ts +1 -1
  218. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js +1 -1
  219. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js.map +1 -1
  220. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js +1 -1
  221. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js.map +1 -1
  222. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.ts +1 -1
  223. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js +40 -4
  224. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js.map +1 -1
  225. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts +4 -0
  226. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts.map +1 -1
  227. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js +1 -1
  228. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js.map +1 -1
  229. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.ts +41 -3
  230. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js +1 -1
  231. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js.map +1 -1
  232. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js +1 -1
  233. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js.map +1 -1
  234. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.ts +1 -1
  235. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js +1 -1
  236. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js.map +1 -1
  237. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js +1 -1
  238. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js.map +1 -1
  239. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.ts +1 -1
  240. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin-dbg.js.map +1 -1
  241. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin.js.map +1 -1
  242. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin.ts +1 -1
  243. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin-dbg.js.map +1 -1
  244. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin.js.map +1 -1
  245. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin.ts +1 -1
  246. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/CurrencyFormatterPlugin-dbg.js.map +1 -1
  247. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/CurrencyFormatterPlugin.d.ts +1 -1
  248. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/CurrencyFormatterPlugin.d.ts.map +1 -1
  249. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/CurrencyFormatterPlugin.js.map +1 -1
  250. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/CurrencyFormatterPlugin.ts +2 -2
  251. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/DateFormatterPlugin-dbg.js.map +1 -1
  252. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/DateFormatterPlugin.d.ts +1 -1
  253. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/DateFormatterPlugin.d.ts.map +1 -1
  254. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/DateFormatterPlugin.js.map +1 -1
  255. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/DateFormatterPlugin.ts +1 -1
  256. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin-dbg.js +1 -1
  257. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin-dbg.js.map +1 -1
  258. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin.d.ts +1 -1
  259. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin.d.ts.map +1 -1
  260. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin.js +1 -1
  261. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin.js.map +1 -1
  262. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/PhoneFormatterPlugin.ts +2 -2
  263. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin-dbg.js +1 -1
  264. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin-dbg.js.map +1 -1
  265. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin.d.ts +1 -1
  266. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin.d.ts.map +1 -1
  267. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin.js +1 -1
  268. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin.js.map +1 -1
  269. package/src/nz/co/siliconst/ui5/metaui/plugins/formatters/TextCaseFormatterPlugin.ts +2 -2
  270. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin-dbg.js +1 -1
  271. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin-dbg.js.map +1 -1
  272. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin.d.ts +1 -1
  273. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin.d.ts.map +1 -1
  274. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin.js +1 -1
  275. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin.js.map +1 -1
  276. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/EmailValidatorPlugin.ts +3 -3
  277. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/IbanValidatorPlugin-dbg.js.map +1 -1
  278. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/IbanValidatorPlugin.d.ts +1 -1
  279. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/IbanValidatorPlugin.d.ts.map +1 -1
  280. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/IbanValidatorPlugin.js.map +1 -1
  281. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/IbanValidatorPlugin.ts +1 -1
  282. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/MinLengthValidatorPlugin-dbg.js.map +1 -1
  283. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/MinLengthValidatorPlugin.d.ts +1 -1
  284. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/MinLengthValidatorPlugin.d.ts.map +1 -1
  285. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/MinLengthValidatorPlugin.js.map +1 -1
  286. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/MinLengthValidatorPlugin.ts +1 -1
  287. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin-dbg.js +2 -2
  288. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin-dbg.js.map +1 -1
  289. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin.d.ts +1 -1
  290. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin.d.ts.map +1 -1
  291. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin.js +1 -1
  292. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin.js.map +1 -1
  293. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/PatternValidatorPlugin.ts +4 -4
  294. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin-dbg.js +3 -2
  295. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin-dbg.js.map +1 -1
  296. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin.d.ts +1 -1
  297. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin.d.ts.map +1 -1
  298. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin.js +1 -1
  299. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin.js.map +1 -1
  300. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/RangeValidatorPlugin.ts +4 -3
  301. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin-dbg.js +3 -1
  302. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin-dbg.js.map +1 -1
  303. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin.d.ts +1 -1
  304. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin.d.ts.map +1 -1
  305. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin.js +1 -1
  306. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin.js.map +1 -1
  307. package/src/nz/co/siliconst/ui5/metaui/plugins/validators/UrlValidatorPlugin.ts +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultLayoutGenerator-dbg.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","error","__ui5_require_async","then","Logger","message","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n } catch (error) {\n // If a single synthesized property fails, swallow it to prevent the entire synthesized form from crashing.\n import(\"../utils/Logger\").then(({ Logger }) => {\n Logger.error(`[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}'`, (error as Error).message);\n });\n }\n }\n return elements;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAAA;AACA;AACA;AACA;;EAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACO,MAAMA,sBAAsB,CAAC;IAChC;AACJ;AACA;AACA;AACA;IACI,OAAcC,YAAYA,CAACC,MAAe,EAAW;MACjD;MACA,IAAIA,MAAM,CAACC,QAAQ,IAAIC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACC,QAAQ,CAAC,IAAID,MAAM,CAACC,QAAQ,CAACG,MAAM,GAAG,CAAC,EAAE;QACjF,OAAO,KAAK;MAChB;MAEA,MAAMD,OAAO,GAAGH,MAAM,CAACK,IAAI,KAAK,OAAO;MACvC,MAAMC,KAAK,GAAGH,OAAO,GAAGH,MAAM,CAACO,KAAK,EAAEC,UAAU,GAAGR,MAAM,CAACQ,UAAU;MAEpE,IAAI,CAACF,KAAK,IAAIG,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,CAACF,MAAM,KAAK,CAAC,EAAE;QAC3C,OAAO,KAAK,CAAC,CAAC;MAClB;MAEA,MAAMO,QAAQ,GAAG,IAAI,CAACC,8BAA8B,CAACN,KAAK,EAAE,cAAc,CAAC;MAE3E,IAAIH,OAAO,EAAE;QACT;QACA;QACA;QACAH,MAAM,CAACC,QAAQ,GAAGU,QAAQ,CAACE,MAAM,CAACC,CAAC,IAAIA,CAAC,CAACT,IAAI,KAAK,SAAS,CAAC;MAChE,CAAC,MAAM;QACH;QACAL,MAAM,CAACC,QAAQ,GAAG,CACd;UACII,IAAI,EAAE,OAAO;UACbU,KAAK,EAAEf,MAAM,CAACgB,KAAK;UACnBL,QAAQ,EAAEA;QACd,CAAC,CACJ;MACL;MAEA,OAAO,IAAI;IACf;;IAEA;AACJ;AACA;AACA;AACA;AACA;IACI,OAAeC,8BAA8BA,CAACN,KAAwE,EAAEW,QAAgB,EAAoB;MACxJ,MAAMN,QAA0B,GAAG,EAAE;MACrC,KAAK,MAAMO,GAAG,IAAIT,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,EAAE;QAClC,IAAI;UACA,MAAMa,IAAI,GAAGb,KAAK,CAACY,GAAG,CAAC;UACvB,MAAME,WAAW,GAAG,GAAGH,QAAQ,IAAIC,GAAG,EAAE;UAExC,IAAIC,IAAI,CAACd,IAAI,KAAK,QAAQ,IAAIc,IAAI,CAACX,UAAU,EAAE;YAC3CG,QAAQ,CAACU,IAAI,CAAC;cACVhB,IAAI,EAAE,OAAO;cACbU,KAAK,EAAEI,IAAI,CAACG,EAAE,EAAEP,KAAK,IAAIG,GAAG;cAC5BP,QAAQ,EAAE,IAAI,CAACC,8BAA8B,CAACO,IAAI,CAACX,UAAU,EAAE,GAAGY,WAAW,aAAa;YAC9F,CAAC,CAAC;UACN,CAAC,MAAM;YACHT,QAAQ,CAACU,IAAI,CAAC;cACVhB,IAAI,EAAE,SAAS;cACfkB,KAAK,EAAEH;YACX,CAAC,CAAC;UACN;QACJ,CAAC,CAAC,OAAOI,KAAK,EAAE;UACZ;UACAC,mBAAA,CAAO,iBAAiB,CAAC,CAACC,IAAI,CAAC,CAAC;YAAEC;UAAO,CAAC,KAAK;YAC3CA,MAAM,CAACH,KAAK,CAAC,kEAAkEN,GAAG,GAAG,EAAGM,KAAK,CAAWI,OAAO,CAAC;UACpH,CAAC,CAAC;QACN;MACJ;MACA,OAAOjB,QAAQ;IACnB;EACJ;EAAC,IAAAkB,SAAA;IAAAC,UAAA;EAAA;EAAAD,SAAA,CAAA/B,sBAAA,GAAAA,sBAAA;EAAA,OAAA+B,SAAA;AAAA","ignoreList":[]}
1
+ {"version":3,"file":"DefaultLayoutGenerator-dbg.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","error","msg","message","__ui5_require_async","then","m","Logger","Error","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n } catch (error) {\n // Do not swallow errors. A failure to synthesize a property is a critical failure.\n const msg = `[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}': ${(error as Error).message}`;\n import(\"../utils/Logger\").then(m => m.Logger.error(msg));\n throw new Error(msg);\n }\n }\n return elements;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAAA;AACA;AACA;AACA;;EAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACO,MAAMA,sBAAsB,CAAC;IAChC;AACJ;AACA;AACA;AACA;IACI,OAAcC,YAAYA,CAACC,MAAe,EAAW;MACjD;MACA,IAAIA,MAAM,CAACC,QAAQ,IAAIC,KAAK,CAACC,OAAO,CAACH,MAAM,CAACC,QAAQ,CAAC,IAAID,MAAM,CAACC,QAAQ,CAACG,MAAM,GAAG,CAAC,EAAE;QACjF,OAAO,KAAK;MAChB;MAEA,MAAMD,OAAO,GAAGH,MAAM,CAACK,IAAI,KAAK,OAAO;MACvC,MAAMC,KAAK,GAAGH,OAAO,GAAGH,MAAM,CAACO,KAAK,EAAEC,UAAU,GAAGR,MAAM,CAACQ,UAAU;MAEpE,IAAI,CAACF,KAAK,IAAIG,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,CAACF,MAAM,KAAK,CAAC,EAAE;QAC3C,OAAO,KAAK,CAAC,CAAC;MAClB;MAEA,MAAMO,QAAQ,GAAG,IAAI,CAACC,8BAA8B,CAACN,KAAK,EAAE,cAAc,CAAC;MAE3E,IAAIH,OAAO,EAAE;QACT;QACA;QACA;QACAH,MAAM,CAACC,QAAQ,GAAGU,QAAQ,CAACE,MAAM,CAACC,CAAC,IAAIA,CAAC,CAACT,IAAI,KAAK,SAAS,CAAC;MAChE,CAAC,MAAM;QACH;QACAL,MAAM,CAACC,QAAQ,GAAG,CACd;UACII,IAAI,EAAE,OAAO;UACbU,KAAK,EAAEf,MAAM,CAACgB,KAAK;UACnBL,QAAQ,EAAEA;QACd,CAAC,CACJ;MACL;MAEA,OAAO,IAAI;IACf;;IAEA;AACJ;AACA;AACA;AACA;AACA;IACI,OAAeC,8BAA8BA,CAACN,KAAwE,EAAEW,QAAgB,EAAoB;MACxJ,MAAMN,QAA0B,GAAG,EAAE;MACrC,KAAK,MAAMO,GAAG,IAAIT,MAAM,CAACC,IAAI,CAACJ,KAAK,CAAC,EAAE;QAClC,IAAI;UACA,MAAMa,IAAI,GAAGb,KAAK,CAACY,GAAG,CAAC;UACvB,MAAME,WAAW,GAAG,GAAGH,QAAQ,IAAIC,GAAG,EAAE;UAExC,IAAIC,IAAI,CAACd,IAAI,KAAK,QAAQ,IAAIc,IAAI,CAACX,UAAU,EAAE;YAC3CG,QAAQ,CAACU,IAAI,CAAC;cACVhB,IAAI,EAAE,OAAO;cACbU,KAAK,EAAEI,IAAI,CAACG,EAAE,EAAEP,KAAK,IAAIG,GAAG;cAC5BP,QAAQ,EAAE,IAAI,CAACC,8BAA8B,CAACO,IAAI,CAACX,UAAU,EAAE,GAAGY,WAAW,aAAa;YAC9F,CAAC,CAAC;UACN,CAAC,MAAM;YACHT,QAAQ,CAACU,IAAI,CAAC;cACVhB,IAAI,EAAE,SAAS;cACfkB,KAAK,EAAEH;YACX,CAAC,CAAC;UACN;QACJ,CAAC,CAAC,OAAOI,KAAK,EAAE;UACZ;UACA,MAAMC,GAAG,GAAG,kEAAkEP,GAAG,MAAOM,KAAK,CAAWE,OAAO,EAAE;UACjHC,mBAAA,CAAO,iBAAiB,CAAC,CAACC,IAAI,CAACC,CAAC,IAAIA,CAAC,CAACC,MAAM,CAACN,KAAK,CAACC,GAAG,CAAC,CAAC;UACxD,MAAM,IAAIM,KAAK,CAACN,GAAG,CAAC;QACxB;MACJ;MACA,OAAOd,QAAQ;IACnB;EACJ;EAAC,IAAAqB,SAAA;IAAAC,UAAA;EAAA;EAAAD,SAAA,CAAAlC,sBAAA,GAAAA,sBAAA;EAAA,OAAAkC,SAAA;AAAA","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- sap.ui.define([],function(){"use strict";function e(e){return new Promise(function(t,r){sap.ui.require([e],function(r){if(!(r&&r.__esModule)){r=r===null||!(typeof r==="object"&&e.endsWith("/library"))?{default:r}:r;Object.defineProperty(r,"__esModule",{value:true})}t(r)},function(e){r(e)})})}class t{static ensureLayout(e){if(e.uiLayout&&Array.isArray(e.uiLayout)&&e.uiLayout.length>0){return false}const t=e.type==="array";const r=t?e.items?.properties:e.properties;if(!r||Object.keys(r).length===0){return false}const o=this.generateElementsFromProperties(r,"#/properties");if(t){e.uiLayout=o.filter(e=>e.type==="Control")}else{e.uiLayout=[{type:"Group",label:e.title,elements:o}]}return true}static generateElementsFromProperties(t,r){const o=[];for(const s of Object.keys(t)){try{const e=t[s];const u=`${r}/${s}`;if(e.type==="object"&&e.properties){o.push({type:"Group",label:e.ui?.label||s,elements:this.generateElementsFromProperties(e.properties,`${u}/properties`)})}else{o.push({type:"Control",scope:u})}}catch(t){e("../utils/Logger").then(({Logger:e})=>{e.error(`[MetaUI] DefaultLayoutGenerator failed to synthesize property '${s}'`,t.message)})}}return o}}var r={__esModule:true};r.DefaultLayoutGenerator=t;return r});
1
+ sap.ui.define([],function(){"use strict";function e(e){return new Promise(function(t,r){sap.ui.require([e],function(r){if(!(r&&r.__esModule)){r=r===null||!(typeof r==="object"&&e.endsWith("/library"))?{default:r}:r;Object.defineProperty(r,"__esModule",{value:true})}t(r)},function(e){r(e)})})}class t{static ensureLayout(e){if(e.uiLayout&&Array.isArray(e.uiLayout)&&e.uiLayout.length>0){return false}const t=e.type==="array";const r=t?e.items?.properties:e.properties;if(!r||Object.keys(r).length===0){return false}const o=this.generateElementsFromProperties(r,"#/properties");if(t){e.uiLayout=o.filter(e=>e.type==="Control")}else{e.uiLayout=[{type:"Group",label:e.title,elements:o}]}return true}static generateElementsFromProperties(t,r){const o=[];for(const s of Object.keys(t)){try{const e=t[s];const n=`${r}/${s}`;if(e.type==="object"&&e.properties){o.push({type:"Group",label:e.ui?.label||s,elements:this.generateElementsFromProperties(e.properties,`${n}/properties`)})}else{o.push({type:"Control",scope:n})}}catch(t){const r=`[MetaUI] DefaultLayoutGenerator failed to synthesize property '${s}': ${t.message}`;e("../utils/Logger").then(e=>e.Logger.error(r));throw new Error(r)}}return o}}var r={__esModule:true};r.DefaultLayoutGenerator=t;return r});
2
2
  //# sourceMappingURL=DefaultLayoutGenerator.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultLayoutGenerator.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","this","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","error","__ui5_require_async","then","Logger","message","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n } catch (error) {\n // If a single synthesized property fails, swallow it to prevent the entire synthesized form from crashing.\n import(\"../utils/Logger\").then(({ Logger }) => {\n Logger.error(`[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}'`, (error as Error).message);\n });\n }\n }\n return elements;\n }\n}\n"],"mappings":"qSAiBO,MAAMA,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAAWC,KAAKC,+BAA+BP,EAAO,gBAE5D,GAAIH,EAAS,CAITH,EAAOC,SAAWU,EAASG,OAAOC,GAAKA,EAAEV,OAAS,UACtD,KAAO,CAEHL,EAAOC,SAAW,CACd,CACII,KAAM,QACNW,MAAOhB,EAAOiB,MACdN,SAAUA,GAGtB,CAEA,OAAO,IACX,CAQA,qCAAeE,CAA+BP,EAA0EY,GACpH,MAAMP,EAA6B,GACnC,IAAK,MAAMQ,KAAOV,OAAOC,KAAKJ,GAAQ,CAClC,IACI,MAAMc,EAAOd,EAAMa,GACnB,MAAME,EAAc,GAAGH,KAAYC,IAEnC,GAAIC,EAAKf,OAAS,UAAYe,EAAKZ,WAAY,CAC3CG,EAASW,KAAK,CACVjB,KAAM,QACNW,MAAOI,EAAKG,IAAIP,OAASG,EACzBR,SAAUC,KAAKC,+BAA+BO,EAAKZ,WAAY,GAAGa,iBAE1E,KAAO,CACHV,EAASW,KAAK,CACVjB,KAAM,UACNmB,MAAOH,GAEf,CACJ,CAAE,MAAOI,GAELC,EAAO,mBAAmBC,KAAK,EAAGC,aAC9BA,EAAOH,MAAM,kEAAkEN,KAASM,EAAgBI,UAEhH,CACJ,CACA,OAAOlB,CACX,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAAhC,yBAAA,OAAAgC,CAAA","ignoreList":[]}
1
+ {"version":3,"file":"DefaultLayoutGenerator.js","names":["DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","this","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","ui","scope","error","msg","message","__ui5_require_async","then","m","Logger","Error","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n if (prop.type === \"object\" && prop.properties) {\n elements.push({\n type: \"Group\",\n label: prop.ui?.label || key,\n elements: this.generateElementsFromProperties(prop.properties, `${currentPath}/properties`)\n });\n } else {\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n }\n } catch (error) {\n // Do not swallow errors. A failure to synthesize a property is a critical failure.\n const msg = `[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}': ${(error as Error).message}`;\n import(\"../utils/Logger\").then(m => m.Logger.error(msg));\n throw new Error(msg);\n }\n }\n return elements;\n }\n}\n"],"mappings":"qSAiBO,MAAMA,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAAWC,KAAKC,+BAA+BP,EAAO,gBAE5D,GAAIH,EAAS,CAITH,EAAOC,SAAWU,EAASG,OAAOC,GAAKA,EAAEV,OAAS,UACtD,KAAO,CAEHL,EAAOC,SAAW,CACd,CACII,KAAM,QACNW,MAAOhB,EAAOiB,MACdN,SAAUA,GAGtB,CAEA,OAAO,IACX,CAQA,qCAAeE,CAA+BP,EAA0EY,GACpH,MAAMP,EAA6B,GACnC,IAAK,MAAMQ,KAAOV,OAAOC,KAAKJ,GAAQ,CAClC,IACI,MAAMc,EAAOd,EAAMa,GACnB,MAAME,EAAc,GAAGH,KAAYC,IAEnC,GAAIC,EAAKf,OAAS,UAAYe,EAAKZ,WAAY,CAC3CG,EAASW,KAAK,CACVjB,KAAM,QACNW,MAAOI,EAAKG,IAAIP,OAASG,EACzBR,SAAUC,KAAKC,+BAA+BO,EAAKZ,WAAY,GAAGa,iBAE1E,KAAO,CACHV,EAASW,KAAK,CACVjB,KAAM,UACNmB,MAAOH,GAEf,CACJ,CAAE,MAAOI,GAEL,MAAMC,EAAM,kEAAkEP,OAAUM,EAAgBE,UACxGC,EAAO,mBAAmBC,KAAKC,GAAKA,EAAEC,OAAON,MAAMC,IACnD,MAAM,IAAIM,MAAMN,EACpB,CACJ,CACA,OAAOf,CACX,EACH,IAAAsB,EAAA,CAAAC,WAAA,MAAAD,EAAAnC,yBAAA,OAAAmC,CAAA","ignoreList":[]}
@@ -81,10 +81,10 @@ export class DefaultLayoutGenerator {
81
81
  });
82
82
  }
83
83
  } catch (error) {
84
- // If a single synthesized property fails, swallow it to prevent the entire synthesized form from crashing.
85
- import("../utils/Logger").then(({ Logger }) => {
86
- Logger.error(`[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}'`, (error as Error).message);
87
- });
84
+ // Do not swallow errors. A failure to synthesize a property is a critical failure.
85
+ const msg = `[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}': ${(error as Error).message}`;
86
+ import("../utils/Logger").then(m => m.Logger.error(msg));
87
+ throw new Error(msg);
88
88
  }
89
89
  }
90
90
  return elements;
@@ -28,15 +28,25 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
28
28
 
29
29
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
30
30
 
31
+ /** Callback to notify the host that an internal field changed. */
32
+
31
33
  /** Tracks whether the entire engine is running in Editable mode. */
32
34
  isEditable = true;
33
35
 
36
+ /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */
37
+ hasPartialRenderingErrors = false;
38
+
39
+ /** Tracks whether the engine should delegate visual state to the global MessageManager. */
40
+ useMessageManager = false;
41
+
34
42
  /**
35
43
  * Initializes a new Engine instance.
36
44
  * @param editable Whether the engine should render form fields as editable or read-only.
45
+ * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.
37
46
  */
38
- constructor(editable = true) {
47
+ constructor(editable = true, useMessageManager = false) {
39
48
  this.isEditable = editable;
49
+ this.useMessageManager = useMessageManager;
40
50
  }
41
51
 
42
52
  /**
@@ -72,6 +82,7 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
72
82
  const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);
73
83
  return layoutManager.render(schema, modelName, this, onSubmit);
74
84
  } catch (error) {
85
+ this.hasPartialRenderingErrors = true;
75
86
  const msg = error.message;
76
87
  Logger.error("[MetaUI Engine] Critical error during layout generation", msg);
77
88
  Logger.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${msg}`);
@@ -94,6 +105,9 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
94
105
  try {
95
106
  const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || "string", fieldMeta.ui?.widget);
96
107
  plugin.setEditable(this.isEditable);
108
+ if (typeof plugin.setUseMessageManager === "function") {
109
+ plugin.setUseMessageManager(this.useMessageManager);
110
+ }
97
111
  if (!isTemplate) {
98
112
  this.activePlugins.push({
99
113
  plugin,
@@ -107,6 +121,7 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
107
121
  }
108
122
  return control;
109
123
  } catch (error) {
124
+ this.hasPartialRenderingErrors = true;
110
125
  const msg = error.message;
111
126
  Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);
112
127
  Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\n\nDetails: ${msg}`);
@@ -131,6 +146,7 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
131
146
  const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);
132
147
  return layoutManager.render(schema, modelName, this, undefined, bindingPath);
133
148
  } catch (error) {
149
+ this.hasPartialRenderingErrors = true;
134
150
  const msg = error.message;
135
151
  Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);
136
152
  Logger.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${msg}`);
@@ -143,13 +159,17 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
143
159
  /**
144
160
  * Iterates through all active plugins and triggers their internal validation pipelines.
145
161
  *
162
+ * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.
146
163
  * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.
147
164
  */
148
- validateAll() {
165
+ validateAll(applyVisualState = false) {
149
166
  const errors = [];
150
167
  for (const item of this.activePlugins) {
151
168
  try {
152
169
  const result = item.plugin.validate();
170
+ if (applyVisualState && typeof item.plugin.setVisualValidationState === "function") {
171
+ item.plugin.setVisualValidationState(result.isValid, result.errorMessage);
172
+ }
153
173
  if (!result.isValid) {
154
174
  // Ensure the path is bound to the error so GeneratorHost knows where to target it
155
175
  result.fieldKey = result.fieldKey || item.path.replace(/^\//, "");
@@ -158,18 +178,25 @@ sap.ui.define(["./ConditionEngine", "./PluginRegistry", "sap/m/Text", "../utils/
158
178
  Logger.error("[MetaUI Validation] Plugin failed validation silently:", item.path || item.plugin.constructor.name);
159
179
  }
160
180
  } catch (error) {
161
- const msg = error.message;
162
- Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);
163
- errors.push({
164
- isValid: false,
165
- errorMessage: `Validation crashed: ${msg}`,
166
- fieldKey: item.path.replace(/^\//, "")
167
- });
181
+ Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, error.message);
168
182
  }
169
183
  }
170
184
  return errors;
171
185
  }
172
186
 
187
+ /**
188
+ * Retrieves an active plugin instance by its absolute binding path.
189
+ * Useful for programmatic field manipulation (e.g., custom error injection).
190
+ *
191
+ * @param path The binding path (e.g. "/General/CustomerName").
192
+ * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.
193
+ */
194
+ getPluginByPath(path) {
195
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
196
+ const match = this.activePlugins.find(p => p.path === cleanPath || p.path === `/${cleanPath}`);
197
+ return match ? match.plugin : undefined;
198
+ }
199
+
173
200
  /**
174
201
  * Cleans up internal state and destroys the condition engine to prevent memory leaks.
175
202
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine-dbg.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","hasPartialRenderingErrors","useMessageManager","constructor","editable","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","setUseMessageManager","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","applyVisualState","errors","item","result","validate","setVisualValidationState","replace","name","getPluginByPath","cleanPath","startsWith","match","find","p","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */\n public hasPartialRenderingErrors: boolean = false;\n\n /** Tracks whether the engine should delegate visual state to the global MessageManager. */\n public readonly useMessageManager: boolean = false;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.\n */\n constructor(editable: boolean = true, useMessageManager: boolean = false) {\n this.isEditable = editable;\n this.useMessageManager = useMessageManager;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n \n if (typeof plugin.setUseMessageManager === \"function\") {\n plugin.setUseMessageManager(this.useMessageManager);\n }\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.\n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(applyVisualState: boolean = false): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (applyVisualState && typeof item.plugin.setVisualValidationState === \"function\") {\n item.plugin.setVisualValidationState(result.isValid, result.errorMessage);\n }\n \n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, (error as Error).message);\n }\n }\n return errors;\n }\n\n /**\n * Retrieves an active plugin instance by its absolute binding path.\n * Useful for programmatic field manipulation (e.g., custom error injection).\n * \n * @param path The binding path (e.g. \"/General/CustomerName\").\n * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.\n */\n public getPluginByPath(path: string): import(\"../interfaces/IPlugin\").IPlugin | undefined {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n const match = this.activePlugins.find(p => p.path === cleanPath || p.path === `/${cleanPath}`);\n return match ? match.plugin : undefined;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -24,13 +24,20 @@ declare module "nz/co/siliconst/ui5/metaui/core/Engine" {
24
24
  /** Deterministic scope ID injected by the host control to prevent clone collisions. */
25
25
  engineScopeId?: string;
26
26
  private activeModel?;
27
+ /** Callback to notify the host that an internal field changed. */
28
+ onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;
27
29
  /** Tracks whether the entire engine is running in Editable mode. */
28
30
  readonly isEditable: boolean;
31
+ /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */
32
+ hasPartialRenderingErrors: boolean;
33
+ /** Tracks whether the engine should delegate visual state to the global MessageManager. */
34
+ readonly useMessageManager: boolean;
29
35
  /**
30
36
  * Initializes a new Engine instance.
31
37
  * @param editable Whether the engine should render form fields as editable or read-only.
38
+ * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.
32
39
  */
33
- constructor(editable?: boolean);
40
+ constructor(editable?: boolean, useMessageManager?: boolean);
34
41
  /**
35
42
  * Bootstraps the layout generation process by resolving the correct layout strategy.
36
43
  *
@@ -66,9 +73,18 @@ declare module "nz/co/siliconst/ui5/metaui/core/Engine" {
66
73
  /**
67
74
  * Iterates through all active plugins and triggers their internal validation pipelines.
68
75
  *
76
+ * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.
69
77
  * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.
70
78
  */
71
- validateAll(): IPluginValidationResult[];
79
+ validateAll(applyVisualState?: boolean): IPluginValidationResult[];
80
+ /**
81
+ * Retrieves an active plugin instance by its absolute binding path.
82
+ * Useful for programmatic field manipulation (e.g., custom error injection).
83
+ *
84
+ * @param path The binding path (e.g. "/General/CustomerName").
85
+ * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.
86
+ */
87
+ getPluginByPath(path: string): import("nz/co/siliconst/ui5/metaui/interfaces/IPlugin").IPlugin | undefined;
72
88
  /**
73
89
  * Cleans up internal state and destroys the condition engine to prevent memory leaks.
74
90
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAE3F,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAQ1C;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,oEAAoE;QACpE,SAAgB,UAAU,EAAE,OAAO,CAAQ;QAE3C;;;WAGG;oBACS,QAAQ,GAAE,OAAc;QAIpC;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAgCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QAwBhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAaxF;;;;WAIG;QACI,WAAW,IAAI,uBAAuB,EAAE;QAqB/C;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"../../../../../../../..","sources":["src/nz/co/siliconst/ui5/metaui/core/Engine.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,wCAAwC,CAAC;IACxD;;;OAGG;IAEH,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAC;IAE3F,OAAO,EAAW,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;IAGjG,OAAO,OAAO,MAAM,qBAAqB,CAAC;IAQ1C;;;;;;;;;OASG;IACH,MAAa,MAAM;QACf,gEAAgE;QAChE,OAAO,CAAC,eAAe,CAAgC;QAEvD,4EAA4E;QAC5E,OAAO,CAAC,aAAa,CAA2C;QAEhE,uFAAuF;QAChF,aAAa,CAAC,EAAE,MAAM,CAAC;QAE9B,OAAO,CAAC,WAAW,CAAC,CAAqB;QAEzC,kEAAkE;QAC3D,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;QAE3G,oEAAoE;QACpE,SAAgB,UAAU,EAAE,OAAO,CAAQ;QAE3C,uFAAuF;QAChF,yBAAyB,EAAE,OAAO,CAAS;QAElD,2FAA2F;QAC3F,SAAgB,iBAAiB,EAAE,OAAO,CAAS;QAEnD;;;;WAIG;oBACS,QAAQ,GAAE,OAAc,EAAE,iBAAiB,GAAE,OAAe;QAKxE;;;;;;;;;;WAUG;QACI,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,SAAS,GAAE,MAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO;QAiCjP;;;;;;;;WAQG;QACI,aAAa,CAAC,SAAS,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,OAAe,GAAG,OAAO;QA6BhI;;;;;;;;WAQG;QACI,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO;QAcxF;;;;;WAKG;QACI,WAAW,CAAC,gBAAgB,GAAE,OAAe,GAAG,uBAAuB,EAAE;QAuBhF;;;;;;WAMG;QACI,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,+CAA+C,EAAE,OAAO,GAAG,SAAS;QAMjH;;WAEG;QACI,OAAO,IAAI,IAAI;KAiCzB;CAEA"}
@@ -1,2 +1,2 @@
1
- sap.ui.define(["./ConditionEngine","./PluginRegistry","sap/m/Text","../utils/Logger","./DefaultLayoutGenerator","sap/ui/core/Messaging"],function(e,t,n,i,a,r){"use strict";const o=e["ConditionEngine"];const s=t["PluginRegistry"];const g=i["Logger"];const l=a["DefaultLayoutGenerator"];class c{conditionEngine=null;activePlugins=[];isEditable=true;constructor(e=true){this.isEditable=e}build(e,t,i="meta",a,r,c){this.conditionEngine=new o(e);this.activePlugins=[];this.activeModel=t;this.engineScopeId=r;this.onChange=(e,t,n,i)=>{if(this.conditionEngine&&t){this.conditionEngine.handleEvent(t,e)}if(c){c(e,t,n,i)}};try{if(l.ensureLayout(e)){g.warn("[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.")}const t=e.layoutStrategy||(e.type==="array"?"table":"form");const n=s.getInstance().getLayout(t);return n.render(e,i,this,a)}catch(e){const t=e.message;g.error("[MetaUI Engine] Critical error during layout generation",t);g.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${t}`);return new n({text:"Critical Layout Error"})}}generateField(e,t,i,a=false){try{const n=s.getInstance().getPlugin(e.type||"string",e.ui?.widget);n.setEditable(this.isEditable);if(!a){this.activePlugins.push({plugin:n,path:t})}const r=a?undefined:this.engineScopeId;const o=n.render(e,t,i,r,this.onChange);if(this.conditionEngine){this.conditionEngine.registerPlugin(t,n)}return o}catch(e){const i=e.message;g.error(`[MetaUI Engine] Failed to generate field at ${t}`,i);g.showErrorPopup(`Failed to generate field '${t}'.\n\nDetails: ${i}`);return new n({text:`[Error generating field ${t}]`})}}generateLayout(e,t,i){try{const n=e.layoutStrategy||(e.type==="array"?"table":"form");const a=s.getInstance().getLayout(n);return a.render(e,t,this,undefined,i)}catch(e){const t=e.message;g.error(`[MetaUI Engine] Critical error generating sub-layout for ${i}`,t);g.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${t}`);return new n({text:"Critical Sub-Layout Error"})}}validateAll(){const e=[];for(const t of this.activePlugins){try{const n=t.plugin.validate();if(!n.isValid){n.fieldKey=n.fieldKey||t.path.replace(/^\//,"");e.push(n);g.error("[MetaUI Validation] Plugin failed validation silently:",t.path||t.plugin.constructor.name)}}catch(n){const i=n.message;g.error(`[MetaUI Validation] Exception during plugin validation at path ${t.path}`,i);e.push({isValid:false,errorMessage:`Validation crashed: ${i}`,fieldKey:t.path.replace(/^\//,"")})}}return e}destroy(){if(this.conditionEngine){this.conditionEngine.destroy();this.conditionEngine=null}const e=r;const t=e.getMessageModel().getData();const n=[];for(const e of this.activePlugins){if(this.activeModel){const i=`/${e.path.replace(/^\//,"")}`;const a=t.filter(e=>e.getTarget()===i&&e.getMessageProcessor()&&e.getMessageProcessor().getId()===this.activeModel.getId());n.push(...a)}if(typeof e.plugin.destroy==="function"){e.plugin.destroy()}}if(n.length>0){e.removeMessages(n)}this.activePlugins=[]}}var u={__esModule:true};u.Engine=c;return u});
1
+ sap.ui.define(["./ConditionEngine","./PluginRegistry","sap/m/Text","../utils/Logger","./DefaultLayoutGenerator","sap/ui/core/Messaging"],function(e,t,n,i,a,r){"use strict";const s=e["ConditionEngine"];const o=t["PluginRegistry"];const g=i["Logger"];const l=a["DefaultLayoutGenerator"];class u{conditionEngine=null;activePlugins=[];isEditable=true;hasPartialRenderingErrors=false;useMessageManager=false;constructor(e=true,t=false){this.isEditable=e;this.useMessageManager=t}build(e,t,i="meta",a,r,u){this.conditionEngine=new s(e);this.activePlugins=[];this.activeModel=t;this.engineScopeId=r;this.onChange=(e,t,n,i)=>{if(this.conditionEngine&&t){this.conditionEngine.handleEvent(t,e)}if(u){u(e,t,n,i)}};try{if(l.ensureLayout(e)){g.warn("[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.")}const t=e.layoutStrategy||(e.type==="array"?"table":"form");const n=o.getInstance().getLayout(t);return n.render(e,i,this,a)}catch(e){this.hasPartialRenderingErrors=true;const t=e.message;g.error("[MetaUI Engine] Critical error during layout generation",t);g.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${t}`);return new n({text:"Critical Layout Error"})}}generateField(e,t,i,a=false){try{const n=o.getInstance().getPlugin(e.type||"string",e.ui?.widget);n.setEditable(this.isEditable);if(typeof n.setUseMessageManager==="function"){n.setUseMessageManager(this.useMessageManager)}if(!a){this.activePlugins.push({plugin:n,path:t})}const r=a?undefined:this.engineScopeId;const s=n.render(e,t,i,r,this.onChange);if(this.conditionEngine){this.conditionEngine.registerPlugin(t,n)}return s}catch(e){this.hasPartialRenderingErrors=true;const i=e.message;g.error(`[MetaUI Engine] Failed to generate field at ${t}`,i);g.showErrorPopup(`Failed to generate field '${t}'.\n\nDetails: ${i}`);return new n({text:`[Error generating field ${t}]`})}}generateLayout(e,t,i){try{const n=e.layoutStrategy||(e.type==="array"?"table":"form");const a=o.getInstance().getLayout(n);return a.render(e,t,this,undefined,i)}catch(e){this.hasPartialRenderingErrors=true;const t=e.message;g.error(`[MetaUI Engine] Critical error generating sub-layout for ${i}`,t);g.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${t}`);return new n({text:"Critical Sub-Layout Error"})}}validateAll(e=false){const t=[];for(const n of this.activePlugins){try{const i=n.plugin.validate();if(e&&typeof n.plugin.setVisualValidationState==="function"){n.plugin.setVisualValidationState(i.isValid,i.errorMessage)}if(!i.isValid){i.fieldKey=i.fieldKey||n.path.replace(/^\//,"");t.push(i);g.error("[MetaUI Validation] Plugin failed validation silently:",n.path||n.plugin.constructor.name)}}catch(e){g.error(`[MetaUI Engine] Error validating plugin at ${n.path}`,e.message)}}return t}getPluginByPath(e){const t=e.startsWith("/")?e:`/${e}`;const n=this.activePlugins.find(e=>e.path===t||e.path===`/${t}`);return n?n.plugin:undefined}destroy(){if(this.conditionEngine){this.conditionEngine.destroy();this.conditionEngine=null}const e=r;const t=e.getMessageModel().getData();const n=[];for(const e of this.activePlugins){if(this.activeModel){const i=`/${e.path.replace(/^\//,"")}`;const a=t.filter(e=>e.getTarget()===i&&e.getMessageProcessor()&&e.getMessageProcessor().getId()===this.activeModel.getId());n.push(...a)}if(typeof e.plugin.destroy==="function"){e.plugin.destroy()}}if(n.length>0){e.removeMessages(n)}this.activePlugins=[]}}var c={__esModule:true};c.Engine=u;return c});
2
2
  //# sourceMappingURL=Engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","constructor","editable","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","errors","item","result","validate","replace","name","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n */\n constructor(editable: boolean = true) {\n this.isEditable = editable;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);\n errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\\//, \"\") });\n }\n }\n return errors;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"Engine.js","names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","hasPartialRenderingErrors","useMessageManager","constructor","editable","this","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getInstance","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","setUseMessageManager","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","applyVisualState","errors","item","result","validate","setVisualValidationState","replace","name","getPluginByPath","cleanPath","startsWith","match","find","p","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */\n public hasPartialRenderingErrors: boolean = false;\n\n /** Tracks whether the engine should delegate visual state to the global MessageManager. */\n public readonly useMessageManager: boolean = false;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.\n */\n constructor(editable: boolean = true, useMessageManager: boolean = false) {\n this.isEditable = editable;\n this.useMessageManager = useMessageManager;\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n plugin.setEditable(this.isEditable);\n \n if (typeof plugin.setUseMessageManager === \"function\") {\n plugin.setUseMessageManager(this.useMessageManager);\n }\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.\n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(applyVisualState: boolean = false): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (applyVisualState && typeof item.plugin.setVisualValidationState === \"function\") {\n item.plugin.setVisualValidationState(result.isValid, result.errorMessage);\n }\n \n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, (error as Error).message);\n }\n }\n return errors;\n }\n\n /**\n * Retrieves an active plugin instance by its absolute binding path.\n * Useful for programmatic field manipulation (e.g., custom error injection).\n * \n * @param path The binding path (e.g. \"/General/CustomerName\").\n * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.\n */\n public getPluginByPath(path: string): import(\"../interfaces/IPlugin\").IPlugin | undefined {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n const match = this.activePlugins.find(p => p.path === cleanPath || p.path === `/${cleanPath}`);\n return match ? match.plugin : undefined;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: sap.ui.core.message.Message[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = existingMessages.filter((msg: sap.ui.core.message.Message) =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -38,15 +38,26 @@ export class Engine {
38
38
 
39
39
  private activeModel?: sap.ui.model.Model;
40
40
 
41
+ /** Callback to notify the host that an internal field changed. */
42
+ public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;
43
+
41
44
  /** Tracks whether the entire engine is running in Editable mode. */
42
45
  public readonly isEditable: boolean = true;
43
46
 
47
+ /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */
48
+ public hasPartialRenderingErrors: boolean = false;
49
+
50
+ /** Tracks whether the engine should delegate visual state to the global MessageManager. */
51
+ public readonly useMessageManager: boolean = false;
52
+
44
53
  /**
45
54
  * Initializes a new Engine instance.
46
55
  * @param editable Whether the engine should render form fields as editable or read-only.
56
+ * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.
47
57
  */
48
- constructor(editable: boolean = true) {
58
+ constructor(editable: boolean = true, useMessageManager: boolean = false) {
49
59
  this.isEditable = editable;
60
+ this.useMessageManager = useMessageManager;
50
61
  }
51
62
 
52
63
  /**
@@ -85,6 +96,7 @@ export class Engine {
85
96
 
86
97
  return layoutManager.render(schema, modelName, this, onSubmit);
87
98
  } catch (error) {
99
+ this.hasPartialRenderingErrors = true;
88
100
  const msg = (error as Error).message;
89
101
  Logger.error("[MetaUI Engine] Critical error during layout generation", msg);
90
102
  Logger.showErrorPopup(`Engine failed to generate the layout.\n\nDetails: ${msg}`);
@@ -105,6 +117,10 @@ export class Engine {
105
117
  try {
106
118
  const plugin = PluginRegistry.getInstance().getPlugin(fieldMeta.type || "string", fieldMeta.ui?.widget);
107
119
  plugin.setEditable(this.isEditable);
120
+
121
+ if (typeof plugin.setUseMessageManager === "function") {
122
+ plugin.setUseMessageManager(this.useMessageManager);
123
+ }
108
124
 
109
125
  if (!isTemplate) {
110
126
  this.activePlugins.push({ plugin, path: bindingPath });
@@ -118,6 +134,7 @@ export class Engine {
118
134
 
119
135
  return control;
120
136
  } catch (error) {
137
+ this.hasPartialRenderingErrors = true;
121
138
  const msg = (error as Error).message;
122
139
  Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);
123
140
  Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\n\nDetails: ${msg}`);
@@ -140,6 +157,7 @@ export class Engine {
140
157
  const layoutManager = PluginRegistry.getInstance().getLayout(layoutStrategy);
141
158
  return layoutManager.render(schema, modelName, this, undefined, bindingPath);
142
159
  } catch (error) {
160
+ this.hasPartialRenderingErrors = true;
143
161
  const msg = (error as Error).message;
144
162
  Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);
145
163
  Logger.showErrorPopup(`Engine failed to generate a sub-layout.\n\nDetails: ${msg}`);
@@ -150,13 +168,18 @@ export class Engine {
150
168
  /**
151
169
  * Iterates through all active plugins and triggers their internal validation pipelines.
152
170
  *
171
+ * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.
153
172
  * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.
154
173
  */
155
- public validateAll(): IPluginValidationResult[] {
174
+ public validateAll(applyVisualState: boolean = false): IPluginValidationResult[] {
156
175
  const errors: IPluginValidationResult[] = [];
157
176
  for (const item of this.activePlugins) {
158
177
  try {
159
178
  const result = item.plugin.validate();
179
+ if (applyVisualState && typeof item.plugin.setVisualValidationState === "function") {
180
+ item.plugin.setVisualValidationState(result.isValid, result.errorMessage);
181
+ }
182
+
160
183
  if (!result.isValid) {
161
184
  // Ensure the path is bound to the error so GeneratorHost knows where to target it
162
185
  result.fieldKey = result.fieldKey || item.path.replace(/^\//, "");
@@ -165,14 +188,25 @@ export class Engine {
165
188
  Logger.error("[MetaUI Validation] Plugin failed validation silently:", item.path || item.plugin.constructor.name);
166
189
  }
167
190
  } catch (error) {
168
- const msg = (error as Error).message;
169
- Logger.error(`[MetaUI Validation] Exception during plugin validation at path ${item.path}`, msg);
170
- errors.push({ isValid: false, errorMessage: `Validation crashed: ${msg}`, fieldKey: item.path.replace(/^\//, "") });
191
+ Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, (error as Error).message);
171
192
  }
172
193
  }
173
194
  return errors;
174
195
  }
175
196
 
197
+ /**
198
+ * Retrieves an active plugin instance by its absolute binding path.
199
+ * Useful for programmatic field manipulation (e.g., custom error injection).
200
+ *
201
+ * @param path The binding path (e.g. "/General/CustomerName").
202
+ * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.
203
+ */
204
+ public getPluginByPath(path: string): import("../interfaces/IPlugin").IPlugin | undefined {
205
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
206
+ const match = this.activePlugins.find(p => p.path === cleanPath || p.path === `/${cleanPath}`);
207
+ return match ? match.plugin : undefined;
208
+ }
209
+
176
210
  /**
177
211
  * Cleans up internal state and destroys the condition engine to prevent memory leaks.
178
212
  */