@nocobase/flow-engine 2.0.0-alpha.3 → 2.0.0-alpha.30

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 (418) hide show
  1. package/lib/BlockScopedFlowEngine.d.ts +23 -0
  2. package/lib/BlockScopedFlowEngine.js +90 -0
  3. package/lib/FlowContextProvider.d.ts +2 -2
  4. package/lib/FlowContextProvider.js +3 -3
  5. package/lib/FlowDefinition.d.ts +4 -2
  6. package/lib/JSRunner.js +3 -0
  7. package/lib/ViewScopedFlowEngine.d.ts +1 -1
  8. package/lib/components/FieldModelRenderer.js +10 -4
  9. package/lib/components/FieldSkeleton.d.ts +10 -0
  10. package/lib/components/FieldSkeleton.js +64 -0
  11. package/lib/components/FlowContextSelector.js +7 -2
  12. package/lib/components/FlowModelRenderer.d.ts +2 -5
  13. package/lib/components/FlowModelRenderer.js +16 -47
  14. package/lib/components/FormItem.js +5 -1
  15. package/lib/{runjs-context/snippets/global/requireAsync.snippet.d.ts → components/dnd/findModelUidPosition.d.ts} +4 -7
  16. package/lib/{runjs-context/snippets/scene/jsblock/jsx-mount.snippet.js → components/dnd/findModelUidPosition.js} +23 -19
  17. package/lib/components/dnd/gridDragPlanner.d.ts +130 -0
  18. package/lib/components/dnd/gridDragPlanner.js +497 -0
  19. package/lib/components/dnd/index.d.ts +2 -2
  20. package/lib/components/dnd/index.js +5 -5
  21. package/lib/components/settings/independents/dropdown/FlowsDropdownButton.js +2 -2
  22. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +17 -5
  23. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +2 -2
  24. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +7 -1
  25. package/lib/components/variables/VariableInput.js +16 -2
  26. package/lib/components/variables/VariableTag.js +43 -2
  27. package/lib/components/variables/types.d.ts +2 -0
  28. package/lib/data-source/index.d.ts +12 -4
  29. package/lib/data-source/index.js +19 -13
  30. package/lib/data-source/sortCollectionsByInherits.d.ts +10 -0
  31. package/lib/data-source/sortCollectionsByInherits.js +71 -0
  32. package/lib/executor/FlowExecutor.d.ts +4 -5
  33. package/lib/executor/FlowExecutor.js +135 -100
  34. package/lib/flowContext.d.ts +33 -5
  35. package/lib/flowContext.js +193 -76
  36. package/lib/flowEngine.d.ts +8 -1
  37. package/lib/flowEngine.js +18 -6
  38. package/lib/flowSettings.d.ts +2 -1
  39. package/lib/flowSettings.js +12 -8
  40. package/lib/hooks/useApplyAutoFlows.js +2 -1
  41. package/lib/index.d.ts +7 -1
  42. package/lib/index.js +32 -3
  43. package/lib/locale/en-US.json +4 -2
  44. package/lib/locale/index.d.ts +4 -0
  45. package/lib/locale/zh-CN.json +4 -2
  46. package/lib/models/CollectionFieldModel.d.ts +2 -0
  47. package/lib/models/CollectionFieldModel.js +43 -3
  48. package/lib/models/flowModel.d.ts +28 -29
  49. package/lib/models/flowModel.js +114 -92
  50. package/lib/models/forkFlowModel.d.ts +4 -4
  51. package/lib/models/forkFlowModel.js +32 -8
  52. package/lib/provider.d.ts +3 -1
  53. package/lib/provider.js +7 -5
  54. package/lib/resources/multiRecordResource.js +2 -0
  55. package/lib/resources/singleRecordResource.js +1 -0
  56. package/lib/resources/sqlResource.d.ts +1 -0
  57. package/lib/resources/sqlResource.js +20 -24
  58. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.d.ts +1 -6
  59. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +27 -20
  60. package/lib/runjs-context/contexts/JSBlockRunJSContext.d.ts +1 -6
  61. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +46 -33
  62. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.d.ts +1 -2
  63. package/lib/runjs-context/contexts/JSCollectionActionRunJSContext.js +14 -15
  64. package/lib/runjs-context/contexts/{LinkageRunJSContext.d.ts → JSColumnRunJSContext.d.ts} +6 -3
  65. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +78 -0
  66. package/lib/runjs-context/contexts/JSFieldRunJSContext.d.ts +1 -6
  67. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +28 -24
  68. package/lib/runjs-context/contexts/JSItemRunJSContext.d.ts +1 -6
  69. package/lib/runjs-context/contexts/JSItemRunJSContext.js +24 -20
  70. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.d.ts +1 -2
  71. package/lib/runjs-context/contexts/JSRecordActionRunJSContext.js +16 -17
  72. package/lib/runjs-context/contexts/base.d.ts +9 -0
  73. package/lib/runjs-context/contexts/base.js +183 -0
  74. package/lib/runjs-context/helpers.d.ts +5 -2
  75. package/lib/runjs-context/helpers.js +36 -27
  76. package/lib/runjs-context/registry.d.ts +7 -4
  77. package/lib/runjs-context/registry.js +10 -42
  78. package/lib/runjs-context/setup.d.ts +9 -0
  79. package/lib/runjs-context/setup.js +82 -0
  80. package/lib/runjs-context/snippets/global/{copy-record-json.snippet.js → api-request.snippet.js} +25 -10
  81. package/lib/runjs-context/snippets/global/clipboard-copy-text.snippet.js +61 -0
  82. package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.js → import-esm.snippet.js} +26 -12
  83. package/lib/runjs-context/snippets/global/message-error.snippet.js +6 -0
  84. package/lib/runjs-context/snippets/global/message-success.snippet.js +6 -0
  85. package/lib/runjs-context/snippets/global/notification-open.snippet.d.ts +3 -8
  86. package/lib/runjs-context/snippets/global/notification-open.snippet.js +8 -1
  87. package/lib/runjs-context/snippets/global/open-view-dialog.snippet.js +10 -3
  88. package/lib/runjs-context/snippets/global/open-view-drawer.snippet.js +10 -3
  89. package/lib/runjs-context/snippets/global/query-selector.snippet.js +53 -0
  90. package/lib/runjs-context/snippets/global/require-amd.snippet.d.ts +11 -0
  91. package/lib/runjs-context/snippets/global/{requireAsync.snippet.js → require-amd.snippet.js} +16 -13
  92. package/lib/runjs-context/snippets/global/window-open.snippet.d.ts +3 -8
  93. package/lib/runjs-context/snippets/global/window-open.snippet.js +8 -1
  94. package/lib/runjs-context/snippets/index.d.ts +14 -3
  95. package/lib/runjs-context/snippets/index.js +161 -40
  96. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.d.ts +11 -0
  97. package/lib/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.js +11 -2
  98. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.d.ts +11 -0
  99. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +64 -0
  100. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.d.ts +11 -0
  101. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +99 -0
  102. package/lib/runjs-context/snippets/{libs → scene/block}/echarts-init.snippet.js +24 -7
  103. package/lib/runjs-context/snippets/scene/block/render-button-handler.snippet.d.ts +11 -0
  104. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-button-handler.snippet.js +17 -9
  105. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.d.ts +11 -0
  106. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +57 -0
  107. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.d.ts +11 -0
  108. package/lib/runjs-context/snippets/scene/block/render-info-card.snippet.js +71 -0
  109. package/lib/runjs-context/snippets/scene/block/render-react-jsx.snippet.d.ts +11 -0
  110. package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.js → block/render-react-jsx.snippet.js} +26 -13
  111. package/lib/runjs-context/snippets/scene/block/render-react.snippet.d.ts +11 -0
  112. package/lib/runjs-context/snippets/scene/{jsblock → block}/render-react.snippet.js +18 -17
  113. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.d.ts +11 -0
  114. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +95 -0
  115. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.d.ts +11 -0
  116. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +84 -0
  117. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.d.ts +11 -0
  118. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +60 -0
  119. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.d.ts +11 -0
  120. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +283 -0
  121. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.d.ts +11 -0
  122. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +124 -0
  123. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.d.ts +11 -0
  124. package/lib/runjs-context/snippets/scene/{jsfield → detail}/color-by-value.snippet.js +13 -3
  125. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.d.ts +11 -0
  126. package/lib/runjs-context/snippets/{global → scene/detail}/copy-to-clipboard.snippet.js +28 -6
  127. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.d.ts +11 -0
  128. package/lib/runjs-context/snippets/scene/{jsfield → detail}/format-number.snippet.js +13 -3
  129. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.d.ts +11 -0
  130. package/lib/runjs-context/snippets/scene/{jsfield → detail}/innerHTML-value.snippet.js +13 -3
  131. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.d.ts +11 -0
  132. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +82 -0
  133. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.d.ts +11 -0
  134. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +80 -0
  135. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.d.ts +11 -0
  136. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +74 -0
  137. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.d.ts +11 -0
  138. package/lib/runjs-context/snippets/scene/form/calculate-total.snippet.js +63 -0
  139. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.d.ts +11 -0
  140. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +81 -0
  141. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.d.ts +11 -0
  142. package/lib/runjs-context/snippets/scene/form/conditional-required.snippet.js +64 -0
  143. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.d.ts +11 -0
  144. package/lib/runjs-context/snippets/scene/form/copy-field-values.snippet.js +74 -0
  145. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.d.ts +11 -0
  146. package/lib/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.js +11 -2
  147. package/lib/runjs-context/snippets/scene/form/set-disabled.snippet.d.ts +11 -0
  148. package/lib/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.js +12 -3
  149. package/lib/runjs-context/snippets/scene/form/set-field-value.snippet.d.ts +11 -0
  150. package/lib/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.js +12 -3
  151. package/lib/runjs-context/snippets/scene/form/set-required.snippet.d.ts +11 -0
  152. package/lib/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.js +12 -3
  153. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.d.ts +11 -0
  154. package/lib/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.js +67 -0
  155. package/lib/runjs-context/snippets/scene/form/toggle-visible.snippet.d.ts +11 -0
  156. package/lib/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.js +12 -3
  157. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.d.ts +11 -0
  158. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +64 -0
  159. package/lib/runjs-context/snippets/scene/table/collection-selected-count.snippet.d.ts +11 -0
  160. package/lib/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.js +11 -2
  161. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.d.ts +11 -0
  162. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +79 -0
  163. package/lib/runjs-context/snippets/scene/table/destroy-selected.snippet.d.ts +11 -0
  164. package/lib/runjs-context/snippets/{global/log-json-record.snippet.js → scene/table/destroy-selected.snippet.js} +24 -11
  165. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.d.ts +11 -0
  166. package/lib/runjs-context/snippets/scene/table/export-selected-json.snippet.js +64 -0
  167. package/lib/runjs-context/snippets/scene/table/iterate-selected-rows.snippet.d.ts +11 -0
  168. package/lib/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.js +11 -2
  169. package/lib/runjs-context/snippets/types.d.ts +9 -1
  170. package/lib/types.d.ts +28 -3
  171. package/lib/types.js +4 -3
  172. package/lib/utils/buildSettingsViewInputArgs.d.ts +19 -0
  173. package/lib/utils/buildSettingsViewInputArgs.js +75 -0
  174. package/lib/utils/createEphemeralContext.d.ts +13 -0
  175. package/lib/utils/createEphemeralContext.js +140 -0
  176. package/lib/utils/index.d.ts +3 -2
  177. package/lib/utils/index.js +5 -2
  178. package/lib/utils/jsxTransform.d.ts +15 -0
  179. package/lib/utils/jsxTransform.js +68 -0
  180. package/lib/utils/params-resolvers.js +3 -3
  181. package/lib/utils/safeGlobals.d.ts +5 -3
  182. package/lib/utils/safeGlobals.js +40 -0
  183. package/lib/utils/schema-utils.js +2 -2
  184. package/lib/utils/serverContextParams.d.ts +1 -0
  185. package/lib/utils/variablesParams.d.ts +9 -5
  186. package/lib/utils/variablesParams.js +47 -36
  187. package/lib/views/PageComponent.js +2 -1
  188. package/lib/views/createViewMeta.d.ts +29 -1
  189. package/lib/views/createViewMeta.js +338 -72
  190. package/lib/views/index.d.ts +1 -0
  191. package/lib/views/index.js +3 -0
  192. package/lib/views/useDialog.d.ts +8 -8
  193. package/lib/views/useDialog.js +8 -7
  194. package/lib/views/useDrawer.d.ts +8 -8
  195. package/lib/views/useDrawer.js +40 -26
  196. package/lib/views/usePage.d.ts +8 -8
  197. package/lib/views/usePage.js +8 -7
  198. package/package.json +5 -3
  199. package/src/BlockScopedFlowEngine.ts +86 -0
  200. package/src/FlowContextProvider.tsx +4 -2
  201. package/src/JSRunner.ts +3 -0
  202. package/src/ViewScopedFlowEngine.ts +1 -1
  203. package/src/__tests__/JSRunner.test.ts +62 -53
  204. package/src/__tests__/blockScopedFlowEngine.test.ts +154 -0
  205. package/src/__tests__/createViewMeta.popup.test.ts +132 -0
  206. package/src/__tests__/flow-engine.test.ts +3 -0
  207. package/src/__tests__/flowContextCreateJSRunner.test.ts +163 -0
  208. package/src/__tests__/flowEngine.saveModel.test.ts +4 -0
  209. package/src/__tests__/flowRunJSContextDefine.test.ts +508 -0
  210. package/src/__tests__/globalFlowRegistry.test.ts +1 -1
  211. package/src/__tests__/runjsContext.test.ts +216 -35
  212. package/src/__tests__/runjsContextImplementations.test.ts +217 -0
  213. package/src/__tests__/runjsContextRuntime.test.ts +269 -0
  214. package/src/__tests__/runjsEdgeCases.test.ts +281 -0
  215. package/src/__tests__/runjsLocales.test.ts +36 -0
  216. package/src/__tests__/runjsRuntimeFeatures.test.ts +449 -0
  217. package/src/__tests__/runjsSnippets.test.ts +140 -0
  218. package/src/__tests__/viewScopedFlowEngine.test.ts +3 -3
  219. package/src/components/DynamicFlowsEditor.tsx +3 -4
  220. package/src/components/FieldModelRenderer.tsx +16 -5
  221. package/src/components/FieldSkeleton.tsx +27 -0
  222. package/src/components/FlowContextSelector.tsx +6 -2
  223. package/src/components/FlowModelRenderer.tsx +30 -78
  224. package/src/components/FormItem.tsx +8 -1
  225. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +5 -5
  226. package/src/components/__tests__/gridDragPlanner.test.ts +494 -0
  227. package/src/components/dnd/README.md +149 -0
  228. package/src/components/dnd/findModelUidPosition.ts +26 -0
  229. package/src/components/dnd/gridDragPlanner.ts +659 -0
  230. package/src/components/dnd/index.tsx +3 -3
  231. package/src/components/settings/independents/dropdown/FlowsDropdownButton.tsx +1 -1
  232. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +17 -4
  233. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +1 -1
  234. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +14 -1
  235. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +424 -0
  236. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +5 -7
  237. package/src/components/variables/VariableInput.tsx +22 -2
  238. package/src/components/variables/VariableTag.tsx +54 -2
  239. package/src/components/variables/types.ts +2 -0
  240. package/src/data-source/__tests__/sortCollectionsByInherits.test.ts +125 -0
  241. package/src/data-source/index.ts +17 -11
  242. package/src/data-source/sortCollectionsByInherits.ts +61 -0
  243. package/src/executor/FlowExecutor.ts +178 -121
  244. package/src/executor/__tests__/ctx-defs-injection.test.ts +197 -0
  245. package/src/executor/__tests__/flowExecutor.test.ts +151 -5
  246. package/src/flowContext.ts +266 -97
  247. package/src/flowEngine.ts +21 -6
  248. package/src/flowSettings.ts +9 -4
  249. package/src/hooks/useApplyAutoFlows.ts +3 -1
  250. package/src/index.ts +12 -1
  251. package/src/locale/en-US.json +4 -2
  252. package/src/locale/zh-CN.json +4 -2
  253. package/src/models/CollectionFieldModel.tsx +43 -4
  254. package/src/models/__tests__/flowModel.getFlows.sort.test.ts +4 -4
  255. package/src/models/__tests__/flowModel.test.ts +234 -111
  256. package/src/models/__tests__/forkFlowModel.test.ts +22 -7
  257. package/src/models/flowModel.tsx +149 -125
  258. package/src/models/forkFlowModel.ts +41 -8
  259. package/src/provider.tsx +10 -7
  260. package/src/resources/multiRecordResource.ts +2 -0
  261. package/src/resources/singleRecordResource.ts +1 -0
  262. package/src/resources/sqlResource.ts +20 -25
  263. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +28 -21
  264. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +46 -34
  265. package/src/runjs-context/contexts/JSCollectionActionRunJSContext.ts +15 -16
  266. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +58 -0
  267. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +30 -25
  268. package/src/runjs-context/contexts/JSItemRunJSContext.ts +25 -21
  269. package/src/runjs-context/contexts/JSRecordActionRunJSContext.ts +17 -18
  270. package/src/runjs-context/contexts/base.ts +171 -0
  271. package/src/runjs-context/helpers.ts +32 -30
  272. package/src/runjs-context/registry.ts +16 -47
  273. package/src/runjs-context/setup.ts +51 -0
  274. package/src/runjs-context/snippets/global/api-request.snippet.ts +38 -0
  275. package/src/runjs-context/snippets/global/clipboard-copy-text.snippet.ts +42 -0
  276. package/src/runjs-context/snippets/global/import-esm.snippet.ts +39 -0
  277. package/src/runjs-context/snippets/global/message-error.snippet.ts +6 -0
  278. package/src/runjs-context/snippets/global/message-success.snippet.ts +6 -0
  279. package/src/runjs-context/snippets/global/notification-open.snippet.ts +11 -1
  280. package/src/runjs-context/snippets/global/open-view-dialog.snippet.ts +10 -3
  281. package/src/runjs-context/snippets/global/open-view-drawer.snippet.ts +10 -3
  282. package/src/runjs-context/snippets/global/query-selector.snippet.ts +34 -0
  283. package/src/runjs-context/snippets/global/require-amd.snippet.ts +30 -0
  284. package/src/runjs-context/snippets/global/window-open.snippet.ts +11 -1
  285. package/src/runjs-context/snippets/index.ts +177 -39
  286. package/src/runjs-context/snippets/scene/{jsblock → block}/add-event-listener.snippet.ts +14 -2
  287. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +45 -0
  288. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +80 -0
  289. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +44 -0
  290. package/src/runjs-context/snippets/scene/block/render-button-handler.snippet.ts +35 -0
  291. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +38 -0
  292. package/src/runjs-context/snippets/scene/block/render-info-card.snippet.ts +52 -0
  293. package/src/runjs-context/snippets/scene/block/render-react-jsx.snippet.ts +39 -0
  294. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +38 -0
  295. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +76 -0
  296. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +65 -0
  297. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +46 -0
  298. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +264 -0
  299. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +105 -0
  300. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +33 -0
  301. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +45 -0
  302. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +32 -0
  303. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +31 -0
  304. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +63 -0
  305. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +61 -0
  306. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +55 -0
  307. package/src/runjs-context/snippets/scene/form/calculate-total.snippet.ts +44 -0
  308. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +62 -0
  309. package/src/runjs-context/snippets/scene/form/conditional-required.snippet.ts +45 -0
  310. package/src/runjs-context/snippets/scene/form/copy-field-values.snippet.ts +55 -0
  311. package/src/runjs-context/snippets/scene/{jsitem → form}/render-basic.snippet.ts +14 -2
  312. package/src/runjs-context/snippets/scene/{linkage → form}/set-disabled.snippet.ts +15 -3
  313. package/src/runjs-context/snippets/scene/{linkage → form}/set-field-value.snippet.ts +15 -3
  314. package/src/runjs-context/snippets/scene/{linkage → form}/set-required.snippet.ts +15 -3
  315. package/src/runjs-context/snippets/scene/form/toggle-multiple-fields.snippet.ts +48 -0
  316. package/src/runjs-context/snippets/scene/{linkage → form}/toggle-visible.snippet.ts +15 -3
  317. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +45 -0
  318. package/src/runjs-context/snippets/scene/{actions → table}/collection-selected-count.snippet.ts +14 -2
  319. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +60 -0
  320. package/src/runjs-context/snippets/scene/table/destroy-selected.snippet.ts +36 -0
  321. package/src/runjs-context/snippets/scene/table/export-selected-json.snippet.ts +45 -0
  322. package/src/runjs-context/snippets/scene/{actions → table}/iterate-selected-rows.snippet.ts +14 -2
  323. package/src/runjs-context/snippets/types.ts +5 -1
  324. package/src/types.ts +34 -0
  325. package/src/utils/__tests__/jsxTransform.test.ts +38 -0
  326. package/src/utils/__tests__/safeGlobals.test.ts +22 -1
  327. package/src/utils/buildSettingsViewInputArgs.ts +72 -0
  328. package/src/utils/createEphemeralContext.ts +142 -0
  329. package/src/utils/index.ts +2 -2
  330. package/src/utils/jsxTransform.ts +39 -0
  331. package/src/utils/params-resolvers.ts +2 -2
  332. package/src/utils/safeGlobals.ts +49 -3
  333. package/src/utils/schema-utils.ts +1 -1
  334. package/src/utils/serverContextParams.ts +1 -0
  335. package/src/utils/variablesParams.ts +50 -38
  336. package/src/views/PageComponent.tsx +1 -1
  337. package/src/views/createViewMeta.ts +393 -70
  338. package/src/views/index.tsx +1 -0
  339. package/src/views/useDialog.tsx +12 -10
  340. package/src/views/useDrawer.tsx +60 -36
  341. package/src/views/usePage.tsx +13 -10
  342. package/lib/components/dnd/getMousePositionOnElement.d.ts +0 -50
  343. package/lib/components/dnd/getMousePositionOnElement.js +0 -95
  344. package/lib/components/dnd/moveBlock.d.ts +0 -33
  345. package/lib/components/dnd/moveBlock.js +0 -302
  346. package/lib/runjs-context/contexts/FlowRunJSContext.d.ts +0 -38
  347. package/lib/runjs-context/contexts/FlowRunJSContext.js +0 -217
  348. package/lib/runjs-context/contexts/LinkageRunJSContext.js +0 -62
  349. package/lib/runjs-context/index.d.ts +0 -19
  350. package/lib/runjs-context/index.js +0 -57
  351. package/lib/runjs-context/snippets/global/api-request-get.snippet.d.ts +0 -16
  352. package/lib/runjs-context/snippets/global/api-request-get.snippet.js +0 -42
  353. package/lib/runjs-context/snippets/global/api-request-post.snippet.d.ts +0 -16
  354. package/lib/runjs-context/snippets/global/api-request-post.snippet.js +0 -42
  355. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.d.ts +0 -16
  356. package/lib/runjs-context/snippets/global/console-log-ctx.snippet.js +0 -41
  357. package/lib/runjs-context/snippets/global/sleep.snippet.d.ts +0 -16
  358. package/lib/runjs-context/snippets/global/sleep.snippet.js +0 -43
  359. package/lib/runjs-context/snippets/global/try-catch-async.snippet.d.ts +0 -16
  360. package/lib/runjs-context/snippets/global/try-catch-async.snippet.js +0 -44
  361. package/lib/runjs-context/snippets/libs/echarts-init.snippet.d.ts +0 -15
  362. package/lib/runjs-context/snippets/scene/actions/collection-selected-count.snippet.d.ts +0 -15
  363. package/lib/runjs-context/snippets/scene/actions/iterate-selected-rows.snippet.d.ts +0 -15
  364. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.d.ts +0 -15
  365. package/lib/runjs-context/snippets/scene/actions/record-id-message.snippet.js +0 -43
  366. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.d.ts +0 -15
  367. package/lib/runjs-context/snippets/scene/actions/run-action-basic.snippet.js +0 -40
  368. package/lib/runjs-context/snippets/scene/jsblock/add-event-listener.snippet.d.ts +0 -15
  369. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.d.ts +0 -15
  370. package/lib/runjs-context/snippets/scene/jsblock/append-style.snippet.js +0 -42
  371. package/lib/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.d.ts +0 -15
  372. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.d.ts +0 -15
  373. package/lib/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.js +0 -41
  374. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.d.ts +0 -15
  375. package/lib/runjs-context/snippets/scene/jsblock/render-basic.snippet.js +0 -41
  376. package/lib/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.d.ts +0 -15
  377. package/lib/runjs-context/snippets/scene/jsblock/render-react.snippet.d.ts +0 -15
  378. package/lib/runjs-context/snippets/scene/jsfield/color-by-value.snippet.d.ts +0 -15
  379. package/lib/runjs-context/snippets/scene/jsfield/format-number.snippet.d.ts +0 -15
  380. package/lib/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.d.ts +0 -15
  381. package/lib/runjs-context/snippets/scene/jsitem/render-basic.snippet.d.ts +0 -15
  382. package/lib/runjs-context/snippets/scene/linkage/set-disabled.snippet.d.ts +0 -15
  383. package/lib/runjs-context/snippets/scene/linkage/set-field-value.snippet.d.ts +0 -15
  384. package/lib/runjs-context/snippets/scene/linkage/set-required.snippet.d.ts +0 -15
  385. package/lib/runjs-context/snippets/scene/linkage/toggle-visible.snippet.d.ts +0 -15
  386. package/src/components/dnd/getMousePositionOnElement.ts +0 -115
  387. package/src/components/dnd/moveBlock.ts +0 -379
  388. package/src/runjs-context/contexts/FlowRunJSContext.ts +0 -190
  389. package/src/runjs-context/contexts/LinkageRunJSContext.ts +0 -35
  390. package/src/runjs-context/index.ts +0 -20
  391. package/src/runjs-context/snippets/global/api-request-get.snippet.ts +0 -20
  392. package/src/runjs-context/snippets/global/api-request-post.snippet.ts +0 -20
  393. package/src/runjs-context/snippets/global/console-log-ctx.snippet.ts +0 -19
  394. package/src/runjs-context/snippets/global/copy-record-json.snippet.ts +0 -21
  395. package/src/runjs-context/snippets/global/copy-to-clipboard.snippet.ts +0 -21
  396. package/src/runjs-context/snippets/global/log-json-record.snippet.ts +0 -21
  397. package/src/runjs-context/snippets/global/requireAsync.snippet.ts +0 -24
  398. package/src/runjs-context/snippets/global/sleep.snippet.ts +0 -21
  399. package/src/runjs-context/snippets/global/try-catch-async.snippet.ts +0 -22
  400. package/src/runjs-context/snippets/global/view-navigation-push.snippet.ts +0 -23
  401. package/src/runjs-context/snippets/libs/echarts-init.snippet.ts +0 -24
  402. package/src/runjs-context/snippets/scene/actions/record-id-message.snippet.ts +0 -21
  403. package/src/runjs-context/snippets/scene/actions/run-action-basic.snippet.ts +0 -18
  404. package/src/runjs-context/snippets/scene/jsblock/append-style.snippet.ts +0 -20
  405. package/src/runjs-context/snippets/scene/jsblock/jsx-mount.snippet.ts +0 -24
  406. package/src/runjs-context/snippets/scene/jsblock/jsx-unmount.snippet.ts +0 -19
  407. package/src/runjs-context/snippets/scene/jsblock/render-basic.snippet.ts +0 -24
  408. package/src/runjs-context/snippets/scene/jsblock/render-button-handler.snippet.ts +0 -24
  409. package/src/runjs-context/snippets/scene/jsblock/render-card.snippet.ts +0 -30
  410. package/src/runjs-context/snippets/scene/jsblock/render-react.snippet.ts +0 -34
  411. package/src/runjs-context/snippets/scene/jsfield/color-by-value.snippet.ts +0 -20
  412. package/src/runjs-context/snippets/scene/jsfield/format-number.snippet.ts +0 -19
  413. package/src/runjs-context/snippets/scene/jsfield/innerHTML-value.snippet.ts +0 -18
  414. /package/lib/runjs-context/snippets/global/{copy-record-json.snippet.d.ts → api-request.snippet.d.ts} +0 -0
  415. /package/lib/runjs-context/snippets/global/{copy-to-clipboard.snippet.d.ts → clipboard-copy-text.snippet.d.ts} +0 -0
  416. /package/lib/runjs-context/snippets/global/{log-json-record.snippet.d.ts → import-esm.snippet.d.ts} +0 -0
  417. /package/lib/runjs-context/snippets/global/{view-navigation-push.snippet.d.ts → query-selector.snippet.d.ts} +0 -0
  418. /package/lib/runjs-context/snippets/scene/{jsblock/render-card.snippet.d.ts → block/echarts-init.snippet.d.ts} +0 -0
