@nocobase/flow-engine 2.0.0-alpha.10

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 (638) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +30 -0
  3. package/lib/ContextPathProxy.d.ts +17 -0
  4. package/lib/ContextPathProxy.js +65 -0
  5. package/lib/ElementProxy.d.ts +17 -0
  6. package/lib/ElementProxy.js +93 -0
  7. package/lib/FlowContextProvider.d.ts +24 -0
  8. package/lib/FlowContextProvider.js +82 -0
  9. package/lib/FlowDefinition.d.ts +423 -0
  10. package/lib/FlowDefinition.js +257 -0
  11. package/lib/JSRunner.d.ts +32 -0
  12. package/lib/JSRunner.js +95 -0
  13. package/lib/ReactView.d.ts +20 -0
  14. package/lib/ReactView.js +120 -0
  15. package/lib/ViewScopedFlowEngine.d.ts +23 -0
  16. package/lib/ViewScopedFlowEngine.js +81 -0
  17. package/lib/acl/Acl.d.ts +31 -0
  18. package/lib/acl/Acl.js +115 -0
  19. package/lib/action-registry/BaseActionRegistry.d.ts +23 -0
  20. package/lib/action-registry/BaseActionRegistry.js +57 -0
  21. package/lib/action-registry/EngineActionRegistry.d.ts +20 -0
  22. package/lib/action-registry/EngineActionRegistry.js +47 -0
  23. package/lib/action-registry/ModelActionRegistry.d.ts +34 -0
  24. package/lib/action-registry/ModelActionRegistry.js +79 -0
  25. package/lib/components/DynamicFlowsEditor.d.ts +17 -0
  26. package/lib/components/DynamicFlowsEditor.js +49 -0
  27. package/lib/components/FieldModelRenderer.d.ts +10 -0
  28. package/lib/components/FieldModelRenderer.js +100 -0
  29. package/lib/components/FlowContextSelector.d.ts +11 -0
  30. package/lib/components/FlowContextSelector.js +221 -0
  31. package/lib/components/FlowErrorFallback.d.ts +25 -0
  32. package/lib/components/FlowErrorFallback.js +264 -0
  33. package/lib/components/FlowModelRenderer.d.ts +61 -0
  34. package/lib/components/FlowModelRenderer.js +214 -0
  35. package/lib/components/FormItem.d.ts +18 -0
  36. package/lib/components/FormItem.js +151 -0
  37. package/lib/components/common/FlowSettingsButton.d.ts +11 -0
  38. package/lib/components/common/FlowSettingsButton.js +66 -0
  39. package/lib/components/common/index.d.ts +9 -0
  40. package/lib/components/common/index.js +30 -0
  41. package/lib/components/common/withFlowDesignMode.d.ts +26 -0
  42. package/lib/components/common/withFlowDesignMode.js +61 -0
  43. package/lib/components/dnd/findModelUidPosition.d.ts +13 -0
  44. package/lib/components/dnd/findModelUidPosition.js +50 -0
  45. package/lib/components/dnd/gridDragPlanner.d.ts +130 -0
  46. package/lib/components/dnd/gridDragPlanner.js +497 -0
  47. package/lib/components/dnd/index.d.ts +24 -0
  48. package/lib/components/dnd/index.js +164 -0
  49. package/lib/components/index.d.ts +18 -0
  50. package/lib/components/index.js +48 -0
  51. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.d.ts +46 -0
  52. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +225 -0
  53. package/lib/components/settings/independents/dropdown/index.d.ts +9 -0
  54. package/lib/components/settings/independents/dropdown/index.js +30 -0
  55. package/lib/components/settings/independents/index.d.ts +1 -0
  56. package/lib/components/settings/independents/index.js +30 -0
  57. package/lib/components/settings/index.d.ts +10 -0
  58. package/lib/components/settings/index.js +32 -0
  59. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +24 -0
  60. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +501 -0
  61. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.d.ts +45 -0
  62. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +231 -0
  63. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +111 -0
  64. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +484 -0
  65. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.d.ts +26 -0
  66. package/lib/components/settings/wrappers/contextual/StepRequiredSettingsDialog.js +342 -0
  67. package/lib/components/settings/wrappers/contextual/StepSettings.d.ts +23 -0
  68. package/lib/components/settings/wrappers/contextual/StepSettings.js +110 -0
  69. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.d.ts +20 -0
  70. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +212 -0
  71. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.d.ts +20 -0
  72. package/lib/components/settings/wrappers/contextual/StepSettingsDrawer.js +47 -0
  73. package/lib/components/settings/wrappers/contextual/index.d.ts +14 -0
  74. package/lib/components/settings/wrappers/contextual/index.js +40 -0
  75. package/lib/components/settings/wrappers/embedded/FlowSettings.d.ts +33 -0
  76. package/lib/components/settings/wrappers/embedded/FlowSettings.js +207 -0
  77. package/lib/components/settings/wrappers/embedded/FlowsSettings.d.ts +41 -0
  78. package/lib/components/settings/wrappers/embedded/FlowsSettings.js +84 -0
  79. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.d.ts +16 -0
  80. package/lib/components/settings/wrappers/embedded/FlowsSettingsContent.js +88 -0
  81. package/lib/components/settings/wrappers/embedded/index.d.ts +10 -0
  82. package/lib/components/settings/wrappers/embedded/index.js +32 -0
  83. package/lib/components/settings/wrappers/index.d.ts +2 -0
  84. package/lib/components/settings/wrappers/index.js +32 -0
  85. package/lib/components/subModel/AddSubModelButton.d.ts +62 -0
  86. package/lib/components/subModel/AddSubModelButton.js +415 -0
  87. package/lib/components/subModel/LazyDropdown.d.ts +55 -0
  88. package/lib/components/subModel/LazyDropdown.js +524 -0
  89. package/lib/components/subModel/index.d.ts +10 -0
  90. package/lib/components/subModel/index.js +32 -0
  91. package/lib/components/subModel/utils.d.ts +34 -0
  92. package/lib/components/subModel/utils.js +287 -0
  93. package/lib/components/variables/InlineVariableTag.d.ts +21 -0
  94. package/lib/components/variables/InlineVariableTag.js +123 -0
  95. package/lib/components/variables/SlateVariableEditor.d.ts +46 -0
  96. package/lib/components/variables/SlateVariableEditor.js +302 -0
  97. package/lib/components/variables/VariableInput.d.ts +11 -0
  98. package/lib/components/variables/VariableInput.js +334 -0
  99. package/lib/components/variables/VariableTag.d.ts +11 -0
  100. package/lib/components/variables/VariableTag.js +189 -0
  101. package/lib/components/variables/VariableTrigger.d.ts +20 -0
  102. package/lib/components/variables/VariableTrigger.js +136 -0
  103. package/lib/components/variables/index.d.ts +15 -0
  104. package/lib/components/variables/index.js +53 -0
  105. package/lib/components/variables/types.d.ts +93 -0
  106. package/lib/components/variables/types.js +24 -0
  107. package/lib/components/variables/useResolvedMetaTree.d.ts +19 -0
  108. package/lib/components/variables/useResolvedMetaTree.js +91 -0
  109. package/lib/components/variables/utils.d.ts +22 -0
  110. package/lib/components/variables/utils.js +177 -0
  111. package/lib/data-source/index.d.ts +180 -0
  112. package/lib/data-source/index.js +737 -0
  113. package/lib/data-source/jioToJoiSchema.d.ts +19 -0
  114. package/lib/data-source/jioToJoiSchema.js +114 -0
  115. package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
  116. package/lib/data-source/sortCollectionsByInherits.js +71 -0
  117. package/lib/decorators/index.d.ts +9 -0
  118. package/lib/decorators/index.js +36 -0
  119. package/lib/decorators/largeField.d.ts +9 -0
  120. package/lib/decorators/largeField.js +42 -0
  121. package/lib/emitter.d.ts +16 -0
  122. package/lib/emitter.js +58 -0
  123. package/lib/event-registry/BaseEventRegistry.d.ts +22 -0
  124. package/lib/event-registry/BaseEventRegistry.js +57 -0
  125. package/lib/event-registry/EngineEventRegistry.d.ts +19 -0
  126. package/lib/event-registry/EngineEventRegistry.js +47 -0
  127. package/lib/event-registry/ModelEventRegistry.d.ts +33 -0
  128. package/lib/event-registry/ModelEventRegistry.js +79 -0
  129. package/lib/executor/FlowExecutor.d.ts +25 -0
  130. package/lib/executor/FlowExecutor.js +290 -0
  131. package/lib/flow-registry/BaseFlowRegistry.d.ts +46 -0
  132. package/lib/flow-registry/BaseFlowRegistry.js +86 -0
  133. package/lib/flow-registry/GlobalFlowRegistry.d.ts +22 -0
  134. package/lib/flow-registry/GlobalFlowRegistry.js +95 -0
  135. package/lib/flow-registry/InstanceFlowRegistry.d.ts +21 -0
  136. package/lib/flow-registry/InstanceFlowRegistry.js +59 -0
  137. package/lib/flow-registry/index.d.ts +11 -0
  138. package/lib/flow-registry/index.js +34 -0
  139. package/lib/flowContext.d.ts +243 -0
  140. package/lib/flowContext.js +1337 -0
  141. package/lib/flowEngine.d.ts +340 -0
  142. package/lib/flowEngine.js +781 -0
  143. package/lib/flowI18n.d.ts +46 -0
  144. package/lib/flowI18n.js +117 -0
  145. package/lib/flowSettings.d.ts +266 -0
  146. package/lib/flowSettings.js +850 -0
  147. package/lib/hooks/index.d.ts +14 -0
  148. package/lib/hooks/index.js +40 -0
  149. package/lib/hooks/useApplyAutoFlows.d.ts +21 -0
  150. package/lib/hooks/useApplyAutoFlows.js +63 -0
  151. package/lib/hooks/useFlowModel.d.ts +29 -0
  152. package/lib/hooks/useFlowModel.js +72 -0
  153. package/lib/hooks/useFlowModelById.d.ts +11 -0
  154. package/lib/hooks/useFlowModelById.js +61 -0
  155. package/lib/hooks/useFlowSettingsContext.d.ts +20 -0
  156. package/lib/hooks/useFlowSettingsContext.js +61 -0
  157. package/lib/hooks/useFlowStep.d.ts +17 -0
  158. package/lib/hooks/useFlowStep.js +56 -0
  159. package/lib/hooks/useNiceDropdownMaxHeight.d.ts +13 -0
  160. package/lib/hooks/useNiceDropdownMaxHeight.js +52 -0
  161. package/lib/index.d.ts +30 -0
  162. package/lib/index.js +93 -0
  163. package/lib/locale/en-US.json +61 -0
  164. package/lib/locale/index.d.ts +141 -0
  165. package/lib/locale/index.js +70 -0
  166. package/lib/locale/zh-CN.json +61 -0
  167. package/lib/models/CollectionFieldModel.d.ts +52 -0
  168. package/lib/models/CollectionFieldModel.js +280 -0
  169. package/lib/models/DisplayItemModel.d.ts +12 -0
  170. package/lib/models/DisplayItemModel.js +41 -0
  171. package/lib/models/EditableItemModel.d.ts +12 -0
  172. package/lib/models/EditableItemModel.js +41 -0
  173. package/lib/models/FilterableItemModel.d.ts +12 -0
  174. package/lib/models/FilterableItemModel.js +41 -0
  175. package/lib/models/flowModel.d.ts +342 -0
  176. package/lib/models/flowModel.js +1154 -0
  177. package/lib/models/forkFlowModel.d.ts +83 -0
  178. package/lib/models/forkFlowModel.js +280 -0
  179. package/lib/models/index.d.ts +14 -0
  180. package/lib/models/index.js +40 -0
  181. package/lib/provider.d.ts +22 -0
  182. package/lib/provider.js +115 -0
  183. package/lib/resources/apiResource.d.ts +34 -0
  184. package/lib/resources/apiResource.js +153 -0
  185. package/lib/resources/baseRecordResource.d.ts +61 -0
  186. package/lib/resources/baseRecordResource.js +264 -0
  187. package/lib/resources/filterItem.d.ts +33 -0
  188. package/lib/resources/filterItem.js +93 -0
  189. package/lib/resources/flowResource.d.ts +45 -0
  190. package/lib/resources/flowResource.js +146 -0
  191. package/lib/resources/index.d.ts +15 -0
  192. package/lib/resources/index.js +42 -0
  193. package/lib/resources/multiRecordResource.d.ts +53 -0
  194. package/lib/resources/multiRecordResource.js +230 -0
  195. package/lib/resources/singleRecordResource.d.ts +23 -0
  196. package/lib/resources/singleRecordResource.js +111 -0
  197. package/lib/resources/sqlResource.d.ts +73 -0
  198. package/lib/resources/sqlResource.js +294 -0
  199. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +11 -0
  200. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +73 -0
  201. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +11 -0
  202. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +91 -0
  203. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +11 -0
  204. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +58 -0
  205. package/lib/runjs-context/contexts/JSColumnRunJSContext.d.ts +15 -0
  206. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
  207. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +11 -0
  208. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +74 -0
  209. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +11 -0
  210. package/lib/runjs-context/contexts/JSItemRunJSContext.js +70 -0
  211. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +11 -0
  212. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +60 -0
  213. package/lib/runjs-context/contexts/base.d.ts +9 -0
  214. package/lib/runjs-context/contexts/base.js +169 -0
  215. package/lib/runjs-context/helpers.d.ts +20 -0
  216. package/lib/runjs-context/helpers.js +88 -0
  217. package/lib/runjs-context/registry.d.ts +20 -0
  218. package/lib/runjs-context/registry.js +61 -0
  219. package/lib/runjs-context/setup.d.ts +9 -0
  220. package/lib/runjs-context/setup.js +82 -0
  221. package/lib/runjs-context/snippets/global/api-request.snippet.d.ts +11 -0
  222. package/lib/runjs-context/snippets/global/api-request.snippet.js +57 -0
  223. package/lib/runjs-context/snippets/global/import-esm.snippet.d.ts +11 -0
  224. package/lib/runjs-context/snippets/global/import-esm.snippet.js +58 -0
  225. package/lib/runjs-context/snippets/global/message-error.snippet.d.ts +11 -0
  226. package/lib/runjs-context/snippets/global/message-error.snippet.js +47 -0
  227. package/lib/runjs-context/snippets/global/message-success.snippet.d.ts +11 -0
  228. package/lib/runjs-context/snippets/global/message-success.snippet.js +47 -0
  229. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +11 -0
  230. package/lib/runjs-context/snippets/global/notification-open.snippet.js +50 -0
  231. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.d.ts +11 -0
  232. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +54 -0
  233. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.d.ts +11 -0
  234. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +54 -0
  235. package/lib/runjs-context/snippets/global/query-selector.snippet.d.ts +11 -0
  236. package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
  237. package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
  238. package/lib/runjs-context/snippets/global/require-amd.snippet.js +49 -0
  239. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +11 -0
  240. package/lib/runjs-context/snippets/global/window-open.snippet.js +48 -0
  241. package/lib/runjs-context/snippets/index.d.ts +22 -0
  242. package/lib/runjs-context/snippets/index.js +213 -0
  243. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
  244. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.js +55 -0
  245. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
  246. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
  247. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
  248. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
  249. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.d.ts +11 -0
  250. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.js +63 -0
  251. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
  252. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.js +52 -0
  253. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
  254. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
  255. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
  256. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +72 -0
  257. package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
  258. package/lib/runjs-context/snippets/scene/block/render-react.snippet.js +57 -0
  259. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
  260. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +100 -0
  261. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
  262. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +85 -0
  263. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
  264. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
  265. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
  266. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
  267. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
  268. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
  269. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
  270. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.js +52 -0
  271. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
  272. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.js +64 -0
  273. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
  274. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.js +51 -0
  275. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
  276. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.js +50 -0
  277. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
  278. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
  279. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
  280. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
  281. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
  282. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
  283. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
  284. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
  285. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
  286. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
  287. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
  288. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
  289. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
  290. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
  291. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
  292. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.js +53 -0
  293. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
  294. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.js +69 -0
  295. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
  296. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.js +68 -0
  297. package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
  298. package/lib/runjs-context/snippets/scene/form/set-required.snippet.js +69 -0
  299. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
  300. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
  301. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
  302. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.js +69 -0
  303. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
  304. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
  305. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
  306. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.js +53 -0
  307. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
  308. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
  309. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
  310. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.js +55 -0
  311. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
  312. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
  313. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
  314. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.js +52 -0
  315. package/lib/runjs-context/snippets/types.d.ts +24 -0
  316. package/lib/runjs-context/snippets/types.js +24 -0
  317. package/lib/types.d.ts +407 -0
  318. package/lib/types.js +43 -0
  319. package/lib/utils/autoFlowError.d.ts +16 -0
  320. package/lib/utils/autoFlowError.js +53 -0
  321. package/lib/utils/constants.d.ts +29 -0
  322. package/lib/utils/constants.js +77 -0
  323. package/lib/utils/context.d.ts +40 -0
  324. package/lib/utils/context.js +63 -0
  325. package/lib/utils/createCollectionContextMeta.d.ts +11 -0
  326. package/lib/utils/createCollectionContextMeta.js +117 -0
  327. package/lib/utils/exceptions.d.ts +22 -0
  328. package/lib/utils/exceptions.js +62 -0
  329. package/lib/utils/flow-definitions.d.ts +11 -0
  330. package/lib/utils/flow-definitions.js +40 -0
  331. package/lib/utils/index.d.ts +22 -0
  332. package/lib/utils/index.js +115 -0
  333. package/lib/utils/inheritance.d.ts +16 -0
  334. package/lib/utils/inheritance.js +53 -0
  335. package/lib/utils/params-resolvers.d.ts +51 -0
  336. package/lib/utils/params-resolvers.js +309 -0
  337. package/lib/utils/parsePathnameToViewParams.d.ts +34 -0
  338. package/lib/utils/parsePathnameToViewParams.js +84 -0
  339. package/lib/utils/safeGlobals.d.ts +16 -0
  340. package/lib/utils/safeGlobals.js +179 -0
  341. package/lib/utils/schema-utils.d.ts +40 -0
  342. package/lib/utils/schema-utils.js +161 -0
  343. package/lib/utils/serverContextParams.d.ts +29 -0
  344. package/lib/utils/serverContextParams.js +106 -0
  345. package/lib/utils/setupRuntimeContextSteps.d.ts +19 -0
  346. package/lib/utils/setupRuntimeContextSteps.js +88 -0
  347. package/lib/utils/translation.d.ts +18 -0
  348. package/lib/utils/translation.js +58 -0
  349. package/lib/utils/variablesParams.d.ts +52 -0
  350. package/lib/utils/variablesParams.js +161 -0
  351. package/lib/views/DialogComponent.d.ts +22 -0
  352. package/lib/views/DialogComponent.js +98 -0
  353. package/lib/views/DrawerComponent.d.ts +11 -0
  354. package/lib/views/DrawerComponent.js +101 -0
  355. package/lib/views/FlowView.d.ts +76 -0
  356. package/lib/views/FlowView.js +81 -0
  357. package/lib/views/PageComponent.d.ts +10 -0
  358. package/lib/views/PageComponent.js +168 -0
  359. package/lib/views/ViewNavigation.d.ts +45 -0
  360. package/lib/views/ViewNavigation.js +97 -0
  361. package/lib/views/createViewMeta.d.ts +44 -0
  362. package/lib/views/createViewMeta.js +377 -0
  363. package/lib/views/index.d.ts +14 -0
  364. package/lib/views/index.js +51 -0
  365. package/lib/views/useDialog.d.ts +32 -0
  366. package/lib/views/useDialog.js +200 -0
  367. package/lib/views/useDrawer.d.ts +33 -0
  368. package/lib/views/useDrawer.js +220 -0
  369. package/lib/views/usePage.d.ts +32 -0
  370. package/lib/views/usePage.js +194 -0
  371. package/lib/views/usePatchElement.d.ts +10 -0
  372. package/lib/views/usePatchElement.js +54 -0
  373. package/lib/views/usePopover.d.ts +17 -0
  374. package/lib/views/usePopover.js +159 -0
  375. package/package.json +37 -0
  376. package/src/ContextPathProxy.ts +45 -0
  377. package/src/ElementProxy.ts +69 -0
  378. package/src/FlowContextProvider.tsx +42 -0
  379. package/src/FlowDefinition.ts +275 -0
  380. package/src/JSRunner.ts +84 -0
  381. package/src/ReactView.tsx +104 -0
  382. package/src/ViewScopedFlowEngine.ts +75 -0
  383. package/src/__tests__/ElementProxy.test.ts +51 -0
  384. package/src/__tests__/JSRunner.test.ts +92 -0
  385. package/src/__tests__/ReactView.test.tsx +63 -0
  386. package/src/__tests__/context-path-proxy.test.ts +35 -0
  387. package/src/__tests__/flow-engine.test.ts +189 -0
  388. package/src/__tests__/flowContext.test.ts +2012 -0
  389. package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
  390. package/src/__tests__/flowEngine.saveModel.test.ts +171 -0
  391. package/src/__tests__/flowI18n.test.ts +28 -0
  392. package/src/__tests__/flowModel.getFlows.test.ts +61 -0
  393. package/src/__tests__/flowModel.openView.navigation.test.ts +78 -0
  394. package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
  395. package/src/__tests__/flowRuntimeContext.test.ts +187 -0
  396. package/src/__tests__/flowSettings.open.test.tsx +1920 -0
  397. package/src/__tests__/flowSettings.test.ts +566 -0
  398. package/src/__tests__/globalFlowRegistry.test.ts +77 -0
  399. package/src/__tests__/isFieldInterfaceMatch.test.ts +51 -0
  400. package/src/__tests__/metaTreeNodeCache.test.ts +234 -0
  401. package/src/__tests__/path-aggregation.test.ts +85 -0
  402. package/src/__tests__/provider.test.tsx +28 -0
  403. package/src/__tests__/renderHiddenInConfig.test.tsx +91 -0
  404. package/src/__tests__/runjsContext.test.ts +241 -0
  405. package/src/__tests__/runjsContextImplementations.test.ts +217 -0
  406. package/src/__tests__/runjsContextRuntime.test.ts +269 -0
  407. package/src/__tests__/runjsEdgeCases.test.ts +281 -0
  408. package/src/__tests__/runjsLocales.test.ts +36 -0
  409. package/src/__tests__/runjsRuntimeFeatures.test.ts +449 -0
  410. package/src/__tests__/runjsSnippets.test.ts +140 -0
  411. package/src/__tests__/viewScopedFlowEngine.test.ts +212 -0
  412. package/src/acl/Acl.tsx +109 -0
  413. package/src/acl/__tests__/Acl.test.tsx +72 -0
  414. package/src/action-registry/BaseActionRegistry.ts +46 -0
  415. package/src/action-registry/EngineActionRegistry.ts +32 -0
  416. package/src/action-registry/ModelActionRegistry.ts +75 -0
  417. package/src/action-registry/__tests__/engineActionRegistry.test.ts +43 -0
  418. package/src/action-registry/__tests__/modelActionRegistry.test.ts +107 -0
  419. package/src/components/DynamicFlowsEditor.tsx +318 -0
  420. package/src/components/FieldModelRenderer.tsx +68 -0
  421. package/src/components/FlowContextSelector.tsx +255 -0
  422. package/src/components/FlowErrorFallback.tsx +316 -0
  423. package/src/components/FlowModelRenderer.tsx +362 -0
  424. package/src/components/FormItem.tsx +136 -0
  425. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +226 -0
  426. package/src/components/__tests__/gridDragPlanner.test.ts +494 -0
  427. package/src/components/common/FlowSettingsButton.tsx +30 -0
  428. package/src/components/common/index.ts +10 -0
  429. package/src/components/common/withFlowDesignMode.tsx +49 -0
  430. package/src/components/dnd/README.md +149 -0
  431. package/src/components/dnd/findModelUidPosition.ts +26 -0
  432. package/src/components/dnd/gridDragPlanner.ts +659 -0
  433. package/src/components/dnd/index.tsx +128 -0
  434. package/src/components/index.ts +20 -0
  435. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +279 -0
  436. package/src/components/settings/independents/dropdown/index.ts +10 -0
  437. package/src/components/settings/independents/index.ts +2 -0
  438. package/src/components/settings/index.ts +11 -0
  439. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +617 -0
  440. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +292 -0
  441. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +655 -0
  442. package/src/components/settings/wrappers/contextual/StepRequiredSettingsDialog.tsx +446 -0
  443. package/src/components/settings/wrappers/contextual/StepSettings.tsx +109 -0
  444. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +223 -0
  445. package/src/components/settings/wrappers/contextual/StepSettingsDrawer.tsx +32 -0
  446. package/src/components/settings/wrappers/contextual/index.ts +15 -0
  447. package/src/components/settings/wrappers/embedded/FlowSettings.tsx +258 -0
  448. package/src/components/settings/wrappers/embedded/FlowsSettings.tsx +111 -0
  449. package/src/components/settings/wrappers/embedded/FlowsSettingsContent.tsx +96 -0
  450. package/src/components/settings/wrappers/embedded/index.ts +11 -0
  451. package/src/components/settings/wrappers/index.ts +5 -0
  452. package/src/components/subModel/AddSubModelButton.tsx +575 -0
  453. package/src/components/subModel/LazyDropdown.tsx +714 -0
  454. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +1185 -0
  455. package/src/components/subModel/__tests__/buildWrapperFieldChildren.test.ts +192 -0
  456. package/src/components/subModel/__tests__/utils.test.ts +425 -0
  457. package/src/components/subModel/index.ts +12 -0
  458. package/src/components/subModel/utils.ts +278 -0
  459. package/src/components/variables/InlineVariableTag.tsx +97 -0
  460. package/src/components/variables/SlateVariableEditor.tsx +384 -0
  461. package/src/components/variables/VariableInput.tsx +360 -0
  462. package/src/components/variables/VariableTag.tsx +175 -0
  463. package/src/components/variables/VariableTrigger.tsx +116 -0
  464. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +553 -0
  465. package/src/components/variables/__tests__/VariableInput.test.tsx +550 -0
  466. package/src/components/variables/__tests__/VariableTag.test.tsx +347 -0
  467. package/src/components/variables/__tests__/test-utils.tsx +62 -0
  468. package/src/components/variables/__tests__/utils.test.ts +310 -0
  469. package/src/components/variables/index.ts +16 -0
  470. package/src/components/variables/types.ts +100 -0
  471. package/src/components/variables/useResolvedMetaTree.ts +76 -0
  472. package/src/components/variables/utils.ts +192 -0
  473. package/src/data-source/__tests__/collection.test.ts +58 -0
  474. package/src/data-source/__tests__/index.test.ts +82 -0
  475. package/src/data-source/__tests__/jioToJoiSchema.test.ts +56 -0
  476. package/src/data-source/__tests__/sortCollectionsByInherits.test.ts +125 -0
  477. package/src/data-source/index.ts +816 -0
  478. package/src/data-source/jioToJoiSchema.ts +103 -0
  479. package/src/data-source/sortCollectionsByInherits.ts +61 -0
  480. package/src/decorators/index.ts +10 -0
  481. package/src/decorators/largeField.ts +14 -0
  482. package/src/emitter.ts +33 -0
  483. package/src/event-registry/BaseEventRegistry.ts +40 -0
  484. package/src/event-registry/EngineEventRegistry.ts +26 -0
  485. package/src/event-registry/ModelEventRegistry.ts +69 -0
  486. package/src/event-registry/__tests__/engineEventRegistry.test.ts +48 -0
  487. package/src/executor/FlowExecutor.ts +302 -0
  488. package/src/executor/__tests__/eventStep.test.ts +157 -0
  489. package/src/executor/__tests__/flowExecutor.test.ts +309 -0
  490. package/src/flow-registry/BaseFlowRegistry.ts +91 -0
  491. package/src/flow-registry/GlobalFlowRegistry.ts +82 -0
  492. package/src/flow-registry/InstanceFlowRegistry.ts +39 -0
  493. package/src/flow-registry/__tests__/globalFlowRegistry.test.ts +141 -0
  494. package/src/flow-registry/__tests__/instance-and-global-registry.test.ts +67 -0
  495. package/src/flow-registry/__tests__/instanceFlowRegistry.test.ts +83 -0
  496. package/src/flow-registry/index.ts +12 -0
  497. package/src/flowContext.ts +1742 -0
  498. package/src/flowEngine.ts +905 -0
  499. package/src/flowI18n.ts +96 -0
  500. package/src/flowSettings.ts +1045 -0
  501. package/src/hooks/index.ts +15 -0
  502. package/src/hooks/useApplyAutoFlows.ts +53 -0
  503. package/src/hooks/useFlowModel.tsx +59 -0
  504. package/src/hooks/useFlowModelById.ts +37 -0
  505. package/src/hooks/useFlowSettingsContext.tsx +37 -0
  506. package/src/hooks/useFlowStep.tsx +19 -0
  507. package/src/hooks/useNiceDropdownMaxHeight.ts +34 -0
  508. package/src/index.ts +46 -0
  509. package/src/locale/en-US.json +61 -0
  510. package/src/locale/index.ts +38 -0
  511. package/src/locale/zh-CN.json +61 -0
  512. package/src/models/CollectionFieldModel.tsx +306 -0
  513. package/src/models/DisplayItemModel.tsx +13 -0
  514. package/src/models/EditableItemModel.tsx +13 -0
  515. package/src/models/FilterableItemModel.tsx +13 -0
  516. package/src/models/__tests__/CollectionFieldModel.test.ts +122 -0
  517. package/src/models/__tests__/defaultParams-on-create.test.ts +83 -0
  518. package/src/models/__tests__/flow-model-oninit.test.ts +44 -0
  519. package/src/models/__tests__/flowModel.actions.integration.test.ts +100 -0
  520. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +100 -0
  521. package/src/models/__tests__/flowModel.test.ts +2869 -0
  522. package/src/models/__tests__/flowRegistry.test.ts +512 -0
  523. package/src/models/__tests__/forkFlowModel.test.ts +1047 -0
  524. package/src/models/__tests__/model-actions.test.ts +70 -0
  525. package/src/models/__tests__/model-events.test.ts +69 -0
  526. package/src/models/flowModel.tsx +1421 -0
  527. package/src/models/forkFlowModel.ts +319 -0
  528. package/src/models/index.ts +17 -0
  529. package/src/provider.tsx +103 -0
  530. package/src/resources/__tests__/apiResource.test.ts +201 -0
  531. package/src/resources/__tests__/baseRecordResource.test.ts +262 -0
  532. package/src/resources/__tests__/filterItem.test.ts +260 -0
  533. package/src/resources/__tests__/flowResource.test.ts +127 -0
  534. package/src/resources/apiResource.ts +148 -0
  535. package/src/resources/baseRecordResource.ts +279 -0
  536. package/src/resources/filterItem.ts +74 -0
  537. package/src/resources/flowResource.ts +143 -0
  538. package/src/resources/index.ts +17 -0
  539. package/src/resources/multiRecordResource.ts +219 -0
  540. package/src/resources/singleRecordResource.ts +83 -0
  541. package/src/resources/sqlResource.ts +299 -0
  542. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +46 -0
  543. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +64 -0
  544. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +31 -0
  545. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
  546. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +48 -0
  547. package/src/runjs-context/contexts/JSItemRunJSContext.ts +43 -0
  548. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +33 -0
  549. package/src/runjs-context/contexts/base.ts +155 -0
  550. package/src/runjs-context/helpers.ts +58 -0
  551. package/src/runjs-context/registry.ts +34 -0
  552. package/src/runjs-context/setup.ts +51 -0
  553. package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
  554. package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
  555. package/src/runjs-context/snippets/global/message-error.snippet.ts +26 -0
  556. package/src/runjs-context/snippets/global/message-success.snippet.ts +26 -0
  557. package/src/runjs-context/snippets/global/notification-open.snippet.ts +31 -0
  558. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +33 -0
  559. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +33 -0
  560. package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
  561. package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
  562. package/src/runjs-context/snippets/global/window-open.snippet.ts +29 -0
  563. package/src/runjs-context/snippets/index.ts +195 -0
  564. package/src/runjs-context/snippets/scene/block/add-event-listener.snippet.ts +41 -0
  565. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
  566. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
  567. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
  568. package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +33 -0
  569. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
  570. package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +53 -0
  571. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
  572. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +81 -0
  573. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +66 -0
  574. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
  575. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
  576. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
  577. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
  578. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
  579. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
  580. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
  581. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
  582. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
  583. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
  584. package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
  585. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
  586. package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
  587. package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
  588. package/src/runjs-context/snippets/scene/form/render-basic.snippet.ts +39 -0
  589. package/src/runjs-context/snippets/scene/form/set-disabled.snippet.ts +50 -0
  590. package/src/runjs-context/snippets/scene/form/set-field-value.snippet.ts +49 -0
  591. package/src/runjs-context/snippets/scene/form/set-required.snippet.ts +50 -0
  592. package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
  593. package/src/runjs-context/snippets/scene/form/toggle-visible.snippet.ts +50 -0
  594. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
  595. package/src/runjs-context/snippets/scene/table/collection-selected-count.snippet.ts +34 -0
  596. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
  597. package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
  598. package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
  599. package/src/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.ts +33 -0
  600. package/src/runjs-context/snippets/types.ts +21 -0
  601. package/src/types.ts +484 -0
  602. package/src/utils/__tests__/context.test.ts +93 -0
  603. package/src/utils/__tests__/params-resolvers.test.ts +652 -0
  604. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +104 -0
  605. package/src/utils/__tests__/safeGlobals.test.ts +29 -0
  606. package/src/utils/__tests__/utils.test.ts +1021 -0
  607. package/src/utils/__tests__/variablesParams.test.ts +52 -0
  608. package/src/utils/autoFlowError.ts +29 -0
  609. package/src/utils/constants.ts +60 -0
  610. package/src/utils/context.ts +70 -0
  611. package/src/utils/createCollectionContextMeta.ts +122 -0
  612. package/src/utils/exceptions.ts +36 -0
  613. package/src/utils/flow-definitions.ts +16 -0
  614. package/src/utils/index.ts +62 -0
  615. package/src/utils/inheritance.ts +39 -0
  616. package/src/utils/params-resolvers.ts +482 -0
  617. package/src/utils/parsePathnameToViewParams.ts +103 -0
  618. package/src/utils/safeGlobals.ts +188 -0
  619. package/src/utils/schema-utils.ts +201 -0
  620. package/src/utils/serverContextParams.ts +112 -0
  621. package/src/utils/setupRuntimeContextSteps.ts +89 -0
  622. package/src/utils/translation.ts +37 -0
  623. package/src/utils/variablesParams.ts +184 -0
  624. package/src/views/DialogComponent.tsx +79 -0
  625. package/src/views/DrawerComponent.tsx +72 -0
  626. package/src/views/FlowView.tsx +103 -0
  627. package/src/views/PageComponent.tsx +150 -0
  628. package/src/views/ViewNavigation.ts +122 -0
  629. package/src/views/__tests__/FlowView.test.ts +31 -0
  630. package/src/views/__tests__/ViewNavigation.test.ts +191 -0
  631. package/src/views/__tests__/usePatchElement.test.tsx +28 -0
  632. package/src/views/createViewMeta.ts +402 -0
  633. package/src/views/index.tsx +15 -0
  634. package/src/views/useDialog.tsx +194 -0
  635. package/src/views/useDrawer.tsx +229 -0
  636. package/src/views/usePage.tsx +185 -0
  637. package/src/views/usePatchElement.tsx +27 -0
  638. package/src/views/usePopover.tsx +131 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import 'ses';
