@nocobase/flow-engine 2.0.0-beta.21 → 2.0.0-beta.23
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/FlowDefinition.d.ts +2 -0
- package/lib/JSRunner.js +23 -1
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +66 -13
- package/lib/components/settings/wrappers/contextual/FlowsContextMenu.js +24 -4
- package/lib/components/variables/VariableInput.js +1 -2
- package/lib/components/variables/VariableTag.js +46 -39
- package/lib/data-source/index.js +11 -5
- package/lib/flowContext.js +5 -1
- package/lib/flowI18n.js +6 -4
- package/lib/locale/en-US.json +2 -1
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/resources/sqlResource.d.ts +3 -3
- package/lib/types.d.ts +12 -0
- package/lib/utils/associationObjectVariable.d.ts +2 -2
- package/lib/utils/index.d.ts +4 -2
- package/lib/utils/index.js +16 -0
- package/lib/utils/resolveRunJSObjectValues.d.ts +16 -0
- package/lib/utils/resolveRunJSObjectValues.js +61 -0
- package/lib/utils/runjsValue.d.ts +29 -0
- package/lib/utils/runjsValue.js +275 -0
- package/lib/utils/safeGlobals.d.ts +14 -0
- package/lib/utils/safeGlobals.js +37 -2
- package/lib/utils/schema-utils.d.ts +10 -0
- package/lib/utils/schema-utils.js +61 -0
- package/package.json +4 -4
- package/src/JSRunner.ts +29 -1
- package/src/__tests__/JSRunner.test.ts +64 -0
- package/src/__tests__/flowContext.test.ts +78 -0
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +99 -14
- package/src/components/settings/wrappers/contextual/FlowsContextMenu.tsx +41 -7
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +94 -1
- package/src/components/variables/VariableInput.tsx +4 -2
- package/src/components/variables/VariableTag.tsx +54 -45
- package/src/components/variables/__tests__/VariableTag.test.tsx +50 -0
- package/src/data-source/index.ts +11 -5
- package/src/flowContext.ts +6 -2
- package/src/flowI18n.ts +7 -5
- package/src/locale/en-US.json +2 -1
- package/src/locale/zh-CN.json +1 -0
- package/src/resources/sqlResource.ts +3 -3
- package/src/types.ts +12 -0
- package/src/utils/__tests__/runjsValue.test.ts +44 -0
- package/src/utils/__tests__/safeGlobals.test.ts +8 -0
- package/src/utils/__tests__/utils.test.ts +95 -0
- package/src/utils/associationObjectVariable.ts +2 -2
- package/src/utils/index.ts +20 -2
- package/src/utils/resolveRunJSObjectValues.ts +46 -0
- package/src/utils/runjsValue.ts +287 -0
- package/src/utils/safeGlobals.ts +55 -1
- package/src/utils/schema-utils.ts +79 -0
package/lib/utils/index.js
CHANGED
|
@@ -44,12 +44,14 @@ __export(utils_exports, {
|
|
|
44
44
|
createRecordResolveOnServerWithLocal: () => import_variablesParams.createRecordResolveOnServerWithLocal,
|
|
45
45
|
createSafeDocument: () => import_safeGlobals.createSafeDocument,
|
|
46
46
|
createSafeNavigator: () => import_safeGlobals.createSafeNavigator,
|
|
47
|
+
createSafeRunJSGlobals: () => import_safeGlobals.createSafeRunJSGlobals,
|
|
47
48
|
createSafeWindow: () => import_safeGlobals.createSafeWindow,
|
|
48
49
|
defineAction: () => import_flow_definitions.defineAction,
|
|
49
50
|
escapeT: () => import_translation.escapeT,
|
|
50
51
|
extractPropertyPath: () => import_context.extractPropertyPath,
|
|
51
52
|
extractUsedVariableNames: () => import_variablesParams.extractUsedVariableNames,
|
|
52
53
|
extractUsedVariablePaths: () => import_variablesParams.extractUsedVariablePaths,
|
|
54
|
+
extractUsedVariablePathsFromRunJS: () => import_runjsValue.extractUsedVariablePathsFromRunJS,
|
|
53
55
|
formatPathToVariable: () => import_context.formatPathToVariable,
|
|
54
56
|
getAutoFlowError: () => import_autoFlowError.getAutoFlowError,
|
|
55
57
|
getT: () => import_translation.getT,
|
|
@@ -57,7 +59,9 @@ __export(utils_exports, {
|
|
|
57
59
|
isBeforeRenderFlow: () => import_flows.isBeforeRenderFlow,
|
|
58
60
|
isCssFile: () => import_resolveModuleUrl.isCssFile,
|
|
59
61
|
isInheritedFrom: () => import_inheritance.isInheritedFrom,
|
|
62
|
+
isRunJSValue: () => import_runjsValue.isRunJSValue,
|
|
60
63
|
isVariableExpression: () => import_context.isVariableExpression,
|
|
64
|
+
normalizeRunJSValue: () => import_runjsValue.normalizeRunJSValue,
|
|
61
65
|
parsePathnameToViewParams: () => import_parsePathnameToViewParams.parsePathnameToViewParams,
|
|
62
66
|
prepareRunJsCode: () => import_runjsTemplateCompat.prepareRunJsCode,
|
|
63
67
|
preprocessRunJsTemplates: () => import_runjsTemplateCompat.preprocessRunJsTemplates,
|
|
@@ -66,8 +70,11 @@ __export(utils_exports, {
|
|
|
66
70
|
resolveDefaultParams: () => import_params_resolvers.resolveDefaultParams,
|
|
67
71
|
resolveExpressions: () => import_params_resolvers.resolveExpressions,
|
|
68
72
|
resolveModuleUrl: () => import_resolveModuleUrl.resolveModuleUrl,
|
|
73
|
+
resolveRunJSObjectValues: () => import_resolveRunJSObjectValues.resolveRunJSObjectValues,
|
|
74
|
+
resolveStepDisabledInSettings: () => import_schema_utils.resolveStepDisabledInSettings,
|
|
69
75
|
resolveStepUiSchema: () => import_schema_utils.resolveStepUiSchema,
|
|
70
76
|
resolveUiMode: () => import_schema_utils.resolveUiMode,
|
|
77
|
+
runjsWithSafeGlobals: () => import_safeGlobals.runjsWithSafeGlobals,
|
|
71
78
|
setAutoFlowError: () => import_autoFlowError.setAutoFlowError,
|
|
72
79
|
setupRuntimeContextSteps: () => import_setupRuntimeContextSteps.setupRuntimeContextSteps,
|
|
73
80
|
shouldHideStepInSettings: () => import_schema_utils.shouldHideStepInSettings,
|
|
@@ -89,6 +96,8 @@ var import_context = require("./context");
|
|
|
89
96
|
var import_autoFlowError = require("./autoFlowError");
|
|
90
97
|
var import_parsePathnameToViewParams = require("./parsePathnameToViewParams");
|
|
91
98
|
var import_safeGlobals = require("./safeGlobals");
|
|
99
|
+
var import_runjsValue = require("./runjsValue");
|
|
100
|
+
var import_resolveRunJSObjectValues = require("./resolveRunJSObjectValues");
|
|
92
101
|
var import_runjsTemplateCompat = require("./runjsTemplateCompat");
|
|
93
102
|
var import_createEphemeralContext = require("./createEphemeralContext");
|
|
94
103
|
var import_pruneFilter = require("./pruneFilter");
|
|
@@ -114,12 +123,14 @@ var import_resolveModuleUrl = require("./resolveModuleUrl");
|
|
|
114
123
|
createRecordResolveOnServerWithLocal,
|
|
115
124
|
createSafeDocument,
|
|
116
125
|
createSafeNavigator,
|
|
126
|
+
createSafeRunJSGlobals,
|
|
117
127
|
createSafeWindow,
|
|
118
128
|
defineAction,
|
|
119
129
|
escapeT,
|
|
120
130
|
extractPropertyPath,
|
|
121
131
|
extractUsedVariableNames,
|
|
122
132
|
extractUsedVariablePaths,
|
|
133
|
+
extractUsedVariablePathsFromRunJS,
|
|
123
134
|
formatPathToVariable,
|
|
124
135
|
getAutoFlowError,
|
|
125
136
|
getT,
|
|
@@ -127,7 +138,9 @@ var import_resolveModuleUrl = require("./resolveModuleUrl");
|
|
|
127
138
|
isBeforeRenderFlow,
|
|
128
139
|
isCssFile,
|
|
129
140
|
isInheritedFrom,
|
|
141
|
+
isRunJSValue,
|
|
130
142
|
isVariableExpression,
|
|
143
|
+
normalizeRunJSValue,
|
|
131
144
|
parsePathnameToViewParams,
|
|
132
145
|
prepareRunJsCode,
|
|
133
146
|
preprocessRunJsTemplates,
|
|
@@ -136,8 +149,11 @@ var import_resolveModuleUrl = require("./resolveModuleUrl");
|
|
|
136
149
|
resolveDefaultParams,
|
|
137
150
|
resolveExpressions,
|
|
138
151
|
resolveModuleUrl,
|
|
152
|
+
resolveRunJSObjectValues,
|
|
153
|
+
resolveStepDisabledInSettings,
|
|
139
154
|
resolveStepUiSchema,
|
|
140
155
|
resolveUiMode,
|
|
156
|
+
runjsWithSafeGlobals,
|
|
141
157
|
setAutoFlowError,
|
|
142
158
|
setupRuntimeContextSteps,
|
|
143
159
|
shouldHideStepInSettings,
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
* Resolve an object's values, executing any RunJSValue entries via ctx.runjs.
|
|
11
|
+
*
|
|
12
|
+
* - Skips `undefined` values
|
|
13
|
+
* - Skips empty RunJS code (treated as not configured)
|
|
14
|
+
* - Throws when a RunJS execution fails
|
|
15
|
+
*/
|
|
16
|
+
export declare function resolveRunJSObjectValues(ctx: unknown, raw: unknown): Promise<Record<string, any>>;
|
|
@@ -0,0 +1,61 @@
|
|
|
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 resolveRunJSObjectValues_exports = {};
|
|
29
|
+
__export(resolveRunJSObjectValues_exports, {
|
|
30
|
+
resolveRunJSObjectValues: () => resolveRunJSObjectValues
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(resolveRunJSObjectValues_exports);
|
|
33
|
+
var import_runjsValue = require("./runjsValue");
|
|
34
|
+
var import_safeGlobals = require("./safeGlobals");
|
|
35
|
+
async function resolveRunJSObjectValues(ctx, raw) {
|
|
36
|
+
const out = {};
|
|
37
|
+
if (!raw || typeof raw !== "object") return out;
|
|
38
|
+
if (Array.isArray(raw)) return out;
|
|
39
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
40
|
+
if (typeof value === "undefined") continue;
|
|
41
|
+
if ((0, import_runjsValue.isRunJSValue)(value)) {
|
|
42
|
+
const { code, version } = (0, import_runjsValue.normalizeRunJSValue)(value);
|
|
43
|
+
if (!code.trim()) continue;
|
|
44
|
+
const ret = await (0, import_safeGlobals.runjsWithSafeGlobals)(ctx, code, { version });
|
|
45
|
+
if (!(ret == null ? void 0 : ret.success)) {
|
|
46
|
+
throw new Error(`RunJS execution failed for "${key}"`);
|
|
47
|
+
}
|
|
48
|
+
if (typeof ret.value !== "undefined") {
|
|
49
|
+
out[key] = ret.value;
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
out[key] = value;
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
__name(resolveRunJSObjectValues, "resolveRunJSObjectValues");
|
|
58
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
59
|
+
0 && (module.exports = {
|
|
60
|
+
resolveRunJSObjectValues
|
|
61
|
+
});
|
|
@@ -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
|
+
});
|
|
@@ -12,3 +12,17 @@ export declare function __resetRunJSSafeGlobalsRegistryForTests(): void;
|
|
|
12
12
|
export declare function createSafeWindow(extra?: Record<string, any>): Record<string, any>;
|
|
13
13
|
export declare function createSafeDocument(extra?: Record<string, any>): Record<string, any>;
|
|
14
14
|
export declare function createSafeNavigator(extra?: Record<string, any>): {};
|
|
15
|
+
/**
|
|
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)
|
|
21
|
+
*/
|
|
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>;
|
package/lib/utils/safeGlobals.js
CHANGED
|
@@ -30,9 +30,11 @@ __export(safeGlobals_exports, {
|
|
|
30
30
|
__resetRunJSSafeGlobalsRegistryForTests: () => __resetRunJSSafeGlobalsRegistryForTests,
|
|
31
31
|
createSafeDocument: () => createSafeDocument,
|
|
32
32
|
createSafeNavigator: () => createSafeNavigator,
|
|
33
|
+
createSafeRunJSGlobals: () => createSafeRunJSGlobals,
|
|
33
34
|
createSafeWindow: () => createSafeWindow,
|
|
34
35
|
registerRunJSSafeDocumentGlobals: () => registerRunJSSafeDocumentGlobals,
|
|
35
|
-
registerRunJSSafeWindowGlobals: () => registerRunJSSafeWindowGlobals
|
|
36
|
+
registerRunJSSafeWindowGlobals: () => registerRunJSSafeWindowGlobals,
|
|
37
|
+
runjsWithSafeGlobals: () => runjsWithSafeGlobals
|
|
36
38
|
});
|
|
37
39
|
module.exports = __toCommonJS(safeGlobals_exports);
|
|
38
40
|
function getRunJSSafeGlobalsRegistry() {
|
|
@@ -196,6 +198,8 @@ function createSafeWindow(extra) {
|
|
|
196
198
|
Math,
|
|
197
199
|
Date,
|
|
198
200
|
FormData,
|
|
201
|
+
...typeof Blob !== "undefined" ? { Blob } : {},
|
|
202
|
+
...typeof URL !== "undefined" ? { URL } : {},
|
|
199
203
|
// 事件侦听仅绑定到真实 window,便于少量需要的全局监听
|
|
200
204
|
addEventListener: addEventListener.bind(window),
|
|
201
205
|
// 安全的 window.open 代理
|
|
@@ -321,12 +325,43 @@ function createSafeNavigator(extra) {
|
|
|
321
325
|
);
|
|
322
326
|
}
|
|
323
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");
|
|
324
357
|
// Annotate the CommonJS export names for ESM import in node:
|
|
325
358
|
0 && (module.exports = {
|
|
326
359
|
__resetRunJSSafeGlobalsRegistryForTests,
|
|
327
360
|
createSafeDocument,
|
|
328
361
|
createSafeNavigator,
|
|
362
|
+
createSafeRunJSGlobals,
|
|
329
363
|
createSafeWindow,
|
|
330
364
|
registerRunJSSafeDocumentGlobals,
|
|
331
|
-
registerRunJSSafeWindowGlobals
|
|
365
|
+
registerRunJSSafeWindowGlobals,
|
|
366
|
+
runjsWithSafeGlobals
|
|
332
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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/flow-engine",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.23",
|
|
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.0.0-beta.
|
|
12
|
-
"@nocobase/shared": "2.0.0-beta.
|
|
11
|
+
"@nocobase/sdk": "2.0.0-beta.23",
|
|
12
|
+
"@nocobase/shared": "2.0.0-beta.23",
|
|
13
13
|
"ahooks": "^3.7.2",
|
|
14
14
|
"dayjs": "^1.11.9",
|
|
15
15
|
"dompurify": "^3.0.2",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
],
|
|
37
37
|
"author": "NocoBase Team",
|
|
38
38
|
"license": "AGPL-3.0",
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "0279d8edffa3af9cab21956bb5f2d07322897271"
|
|
40
40
|
}
|