@nocobase/flow-engine 2.0.0-beta.9 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/lib/BlockScopedFlowEngine.js +0 -1
  2. package/lib/FlowDefinition.d.ts +2 -0
  3. package/lib/JSRunner.d.ts +6 -0
  4. package/lib/JSRunner.js +32 -2
  5. package/lib/ViewScopedFlowEngine.js +3 -0
  6. package/lib/acl/Acl.js +13 -3
  7. package/lib/components/FlowContextSelector.js +155 -10
  8. package/lib/components/settings/wrappers/component/SwitchWithTitle.js +2 -1
  9. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +76 -15
  10. package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +24 -4
  11. package/lib/components/settings/wrappers/contextual/StepSettingsDialog.js +5 -1
  12. package/lib/components/variables/VariableInput.js +9 -4
  13. package/lib/components/variables/VariableTag.js +46 -39
  14. package/lib/components/variables/utils.d.ts +7 -0
  15. package/lib/components/variables/utils.js +42 -2
  16. package/lib/data-source/index.d.ts +7 -27
  17. package/lib/data-source/index.js +81 -51
  18. package/lib/executor/FlowExecutor.d.ts +2 -1
  19. package/lib/executor/FlowExecutor.js +163 -22
  20. package/lib/flowContext.d.ts +230 -7
  21. package/lib/flowContext.js +2267 -148
  22. package/lib/flowEngine.d.ts +21 -0
  23. package/lib/flowEngine.js +56 -8
  24. package/lib/flowI18n.js +6 -4
  25. package/lib/flowSettings.js +17 -11
  26. package/lib/index.d.ts +7 -1
  27. package/lib/index.js +21 -0
  28. package/lib/locale/en-US.json +9 -2
  29. package/lib/locale/index.d.ts +14 -0
  30. package/lib/locale/zh-CN.json +8 -1
  31. package/lib/models/CollectionFieldModel.d.ts +1 -0
  32. package/lib/models/CollectionFieldModel.js +3 -2
  33. package/lib/models/flowModel.js +12 -1
  34. package/lib/provider.js +5 -5
  35. package/lib/resources/baseRecordResource.d.ts +5 -0
  36. package/lib/resources/baseRecordResource.js +24 -0
  37. package/lib/resources/multiRecordResource.d.ts +1 -0
  38. package/lib/resources/multiRecordResource.js +11 -4
  39. package/lib/resources/singleRecordResource.js +2 -0
  40. package/lib/resources/sqlResource.d.ts +4 -3
  41. package/lib/resources/sqlResource.js +8 -3
  42. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +12 -2
  43. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +2 -2
  44. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.d.ts +16 -0
  45. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +125 -0
  46. package/lib/runjs-context/contexts/JSItemRunJSContext.js +12 -2
  47. package/lib/runjs-context/contexts/base.js +706 -41
  48. package/lib/runjs-context/contributions.d.ts +33 -0
  49. package/lib/runjs-context/contributions.js +88 -0
  50. package/lib/runjs-context/helpers.js +12 -1
  51. package/lib/runjs-context/setup.js +6 -0
  52. package/lib/runjs-context/snippets/global/api-request.snippet.js +3 -3
  53. package/lib/runjs-context/snippets/global/import-esm.snippet.js +2 -3
  54. package/lib/runjs-context/snippets/global/query-selector.snippet.js +8 -3
  55. package/lib/runjs-context/snippets/global/require-amd.snippet.js +1 -1
  56. package/lib/runjs-context/snippets/index.d.ts +11 -1
  57. package/lib/runjs-context/snippets/index.js +61 -40
  58. package/lib/runjs-context/snippets/scene/block/add-event-listener.snippet.js +10 -7
  59. package/lib/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.js +3 -3
  60. package/lib/runjs-context/snippets/scene/block/chartjs-bar.snippet.js +2 -2
  61. package/lib/runjs-context/snippets/scene/block/echarts-init.snippet.js +2 -2
  62. package/lib/runjs-context/snippets/scene/block/render-iframe.snippet.js +2 -2
  63. package/lib/runjs-context/snippets/scene/block/render-react.snippet.js +1 -1
  64. package/lib/runjs-context/snippets/scene/block/render-statistics.snippet.js +1 -1
  65. package/lib/runjs-context/snippets/scene/block/render-timeline.snippet.js +1 -1
  66. package/lib/runjs-context/snippets/scene/block/resource-example.snippet.js +5 -5
  67. package/lib/runjs-context/snippets/scene/block/three-users-orbit.snippet.js +6 -6
  68. package/lib/runjs-context/snippets/scene/block/vue-component.snippet.js +3 -4
  69. package/lib/runjs-context/snippets/scene/detail/color-by-value.snippet.js +1 -1
  70. package/lib/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.js +20 -3
  71. package/lib/runjs-context/snippets/scene/detail/format-number.snippet.js +1 -1
  72. package/lib/runjs-context/snippets/scene/detail/innerHTML-value.snippet.js +1 -1
  73. package/lib/runjs-context/snippets/scene/detail/percentage-bar.snippet.js +3 -3
  74. package/lib/runjs-context/snippets/scene/detail/relative-time.snippet.js +3 -3
  75. package/lib/runjs-context/snippets/scene/detail/status-tag.snippet.js +2 -2
  76. package/lib/runjs-context/snippets/scene/form/cascade-select.snippet.js +1 -1
  77. package/lib/runjs-context/snippets/scene/form/render-basic.snippet.js +2 -2
  78. package/lib/runjs-context/snippets/scene/table/cell-open-dialog.snippet.js +6 -3
  79. package/lib/runjs-context/snippets/scene/table/concat-fields.snippet.js +3 -1
  80. package/lib/runjsLibs.d.ts +28 -0
  81. package/lib/runjsLibs.js +532 -0
  82. package/lib/scheduler/ModelOperationScheduler.d.ts +2 -0
  83. package/lib/scheduler/ModelOperationScheduler.js +25 -21
  84. package/lib/types.d.ts +27 -0
  85. package/lib/utils/associationObjectVariable.d.ts +2 -2
  86. package/lib/utils/createCollectionContextMeta.js +1 -0
  87. package/lib/utils/createEphemeralContext.js +2 -2
  88. package/lib/utils/dateVariable.d.ts +16 -0
  89. package/lib/utils/dateVariable.js +380 -0
  90. package/lib/utils/exceptions.d.ts +7 -0
  91. package/lib/utils/exceptions.js +10 -0
  92. package/lib/utils/index.d.ts +8 -3
  93. package/lib/utils/index.js +45 -0
  94. package/lib/utils/params-resolvers.js +16 -9
  95. package/lib/utils/resolveModuleUrl.d.ts +58 -0
  96. package/lib/utils/resolveModuleUrl.js +65 -0
  97. package/lib/utils/resolveRunJSObjectValues.d.ts +16 -0
  98. package/lib/utils/resolveRunJSObjectValues.js +61 -0
  99. package/lib/utils/runjsModuleLoader.d.ts +58 -0
  100. package/lib/utils/runjsModuleLoader.js +422 -0
  101. package/lib/utils/runjsTemplateCompat.d.ts +35 -0
  102. package/lib/utils/runjsTemplateCompat.js +743 -0
  103. package/lib/utils/runjsValue.d.ts +29 -0
  104. package/lib/utils/runjsValue.js +275 -0
  105. package/lib/utils/safeGlobals.d.ts +18 -8
  106. package/lib/utils/safeGlobals.js +164 -17
  107. package/lib/utils/schema-utils.d.ts +10 -0
  108. package/lib/utils/schema-utils.js +61 -0
  109. package/lib/views/createViewMeta.d.ts +0 -7
  110. package/lib/views/createViewMeta.js +19 -70
  111. package/lib/views/index.d.ts +1 -2
  112. package/lib/views/index.js +4 -3
  113. package/lib/views/useDialog.js +7 -2
  114. package/lib/views/useDrawer.js +7 -2
  115. package/lib/views/usePage.d.ts +4 -0
  116. package/lib/views/usePage.js +43 -6
  117. package/lib/views/usePopover.js +4 -1
  118. package/lib/views/viewEvents.d.ts +17 -0
  119. package/lib/views/viewEvents.js +90 -0
  120. package/package.json +4 -4
  121. package/src/BlockScopedFlowEngine.ts +2 -5
  122. package/src/JSRunner.ts +44 -2
  123. package/src/ViewScopedFlowEngine.ts +4 -0
  124. package/src/__tests__/JSRunner.test.ts +64 -0
  125. package/src/__tests__/createViewMeta.popup.test.ts +62 -1
  126. package/src/__tests__/flowContext.test.ts +693 -1
  127. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +63 -0
  128. package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
  129. package/src/__tests__/flowRunJSContextDefine.test.ts +63 -0
  130. package/src/__tests__/flowRuntimeContext.test.ts +2 -1
  131. package/src/__tests__/flowSettings.open.test.tsx +123 -19
  132. package/src/__tests__/runjsContext.test.ts +10 -7
  133. package/src/__tests__/runjsContextImplementations.test.ts +34 -3
  134. package/src/__tests__/runjsContextRuntime.test.ts +3 -3
  135. package/src/__tests__/runjsContributions.test.ts +89 -0
  136. package/src/__tests__/runjsExternalLibs.test.ts +242 -0
  137. package/src/__tests__/runjsLibsLazyLoading.test.ts +44 -0
  138. package/src/__tests__/runjsLocales.test.ts +4 -1
  139. package/src/__tests__/runjsPreprocessDefault.test.ts +49 -0
  140. package/src/__tests__/runjsRuntimeFeatures.test.ts +166 -0
  141. package/src/__tests__/runjsSnippets.test.ts +40 -3
  142. package/src/acl/Acl.tsx +3 -3
  143. package/src/components/FlowContextSelector.tsx +208 -12
  144. package/src/components/settings/wrappers/component/SwitchWithTitle.tsx +2 -1
  145. package/src/components/settings/wrappers/component/__tests__/InlineControls.test.tsx +74 -0
  146. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +109 -16
  147. package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +41 -7
  148. package/src/components/settings/wrappers/contextual/StepSettingsDialog.tsx +13 -2
  149. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +157 -5
  150. package/src/components/variables/VariableInput.tsx +12 -4
  151. package/src/components/variables/VariableTag.tsx +54 -45
  152. package/src/components/variables/__tests__/FlowContextSelector.test.tsx +260 -3
  153. package/src/components/variables/__tests__/VariableTag.test.tsx +50 -0
  154. package/src/components/variables/__tests__/utils.test.ts +81 -3
  155. package/src/components/variables/utils.ts +67 -6
  156. package/src/data-source/index.ts +85 -110
  157. package/src/executor/FlowExecutor.ts +200 -23
  158. package/src/executor/__tests__/flowExecutor.test.ts +66 -0
  159. package/src/flowContext.ts +2986 -211
  160. package/src/flowEngine.ts +59 -8
  161. package/src/flowI18n.ts +7 -5
  162. package/src/flowSettings.ts +18 -12
  163. package/src/index.ts +14 -1
  164. package/src/locale/en-US.json +9 -2
  165. package/src/locale/zh-CN.json +8 -1
  166. package/src/models/CollectionFieldModel.tsx +3 -1
  167. package/src/models/__tests__/dispatchEvent.when.test.ts +554 -0
  168. package/src/models/__tests__/flowModel.test.ts +20 -4
  169. package/src/models/flowModel.tsx +13 -1
  170. package/src/provider.tsx +7 -6
  171. package/src/resources/__tests__/multiRecordResource.test.ts +44 -0
  172. package/src/resources/__tests__/sqlResource.test.ts +60 -0
  173. package/src/resources/baseRecordResource.ts +31 -0
  174. package/src/resources/multiRecordResource.ts +11 -4
  175. package/src/resources/singleRecordResource.ts +3 -0
  176. package/src/resources/sqlResource.ts +11 -6
  177. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +10 -0
  178. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +6 -2
  179. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +106 -0
  180. package/src/runjs-context/contexts/JSItemRunJSContext.ts +10 -0
  181. package/src/runjs-context/contexts/base.ts +715 -44
  182. package/src/runjs-context/contributions.ts +88 -0
  183. package/src/runjs-context/helpers.ts +11 -1
  184. package/src/runjs-context/setup.ts +6 -0
  185. package/src/runjs-context/snippets/global/api-request.snippet.ts +3 -3
  186. package/src/runjs-context/snippets/global/import-esm.snippet.ts +2 -3
  187. package/src/runjs-context/snippets/global/query-selector.snippet.ts +8 -3
  188. package/src/runjs-context/snippets/global/require-amd.snippet.ts +1 -1
  189. package/src/runjs-context/snippets/index.ts +75 -41
  190. package/src/runjs-context/snippets/scene/block/add-event-listener.snippet.ts +11 -13
  191. package/src/runjs-context/snippets/scene/block/api-fetch-render-list.snippet.ts +3 -3
  192. package/src/runjs-context/snippets/scene/block/chartjs-bar.snippet.ts +2 -2
  193. package/src/runjs-context/snippets/scene/block/echarts-init.snippet.ts +2 -2
  194. package/src/runjs-context/snippets/scene/block/render-iframe.snippet.ts +2 -2
  195. package/src/runjs-context/snippets/scene/block/render-react.snippet.ts +1 -1
  196. package/src/runjs-context/snippets/scene/block/render-statistics.snippet.ts +1 -1
  197. package/src/runjs-context/snippets/scene/block/render-timeline.snippet.ts +1 -1
  198. package/src/runjs-context/snippets/scene/block/resource-example.snippet.ts +6 -11
  199. package/src/runjs-context/snippets/scene/block/three-users-orbit.snippet.ts +6 -6
  200. package/src/runjs-context/snippets/scene/block/vue-component.snippet.ts +3 -4
  201. package/src/runjs-context/snippets/scene/detail/color-by-value.snippet.ts +1 -1
  202. package/src/runjs-context/snippets/scene/detail/copy-to-clipboard.snippet.ts +20 -3
  203. package/src/runjs-context/snippets/scene/detail/format-number.snippet.ts +1 -1
  204. package/src/runjs-context/snippets/scene/detail/innerHTML-value.snippet.ts +1 -1
  205. package/src/runjs-context/snippets/scene/detail/percentage-bar.snippet.ts +3 -3
  206. package/src/runjs-context/snippets/scene/detail/relative-time.snippet.ts +3 -3
  207. package/src/runjs-context/snippets/scene/detail/status-tag.snippet.ts +2 -2
  208. package/src/runjs-context/snippets/scene/form/cascade-select.snippet.ts +1 -1
  209. package/src/runjs-context/snippets/scene/form/render-basic.snippet.ts +3 -8
  210. package/src/runjs-context/snippets/scene/table/cell-open-dialog.snippet.ts +6 -3
  211. package/src/runjs-context/snippets/scene/table/concat-fields.snippet.ts +3 -1
  212. package/src/runjsLibs.ts +622 -0
  213. package/src/scheduler/ModelOperationScheduler.ts +27 -21
  214. package/src/types.ts +38 -1
  215. package/src/utils/__tests__/dateVariable.test.ts +101 -0
  216. package/src/utils/__tests__/params-resolvers.test.ts +40 -0
  217. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +38 -0
  218. package/src/utils/__tests__/runjsTemplateCompat.test.ts +159 -0
  219. package/src/utils/__tests__/runjsValue.test.ts +44 -0
  220. package/src/utils/__tests__/safeGlobals.test.ts +57 -2
  221. package/src/utils/__tests__/utils.test.ts +95 -0
  222. package/src/utils/associationObjectVariable.ts +2 -2
  223. package/src/utils/createCollectionContextMeta.ts +1 -0
  224. package/src/utils/createEphemeralContext.ts +5 -4
  225. package/src/utils/dateVariable.ts +397 -0
  226. package/src/utils/exceptions.ts +11 -0
  227. package/src/utils/index.ts +37 -3
  228. package/src/utils/params-resolvers.ts +23 -9
  229. package/src/utils/resolveModuleUrl.ts +91 -0
  230. package/src/utils/resolveRunJSObjectValues.ts +46 -0
  231. package/src/utils/runjsModuleLoader.ts +553 -0
  232. package/src/utils/runjsTemplateCompat.ts +828 -0
  233. package/src/utils/runjsValue.ts +287 -0
  234. package/src/utils/safeGlobals.ts +188 -17
  235. package/src/utils/schema-utils.ts +79 -0
  236. package/src/views/__tests__/FlowView.usePage.test.tsx +54 -1
  237. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +35 -8
  238. package/src/views/__tests__/viewEvents.resolveOpenerEngine.test.ts +28 -0
  239. package/src/views/createViewMeta.ts +22 -75
  240. package/src/views/index.tsx +1 -2
  241. package/src/views/useDialog.tsx +8 -1
  242. package/src/views/useDrawer.tsx +8 -1
  243. package/src/views/usePage.tsx +51 -5
  244. package/src/views/usePopover.tsx +4 -1
  245. package/src/views/viewEvents.ts +55 -0