@@ -0,0 +1,269 @@
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, it, expect, beforeAll } from 'vitest';
11
+ import { FlowContext } from '../flowContext';
12
+ import { createJSRunnerWithVersion, getRunJSDocFor } from '..';
13
+ import { setupRunJSContexts } from '../runjs-context/setup';
14
+
15
+ describe('RunJS Context Runtime Behavior', () => {
16
+ beforeAll(async () => {
17
+ await setupRunJSContexts();
18
+ });
19
+
20
+ describe('JSBlockRunJSContext', () => {
21
+ it('should create JSBlock context successfully', async () => {
22
+ const ctx = new FlowContext();
23
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSBlockModel' } } });
24
+
25
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
26
+ const result = await runner.run('return typeof ctx !== "undefined"');
27
+
28
+ expect(result?.success).toBe(true);
29
+ expect(result?.value).toBe(true);
30
+ });
31
+
32
+ it('should have element property in documentation', () => {
33
+ const ctx: any = { model: { constructor: { name: 'JSBlockModel' } } };
34
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
35
+
36
+ expect(doc?.properties?.element).toBeTruthy();
37
+ expect(doc?.properties?.React).toBeTruthy();
38
+ expect(doc?.properties?.antd).toBeTruthy();
39
+ });
40
+
41
+ it('should have onRefReady method in documentation', () => {
42
+ const ctx: any = { model: { constructor: { name: 'JSBlockModel' } } };
43
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
44
+
45
+ expect(doc?.methods?.onRefReady).toBeTruthy();
46
+ expect(doc?.methods?.requireAsync).toBeTruthy();
47
+ });
48
+ });
49
+
50
+ describe('JSFieldRunJSContext', () => {
51
+ it('should create JSField context successfully', async () => {
52
+ const ctx = new FlowContext();
53
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSFieldModel' } } });
54
+
55
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
56
+ const result = await runner.run('return typeof ctx !== "undefined"');
57
+
58
+ expect(result?.success).toBe(true);
59
+ expect(result?.value).toBe(true);
60
+ });
61
+
62
+ it('should have field-specific properties in documentation', () => {
63
+ const ctx: any = { model: { constructor: { name: 'JSFieldModel' } } };
64
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
65
+
66
+ expect(doc?.properties?.element).toBeTruthy();
67
+ expect(doc?.properties?.value).toBeTruthy();
68
+ expect(doc?.properties?.record).toBeTruthy();
69
+ expect(doc?.properties?.collection).toBeTruthy();
70
+ });
71
+ });
72
+
73
+ describe('JSItemRunJSContext', () => {
74
+ it('should create JSItem context successfully', async () => {
75
+ const ctx = new FlowContext();
76
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSItemModel' } } });
77
+
78
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
79
+ const result = await runner.run('return typeof ctx !== "undefined"');
80
+
81
+ expect(result?.success).toBe(true);
82
+ expect(result?.value).toBe(true);
83
+ });
84
+
85
+ it('should have item-specific properties in documentation', () => {
86
+ const ctx: any = { model: { constructor: { name: 'JSItemModel' } } };
87
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
88
+
89
+ expect(doc?.properties?.element).toBeTruthy();
90
+ expect(doc?.properties?.record).toBeTruthy();
91
+ expect(doc?.properties?.resource).toBeTruthy();
92
+ });
93
+ });
94
+
95
+ describe('JSColumnRunJSContext', () => {
96
+ it('should create JSColumn context successfully', async () => {
97
+ const ctx = new FlowContext();
98
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSColumnModel' } } });
99
+
100
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
101
+ const result = await runner.run('return typeof ctx !== "undefined"');
102
+
103
+ expect(result?.success).toBe(true);
104
+ expect(result?.value).toBe(true);
105
+ });
106
+
107
+ it('should have column-specific properties in documentation', () => {
108
+ const ctx: any = { model: { constructor: { name: 'JSColumnModel' } } };
109
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
110
+
111
+ expect(doc?.properties?.element).toBeTruthy();
112
+ expect(doc?.properties?.record).toBeTruthy();
113
+ expect(doc?.properties?.recordIndex).toBeTruthy();
114
+ expect(doc?.properties?.collection).toBeTruthy();
115
+ expect(doc?.properties?.viewer).toBeTruthy();
116
+ });
117
+ });
118
+
119
+ describe('FormJSFieldItemRunJSContext', () => {
120
+ it('should create FormJSFieldItem context successfully', async () => {
121
+ const ctx = new FlowContext();
122
+ ctx.defineProperty('model', { value: { constructor: { name: 'FormJSFieldItemModel' } } });
123
+
124
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
125
+ const result = await runner.run('return typeof ctx !== "undefined"');
126
+
127
+ expect(result?.success).toBe(true);
128
+ expect(result?.value).toBe(true);
129
+ });
130
+
131
+ it('should have form field-specific properties and methods in documentation', () => {
132
+ const ctx: any = { model: { constructor: { name: 'FormJSFieldItemModel' } } };
133
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
134
+
135
+ expect(doc?.properties?.element).toBeTruthy();
136
+ expect(doc?.properties?.value).toBeTruthy();
137
+ expect(doc?.properties?.record).toBeTruthy();
138
+ expect(doc?.methods?.setProps).toBeTruthy();
139
+ });
140
+ });
141
+
142
+ describe('JSRecordActionRunJSContext', () => {
143
+ it('should create JSRecordAction context successfully', async () => {
144
+ const ctx = new FlowContext();
145
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSRecordActionModel' } } });
146
+
147
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
148
+ const result = await runner.run('return typeof ctx !== "undefined"');
149
+
150
+ expect(result?.success).toBe(true);
151
+ expect(result?.value).toBe(true);
152
+ });
153
+
154
+ it('should have record action-specific properties in documentation', () => {
155
+ const ctx: any = { model: { constructor: { name: 'JSRecordActionModel' } } };
156
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
157
+
158
+ expect(doc?.properties?.record).toBeTruthy();
159
+ expect(doc?.properties?.filterByTk).toBeTruthy();
160
+ });
161
+ });
162
+
163
+ describe('JSCollectionActionRunJSContext', () => {
164
+ it('should create JSCollectionAction context successfully', async () => {
165
+ const ctx = new FlowContext();
166
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSCollectionActionModel' } } });
167
+
168
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
169
+ const result = await runner.run('return typeof ctx !== "undefined"');
170
+
171
+ expect(result?.success).toBe(true);
172
+ expect(result?.value).toBe(true);
173
+ });
174
+
175
+ it('should have collection action-specific properties in documentation', () => {
176
+ const ctx: any = { model: { constructor: { name: 'JSCollectionActionModel' } } };
177
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
178
+
179
+ expect(doc?.properties?.resource).toBeTruthy();
180
+ });
181
+ });
182
+
183
+ describe('Cross-context features', () => {
184
+ it('should provide React and antd in all contexts', async () => {
185
+ const contextTypes = [
186
+ 'JSBlockModel',
187
+ 'JSFieldModel',
188
+ 'JSItemModel',
189
+ 'JSColumnModel',
190
+ 'FormJSFieldItemModel',
191
+ 'JSRecordActionModel',
192
+ 'JSCollectionActionModel',
193
+ ];
194
+
195
+ for (const modelName of contextTypes) {
196
+ const ctx = new FlowContext();
197
+ ctx.defineProperty('model', { value: { constructor: { name: modelName } } });
198
+
199
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
200
+ const result = await runner.run(`
201
+ return {
202
+ hasReact: typeof ctx.React !== "undefined",
203
+ hasAntd: typeof ctx.antd !== "undefined",
204
+ hasReactDOM: typeof ctx.ReactDOM !== "undefined"
205
+ }
206
+ `);
207
+
208
+ expect(result?.success).toBe(true);
209
+ expect(result?.value).toEqual({
210
+ hasReact: true,
211
+ hasAntd: true,
212
+ hasReactDOM: true,
213
+ });
214
+ }
215
+ });
216
+
217
+ it('should access base context properties in documentation', () => {
218
+ const contextTypes = ['JSBlockModel', 'JSFieldModel', 'JSColumnModel'];
219
+
220
+ for (const modelName of contextTypes) {
221
+ const ctx: any = { model: { constructor: { name: modelName } } };
222
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
223
+
224
+ // Base properties from FlowRunJSContext
225
+ expect(doc?.properties?.logger).toBeTruthy();
226
+ expect(doc?.properties?.message).toBeTruthy();
227
+ expect(doc?.properties?.api).toBeTruthy();
228
+ expect(doc?.methods?.t).toBeTruthy();
229
+ expect(doc?.methods?.requireAsync).toBeTruthy();
230
+ }
231
+ });
232
+ });
233
+
234
+ describe('Documentation completeness', () => {
235
+ it('should provide complete documentation for all context types', () => {
236
+ const contextTypes = [
237
+ 'JSBlockModel',
238
+ 'JSFieldModel',
239
+ 'JSItemModel',
240
+ 'JSColumnModel',
241
+ 'FormJSFieldItemModel',
242
+ 'JSRecordActionModel',
243
+ 'JSCollectionActionModel',
244
+ ];
245
+
246
+ for (const modelName of contextTypes) {
247
+ const ctx: any = { model: { constructor: { name: modelName } } };
248
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
249
+
250
+ expect(doc).toBeTruthy();
251
+ expect(doc?.label).toBeTruthy();
252
+ expect(doc?.properties).toBeTruthy();
253
+ expect(typeof doc?.properties).toBe('object');
254
+ }
255
+ });
256
+
257
+ it('should provide locale-specific documentation', () => {
258
+ const ctx = new FlowContext();
259
+ ctx.defineProperty('model', { value: { constructor: { name: 'JSFieldModel' } } });
260
+ ctx.defineProperty('api', { value: { auth: { locale: 'zh-CN' } } });
261
+
262
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
263
+
264
+ expect(doc).toBeTruthy();
265
+ // Should have Chinese documentation
266
+ expect(doc?.label).toContain('JS');
267
+ });
268
+ });
269
+ });
@@ -0,0 +1,281 @@
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, it, expect, beforeAll } from 'vitest';
11
+ import { FlowContext, FlowEngineContext, FlowRunJSContext } from '../flowContext';
12
+ import { FlowEngine } from '../flowEngine';
13
+ import { createJSRunnerWithVersion, RunJSContextRegistry } from '..';
14
+ import { setupRunJSContexts } from '../runjs-context/setup';
15
+
16
+ describe('RunJS Edge Cases and Error Handling', () => {
17
+ let engine: FlowEngine;
18
+ let engineCtx: FlowEngineContext;
19
+
20
+ beforeAll(async () => {
21
+ await setupRunJSContexts();
22
+ engine = new FlowEngine();
23
+ engineCtx = new FlowEngineContext(engine);
24
+ });
25
+
26
+ describe('Missing or invalid model scenarios', () => {
27
+ it('should handle undefined model', async () => {
28
+ const ctx = new FlowEngineContext(engine);
29
+ const runner = await ctx.createJSRunner();
30
+
31
+ expect(runner).toBeDefined();
32
+ const result = await runner.run('return typeof ctx !== "undefined"');
33
+ expect(result?.success).toBe(true);
34
+ expect(result?.value).toBe(true);
35
+ });
36
+
37
+ it('should handle null model', async () => {
38
+ const ctx = new FlowEngineContext(engine);
39
+ (ctx as any).defineProperty('model', { value: null });
40
+
41
+ const runner = await ctx.createJSRunner();
42
+ expect(runner).toBeDefined();
43
+ });
44
+
45
+ it('should handle model without constructor', async () => {
46
+ const ctx = new FlowEngineContext(engine);
47
+ (ctx as any).defineProperty('model', { value: {} });
48
+
49
+ const runner = await ctx.createJSRunner();
50
+ expect(runner).toBeDefined();
51
+ });
52
+
53
+ it('should handle unrecognized model type', async () => {
54
+ const ctx = new FlowEngineContext(engine);
55
+ (ctx as any).defineProperty('model', {
56
+ value: { constructor: { name: 'UnknownModelType' } },
57
+ });
58
+
59
+ const runner = await ctx.createJSRunner();
60
+ expect(runner).toBeDefined();
61
+
62
+ const result = await runner.run('return typeof ctx !== "undefined"');
63
+ expect(result?.success).toBe(true);
64
+ expect(result?.value).toBe(true);
65
+ });
66
+ });
67
+
68
+ describe('Invalid version handling', () => {
69
+ it('should handle missing version gracefully', async () => {
70
+ const ctx = new FlowContext();
71
+ ctx.defineProperty('model', {
72
+ value: { constructor: { name: 'JSBlockModel' } },
73
+ });
74
+
75
+ const runner = createJSRunnerWithVersion.call(ctx, {} as any);
76
+ expect(runner).toBeDefined();
77
+ });
78
+
79
+ it('should throw error for invalid version string', async () => {
80
+ const ctx = new FlowContext();
81
+ ctx.defineProperty('model', {
82
+ value: { constructor: { name: 'JSBlockModel' } },
83
+ });
84
+
85
+ expect(() => {
86
+ createJSRunnerWithVersion.call(ctx, {
87
+ version: 'invalid-version',
88
+ } as any);
89
+ }).toThrow();
90
+ });
91
+ });
92
+
93
+ describe('Code execution edge cases', () => {
94
+ it('should handle empty code', async () => {
95
+ const runner = await engineCtx.createJSRunner();
96
+ const result = await runner.run('');
97
+
98
+ expect(result).toBeDefined();
99
+ });
100
+
101
+ it('should handle whitespace-only code', async () => {
102
+ const runner = await engineCtx.createJSRunner();
103
+ const result = await runner.run(' \n\n\t\t ');
104
+
105
+ expect(result).toBeDefined();
106
+ });
107
+
108
+ it('should handle syntax errors', async () => {
109
+ const runner = await engineCtx.createJSRunner();
110
+ const result = await runner.run('return {invalid: syntax');
111
+
112
+ expect(result?.success).toBe(false);
113
+ expect(result?.error).toBeDefined();
114
+ });
115
+
116
+ it('should handle rejected promises', async () => {
117
+ const runner = await engineCtx.createJSRunner();
118
+ const result = await runner.run(`
119
+ return Promise.reject(new Error('Rejected'));
120
+ `);
121
+
122
+ expect(result?.success).toBe(false);
123
+ expect(result?.error).toBeDefined();
124
+ });
125
+
126
+ it('should handle code that returns undefined', async () => {
127
+ const runner = await engineCtx.createJSRunner();
128
+ const result = await runner.run('return undefined');
129
+
130
+ expect(result?.success).toBe(true);
131
+ expect(result?.value).toBeUndefined();
132
+ });
133
+
134
+ it('should handle code that returns null', async () => {
135
+ const runner = await engineCtx.createJSRunner();
136
+ const result = await runner.run('return null');
137
+
138
+ expect(result?.success).toBe(true);
139
+ expect(result?.value).toBeNull();
140
+ });
141
+ });
142
+
143
+ describe('Context property edge cases', () => {
144
+ it('should handle value of 0', async () => {
145
+ const ctx = new FlowContext();
146
+ ctx.defineProperty('model', {
147
+ value: {
148
+ constructor: { name: 'JSFieldModel' },
149
+ },
150
+ });
151
+ ctx.defineProperty('value', { value: 0 });
152
+
153
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
154
+ const result = await runner.run('return typeof ctx !== "undefined"');
155
+
156
+ expect(result?.success).toBe(true);
157
+ expect(result?.value).toBe(true);
158
+ });
159
+
160
+ it('should handle empty string value', async () => {
161
+ const ctx = new FlowContext();
162
+ ctx.defineProperty('model', {
163
+ value: {
164
+ constructor: { name: 'JSFieldModel' },
165
+ },
166
+ });
167
+ ctx.defineProperty('value', { value: '' });
168
+
169
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
170
+ const result = await runner.run('return typeof ctx !== "undefined"');
171
+
172
+ expect(result?.success).toBe(true);
173
+ expect(result?.value).toBe(true);
174
+ });
175
+
176
+ it('should handle false boolean value', async () => {
177
+ const ctx = new FlowContext();
178
+ ctx.defineProperty('model', {
179
+ value: {
180
+ constructor: { name: 'JSFieldModel' },
181
+ },
182
+ });
183
+ ctx.defineProperty('value', { value: false });
184
+
185
+ const runner = createJSRunnerWithVersion.call(ctx, { version: 'v1' });
186
+ const result = await runner.run('return typeof ctx !== "undefined"');
187
+
188
+ expect(result?.success).toBe(true);
189
+ expect(result?.value).toBe(true);
190
+ });
191
+ });
192
+
193
+ describe('Registry edge cases', () => {
194
+ it('should handle repeated setup calls idempotently', async () => {
195
+ await setupRunJSContexts();
196
+ await setupRunJSContexts();
197
+ await setupRunJSContexts();
198
+
199
+ const ctor = RunJSContextRegistry['resolve']('v1' as any, 'JSBlockModel');
200
+ expect(ctor).toBeDefined();
201
+ });
202
+
203
+ it('should handle context creation with minimal delegate', () => {
204
+ const minimalCtx = new FlowContext();
205
+ const runCtx = new FlowRunJSContext(minimalCtx);
206
+
207
+ expect(runCtx).toBeDefined();
208
+ expect((runCtx as any).React).toBeDefined();
209
+ expect((runCtx as any).antd).toBeDefined();
210
+ expect((runCtx as any).ReactDOM).toBeDefined();
211
+ });
212
+
213
+ it('should handle context creation with null delegate', () => {
214
+ expect(() => {
215
+ new FlowRunJSContext(null as any);
216
+ }).toThrow();
217
+ });
218
+
219
+ it('should handle context creation with undefined delegate', () => {
220
+ expect(() => {
221
+ new FlowRunJSContext(undefined as any);
222
+ }).toThrow();
223
+ });
224
+ });
225
+
226
+ describe('Timeout edge cases', () => {
227
+ it('should handle very large timeout', async () => {
228
+ const runner = await engineCtx.createJSRunner({ timeoutMs: 999999999 });
229
+ const result = await runner.run('return 1 + 1');
230
+
231
+ expect(result?.success).toBe(true);
232
+ expect(result?.value).toBe(2);
233
+ });
234
+
235
+ it('should handle code that completes before timeout', async () => {
236
+ const runner = await engineCtx.createJSRunner({ timeoutMs: 200 });
237
+ const result = await runner.run(`
238
+ return new Promise(resolve => {
239
+ setTimeout(() => resolve('done'), 50);
240
+ });
241
+ `);
242
+
243
+ expect(result?.success).toBe(true);
244
+ expect(result?.value).toBe('done');
245
+ });
246
+ });
247
+
248
+ describe('Complex scenarios', () => {
249
+ it('should handle multiple concurrent runners', async () => {
250
+ const runners = await Promise.all([
251
+ engineCtx.createJSRunner(),
252
+ engineCtx.createJSRunner(),
253
+ engineCtx.createJSRunner(),
254
+ ]);
255
+
256
+ const results = await Promise.all([
257
+ runners[0].run('return 1'),
258
+ runners[1].run('return 2'),
259
+ runners[2].run('return 3'),
260
+ ]);
261
+
262
+ expect(results[0]?.value).toBe(1);
263
+ expect(results[1]?.value).toBe(2);
264
+ expect(results[2]?.value).toBe(3);
265
+ });
266
+
267
+ it('should handle recursive code execution', async () => {
268
+ const runner = await engineCtx.createJSRunner({ timeoutMs: 1000 });
269
+ const result = await runner.run(`
270
+ function factorial(n) {
271
+ if (n <= 1) return 1;
272
+ return n * factorial(n - 1);
273
+ }
274
+ return factorial(10);
275
+ `);
276
+
277
+ expect(result?.success).toBe(true);
278
+ expect(result?.value).toBe(3628800);
279
+ });
280
+ });
281
+ });
@@ -0,0 +1,36 @@
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, it, expect, beforeAll } from 'vitest';
11
+ import { getRunJSDocFor } from '..';
12
+ import { setupRunJSContexts } from '../runjs-context/setup';
13
+ import { FlowContext } from '../flowContext';
14
+
15
+ describe('RunJS locales patch (engine doc)', () => {
16
+ beforeAll(async () => {
17
+ await setupRunJSContexts();
18
+ });
19
+
20
+ it('should merge zh-CN locales for subclass doc label', () => {
21
+ const ctx = new FlowContext();
22
+ (ctx as any).defineProperty('model', { value: { constructor: { name: 'JSFieldModel' } } });
23
+ (ctx as any).defineProperty('api', { value: { auth: { locale: 'zh-CN' } } });
24
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
25
+ expect(doc?.label || '').toMatch(/JS 字段|JS 字段 RunJS 上下文/);
26
+ });
27
+
28
+ it('should localize base properties/methods via locales', () => {
29
+ const ctx = new FlowContext();
30
+ (ctx as any).defineProperty('model', { value: { constructor: { name: 'JSBlockModel' } } });
31
+ (ctx as any).defineProperty('api', { value: { auth: { locale: 'zh-CN' } } });
32
+ const doc = getRunJSDocFor(ctx as any, { version: 'v1' });
33
+ expect(String(doc?.properties?.message || '')).toMatch(/Ant Design 全局消息 API/);
34
+ expect(String(doc?.methods?.t || '')).toMatch(/国际化函数/);
35
+ });
36
+ });