11
+
12
+ export interface JSRunnerOptions {
13
+ timeoutMs?: number;
14
+ globals?: Record<string, any>;
15
+ version?: string;
16
+ }
17
+
18
+ export class JSRunner {
19
+ private globals: Record<string, any>;
20
+ private timeoutMs: number;
21
+
22
+ constructor(options: JSRunnerOptions = {}) {
23
+ const bindWindowFn = (key: 'setTimeout' | 'clearTimeout' | 'setInterval' | 'clearInterval') => {
24
+ if (typeof window !== 'undefined' && typeof window[key] === 'function') {
25
+ return window[key].bind(window);
26
+ }
27
+ const fn = globalThis[key];
28
+ return typeof fn === 'function' ? fn.bind(globalThis) : fn;
29
+ };
30
+
31
+ this.globals = {
32
+ console,
33
+ setTimeout: bindWindowFn('setTimeout'),
34
+ clearTimeout: bindWindowFn('clearTimeout'),
35
+ setInterval: bindWindowFn('setInterval'),
36
+ clearInterval: bindWindowFn('clearInterval'),
37
+ ...(options.globals || {}),
38
+ };
39
+ this.timeoutMs = options.timeoutMs ?? 5000; // 默认 5 秒超时
40
+ }
41
+
42
+ /**
43
+ * 注册单个变量或函数
44
+ */
45
+ register(name: string, value: any): void {
46
+ this.globals[name] = value;
47
+ }
48
+
49
+ /**
50
+ * 异步运行代码,带错误处理和超时机制
51
+ */
52
+ async run(code: string): Promise<{
53
+ success: boolean;
54
+ value?: any;
55
+ error?: any;
56
+ timeout?: boolean;
57
+ }> {
58
+ const wrapped = `(async () => {
59
+ try {
60
+ ${code};
61
+ } catch (e) {
62
+ throw e;
63
+ }
64
+ })()`;
65
+
66
+ const compartment = new Compartment(this.globals);
67
+
68
+ try {
69
+ const task = compartment.evaluate(wrapped);
70
+ const timeoutPromise = new Promise((_resolve, reject) =>
71
+ setTimeout(() => reject(new Error('Execution timed out')), this.timeoutMs),
72
+ );
73
+ const result = await Promise.race([task, timeoutPromise]);
74
+ return { success: true, value: result };
75
+ } catch (err) {
76
+ console.error(err);
77
+ return {
78
+ success: false,
79
+ error: err,
80
+ timeout: err.message === 'Execution timed out',
81
+ };
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { App, ConfigProvider } from 'antd';
11
+ import React from 'react';
12
+ import { Root, RootOptions, createRoot } from 'react-dom/client';
13
+ import { FlowEngine } from './flowEngine';
14
+ import { FlowEngineProvider } from './provider';
15
+
16
+ function Provider({ config, engine, children }) {
17
+ return (
18
+ <FlowEngineProvider engine={engine}>
19
+ <ConfigProvider {...config}>
20
+ <App>{children}</App>
21
+ </ConfigProvider>
22
+ </FlowEngineProvider>
23
+ );
24
+ }
25
+
26
+ export class ReactView {
27
+ private refreshCallback: (() => void) | null = null;
28
+
29
+ constructor(private flowEngine: FlowEngine) {}
30
+
31
+ createRoot(container: HTMLElement, options: RootOptions = {}): Root {
32
+ const root = createRoot(container, options);
33
+ let currentChildren: React.ReactNode;
34
+
35
+ const doRender = () => {
36
+ root.render(
37
+ <Provider engine={this.flowEngine} config={this.flowEngine.context.antdConfig}>
38
+ {currentChildren}
39
+ </Provider>,
40
+ );
41
+ };
42
+
43
+ const flowRoot = {
44
+ render: (children: React.ReactNode) => {
45
+ currentChildren = children;
46
+ this.refreshCallback = doRender;
47
+ doRender();
48
+ },
49
+ unmount: () => {
50
+ this.refreshCallback = null;
51
+ currentChildren = null;
52
+ root.unmount();
53
+ },
54
+ };
55
+
56
+ return flowRoot;
57
+ }
58
+
59
+ // 重新渲染当前根
60
+ refresh() {
61
+ if (this.refreshCallback) {
62
+ this.refreshCallback();
63
+ }
64
+ }
65
+
66
+ render(children: React.ReactNode | ((root: Root) => React.ReactNode), options: any = {}) {
67
+ const container = document.createElement('span');
68
+ const { onRendered } = options;
69
+ let root: Root;
70
+
71
+ const renderContent = (root: Root) => {
72
+ const content = typeof children === 'function' ? (children as (root: Root) => React.ReactNode)(root) : children;
73
+ return (
74
+ <Provider engine={this.flowEngine} config={this.flowEngine.context.antdConfig}>
75
+ {content}
76
+ </Provider>
77
+ );
78
+ };
79
+
80
+ if (onRendered) {
81
+ onRendered(() => {
82
+ root = createRoot(container);
83
+ root.render(renderContent(root));
84
+ });
85
+ } else {
86
+ root = createRoot(container);
87
+ root.render(renderContent(root));
88
+ }
89
+
90
+ (container as any)._reactRoot = root;
91
+
92
+ return container;
93
+ }
94
+
95
+ onRefReady<T extends HTMLElement>(ref: React.RefObject<T>, cb: (el: T) => void, timeout = 10000) {
96
+ const start = Date.now();
97
+ function check() {
98
+ if (ref.current) return cb(ref.current);
99
+ if (Date.now() - start > timeout) return;
100
+ setTimeout(check, 30);
101
+ }
102
+ check();
103
+ }
104
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { FlowEngine } from './flowEngine';
11
+
12
+ /**
13
+ * ViewScopedFlowEngine(视图作用域引擎)
14
+ *
15
+ * 设计目标:
16
+ * - 仅在视图(dialog/drawer/embed)作用域内隔离“模型实例表”和“事件缓存”;
17
+ * - 其余能力(动作/事件/模型类/资源/仓库/设置/日志/翻译等)全部直接代理到父引擎;
18
+ * - 使用 Proxy 实现“最小代理”,保持与父引擎的全局一致性。
19
+ *
20
+ * 注意:
21
+ * - 本地化的字段仅有:`_modelInstances`、`_applyFlowCache`、`executor`、`context`;
22
+ * - 其它字段/方法均通过 Proxy 转发到父引擎;
23
+ * - 这满足“同一 uid 在不同视图中互不污染(实例/缓存隔离)”与“共享全局注册/仓库”的诉求。
24
+ */
25
+ export function createViewScopedEngine(parent: FlowEngine): FlowEngine {
26
+ const local = new FlowEngine();
27
+ if (parent.modelRepository) {
28
+ local.setModelRepository(parent.modelRepository);
29
+ }
30
+ local.context.addDelegate(parent.context);
31
+
32
+ // 默认全部代理到父引擎,只有少数字段(实例/缓存/执行器/上下文/链表指针)使用本地值
33
+ const localOnly = new Set<keyof FlowEngine | string>([
34
+ '_modelInstances',
35
+ '_applyFlowCache',
36
+ 'executor',
37
+ 'context',
38
+ 'previousEngine',
39
+ 'nextEngine',
40
+ // 栈指针维护方法需要在本地执行,而非代理到父引擎
41
+ 'unlinkFromStack',
42
+ 'linkAfter',
43
+ '_previousEngine',
44
+ '_nextEngine',
45
+ ]);
46
+
47
+ const handler: ProxyHandler<FlowEngine> = {
48
+ get(target, prop: string, receiver) {
49
+ // 本地化字段(实例/缓存/执行器/上下文)
50
+ if (localOnly.has(prop)) {
51
+ return Reflect.get(target, prop, receiver);
52
+ }
53
+ // 其它一律代理到父引擎
54
+ const value = Reflect.get(parent, prop, receiver);
55
+ // 某些依赖 this 的方法需要绑定到父引擎实例
56
+ if (prop === 'registerModels' && typeof value === 'function') {
57
+ return value.bind(parent);
58
+ }
59
+ return value;
60
+ },
61
+ set(target, prop: string, value: unknown) {
62
+ if (localOnly.has(prop)) {
63
+ return Reflect.set(target, prop, value);
64
+ }
65
+ return Reflect.set(parent, prop, value);
66
+ },
67
+ has(target, prop: string) {
68
+ return prop in target || prop in parent;
69
+ },
70
+ };
71
+
72
+ // 建立 previous/next 链表指针,表示视图栈关系
73
+ local.linkAfter(parent);
74
+ return new Proxy(local, handler) as FlowEngine;
75
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { describe, expect, it } from 'vitest';
11
+ import { ElementProxy } from '../ElementProxy';
12
+
13
+ describe('ElementProxy', () => {
14
+ it('proxies element methods and properties', () => {
15
+ const el = document.createElement('div');
16
+ const proxy: any = new ElementProxy(el);
17
+
18
+ proxy.setAttribute('data-x', '1');
19
+ expect(el.getAttribute('data-x')).toBe('1');
20
+
21
+ proxy.id = 'abc';
22
+ expect(el.id).toBe('abc');
23
+ expect(proxy.id).toBe('abc');
24
+ });
25
+
26
+ it('sanitizes innerHTML/outerHTML setters', () => {
27
+ const el = document.createElement('div');
28
+ const proxy: any = new ElementProxy(el);
29
+
30
+ proxy.innerHTML = '<img src=x onerror=alert(1)><span>ok</span>';
31
+ expect(proxy.innerHTML).toContain('<span>ok</span>');
32
+ expect(proxy.innerHTML).not.toContain('onerror');
33
+
34
+ const container = document.createElement('div');
35
+ container.appendChild(el);
36
+ proxy.outerHTML = '<div onload=1>unsafe</div>';
37
+ expect(container.innerHTML).toContain('unsafe');
38
+ expect(container.innerHTML).not.toContain('onload');
39
+ });
40
+
41
+ it('appendChild accepts string or HTMLElement', () => {
42
+ const el = document.createElement('div');
43
+ const proxy: any = new ElementProxy(el);
44
+ proxy.appendChild('hello');
45
+ const span = document.createElement('span');
46
+ span.textContent = 'world';
47
+ proxy.appendChild(span);
48
+ expect(el.textContent).toContain('hello');
49
+ expect(el.querySelector('span')?.textContent).toBe('world');
50
+ });
51
+ });
@@ -0,0 +1,92 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { JSRunner } from '../JSRunner';
11
+
12
+ describe('JSRunner', () => {
13
+ it('should run simple code successfully', async () => {
14
+ const runner = new JSRunner();
15
+ const result = await runner.run(`
16
+ const x = 10;
17
+ return x + 5;
18
+ `);
19
+ expect(result.success).toBe(true);
20
+ expect(result.value).toBe(15);
21
+ });
22
+
23
+ it('should handle syntax errors in the code', async () => {
24
+ const runner = new JSRunner();
25
+ const result = await runner.run('const x = 10 x + 5;'); // Syntax error
26
+ expect(result.success).toBe(false);
27
+ expect(result.error).toBeInstanceOf(SyntaxError);
28
+ });
29
+
30
+ it('should handle runtime errors in the code', async () => {
31
+ const runner = new JSRunner();
32
+ const result = await runner.run(`
33
+ const x = 10;
34
+ throw new Error('Test error');
35
+ `);
36
+ expect(result.success).toBe(false);
37
+ expect(result.error).toBeInstanceOf(Error);
38
+ expect(result.error.message).toBe('Test error');
39
+ });
40
+
41
+ it('should handle timeout errors', async () => {
42
+ const runner = new JSRunner({ timeoutMs: 100 }); // Set a short timeout
43
+ const result = await runner.run(`
44
+ await new Promise(resolve => setTimeout(resolve, 500)); // Exceeds timeout
45
+ return 'Done';
46
+ `);
47
+ console.log(result);
48
+ expect(result.success).toBe(false);
49
+ expect(result.timeout).toBe(true);
50
+ expect(result.error.message).toBe('Execution timed out');
51
+ });
52
+
53
+ it('should use registered globals', async () => {
54
+ const runner = new JSRunner();
55
+ runner.register('globalVar', 42);
56
+ const result = await runner.run(`
57
+ return globalVar + 8;
58
+ `);
59
+ expect(result.success).toBe(true);
60
+ expect(result.value).toBe(50);
61
+ });
62
+
63
+ it('should handle code with async/await', async () => {
64
+ const runner = new JSRunner();
65
+ const result = await runner.run(`
66
+ const fetchData = async () => {
67
+ return new Promise(resolve => setTimeout(() => resolve(100), 50));
68
+ };
69
+ const data = await fetchData();
70
+ return data + 50;
71
+ `);
72
+ expect(result.success).toBe(true);
73
+ expect(result.value).toBe(150);
74
+ });
75
+
76
+ it('should handle empty code', async () => {
77
+ const runner = new JSRunner();
78
+ const result = await runner.run('');
79
+ expect(result.success).toBe(true);
80
+ expect(result.value).toBe(undefined);
81
+ });
82
+
83
+ it('should handle code returning undefined explicitly', async () => {
84
+ const runner = new JSRunner();
85
+ const result = await runner.run(`
86
+ const x = 10;
87
+ return undefined;
88
+ `);
89
+ expect(result.success).toBe(true);
90
+ expect(result.value).toBe(undefined);
91
+ });
92
+ });
@@ -0,0 +1,63 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import React from 'react';
11
+ import { describe, expect, it } from 'vitest';
12
+ import { ReactView } from '../ReactView';
13
+ import { FlowEngine } from '../flowEngine';
14
+
15
+ describe('ReactView', () => {
16
+ it('createRoot returns object with render/unmount and refresh re-renders', () => {
17
+ const engine = new FlowEngine();
18
+ const view = new ReactView(engine);
19
+ const container = document.createElement('div');
20
+ const root = view.createRoot(container);
21
+ expect(typeof root.render).toBe('function');
22
+ expect(typeof root.unmount).toBe('function');
23
+ root.render(<div id="x">A</div>);
24
+ // refresh should not throw
25
+ view.refresh();
26
+ root.unmount();
27
+ });
28
+
29
+ it('render returns a DOM node with _reactRoot and supports onRendered hook', () => {
30
+ const engine = new FlowEngine();
31
+ const view = new ReactView(engine);
32
+ let ready: any;
33
+ const node = view.render(<span>Hi</span>, {
34
+ onRendered: (cb: any) => {
35
+ ready = cb;
36
+ },
37
+ });
38
+ expect(ready).toBeTypeOf('function');
39
+ // run the deferred render
40
+ ready();
41
+ // do not assert internal implementation detail (_reactRoot)
42
+ // just ensure the callback can be invoked without errors
43
+ });
44
+
45
+ it('onRefReady calls callback when ref becomes available', async () => {
46
+ const engine = new FlowEngine();
47
+ const view = new ReactView(engine);
48
+ const ref = { current: null } as any;
49
+ let called = false;
50
+ setTimeout(() => (ref.current = document.createElement('div')));
51
+ await new Promise<void>((resolve) => {
52
+ view.onRefReady(
53
+ ref,
54
+ () => {
55
+ called = true;
56
+ resolve();
57
+ },
58
+ 200,
59
+ );
60
+ });
61
+ expect(called).toBe(true);
62
+ });
63
+ });
@@ -0,0 +1,35 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { ContextPathProxy } from '../ContextPathProxy';
11
+
12
+ describe('createContextProxy', () => {
13
+ it('should return correct string template for root', () => {
14
+ const ctx = ContextPathProxy.create();
15
+ expect(ctx.toString()).toBe('{{ctx}}');
16
+ expect(`${ctx}`).toBe('{{ctx}}');
17
+ });
18
+
19
+ it('should support nested property access and string template', () => {
20
+ const ctx = ContextPathProxy.create();
21
+ expect(`${ctx.steps}`).toBe('{{ctx.steps}}');
22
+ expect(`${ctx.steps.step1}`).toBe('{{ctx.steps.step1}}');
23
+ expect(`${ctx.steps.step1.result}`).toBe('{{ctx.steps.step1.result}}');
24
+ });
25
+
26
+ it('should support valueOf for implicit conversion', () => {
27
+ const ctx = ContextPathProxy.create();
28
+ expect(ctx.steps.step1.result == '{{ctx.steps.step1.result}}').toBe(true);
29
+ });
30
+
31
+ it('should return undefined for symbol property', () => {
32
+ const ctx = ContextPathProxy.create();
33
+ expect((ctx as any)[Symbol.toPrimitive]).toBeUndefined();
34
+ });
35
+ });
@@ -0,0 +1,189 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
11
+ import { FlowEngine } from '../flowEngine';
12
+ import { FlowModel } from '../models';
13
+ import type { IFlowModelRepository } from '../types';
14
+
15
+ class BaseModel extends FlowModel {}
16
+ class SubModelA extends BaseModel {}
17
+ class SubModelB extends BaseModel {}
18
+ class SubModelC extends SubModelA {}
19
+
20
+ describe('FlowEngine', () => {
21
+ let engine: FlowEngine;
22
+
23
+ beforeEach(() => {
24
+ engine = new FlowEngine();
25
+ engine.registerModels({
26
+ BaseModel,
27
+ SubModelA,
28
+ SubModelB,
29
+ SubModelC,
30
+ });
31
+ });
32
+
33
+ it('getModelClass should return correct class', () => {
34
+ expect(engine.getModelClass('BaseModel')).toBe(BaseModel);
35
+ expect(engine.getModelClass('SubModelA')).toBe(SubModelA);
36
+ expect(engine.getModelClass('NotExist')).toBeUndefined();
37
+ });
38
+
39
+ it('getSubclassesOf should return all subclasses', () => {
40
+ const result = engine.getSubclassesOf(BaseModel);
41
+ expect(result.has('BaseModel')).toBe(false);
42
+ expect(result.has('SubModelA')).toBe(true);
43
+ expect(result.has('SubModelB')).toBe(true);
44
+ expect(result.has('SubModelC')).toBe(true);
45
+ });
46
+
47
+ it('getSubclassesOf should support filter', () => {
48
+ const result = engine.getSubclassesOf(BaseModel, (ModelClass, name) => name.startsWith('SubModel'));
49
+ expect(result.has('BaseModel')).toBe(false);
50
+ expect(result.has('SubModelA')).toBe(true);
51
+ expect(result.has('SubModelB')).toBe(true);
52
+ expect(result.has('SubModelC')).toBe(true);
53
+ });
54
+
55
+ it('findModelClass should find by predicate', () => {
56
+ const found = engine.findModelClass((name) => name === 'SubModelB');
57
+ expect(found).toBeDefined();
58
+ expect(found?.[0]).toBe('SubModelB');
59
+ expect(found?.[1]).toBe(SubModelB);
60
+ });
61
+
62
+ it('filterModelClassByParent should return correct subclasses', () => {
63
+ const result = engine.filterModelClassByParent(SubModelA);
64
+ expect(result.has('SubModelA')).toBe(false);
65
+ expect(result.has('SubModelC')).toBe(true);
66
+ expect(result.has('BaseModel')).toBe(false);
67
+ expect(result.has('SubModelB')).toBe(false);
68
+ });
69
+
70
+ it('registerAction/getAction should work', () => {
71
+ engine.registerActions({
72
+ testAction: {
73
+ name: 'testAction',
74
+ handler: vi.fn(),
75
+ },
76
+ });
77
+ const action = engine.getAction('testAction');
78
+ expect(action).toBeDefined();
79
+ expect(action?.name).toBe('testAction');
80
+ });
81
+
82
+ it('registerModels should overwrite existing model', () => {
83
+ class NewBaseModel extends FlowModel {}
84
+ engine.registerModels({ BaseModel: NewBaseModel });
85
+ expect(engine.getModelClass('BaseModel')).toBe(NewBaseModel);
86
+ });
87
+
88
+ describe('loadOrCreateModel', () => {
89
+ class MockFlowModelRepository implements IFlowModelRepository {
90
+ // 使用可配置返回值,便于不同用例控制 findOne 行为
91
+ findOneResult: any = null;
92
+ save = vi.fn(async (model: FlowModel) => ({ success: true, uid: model.uid }));
93
+ async findOne() {
94
+ // 返回深拷贝,避免被测试过程修改
95
+ return this.findOneResult ? JSON.parse(JSON.stringify(this.findOneResult)) : null;
96
+ }
97
+ async destroy() {
98
+ return true;
99
+ }
100
+ async move() {}
101
+ }
102
+
103
+ let repo: MockFlowModelRepository;
104
+
105
+ beforeEach(() => {
106
+ repo = new MockFlowModelRepository();
107
+ engine.setModelRepository(repo);
108
+ });
109
+
110
+ it('should set as object subModel when subType=object even if subKey="array" (regression for subType check)', async () => {
111
+ // 父模型
112
+ const parent = engine.createModel({ uid: 'p1', use: 'FlowModel' });
113
+
114
+ // 仓库返回数据:subKey 恰好为 'array',但 subType 是 'object'
115
+ repo.findOneResult = {
116
+ uid: 'c1',
117
+ use: 'FlowModel',
118
+ parentId: parent.uid,
119
+ subKey: 'array',
120
+ subType: 'object',
121
+ };
122
+
123
+ const child = await engine.loadOrCreateModel({
124
+ uid: 'c1',
125
+ use: 'FlowModel',
126
+ parentId: parent.uid,
127
+ subKey: 'array',
128
+ subType: 'object',
129
+ });
130
+
131
+ expect(child).toBeTruthy();
132
+ // 关键断言:应按 object 模式挂载,而不是数组
133
+ const mounted = (parent.subModels as any)['array'];
134
+ expect(Array.isArray(mounted)).toBe(false);
135
+ expect(mounted?.uid).toBe('c1');
136
+ expect(mounted).toBe(child);
137
+ });
138
+
139
+ it('should add to array subModels when subType=array', async () => {
140
+ const parent = engine.createModel({ uid: 'p2', use: 'FlowModel' });
141
+
142
+ repo.findOneResult = {
143
+ uid: 'c2',
144
+ use: 'FlowModel',
145
+ parentId: parent.uid,
146
+ subKey: 'items',
147
+ subType: 'array',
148
+ };
149
+
150
+ const child = await engine.loadOrCreateModel({
151
+ uid: 'c2',
152
+ use: 'FlowModel',
153
+ parentId: parent.uid,
154
+ subKey: 'items',
155
+ subType: 'array',
156
+ });
157
+
158
+ expect(child).toBeTruthy();
159
+ const arr = (parent.subModels as any)['items'];
160
+ expect(Array.isArray(arr)).toBe(true);
161
+ expect(arr.length).toBe(1);
162
+ expect(arr[0].uid).toBe('c2');
163
+ });
164
+
165
+ it('should create and save when repo has no data, then mount under parent accordingly (object case)', async () => {
166
+ const parent = engine.createModel({ uid: 'p3', use: 'FlowModel' });
167
+
168
+ // 仓库查无数据
169
+ repo.findOneResult = null;
170
+
171
+ const child = await engine.loadOrCreateModel({
172
+ uid: 'c3',
173
+ use: 'FlowModel',
174
+ parentId: parent.uid,
175
+ subKey: 'info',
176
+ subType: 'object',
177
+ });
178
+
179
+ expect(child).toBeTruthy();
180
+ // 应触发一次保存(create 后会调用 save)
181
+ expect(repo.save).toHaveBeenCalledTimes(1);
182
+
183
+ // 正确以对象形式挂载
184
+ const mounted = (parent.subModels as any)['info'];
185
+ expect(Array.isArray(mounted)).toBe(false);
186
+ expect(mounted?.uid).toBe('c3');
187
+ });
188
+ });
189
+ });