@@ -0,0 +1,29 @@
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
+ export type RunJSValue = {
10
+ code: string;
11
+ version?: string;
12
+ };
13
+ /**
14
+ * Strictly detect RunJSValue to avoid conflicting with normal constant objects.
15
+ * - MUST be a plain object (not array)
16
+ * - MUST include string `code`
17
+ * - MAY include string `version`
18
+ * - MUST NOT include any other enumerable keys
19
+ */
20
+ export declare function isRunJSValue(value: any): value is RunJSValue;
21
+ export declare function normalizeRunJSValue(value: RunJSValue): Required<RunJSValue>;
22
+ /**
23
+ * Heuristic extraction of ctx variable usage from RunJS code.
24
+ *
25
+ * Returns a map: varName -> string[] subPaths
26
+ * - subPath '' means the variable root is used (or dependency is dynamic), caller MAY treat it as wildcard.
27
+ * - Only best-effort parsing; correctness prefers over-approximation.
28
+ */
29
+ export declare function extractUsedVariablePathsFromRunJS(code: string): Record<string, string[]>;
@@ -0,0 +1,275 @@
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
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
15
+ var __export = (target, all) => {
16
+ for (var name in all)
17
+ __defProp(target, name, { get: all[name], enumerable: true });
18
+ };
19
+ var __copyProps = (to, from, except, desc) => {
20
+ if (from && typeof from === "object" || typeof from === "function") {
21
+ for (let key of __getOwnPropNames(from))
22
+ if (!__hasOwnProp.call(to, key) && key !== except)
23
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
24
+ }
25
+ return to;
26
+ };
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var runjsValue_exports = {};
29
+ __export(runjsValue_exports, {
30
+ extractUsedVariablePathsFromRunJS: () => extractUsedVariablePathsFromRunJS,
31
+ isRunJSValue: () => isRunJSValue,
32
+ normalizeRunJSValue: () => normalizeRunJSValue
33
+ });
34
+ module.exports = __toCommonJS(runjsValue_exports);
35
+ const RUNJS_ALLOWED_KEYS = /* @__PURE__ */ new Set(["code", "version"]);
36
+ function isRunJSValue(value) {
37
+ if (!value || typeof value !== "object") return false;
38
+ if (Array.isArray(value)) return false;
39
+ const keys = Object.keys(value);
40
+ if (!keys.includes("code")) return false;
41
+ if (typeof value.code !== "string") return false;
42
+ if ("version" in value && value.version != null && typeof value.version !== "string") return false;
43
+ for (const k of keys) {
44
+ if (!RUNJS_ALLOWED_KEYS.has(k)) return false;
45
+ }
46
+ return true;
47
+ }
48
+ __name(isRunJSValue, "isRunJSValue");
49
+ function normalizeRunJSValue(value) {
50
+ return {
51
+ code: String((value == null ? void 0 : value.code) ?? ""),
52
+ version: String((value == null ? void 0 : value.version) ?? "v1")
53
+ };
54
+ }
55
+ __name(normalizeRunJSValue, "normalizeRunJSValue");
56
+ function stripStringsAndComments(code) {
57
+ let out = "";
58
+ let state = "code";
59
+ for (let i = 0; i < code.length; i++) {
60
+ const ch = code[i];
61
+ const next = i + 1 < code.length ? code[i + 1] : "";
62
+ if (state === "code") {
63
+ if (ch === "/" && next === "/") {
64
+ out += " ";
65
+ i++;
66
+ state = "line";
67
+ continue;
68
+ }
69
+ if (ch === "/" && next === "*") {
70
+ out += " ";
71
+ i++;
72
+ state = "block";
73
+ continue;
74
+ }
75
+ if (ch === "'") {
76
+ out += " ";
77
+ state = "single";
78
+ continue;
79
+ }
80
+ if (ch === '"') {
81
+ out += " ";
82
+ state = "double";
83
+ continue;
84
+ }
85
+ out += ch;
86
+ continue;
87
+ }
88
+ if (state === "line") {
89
+ if (ch === "\n") {
90
+ out += "\n";
91
+ state = "code";
92
+ } else {
93
+ out += " ";
94
+ }
95
+ continue;
96
+ }
97
+ if (state === "block") {
98
+ if (ch === "*" && next === "/") {
99
+ out += " ";
100
+ i++;
101
+ state = "code";
102
+ } else {
103
+ out += ch === "\n" ? "\n" : " ";
104
+ }
105
+ continue;
106
+ }
107
+ if (state === "single") {
108
+ if (ch === "\\") {
109
+ out += " ";
110
+ i++;
111
+ continue;
112
+ }
113
+ if (ch === "'") {
114
+ out += " ";
115
+ state = "code";
116
+ } else {
117
+ out += ch === "\n" ? "\n" : " ";
118
+ }
119
+ continue;
120
+ }
121
+ if (ch === "\\") {
122
+ out += " ";
123
+ i++;
124
+ continue;
125
+ }
126
+ if (ch === '"') {
127
+ out += " ";
128
+ state = "code";
129
+ } else {
130
+ out += ch === "\n" ? "\n" : " ";
131
+ }
132
+ }
133
+ return out;
134
+ }
135
+ __name(stripStringsAndComments, "stripStringsAndComments");
136
+ function stripComments(code) {
137
+ let out = "";
138
+ let state = "code";
139
+ for (let i = 0; i < code.length; i++) {
140
+ const ch = code[i];
141
+ const next = i + 1 < code.length ? code[i + 1] : "";
142
+ if (state === "code") {
143
+ if (ch === "/" && next === "/") {
144
+ out += " ";
145
+ i++;
146
+ state = "line";
147
+ continue;
148
+ }
149
+ if (ch === "/" && next === "*") {
150
+ out += " ";
151
+ i++;
152
+ state = "block";
153
+ continue;
154
+ }
155
+ if (ch === "'") {
156
+ out += ch;
157
+ state = "single";
158
+ continue;
159
+ }
160
+ if (ch === '"') {
161
+ out += ch;
162
+ state = "double";
163
+ continue;
164
+ }
165
+ out += ch;
166
+ continue;
167
+ }
168
+ if (state === "line") {
169
+ if (ch === "\n") {
170
+ out += "\n";
171
+ state = "code";
172
+ } else {
173
+ out += " ";
174
+ }
175
+ continue;
176
+ }
177
+ if (state === "block") {
178
+ if (ch === "*" && next === "/") {
179
+ out += " ";
180
+ i++;
181
+ state = "code";
182
+ } else {
183
+ out += ch === "\n" ? "\n" : " ";
184
+ }
185
+ continue;
186
+ }
187
+ if (state === "single") {
188
+ out += ch;
189
+ if (ch === "\\") {
190
+ const nextCh = i + 1 < code.length ? code[i + 1] : "";
191
+ if (nextCh) {
192
+ out += nextCh;
193
+ i++;
194
+ }
195
+ continue;
196
+ }
197
+ if (ch === "'") {
198
+ state = "code";
199
+ }
200
+ continue;
201
+ }
202
+ out += ch;
203
+ if (ch === "\\") {
204
+ const nextCh = i + 1 < code.length ? code[i + 1] : "";
205
+ if (nextCh) {
206
+ out += nextCh;
207
+ i++;
208
+ }
209
+ continue;
210
+ }
211
+ if (ch === '"') {
212
+ state = "code";
213
+ }
214
+ }
215
+ return out;
216
+ }
217
+ __name(stripComments, "stripComments");
218
+ function normalizeSubPath(raw) {
219
+ if (!raw) return { subPath: "", wildcard: false };
220
+ let s = raw;
221
+ s = s.replace(/\[['"]([a-zA-Z_$][a-zA-Z0-9_$]*)['"]\]/g, ".$1");
222
+ const bracketRe = /\[([^\]]+)\]/g;
223
+ let m;
224
+ while (m = bracketRe.exec(s)) {
225
+ const inner = String(m[1] ?? "").trim();
226
+ if (/^\d+$/.test(inner)) continue;
227
+ if (/^['"][a-zA-Z_$][a-zA-Z0-9_$]*['"]$/.test(inner)) continue;
228
+ return { subPath: s.startsWith(".") ? s.slice(1) : s, wildcard: true };
229
+ }
230
+ if (s.startsWith(".")) s = s.slice(1);
231
+ return { subPath: s, wildcard: false };
232
+ }
233
+ __name(normalizeSubPath, "normalizeSubPath");
234
+ function extractUsedVariablePathsFromRunJS(code) {
235
+ if (typeof code !== "string" || !code.trim()) return {};
236
+ const src = stripStringsAndComments(code);
237
+ const srcWithStrings = stripComments(code);
238
+ const usage = /* @__PURE__ */ new Map();
239
+ const add = /* @__PURE__ */ __name((varName, subPath) => {
240
+ if (!varName) return;
241
+ const set = usage.get(varName) || /* @__PURE__ */ new Set();
242
+ set.add(subPath || "");
243
+ usage.set(varName, set);
244
+ }, "add");
245
+ const dotRe = /ctx\.([a-zA-Z_$][a-zA-Z0-9_$]*(?:(?:\.[a-zA-Z_$][a-zA-Z0-9_$]*)|(?:\[[^\]]+\]))*)(?!\s*\()/g;
246
+ let match;
247
+ while (match = dotRe.exec(src)) {
248
+ const pathAfterCtx = match[1] || "";
249
+ const firstKeyMatch = pathAfterCtx.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)/);
250
+ if (!firstKeyMatch) continue;
251
+ const firstKey = firstKeyMatch[1];
252
+ const rest = pathAfterCtx.slice(firstKey.length);
253
+ const { subPath, wildcard } = normalizeSubPath(rest);
254
+ add(firstKey, wildcard ? "" : subPath);
255
+ }
256
+ const bracketRootRe = /ctx\s*\[\s*(['"])([a-zA-Z_$][a-zA-Z0-9_$]*)\1\s*\]((?:(?:\.[a-zA-Z_$][a-zA-Z0-9_$]*)|(?:\[[^\]]+\]))*)(?!\s*\()/g;
257
+ while (match = bracketRootRe.exec(srcWithStrings)) {
258
+ const varName = match[2] || "";
259
+ const rest = match[3] || "";
260
+ const { subPath, wildcard } = normalizeSubPath(rest);
261
+ add(varName, wildcard ? "" : subPath);
262
+ }
263
+ const out = {};
264
+ for (const [k, set] of usage.entries()) {
265
+ out[k] = Array.from(set);
266
+ }
267
+ return out;
268
+ }
269
+ __name(extractUsedVariablePathsFromRunJS, "extractUsedVariablePathsFromRunJS");
270
+ // Annotate the CommonJS export names for ESM import in node:
271
+ 0 && (module.exports = {
272
+ extractUsedVariablePathsFromRunJS,
273
+ isRunJSValue,
274
+ normalizeRunJSValue
275
+ });
@@ -6,13 +6,23 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
+ export declare function registerRunJSSafeWindowGlobals(keys: Iterable<string> | null | undefined): void;
10
+ export declare function registerRunJSSafeDocumentGlobals(keys: Iterable<string> | null | undefined): void;
11
+ export declare function __resetRunJSSafeGlobalsRegistryForTests(): void;
12
+ export declare function createSafeWindow(extra?: Record<string, any>): Record<string, any>;
13
+ export declare function createSafeDocument(extra?: Record<string, any>): Record<string, any>;
14
+ export declare function createSafeNavigator(extra?: Record<string, any>): {};
9
15
  /**
10
- * 统一的安全全局对象代理:window/document/navigator
11
- * - window:仅允许常用的定时器、console、Math、Date、FormData、addEventListener、open(安全包装)、location(安全代理)
12
- * - document:仅允许 createElement/querySelector/querySelectorAll
13
- * - navigator:仅提供极少量低风险能力(clipboard.writeText、onLine、language、languages)
14
- * - 不允许随意访问未声明的属性,最小权限原则
16
+ * Create a safe globals object for RunJS execution.
17
+ *
18
+ * - Always tries to provide `navigator`
19
+ * - Best-effort provides `window` and `document` in browser environments
20
+ * - Never throws (so callers can decide how to handle missing globals)
15
21
  */
16
- export declare function createSafeWindow(extra?: Record<string, any>): {};
17
- export declare function createSafeDocument(extra?: Record<string, any>): {};
18
- export declare function createSafeNavigator(extra?: Record<string, any>): {};
22
+ export declare function createSafeRunJSGlobals(extraGlobals?: Record<string, any>): Record<string, any>;
23
+ /**
24
+ * Execute RunJS with safe globals (window/document/navigator).
25
+ *
26
+ * Keeps `this` binding by calling `ctx.runjs(...)` instead of passing bare function references.
27
+ */
28
+ export declare function runjsWithSafeGlobals(ctx: unknown, code: string, options?: any, extraGlobals?: Record<string, any>): Promise<any>;
@@ -27,14 +27,75 @@ var __copyProps = (to, from, except, desc) => {
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
28
  var safeGlobals_exports = {};
29
29
  __export(safeGlobals_exports, {
30
+ __resetRunJSSafeGlobalsRegistryForTests: () => __resetRunJSSafeGlobalsRegistryForTests,
30
31
  createSafeDocument: () => createSafeDocument,
31
32
  createSafeNavigator: () => createSafeNavigator,
32
- createSafeWindow: () => createSafeWindow
33
+ createSafeRunJSGlobals: () => createSafeRunJSGlobals,
34
+ createSafeWindow: () => createSafeWindow,
35
+ registerRunJSSafeDocumentGlobals: () => registerRunJSSafeDocumentGlobals,
36
+ registerRunJSSafeWindowGlobals: () => registerRunJSSafeWindowGlobals,
37
+ runjsWithSafeGlobals: () => runjsWithSafeGlobals
33
38
  });
34
39
  module.exports = __toCommonJS(safeGlobals_exports);
40
+ function getRunJSSafeGlobalsRegistry() {
41
+ var _a, _b;
42
+ const g = globalThis;
43
+ if (((_a = g.__nocobaseRunJSSafeGlobalsRegistry) == null ? void 0 : _a.windowAllow) && ((_b = g.__nocobaseRunJSSafeGlobalsRegistry) == null ? void 0 : _b.documentAllow)) {
44
+ return g.__nocobaseRunJSSafeGlobalsRegistry;
45
+ }
46
+ const reg = {
47
+ windowAllow: /* @__PURE__ */ new Set(),
48
+ documentAllow: /* @__PURE__ */ new Set()
49
+ };
50
+ g.__nocobaseRunJSSafeGlobalsRegistry = reg;
51
+ return reg;
52
+ }
53
+ __name(getRunJSSafeGlobalsRegistry, "getRunJSSafeGlobalsRegistry");
54
+ function registerRunJSSafeWindowGlobals(keys) {
55
+ if (!keys) return;
56
+ const reg = getRunJSSafeGlobalsRegistry();
57
+ for (const k of keys) {
58
+ if (typeof k !== "string") continue;
59
+ const key = k.trim();
60
+ if (!key) continue;
61
+ reg.windowAllow.add(key);
62
+ }
63
+ }
64
+ __name(registerRunJSSafeWindowGlobals, "registerRunJSSafeWindowGlobals");
65
+ function registerRunJSSafeDocumentGlobals(keys) {
66
+ if (!keys) return;
67
+ const reg = getRunJSSafeGlobalsRegistry();
68
+ for (const k of keys) {
69
+ if (typeof k !== "string") continue;
70
+ const key = k.trim();
71
+ if (!key) continue;
72
+ reg.documentAllow.add(key);
73
+ }
74
+ }
75
+ __name(registerRunJSSafeDocumentGlobals, "registerRunJSSafeDocumentGlobals");
76
+ function __resetRunJSSafeGlobalsRegistryForTests() {
77
+ var _a, _b, _c, _d;
78
+ const g = globalThis;
79
+ if (g.__nocobaseRunJSSafeGlobalsRegistry) {
80
+ try {
81
+ (_b = (_a = g.__nocobaseRunJSSafeGlobalsRegistry.windowAllow) == null ? void 0 : _a.clear) == null ? void 0 : _b.call(_a);
82
+ (_d = (_c = g.__nocobaseRunJSSafeGlobalsRegistry.documentAllow) == null ? void 0 : _c.clear) == null ? void 0 : _d.call(_c);
83
+ } catch {
84
+ }
85
+ }
86
+ }
87
+ __name(__resetRunJSSafeGlobalsRegistryForTests, "__resetRunJSSafeGlobalsRegistryForTests");
88
+ function isAllowedDynamicWindowKey(key) {
89
+ return getRunJSSafeGlobalsRegistry().windowAllow.has(key);
90
+ }
91
+ __name(isAllowedDynamicWindowKey, "isAllowedDynamicWindowKey");
92
+ function isAllowedDynamicDocumentKey(key) {
93
+ return getRunJSSafeGlobalsRegistry().documentAllow.has(key);
94
+ }
95
+ __name(isAllowedDynamicDocumentKey, "isAllowedDynamicDocumentKey");
35
96
  function createSafeWindow(extra) {
36
97
  const getSafeBaseHref = /* @__PURE__ */ __name(() => `${window.location.origin}${window.location.pathname}`, "getSafeBaseHref");
37
- const safeOpen = /* @__PURE__ */ __name((url, target, features) => {
98
+ const safeOpen = /* @__PURE__ */ __name((url, target2, features) => {
38
99
  const isSafeUrl = /* @__PURE__ */ __name((u) => {
39
100
  try {
40
101
  const parsed = new URL(u, getSafeBaseHref());
@@ -137,6 +198,8 @@ function createSafeWindow(extra) {
137
198
  Math,
138
199
  Date,
139
200
  FormData,
201
+ ...typeof Blob !== "undefined" ? { Blob } : {},
202
+ ...typeof URL !== "undefined" ? { URL } : {},
140
203
  // 事件侦听仅绑定到真实 window,便于少量需要的全局监听
141
204
  addEventListener: addEventListener.bind(window),
142
205
  // 安全的 window.open 代理
@@ -145,15 +208,40 @@ function createSafeWindow(extra) {
145
208
  location: safeLocation,
146
209
  ...extra || {}
147
210
  };
148
- return new Proxy(
149
- {},
150
- {
151
- get(_target, prop) {
152
- if (prop in allowedGlobals) return allowedGlobals[prop];
153
- throw new Error(`Access to global property "${prop}" is not allowed.`);
211
+ const target = /* @__PURE__ */ Object.create(null);
212
+ return new Proxy(target, {
213
+ get(t, prop) {
214
+ if (typeof prop !== "string") {
215
+ return Reflect.get(t, prop);
216
+ }
217
+ if (prop in allowedGlobals) return allowedGlobals[prop];
218
+ if (Object.prototype.hasOwnProperty.call(t, prop)) return t[prop];
219
+ if (isAllowedDynamicWindowKey(prop)) {
220
+ const v = window[prop];
221
+ if (typeof v === "function") return v.bind(window);
222
+ return v;
223
+ }
224
+ throw new Error(`Access to global property "${prop}" is not allowed.`);
225
+ },
226
+ set(t, prop, value) {
227
+ if (typeof prop !== "string") {
228
+ Reflect.set(t, prop, value);
229
+ return true;
230
+ }
231
+ if (prop in allowedGlobals) {
232
+ throw new Error(`Mutation of global property "${prop}" is not allowed.`);
154
233
  }
234
+ t[prop] = value;
235
+ return true;
236
+ },
237
+ has(t, prop) {
238
+ if (typeof prop !== "string") return Reflect.has(t, prop);
239
+ if (prop in allowedGlobals) return true;
240
+ if (Object.prototype.hasOwnProperty.call(t, prop)) return true;
241
+ if (isAllowedDynamicWindowKey(prop)) return true;
242
+ return false;
155
243
  }
156
- );
244
+ });
157
245
  }
158
246
  __name(createSafeWindow, "createSafeWindow");
159
247
  function createSafeDocument(extra) {
@@ -163,15 +251,40 @@ function createSafeDocument(extra) {
163
251
  querySelectorAll: document.querySelectorAll.bind(document),
164
252
  ...extra || {}
165
253
  };
166
- return new Proxy(
167
- {},
168
- {
169
- get(_target, prop) {
170
- if (prop in allowed) return allowed[prop];
171
- throw new Error(`Access to document property "${prop}" is not allowed.`);
254
+ const target = /* @__PURE__ */ Object.create(null);
255
+ return new Proxy(target, {
256
+ get(t, prop) {
257
+ if (typeof prop !== "string") {
258
+ return Reflect.get(t, prop);
259
+ }
260
+ if (prop in allowed) return allowed[prop];
261
+ if (Object.prototype.hasOwnProperty.call(t, prop)) return t[prop];
262
+ if (isAllowedDynamicDocumentKey(prop)) {
263
+ const v = document[prop];
264
+ if (typeof v === "function") return v.bind(document);
265
+ return v;
266
+ }
267
+ throw new Error(`Access to document property "${prop}" is not allowed.`);
268
+ },
269
+ set(t, prop, value) {
270
+ if (typeof prop !== "string") {
271
+ Reflect.set(t, prop, value);
272
+ return true;
273
+ }
274
+ if (prop in allowed) {
275
+ throw new Error(`Mutation of document property "${prop}" is not allowed.`);
172
276
  }
277
+ t[prop] = value;
278
+ return true;
279
+ },
280
+ has(t, prop) {
281
+ if (typeof prop !== "string") return Reflect.has(t, prop);
282
+ if (prop in allowed) return true;
283
+ if (Object.prototype.hasOwnProperty.call(t, prop)) return true;
284
+ if (isAllowedDynamicDocumentKey(prop)) return true;
285
+ return false;
173
286
  }
174
- );
287
+ });
175
288
  }
176
289
  __name(createSafeDocument, "createSafeDocument");
177
290
  function createSafeNavigator(extra) {
@@ -212,9 +325,43 @@ function createSafeNavigator(extra) {
212
325
  );
213
326
  }
214
327
  __name(createSafeNavigator, "createSafeNavigator");
328
+ function createSafeRunJSGlobals(extraGlobals) {
329
+ const globals = {};
330
+ try {
331
+ const navigator = createSafeNavigator();
332
+ globals.navigator = navigator;
333
+ try {
334
+ globals.window = createSafeWindow({ navigator });
335
+ } catch {
336
+ }
337
+ } catch {
338
+ }
339
+ try {
340
+ globals.document = createSafeDocument();
341
+ } catch {
342
+ }
343
+ return extraGlobals ? { ...globals, ...extraGlobals } : globals;
344
+ }
345
+ __name(createSafeRunJSGlobals, "createSafeRunJSGlobals");
346
+ async function runjsWithSafeGlobals(ctx, code, options, extraGlobals) {
347
+ if (!ctx || typeof ctx !== "object" && typeof ctx !== "function") return void 0;
348
+ const runjs = ctx.runjs;
349
+ if (typeof runjs !== "function") return void 0;
350
+ return ctx.runjs(
351
+ code,
352
+ createSafeRunJSGlobals(extraGlobals),
353
+ options
354
+ );
355
+ }
356
+ __name(runjsWithSafeGlobals, "runjsWithSafeGlobals");
215
357
  // Annotate the CommonJS export names for ESM import in node:
216
358
  0 && (module.exports = {
359
+ __resetRunJSSafeGlobalsRegistryForTests,
217
360
  createSafeDocument,
218
361
  createSafeNavigator,
219
- createSafeWindow
362
+ createSafeRunJSGlobals,
363
+ createSafeWindow,
364
+ registerRunJSSafeDocumentGlobals,
365
+ registerRunJSSafeWindowGlobals,
366
+ runjsWithSafeGlobals
220
367
  });
@@ -44,3 +44,13 @@ export declare function resolveStepUiSchema<TModel extends FlowModel = FlowModel
44
44
  * - hideInSettings 可为布尔值或函数(接收 FlowRuntimeContext)。
45
45
  */
46
46
  export declare function shouldHideStepInSettings<TModel extends FlowModel = FlowModel>(model: TModel, flow: any, step: StepDefinition): Promise<boolean>;
47
+ /**
48
+ * 解析步骤在设置菜单中的禁用状态与提示文案。
49
+ * - 支持 StepDefinition.disabledInSettings 与 ActionDefinition.disabledInSettings(step 优先)。
50
+ * - 支持 StepDefinition.disabledReasonInSettings 与 ActionDefinition.disabledReasonInSettings(step 优先)。
51
+ * - 以上属性均支持静态值与函数(接收 FlowRuntimeContext)。
52
+ */
53
+ export declare function resolveStepDisabledInSettings<TModel extends FlowModel = FlowModel>(model: TModel, flow: any, step: StepDefinition): Promise<{
54
+ disabled: boolean;
55
+ reason?: string;
56
+ }>;
@@ -28,6 +28,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
28
28
  var schema_utils_exports = {};
29
29
  __export(schema_utils_exports, {
30
30
  compileUiSchema: () => compileUiSchema,
31
+ resolveStepDisabledInSettings: () => resolveStepDisabledInSettings,
31
32
  resolveStepUiSchema: () => resolveStepUiSchema,
32
33
  resolveUiMode: () => resolveUiMode,
33
34
  shouldHideStepInSettings: () => shouldHideStepInSettings
@@ -217,9 +218,69 @@ async function shouldHideStepInSettings(model, flow, step) {
217
218
  return !!hideInSettings;
218
219
  }
219
220
  __name(shouldHideStepInSettings, "shouldHideStepInSettings");
221
+ async function resolveStepDisabledInSettings(model, flow, step) {
222
+ var _a;
223
+ if (!step) return { disabled: false };
224
+ let disabledInSettings = step.disabledInSettings;
225
+ let disabledReasonInSettings = step.disabledReasonInSettings;
226
+ if ((typeof disabledInSettings === "undefined" || typeof disabledReasonInSettings === "undefined") && step.use) {
227
+ try {
228
+ const action = (_a = model.getAction) == null ? void 0 : _a.call(model, step.use);
229
+ if (typeof disabledInSettings === "undefined") {
230
+ disabledInSettings = action == null ? void 0 : action.disabledInSettings;
231
+ }
232
+ if (typeof disabledReasonInSettings === "undefined") {
233
+ disabledReasonInSettings = action == null ? void 0 : action.disabledReasonInSettings;
234
+ }
235
+ } catch (error) {
236
+ console.warn(`Failed to get action ${step.use}:`, error);
237
+ }
238
+ }
239
+ let ctx = null;
240
+ const getContext = /* @__PURE__ */ __name(() => {
241
+ if (ctx) return ctx;
242
+ ctx = new import_flowContext.FlowRuntimeContext(model, flow.key, "settings");
243
+ (0, import_setupRuntimeContextSteps.setupRuntimeContextSteps)(ctx, flow.steps, model, flow.key);
244
+ ctx.defineProperty("currentStep", { value: step });
245
+ return ctx;
246
+ }, "getContext");
247
+ let disabled = false;
248
+ if (typeof disabledInSettings === "function") {
249
+ try {
250
+ disabled = !!await disabledInSettings(getContext());
251
+ } catch (error) {
252
+ console.warn(`Error evaluating disabledInSettings for step '${step.key || ""}' in flow '${flow.key}':`, error);
253
+ return { disabled: false };
254
+ }
255
+ } else {
256
+ disabled = !!disabledInSettings;
257
+ }
258
+ if (!disabled) {
259
+ return { disabled: false };
260
+ }
261
+ let reason;
262
+ if (typeof disabledReasonInSettings === "function") {
263
+ try {
264
+ const resolved = await disabledReasonInSettings(getContext());
265
+ if (typeof resolved !== "undefined" && resolved !== null && resolved !== "") {
266
+ reason = String(resolved);
267
+ }
268
+ } catch (error) {
269
+ console.warn(
270
+ `Error evaluating disabledReasonInSettings for step '${step.key || ""}' in flow '${flow.key}':`,
271
+ error
272
+ );
273
+ }
274
+ } else if (typeof disabledReasonInSettings !== "undefined" && disabledReasonInSettings !== null && disabledReasonInSettings !== "") {
275
+ reason = String(disabledReasonInSettings);
276
+ }
277
+ return { disabled: true, reason };
278
+ }
279
+ __name(resolveStepDisabledInSettings, "resolveStepDisabledInSettings");
220
280
  // Annotate the CommonJS export names for ESM import in node:
221
281
  0 && (module.exports = {
222
282
  compileUiSchema,
283
+ resolveStepDisabledInSettings,
223
284
  resolveStepUiSchema,
224
285
  resolveUiMode,
225
286
  shouldHideStepInSettings
@@ -8,13 +8,6 @@
8
8
  */
9
9
  import type { FlowContext, PropertyMetaFactory } from '../flowContext';
10
10
  import type { FlowView } from './FlowView';
11
- /**
12
- * Create a meta factory for ctx.view that includes:
13
- * - buildVariablesParams: { record } via inferRecordRef
14
- * - properties.record: full collection meta via buildRecordMeta
15
- * - type/preventClose/inputArgs/navigation fields for better variable selection UX
16
- */
17
- export declare function createViewMeta(ctx: FlowContext): PropertyMetaFactory;
18
11
  /**
19
12
  * 为 ctx.popup 构建元信息:
20
13
  * - popup.record:当前弹窗记录(服务端解析)