@nocobase/flow-engine 2.2.0-beta.3 → 2.2.0-beta.6
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.
- package/lib/JSRunner.d.ts +1 -0
- package/lib/JSRunner.js +110 -20
- package/lib/flowContext.js +55 -28
- package/lib/flowSettings.d.ts +5 -1
- package/lib/flowSettings.js +70 -0
- package/lib/runjs-context/helpers.js +12 -5
- package/lib/types.d.ts +12 -0
- package/lib/utils/index.d.ts +0 -1
- package/lib/utils/index.js +0 -11
- package/lib/utils/resolveRunJSObjectValues.js +3 -2
- package/lib/utils/runjsModuleLoader.js +0 -30
- package/package.json +4 -4
- package/src/JSRunner.ts +112 -25
- package/src/__tests__/JSRunner.test.ts +4 -5
- package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
- package/src/__tests__/flowSettings.test.ts +72 -0
- package/src/flowContext.ts +55 -25
- package/src/flowSettings.ts +85 -1
- package/src/runjs-context/helpers.ts +12 -6
- package/src/types.ts +14 -0
- package/src/utils/index.ts +0 -9
- package/src/utils/resolveRunJSObjectValues.ts +5 -2
- package/src/utils/runjsModuleLoader.ts +0 -32
- package/lib/utils/safeGlobals.d.ts +0 -28
- package/lib/utils/safeGlobals.js +0 -367
- package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +0 -38
- package/src/utils/__tests__/safeGlobals.test.ts +0 -106
- package/src/utils/safeGlobals.ts +0 -406
package/lib/JSRunner.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface JSRunnerOptions {
|
|
|
27
27
|
* 3. Fallback keeps v1-compatible behavior (enabled).
|
|
28
28
|
*/
|
|
29
29
|
export declare function shouldPreprocessRunJSTemplates(options?: Pick<JSRunnerOptions, 'preprocessTemplates' | 'version'>): boolean;
|
|
30
|
+
export declare const RUNJS_ALLOWED_BARE_GLOBAL_NAMES: readonly ["ctx", "console", "window", "document", "navigator", "setTimeout", "clearTimeout", "setInterval", "clearInterval", "Array", "ArrayBuffer", "BigInt", "BigInt64Array", "BigUint64Array", "Boolean", "DataView", "Date", "Error", "EvalError", "FinalizationRegistry", "Float32Array", "Float64Array", "Int8Array", "Int16Array", "Int32Array", "Map", "Math", "Number", "Object", "Promise", "Proxy", "RangeError", "ReferenceError", "Reflect", "RegExp", "Set", "String", "Symbol", "SyntaxError", "TypeError", "URIError", "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "WeakMap", "WeakRef", "WeakSet", "JSON", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "isFinite", "isNaN", "parseFloat", "parseInt", "undefined", "NaN", "Infinity", "fetch", "localStorage", "sessionStorage", "XMLHttpRequest", "WebSocket", "Worker", "SharedWorker", "ServiceWorker", "BroadcastChannel", "EventSource", "indexedDB", "caches", "Function", "eval", "globalThis", "Intl", "Blob", "URL", "location"];
|
|
30
31
|
export declare class JSRunner {
|
|
31
32
|
private globals;
|
|
32
33
|
private timeoutMs;
|
package/lib/JSRunner.js
CHANGED
|
@@ -28,6 +28,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
28
28
|
var JSRunner_exports = {};
|
|
29
29
|
__export(JSRunner_exports, {
|
|
30
30
|
JSRunner: () => JSRunner,
|
|
31
|
+
RUNJS_ALLOWED_BARE_GLOBAL_NAMES: () => RUNJS_ALLOWED_BARE_GLOBAL_NAMES,
|
|
31
32
|
shouldPreprocessRunJSTemplates: () => shouldPreprocessRunJSTemplates
|
|
32
33
|
});
|
|
33
34
|
module.exports = __toCommonJS(JSRunner_exports);
|
|
@@ -40,6 +41,113 @@ function shouldPreprocessRunJSTemplates(options) {
|
|
|
40
41
|
return (options == null ? void 0 : options.version) !== "v2";
|
|
41
42
|
}
|
|
42
43
|
__name(shouldPreprocessRunJSTemplates, "shouldPreprocessRunJSTemplates");
|
|
44
|
+
const RUNJS_BROWSER_GLOBAL_NAMES = [
|
|
45
|
+
"fetch",
|
|
46
|
+
"localStorage",
|
|
47
|
+
"sessionStorage",
|
|
48
|
+
"XMLHttpRequest",
|
|
49
|
+
"WebSocket",
|
|
50
|
+
"Worker",
|
|
51
|
+
"SharedWorker",
|
|
52
|
+
"ServiceWorker",
|
|
53
|
+
"BroadcastChannel",
|
|
54
|
+
"EventSource",
|
|
55
|
+
"indexedDB",
|
|
56
|
+
"caches",
|
|
57
|
+
"Function",
|
|
58
|
+
"eval",
|
|
59
|
+
"globalThis",
|
|
60
|
+
"Intl",
|
|
61
|
+
"Blob",
|
|
62
|
+
"URL",
|
|
63
|
+
"location"
|
|
64
|
+
];
|
|
65
|
+
const RUNJS_ALLOWED_BARE_GLOBAL_NAMES = [
|
|
66
|
+
"ctx",
|
|
67
|
+
"console",
|
|
68
|
+
"window",
|
|
69
|
+
"document",
|
|
70
|
+
"navigator",
|
|
71
|
+
"setTimeout",
|
|
72
|
+
"clearTimeout",
|
|
73
|
+
"setInterval",
|
|
74
|
+
"clearInterval",
|
|
75
|
+
"Array",
|
|
76
|
+
"ArrayBuffer",
|
|
77
|
+
"BigInt",
|
|
78
|
+
"BigInt64Array",
|
|
79
|
+
"BigUint64Array",
|
|
80
|
+
"Boolean",
|
|
81
|
+
"DataView",
|
|
82
|
+
"Date",
|
|
83
|
+
"Error",
|
|
84
|
+
"EvalError",
|
|
85
|
+
"FinalizationRegistry",
|
|
86
|
+
"Float32Array",
|
|
87
|
+
"Float64Array",
|
|
88
|
+
"Int8Array",
|
|
89
|
+
"Int16Array",
|
|
90
|
+
"Int32Array",
|
|
91
|
+
"Map",
|
|
92
|
+
"Math",
|
|
93
|
+
"Number",
|
|
94
|
+
"Object",
|
|
95
|
+
"Promise",
|
|
96
|
+
"Proxy",
|
|
97
|
+
"RangeError",
|
|
98
|
+
"ReferenceError",
|
|
99
|
+
"Reflect",
|
|
100
|
+
"RegExp",
|
|
101
|
+
"Set",
|
|
102
|
+
"String",
|
|
103
|
+
"Symbol",
|
|
104
|
+
"SyntaxError",
|
|
105
|
+
"TypeError",
|
|
106
|
+
"URIError",
|
|
107
|
+
"Uint8Array",
|
|
108
|
+
"Uint8ClampedArray",
|
|
109
|
+
"Uint16Array",
|
|
110
|
+
"Uint32Array",
|
|
111
|
+
"WeakMap",
|
|
112
|
+
"WeakRef",
|
|
113
|
+
"WeakSet",
|
|
114
|
+
"JSON",
|
|
115
|
+
"decodeURI",
|
|
116
|
+
"decodeURIComponent",
|
|
117
|
+
"encodeURI",
|
|
118
|
+
"encodeURIComponent",
|
|
119
|
+
"isFinite",
|
|
120
|
+
"isNaN",
|
|
121
|
+
"parseFloat",
|
|
122
|
+
"parseInt",
|
|
123
|
+
"undefined",
|
|
124
|
+
"NaN",
|
|
125
|
+
"Infinity",
|
|
126
|
+
...RUNJS_BROWSER_GLOBAL_NAMES
|
|
127
|
+
];
|
|
128
|
+
function collectRunJSBrowserGlobals(providedGlobals = {}) {
|
|
129
|
+
const windowGlobal = providedGlobals.window;
|
|
130
|
+
if (!windowGlobal || typeof windowGlobal !== "object") {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
const windowRecord = windowGlobal;
|
|
134
|
+
const globals = {};
|
|
135
|
+
RUNJS_BROWSER_GLOBAL_NAMES.forEach((name) => {
|
|
136
|
+
if (Object.prototype.hasOwnProperty.call(providedGlobals, name)) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
const value = windowRecord[name];
|
|
141
|
+
if (typeof value === "undefined") {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
globals[name] = name === "fetch" && typeof value === "function" ? value.bind(windowGlobal) : value;
|
|
145
|
+
} catch {
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return globals;
|
|
149
|
+
}
|
|
150
|
+
__name(collectRunJSBrowserGlobals, "collectRunJSBrowserGlobals");
|
|
43
151
|
const BARE_CTX_TEMPLATE_RE = /(^|[=(:,[\s)])(\{\{\s*(ctx(?:\.|\[|\?\.)[^}]*)\s*\}\})/m;
|
|
44
152
|
function extractDeprecatedCtxTemplateUsage(code) {
|
|
45
153
|
const src = String(code || "");
|
|
@@ -78,7 +186,6 @@ const _JSRunner = class _JSRunner {
|
|
|
78
186
|
globals;
|
|
79
187
|
timeoutMs;
|
|
80
188
|
constructor(options = {}) {
|
|
81
|
-
var _a, _b;
|
|
82
189
|
const bindWindowFn = /* @__PURE__ */ __name((key) => {
|
|
83
190
|
if (typeof window !== "undefined" && typeof window[key] === "function") {
|
|
84
191
|
return window[key].bind(window);
|
|
@@ -87,25 +194,7 @@ const _JSRunner = class _JSRunner {
|
|
|
87
194
|
return typeof fn === "function" ? fn.bind(globalThis) : fn;
|
|
88
195
|
}, "bindWindowFn");
|
|
89
196
|
const providedGlobals = options.globals || {};
|
|
90
|
-
const liftedGlobals =
|
|
91
|
-
if (!Object.prototype.hasOwnProperty.call(providedGlobals, "Blob")) {
|
|
92
|
-
try {
|
|
93
|
-
const blobCtor = (_a = providedGlobals.window) == null ? void 0 : _a.Blob;
|
|
94
|
-
if (typeof blobCtor !== "undefined") {
|
|
95
|
-
liftedGlobals.Blob = blobCtor;
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
if (!Object.prototype.hasOwnProperty.call(providedGlobals, "URL")) {
|
|
101
|
-
try {
|
|
102
|
-
const urlCtor = (_b = providedGlobals.window) == null ? void 0 : _b.URL;
|
|
103
|
-
if (typeof urlCtor !== "undefined") {
|
|
104
|
-
liftedGlobals.URL = urlCtor;
|
|
105
|
-
}
|
|
106
|
-
} catch {
|
|
107
|
-
}
|
|
108
|
-
}
|
|
197
|
+
const liftedGlobals = collectRunJSBrowserGlobals(providedGlobals);
|
|
109
198
|
this.globals = {
|
|
110
199
|
console,
|
|
111
200
|
setTimeout: bindWindowFn("setTimeout"),
|
|
@@ -169,5 +258,6 @@ let JSRunner = _JSRunner;
|
|
|
169
258
|
// Annotate the CommonJS export names for ESM import in node:
|
|
170
259
|
0 && (module.exports = {
|
|
171
260
|
JSRunner,
|
|
261
|
+
RUNJS_ALLOWED_BARE_GLOBAL_NAMES,
|
|
172
262
|
shouldPreprocessRunJSTemplates
|
|
173
263
|
});
|
package/lib/flowContext.js
CHANGED
|
@@ -2294,6 +2294,36 @@ const _BaseFlowModelContext = class _BaseFlowModelContext extends BaseFlowEngine
|
|
|
2294
2294
|
};
|
|
2295
2295
|
__name(_BaseFlowModelContext, "BaseFlowModelContext");
|
|
2296
2296
|
let BaseFlowModelContext = _BaseFlowModelContext;
|
|
2297
|
+
const OPEN_VIEW_INHERITED_INPUT_ARG_KEYS = [
|
|
2298
|
+
"dataSourceKey",
|
|
2299
|
+
"collectionName",
|
|
2300
|
+
"associationName",
|
|
2301
|
+
"filterByTk",
|
|
2302
|
+
"sourceId",
|
|
2303
|
+
"tabUid"
|
|
2304
|
+
];
|
|
2305
|
+
function pickDefinedKeys(source, keys) {
|
|
2306
|
+
const res = {};
|
|
2307
|
+
for (const key of keys) {
|
|
2308
|
+
if (typeof (source == null ? void 0 : source[key]) !== "undefined") {
|
|
2309
|
+
res[key] = source[key];
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
return res;
|
|
2313
|
+
}
|
|
2314
|
+
__name(pickDefinedKeys, "pickDefinedKeys");
|
|
2315
|
+
function pickDefinedOpenViewInputArgs(source) {
|
|
2316
|
+
return pickDefinedKeys(source, OPEN_VIEW_INHERITED_INPUT_ARG_KEYS);
|
|
2317
|
+
}
|
|
2318
|
+
__name(pickDefinedOpenViewInputArgs, "pickDefinedOpenViewInputArgs");
|
|
2319
|
+
function applyDefinedDefaults(target, defaults) {
|
|
2320
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
2321
|
+
if (typeof target[key] === "undefined") {
|
|
2322
|
+
target[key] = value;
|
|
2323
|
+
}
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
__name(applyDefinedDefaults, "applyDefinedDefaults");
|
|
2297
2327
|
const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContext {
|
|
2298
2328
|
// public dataSourceManager: DataSourceManager;
|
|
2299
2329
|
constructor(engine) {
|
|
@@ -2680,7 +2710,17 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
2680
2710
|
doc = {};
|
|
2681
2711
|
}
|
|
2682
2712
|
const deprecatedCtx = createRunJSDeprecationProxy(runCtx, { doc });
|
|
2683
|
-
const
|
|
2713
|
+
const browserGlobals = {};
|
|
2714
|
+
if (typeof window !== "undefined") {
|
|
2715
|
+
browserGlobals.window = window;
|
|
2716
|
+
if (typeof navigator !== "undefined") {
|
|
2717
|
+
browserGlobals.navigator = navigator;
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
if (typeof document !== "undefined") {
|
|
2721
|
+
browserGlobals.document = document;
|
|
2722
|
+
}
|
|
2723
|
+
const globals = { ctx: deprecatedCtx, ...browserGlobals, ...(options == null ? void 0 : options.globals) || {} };
|
|
2684
2724
|
const { timeoutMs } = options || {};
|
|
2685
2725
|
return new import_JSRunner.JSRunner({ globals, timeoutMs });
|
|
2686
2726
|
});
|
|
@@ -2791,23 +2831,19 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2791
2831
|
}
|
|
2792
2832
|
});
|
|
2793
2833
|
this.defineMethod("openView", async function(uid, options) {
|
|
2794
|
-
var _a, _b, _c, _d
|
|
2795
|
-
const
|
|
2834
|
+
var _a, _b, _c, _d;
|
|
2835
|
+
const inheritedInputArgs = {
|
|
2836
|
+
...typeof ((_a = this.model) == null ? void 0 : _a["getInputArgs"]) === "function" ? pickDefinedOpenViewInputArgs(this.model["getInputArgs"]()) : {},
|
|
2837
|
+
...pickDefinedOpenViewInputArgs(this.inputArgs)
|
|
2838
|
+
};
|
|
2839
|
+
const opts = { ...options || {} };
|
|
2840
|
+
applyDefinedDefaults(opts, inheritedInputArgs);
|
|
2796
2841
|
if (opts.defineProperties || opts.defineMethods) {
|
|
2797
2842
|
opts.navigation = false;
|
|
2798
2843
|
}
|
|
2799
2844
|
let model2 = null;
|
|
2800
2845
|
model2 = await this.engine.loadModel({ uid });
|
|
2801
2846
|
if (!model2) {
|
|
2802
|
-
const pickDefined = /* @__PURE__ */ __name((src, keys) => {
|
|
2803
|
-
const res = {};
|
|
2804
|
-
for (const k of keys) {
|
|
2805
|
-
if (typeof (src == null ? void 0 : src[k]) !== "undefined") {
|
|
2806
|
-
res[k] = src[k];
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
return res;
|
|
2810
|
-
}, "pickDefined");
|
|
2811
2847
|
model2 = this.engine.createModel({
|
|
2812
2848
|
uid,
|
|
2813
2849
|
// 注意: 新建的 model 应该使用 ${parentModel.uid}-xxx 形式的 uid
|
|
@@ -2819,7 +2855,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2819
2855
|
popupSettings: {
|
|
2820
2856
|
openView: {
|
|
2821
2857
|
// 仅在创建时持久化一份默认配置;运行时以本次 opts 为准,避免多个 opener 互相覆盖。
|
|
2822
|
-
...
|
|
2858
|
+
...pickDefinedKeys(opts, ["dataSourceKey", "collectionName", "associationName", "mode", "size"])
|
|
2823
2859
|
}
|
|
2824
2860
|
}
|
|
2825
2861
|
}
|
|
@@ -2827,12 +2863,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2827
2863
|
await model2.save();
|
|
2828
2864
|
}
|
|
2829
2865
|
model2.setParent(this.model);
|
|
2830
|
-
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((
|
|
2866
|
+
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((_c = (_b = model2.stepParams) == null ? void 0 : _b.popupSettings) == null ? void 0 : _c.openView) ? model2.uid : this.model.uid);
|
|
2831
2867
|
const parentView = this.view;
|
|
2832
2868
|
const pendingType = (opts == null ? void 0 : opts.isMobileLayout) ? "embed" : (opts == null ? void 0 : opts.mode) || "drawer";
|
|
2833
2869
|
const pendingInputArgs = { ...opts, viewUid, navigation: opts.navigation };
|
|
2834
|
-
pendingInputArgs.filterByTk = pendingInputArgs.filterByTk || ((_c = this.inputArgs) == null ? void 0 : _c.filterByTk);
|
|
2835
|
-
pendingInputArgs.sourceId = pendingInputArgs.sourceId || ((_d = this.inputArgs) == null ? void 0 : _d.sourceId);
|
|
2836
2870
|
const pendingView = {
|
|
2837
2871
|
type: pendingType,
|
|
2838
2872
|
inputArgs: pendingInputArgs,
|
|
@@ -2841,7 +2875,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2841
2875
|
engineCtx: this.engine.context
|
|
2842
2876
|
};
|
|
2843
2877
|
model2.context.defineProperty("view", { value: pendingView });
|
|
2844
|
-
const popupFlow = (
|
|
2878
|
+
const popupFlow = (_d = model2.getFlow) == null ? void 0 : _d.call(model2, "popupSettings");
|
|
2845
2879
|
const on = popupFlow == null ? void 0 : popupFlow.on;
|
|
2846
2880
|
let openEventName = "click";
|
|
2847
2881
|
if (typeof on === "string" && on) {
|
|
@@ -2849,17 +2883,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2849
2883
|
} else if (on && typeof on === "object" && typeof on.eventName === "string" && on.eventName) {
|
|
2850
2884
|
openEventName = on.eventName;
|
|
2851
2885
|
}
|
|
2852
|
-
await model2.dispatchEvent(
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
// ...this.model?.['getInputArgs']?.(), // 避免部分关系字段信息丢失, 仿照 ClickableCollectionField 做法
|
|
2857
|
-
...opts
|
|
2858
|
-
},
|
|
2859
|
-
{
|
|
2860
|
-
debounce: true
|
|
2861
|
-
}
|
|
2862
|
-
);
|
|
2886
|
+
await model2.dispatchEvent(openEventName, {
|
|
2887
|
+
// navigation: false, // TODO: 路由模式有bug,不支持多层同样viewId的弹窗,因此这里默认先用false
|
|
2888
|
+
...opts
|
|
2889
|
+
});
|
|
2863
2890
|
});
|
|
2864
2891
|
this.defineMethod("getEvents", function() {
|
|
2865
2892
|
return this.model.getEvents();
|
package/lib/flowSettings.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { FlowEngine } from '.';
|
|
11
11
|
import type { FlowModel } from './models';
|
|
12
|
-
import { StepSettingsDialogProps, ToolbarItemConfig } from './types';
|
|
12
|
+
import { DynamicFlowSource, DynamicFlowSourceProvider, StepSettingsDialogProps, ToolbarItemConfig } from './types';
|
|
13
13
|
/**
|
|
14
14
|
* 打开流程设置的参数接口
|
|
15
15
|
*/
|
|
@@ -93,6 +93,7 @@ export declare class FlowSettings {
|
|
|
93
93
|
enabled: boolean;
|
|
94
94
|
private engine;
|
|
95
95
|
toolbarItems: ToolbarItemConfig[];
|
|
96
|
+
private dynamicFlowSourceProviders;
|
|
96
97
|
constructor(engine: FlowEngine);
|
|
97
98
|
on(event: 'beforeOpen', callback: (...args: any[]) => void): void;
|
|
98
99
|
off(event: 'beforeOpen', callback: (...args: any[]) => void): void;
|
|
@@ -206,6 +207,9 @@ export declare class FlowSettings {
|
|
|
206
207
|
* @returns {ToolbarItemConfig[]} 所有项目配置
|
|
207
208
|
*/
|
|
208
209
|
getToolbarItems(): ToolbarItemConfig[];
|
|
210
|
+
registerDynamicFlowSourceProvider(provider: DynamicFlowSourceProvider): () => void;
|
|
211
|
+
hasDynamicFlowSourceProvider(model: FlowModel): boolean;
|
|
212
|
+
getDynamicFlowSources(model: FlowModel): Promise<DynamicFlowSource[]>;
|
|
209
213
|
/**
|
|
210
214
|
* 清空所有工具栏项目
|
|
211
215
|
* @example
|
package/lib/flowSettings.js
CHANGED
|
@@ -78,6 +78,7 @@ const _FlowSettings = class _FlowSettings {
|
|
|
78
78
|
__privateAdd(this, _forceEnabled, false);
|
|
79
79
|
// 强制启用状态,主要用于设计模式下的强制启用
|
|
80
80
|
__publicField(this, "toolbarItems", []);
|
|
81
|
+
__publicField(this, "dynamicFlowSourceProviders", []);
|
|
81
82
|
__privateAdd(this, _emitter, new import_emitter.Emitter());
|
|
82
83
|
this.engine = engine;
|
|
83
84
|
this.enabled = false;
|
|
@@ -369,6 +370,75 @@ const _FlowSettings = class _FlowSettings {
|
|
|
369
370
|
getToolbarItems() {
|
|
370
371
|
return [...this.toolbarItems];
|
|
371
372
|
}
|
|
373
|
+
registerDynamicFlowSourceProvider(provider) {
|
|
374
|
+
const existingIndex = this.dynamicFlowSourceProviders.findIndex((item) => item.key === provider.key);
|
|
375
|
+
if (existingIndex !== -1) {
|
|
376
|
+
console.warn(
|
|
377
|
+
`FlowSettings: Dynamic flow source provider with key '${provider.key}' already exists and will be replaced.`
|
|
378
|
+
);
|
|
379
|
+
this.dynamicFlowSourceProviders[existingIndex] = provider;
|
|
380
|
+
} else {
|
|
381
|
+
this.dynamicFlowSourceProviders.push(provider);
|
|
382
|
+
}
|
|
383
|
+
this.dynamicFlowSourceProviders.sort((a, b) => (a.sort || 0) - (b.sort || 0));
|
|
384
|
+
return () => {
|
|
385
|
+
const index = this.dynamicFlowSourceProviders.indexOf(provider);
|
|
386
|
+
if (index !== -1) {
|
|
387
|
+
this.dynamicFlowSourceProviders.splice(index, 1);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
hasDynamicFlowSourceProvider(model) {
|
|
392
|
+
return this.dynamicFlowSourceProviders.some((provider) => {
|
|
393
|
+
try {
|
|
394
|
+
return provider.visible ? provider.visible(model) : true;
|
|
395
|
+
} catch (error) {
|
|
396
|
+
console.warn(`FlowSettings: Dynamic flow source provider '${provider.key}' visibility check failed.`, error);
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
async getDynamicFlowSources(model) {
|
|
402
|
+
const t = (0, import_utils.getT)(model);
|
|
403
|
+
const selfSource = {
|
|
404
|
+
key: "self",
|
|
405
|
+
label: t("Current block"),
|
|
406
|
+
model,
|
|
407
|
+
sort: -1e3
|
|
408
|
+
};
|
|
409
|
+
const sources = [];
|
|
410
|
+
const seenKeys = /* @__PURE__ */ new Set(["self"]);
|
|
411
|
+
const seenModelUids = /* @__PURE__ */ new Set([model.uid]);
|
|
412
|
+
for (const provider of this.dynamicFlowSourceProviders) {
|
|
413
|
+
try {
|
|
414
|
+
if (provider.visible && !provider.visible(model)) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const providerSources = await provider.getSources(model);
|
|
418
|
+
for (const source of providerSources || []) {
|
|
419
|
+
if (!(source == null ? void 0 : source.key) || !source.model) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const key = String(source.key);
|
|
423
|
+
const uid = source.model.uid;
|
|
424
|
+
if (seenKeys.has(key) || seenModelUids.has(uid)) {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
seenKeys.add(key);
|
|
428
|
+
seenModelUids.add(uid);
|
|
429
|
+
sources.push({
|
|
430
|
+
...source,
|
|
431
|
+
key,
|
|
432
|
+
label: source.label || key,
|
|
433
|
+
sort: source.sort || 0
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
} catch (error) {
|
|
437
|
+
console.warn(`FlowSettings: Dynamic flow source provider '${provider.key}' failed.`, error);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return [selfSource, ...sources.sort((a, b) => (a.sort || 0) - (b.sort || 0))];
|
|
441
|
+
}
|
|
372
442
|
/**
|
|
373
443
|
* 清空所有工具栏项目
|
|
374
444
|
* @example
|
|
@@ -71,18 +71,25 @@ function createJSRunnerWithVersion(options) {
|
|
|
71
71
|
doc = {};
|
|
72
72
|
}
|
|
73
73
|
const deprecatedCtx = (0, import_flowContext.createRunJSDeprecationProxy)(runCtx, { doc });
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
|
|
77
|
-
if (typeof
|
|
74
|
+
const browserGlobals = {};
|
|
75
|
+
if (typeof window !== "undefined") {
|
|
76
|
+
browserGlobals.window = window;
|
|
77
|
+
if (typeof navigator !== "undefined") {
|
|
78
|
+
browserGlobals.navigator = navigator;
|
|
79
|
+
}
|
|
78
80
|
}
|
|
81
|
+
if (typeof document !== "undefined") {
|
|
82
|
+
browserGlobals.document = document;
|
|
83
|
+
}
|
|
84
|
+
const globals = { ctx: deprecatedCtx, ...browserGlobals, ...(options == null ? void 0 : options.globals) || {} };
|
|
79
85
|
const { timeoutMs } = options || {};
|
|
80
86
|
return new import_JSRunner.JSRunner({ globals, timeoutMs });
|
|
81
87
|
}
|
|
82
88
|
__name(createJSRunnerWithVersion, "createJSRunnerWithVersion");
|
|
83
89
|
function getRunJSScenesForModel(modelClass, version = "v1") {
|
|
84
90
|
const meta = import_registry.RunJSContextRegistry.getMeta(version, modelClass);
|
|
85
|
-
|
|
91
|
+
const scenes = meta == null ? void 0 : meta.scenes;
|
|
92
|
+
return Array.isArray(scenes) ? [...scenes] : [];
|
|
86
93
|
}
|
|
87
94
|
__name(getRunJSScenesForModel, "getRunJSScenesForModel");
|
|
88
95
|
function getRunJSScenesForContext(ctx, { version = "v1" } = {}) {
|
package/lib/types.d.ts
CHANGED
|
@@ -500,6 +500,18 @@ export interface ToolbarItemConfig {
|
|
|
500
500
|
/** 排序权重,数字越小越靠右(先添加的在右边) */
|
|
501
501
|
sort?: number;
|
|
502
502
|
}
|
|
503
|
+
export interface DynamicFlowSource {
|
|
504
|
+
key: string;
|
|
505
|
+
label: React.ReactNode;
|
|
506
|
+
model: FlowModel;
|
|
507
|
+
sort?: number;
|
|
508
|
+
}
|
|
509
|
+
export interface DynamicFlowSourceProvider {
|
|
510
|
+
key: string;
|
|
511
|
+
sort?: number;
|
|
512
|
+
visible?: (model: FlowModel) => boolean;
|
|
513
|
+
getSources: (model: FlowModel) => DynamicFlowSource[] | Promise<DynamicFlowSource[]>;
|
|
514
|
+
}
|
|
503
515
|
export interface ApplyFlowCacheEntry {
|
|
504
516
|
status: 'pending' | 'resolved' | 'rejected';
|
|
505
517
|
promise: Promise<any>;
|
package/lib/utils/index.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ export { extractPropertyPath, formatPathToVariable, isVariableExpression } from
|
|
|
21
21
|
export { clearAutoFlowError, getAutoFlowError, setAutoFlowError, type AutoFlowError } from './autoFlowError';
|
|
22
22
|
export { parsePathnameToViewParams, type ViewParam } from './parsePathnameToViewParams';
|
|
23
23
|
export { decodeBase64Url, encodeBase64Url, isCompleteCtxDatePath, isCtxDatePathPrefix, isCtxDateExpression, parseCtxDateExpression, resolveCtxDatePath, serializeCtxDateValue, } from './dateVariable';
|
|
24
|
-
export { createSafeDocument, createSafeWindow, createSafeNavigator, createSafeRunJSGlobals, runjsWithSafeGlobals, } from './safeGlobals';
|
|
25
24
|
export { isRunJSValue, normalizeRunJSValue, extractUsedVariablePathsFromRunJS, type RunJSValue } from './runjsValue';
|
|
26
25
|
export { resolveRunJSObjectValues } from './resolveRunJSObjectValues';
|
|
27
26
|
export { prepareRunJsCode, preprocessRunJsTemplates } from './runjsTemplateCompat';
|
package/lib/utils/index.js
CHANGED
|
@@ -44,10 +44,6 @@ __export(utils_exports, {
|
|
|
44
44
|
createEphemeralContext: () => import_createEphemeralContext.createEphemeralContext,
|
|
45
45
|
createRecordMetaFactory: () => import_variablesParams.createRecordMetaFactory,
|
|
46
46
|
createRecordResolveOnServerWithLocal: () => import_variablesParams.createRecordResolveOnServerWithLocal,
|
|
47
|
-
createSafeDocument: () => import_safeGlobals.createSafeDocument,
|
|
48
|
-
createSafeNavigator: () => import_safeGlobals.createSafeNavigator,
|
|
49
|
-
createSafeRunJSGlobals: () => import_safeGlobals.createSafeRunJSGlobals,
|
|
50
|
-
createSafeWindow: () => import_safeGlobals.createSafeWindow,
|
|
51
47
|
decodeBase64Url: () => import_dateVariable.decodeBase64Url,
|
|
52
48
|
defineAction: () => import_flow_definitions.defineAction,
|
|
53
49
|
encodeBase64Url: () => import_dateVariable.encodeBase64Url,
|
|
@@ -84,7 +80,6 @@ __export(utils_exports, {
|
|
|
84
80
|
resolveStepDisabledInSettings: () => import_schema_utils.resolveStepDisabledInSettings,
|
|
85
81
|
resolveStepUiSchema: () => import_schema_utils.resolveStepUiSchema,
|
|
86
82
|
resolveUiMode: () => import_schema_utils.resolveUiMode,
|
|
87
|
-
runjsWithSafeGlobals: () => import_safeGlobals.runjsWithSafeGlobals,
|
|
88
83
|
serializeCtxDateValue: () => import_dateVariable.serializeCtxDateValue,
|
|
89
84
|
setAutoFlowError: () => import_autoFlowError.setAutoFlowError,
|
|
90
85
|
setupRuntimeContextSteps: () => import_setupRuntimeContextSteps.setupRuntimeContextSteps,
|
|
@@ -108,7 +103,6 @@ var import_context = require("./context");
|
|
|
108
103
|
var import_autoFlowError = require("./autoFlowError");
|
|
109
104
|
var import_parsePathnameToViewParams = require("./parsePathnameToViewParams");
|
|
110
105
|
var import_dateVariable = require("./dateVariable");
|
|
111
|
-
var import_safeGlobals = require("./safeGlobals");
|
|
112
106
|
var import_runjsValue = require("./runjsValue");
|
|
113
107
|
var import_resolveRunJSObjectValues = require("./resolveRunJSObjectValues");
|
|
114
108
|
var import_runjsTemplateCompat = require("./runjsTemplateCompat");
|
|
@@ -137,10 +131,6 @@ var import_randomId = require("./randomId");
|
|
|
137
131
|
createEphemeralContext,
|
|
138
132
|
createRecordMetaFactory,
|
|
139
133
|
createRecordResolveOnServerWithLocal,
|
|
140
|
-
createSafeDocument,
|
|
141
|
-
createSafeNavigator,
|
|
142
|
-
createSafeRunJSGlobals,
|
|
143
|
-
createSafeWindow,
|
|
144
134
|
decodeBase64Url,
|
|
145
135
|
defineAction,
|
|
146
136
|
encodeBase64Url,
|
|
@@ -177,7 +167,6 @@ var import_randomId = require("./randomId");
|
|
|
177
167
|
resolveStepDisabledInSettings,
|
|
178
168
|
resolveStepUiSchema,
|
|
179
169
|
resolveUiMode,
|
|
180
|
-
runjsWithSafeGlobals,
|
|
181
170
|
serializeCtxDateValue,
|
|
182
171
|
setAutoFlowError,
|
|
183
172
|
setupRuntimeContextSteps,
|
|
@@ -31,8 +31,8 @@ __export(resolveRunJSObjectValues_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(resolveRunJSObjectValues_exports);
|
|
33
33
|
var import_runjsValue = require("./runjsValue");
|
|
34
|
-
var import_safeGlobals = require("./safeGlobals");
|
|
35
34
|
async function resolveRunJSObjectValues(ctx, raw) {
|
|
35
|
+
var _a;
|
|
36
36
|
const out = {};
|
|
37
37
|
if (!raw || typeof raw !== "object") return out;
|
|
38
38
|
if (Array.isArray(raw)) return out;
|
|
@@ -41,7 +41,8 @@ async function resolveRunJSObjectValues(ctx, raw) {
|
|
|
41
41
|
if ((0, import_runjsValue.isRunJSValue)(value)) {
|
|
42
42
|
const { code, version } = (0, import_runjsValue.normalizeRunJSValue)(value);
|
|
43
43
|
if (!code.trim()) continue;
|
|
44
|
-
const
|
|
44
|
+
const runjsCtx = ctx;
|
|
45
|
+
const ret = await ((_a = runjsCtx == null ? void 0 : runjsCtx.runjs) == null ? void 0 : _a.call(runjsCtx, code, void 0, { version }));
|
|
45
46
|
if (!(ret == null ? void 0 : ret.success)) {
|
|
46
47
|
throw new Error(`RunJS execution failed for "${key}"`);
|
|
47
48
|
}
|
|
@@ -34,27 +34,6 @@ __export(runjsModuleLoader_exports, {
|
|
|
34
34
|
module.exports = __toCommonJS(runjsModuleLoader_exports);
|
|
35
35
|
var import_runjsLibs = require("../runjsLibs");
|
|
36
36
|
var import_resolveModuleUrl = require("./resolveModuleUrl");
|
|
37
|
-
var import_safeGlobals = require("./safeGlobals");
|
|
38
|
-
function snapshotOwnKeys(obj) {
|
|
39
|
-
try {
|
|
40
|
-
if (!obj || typeof obj !== "object" && typeof obj !== "function") return [];
|
|
41
|
-
return Object.getOwnPropertyNames(obj);
|
|
42
|
-
} catch (_) {
|
|
43
|
-
return [];
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
__name(snapshotOwnKeys, "snapshotOwnKeys");
|
|
47
|
-
function diffAddedKeys(afterKeys, beforeKeys) {
|
|
48
|
-
if (!afterKeys.length) return [];
|
|
49
|
-
if (!beforeKeys.length) return [...afterKeys];
|
|
50
|
-
const beforeSet = new Set(beforeKeys);
|
|
51
|
-
const added = [];
|
|
52
|
-
for (const k of afterKeys) {
|
|
53
|
-
if (!beforeSet.has(k)) added.push(k);
|
|
54
|
-
}
|
|
55
|
-
return added;
|
|
56
|
-
}
|
|
57
|
-
__name(diffAddedKeys, "diffAddedKeys");
|
|
58
37
|
async function withRunjsModuleLoadLock(task) {
|
|
59
38
|
const g = globalThis;
|
|
60
39
|
g.__nocobaseRunjsModuleLoadLock = (g.__nocobaseRunjsModuleLoadLock || Promise.resolve()).catch(() => {
|
|
@@ -222,8 +201,6 @@ async function prefetchEsmModule(url, options) {
|
|
|
222
201
|
__name(prefetchEsmModule, "prefetchEsmModule");
|
|
223
202
|
async function runjsRequireAsync(requirejs, url) {
|
|
224
203
|
return await withRunjsModuleLoadLock(async () => {
|
|
225
|
-
const beforeWinKeys = typeof window !== "undefined" ? snapshotOwnKeys(window) : [];
|
|
226
|
-
const beforeDocKeys = typeof document !== "undefined" ? snapshotOwnKeys(document) : [];
|
|
227
204
|
let result;
|
|
228
205
|
let error;
|
|
229
206
|
try {
|
|
@@ -242,13 +219,6 @@ async function runjsRequireAsync(requirejs, url) {
|
|
|
242
219
|
});
|
|
243
220
|
} catch (e) {
|
|
244
221
|
error = e;
|
|
245
|
-
} finally {
|
|
246
|
-
const afterWinKeys = typeof window !== "undefined" ? snapshotOwnKeys(window) : [];
|
|
247
|
-
const afterDocKeys = typeof document !== "undefined" ? snapshotOwnKeys(document) : [];
|
|
248
|
-
const addedWinKeys = diffAddedKeys(afterWinKeys, beforeWinKeys);
|
|
249
|
-
const addedDocKeys = diffAddedKeys(afterDocKeys, beforeDocKeys);
|
|
250
|
-
(0, import_safeGlobals.registerRunJSSafeWindowGlobals)(addedWinKeys);
|
|
251
|
-
(0, import_safeGlobals.registerRunJSSafeDocumentGlobals)(addedDocKeys);
|
|
252
222
|
}
|
|
253
223
|
if (error) throw error;
|
|
254
224
|
return result;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/flow-engine",
|
|
3
|
-
"version": "2.2.0-beta.
|
|
3
|
+
"version": "2.2.0-beta.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A standalone flow engine for NocoBase, managing workflows, models, and actions.",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@formily/antd-v5": "1.x",
|
|
10
10
|
"@formily/reactive": "2.x",
|
|
11
|
-
"@nocobase/sdk": "2.2.0-beta.
|
|
12
|
-
"@nocobase/shared": "2.2.0-beta.
|
|
11
|
+
"@nocobase/sdk": "2.2.0-beta.6",
|
|
12
|
+
"@nocobase/shared": "2.2.0-beta.6",
|
|
13
13
|
"ahooks": "^3.7.2",
|
|
14
14
|
"axios": "^1.7.0",
|
|
15
15
|
"dayjs": "^1.11.9",
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
],
|
|
38
38
|
"author": "NocoBase Team",
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "dc9246516f8a3efd6056f22fe7b3bc947bd4575b"
|
|
41
41
|
}
|