@nocobase/flow-engine 2.2.0-beta.1 → 2.2.0-beta.11
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/components/FieldModelRenderer.js +44 -31
- package/lib/components/MobilePopup.js +28 -10
- package/lib/components/MobilePopup.style.js +27 -6
- package/lib/components/dnd/index.js +9 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +86 -32
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +20 -0
- package/lib/flowContext.d.ts +1 -1
- package/lib/flowContext.js +97 -42
- package/lib/flowEngine.js +6 -0
- package/lib/flowSettings.d.ts +5 -1
- package/lib/flowSettings.js +70 -0
- package/lib/locale/en-US.json +1 -0
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/resources/apiResource.js +2 -1
- package/lib/resources/baseRecordResource.js +6 -17
- package/lib/resources/multiRecordResource.js +13 -3
- package/lib/resources/singleRecordResource.js +7 -2
- package/lib/runjs-context/helpers.js +12 -5
- package/lib/types.d.ts +12 -0
- package/lib/utils/dataSourceDirty.d.ts +20 -0
- package/lib/utils/dataSourceDirty.js +139 -0
- package/lib/utils/dirtyAwareApiClient.d.ts +11 -0
- package/lib/utils/dirtyAwareApiClient.js +632 -0
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +11 -11
- package/lib/utils/loadedPageCache.d.ts +1 -0
- package/lib/utils/loadedPageCache.js +6 -0
- package/lib/utils/openViewRouteState.d.ts +28 -0
- package/lib/utils/openViewRouteState.js +125 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +3 -0
- package/lib/utils/parsePathnameToViewParams.js +18 -1
- package/lib/utils/resolveRunJSObjectValues.js +3 -2
- package/lib/utils/runjsModuleLoader.js +0 -30
- package/lib/views/ViewNavigation.js +5 -0
- package/package.json +4 -4
- package/src/JSRunner.ts +112 -25
- package/src/__tests__/JSRunner.test.ts +4 -5
- package/src/__tests__/flowContext.test.ts +154 -0
- package/src/__tests__/flowEngine.dataSourceDirty.test.ts +51 -0
- package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
- package/src/__tests__/flowSettings.test.ts +72 -0
- package/src/__tests__/runjsRuntimeFeatures.test.ts +15 -2
- package/src/__tests__/viewScopedFlowEngine.test.ts +72 -6
- package/src/components/FieldModelRenderer.tsx +50 -36
- package/src/components/MobilePopup.style.ts +34 -7
- package/src/components/MobilePopup.tsx +30 -10
- package/src/components/__tests__/FieldModelRenderer.test.tsx +165 -0
- package/src/components/__tests__/MobilePopup.style.test.tsx +103 -0
- package/src/components/__tests__/MobilePopup.test.tsx +109 -0
- package/src/components/dnd/index.tsx +11 -2
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +105 -35
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +381 -12
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +28 -0
- package/src/flowContext.ts +104 -36
- package/src/flowEngine.ts +6 -0
- package/src/flowSettings.ts +85 -1
- package/src/locale/en-US.json +1 -0
- package/src/locale/zh-CN.json +1 -0
- package/src/resources/apiResource.ts +2 -1
- package/src/resources/baseRecordResource.ts +6 -23
- package/src/resources/multiRecordResource.ts +13 -3
- package/src/resources/singleRecordResource.ts +6 -1
- package/src/runjs-context/helpers.ts +12 -6
- package/src/types.ts +14 -0
- package/src/utils/__tests__/dirtyAwareApiClient.test.ts +713 -0
- package/src/utils/__tests__/openViewRouteState.test.ts +40 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +36 -0
- package/src/utils/dataSourceDirty.ts +126 -0
- package/src/utils/dirtyAwareApiClient.ts +742 -0
- package/src/utils/index.ts +10 -9
- package/src/utils/loadedPageCache.ts +7 -0
- package/src/utils/openViewRouteState.ts +107 -0
- package/src/utils/parsePathnameToViewParams.ts +23 -1
- package/src/utils/resolveRunJSObjectValues.ts +5 -2
- package/src/utils/runjsModuleLoader.ts +0 -32
- package/src/views/ViewNavigation.ts +6 -1
- package/src/views/__tests__/ViewNavigation.test.ts +15 -0
- 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/utils/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(utils_exports, {
|
|
|
33
33
|
FlowExitAllException: () => import_exceptions.FlowExitAllException,
|
|
34
34
|
FlowExitException: () => import_exceptions.FlowExitException,
|
|
35
35
|
MENU_KEYS: () => import_constants.MENU_KEYS,
|
|
36
|
+
RUNJS_OPEN_VIEW_ROUTE_STATE: () => import_openViewRouteState.RUNJS_OPEN_VIEW_ROUTE_STATE,
|
|
36
37
|
buildRecordMeta: () => import_variablesParams.buildRecordMeta,
|
|
37
38
|
clearAutoFlowError: () => import_autoFlowError.clearAutoFlowError,
|
|
38
39
|
collectContextParamsForTemplate: () => import_variablesParams.collectContextParamsForTemplate,
|
|
@@ -42,15 +43,14 @@ __export(utils_exports, {
|
|
|
42
43
|
createCollectionContextMeta: () => import_createCollectionContextMeta.createCollectionContextMeta,
|
|
43
44
|
createCurrentRecordMetaFactory: () => import_variablesParams.createCurrentRecordMetaFactory,
|
|
44
45
|
createEphemeralContext: () => import_createEphemeralContext.createEphemeralContext,
|
|
46
|
+
createOpenViewRouteState: () => import_openViewRouteState.createOpenViewRouteState,
|
|
45
47
|
createRecordMetaFactory: () => import_variablesParams.createRecordMetaFactory,
|
|
46
48
|
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
49
|
decodeBase64Url: () => import_dateVariable.decodeBase64Url,
|
|
50
|
+
decodeOpenViewRouteState: () => import_openViewRouteState.decodeOpenViewRouteState,
|
|
52
51
|
defineAction: () => import_flow_definitions.defineAction,
|
|
53
52
|
encodeBase64Url: () => import_dateVariable.encodeBase64Url,
|
|
53
|
+
encodeOpenViewRouteState: () => import_openViewRouteState.encodeOpenViewRouteState,
|
|
54
54
|
escapeT: () => import_translation.escapeT,
|
|
55
55
|
extractPropertyPath: () => import_context.extractPropertyPath,
|
|
56
56
|
extractUsedVariableNames: () => import_variablesParams.extractUsedVariableNames,
|
|
@@ -66,6 +66,7 @@ __export(utils_exports, {
|
|
|
66
66
|
isCtxDateExpression: () => import_dateVariable.isCtxDateExpression,
|
|
67
67
|
isCtxDatePathPrefix: () => import_dateVariable.isCtxDatePathPrefix,
|
|
68
68
|
isInheritedFrom: () => import_inheritance.isInheritedFrom,
|
|
69
|
+
isOpenViewRouteStateToken: () => import_openViewRouteState.isOpenViewRouteStateToken,
|
|
69
70
|
isRunJSValue: () => import_runjsValue.isRunJSValue,
|
|
70
71
|
isVariableExpression: () => import_context.isVariableExpression,
|
|
71
72
|
normalizeRunJSValue: () => import_runjsValue.normalizeRunJSValue,
|
|
@@ -84,7 +85,6 @@ __export(utils_exports, {
|
|
|
84
85
|
resolveStepDisabledInSettings: () => import_schema_utils.resolveStepDisabledInSettings,
|
|
85
86
|
resolveStepUiSchema: () => import_schema_utils.resolveStepUiSchema,
|
|
86
87
|
resolveUiMode: () => import_schema_utils.resolveUiMode,
|
|
87
|
-
runjsWithSafeGlobals: () => import_safeGlobals.runjsWithSafeGlobals,
|
|
88
88
|
serializeCtxDateValue: () => import_dateVariable.serializeCtxDateValue,
|
|
89
89
|
setAutoFlowError: () => import_autoFlowError.setAutoFlowError,
|
|
90
90
|
setupRuntimeContextSteps: () => import_setupRuntimeContextSteps.setupRuntimeContextSteps,
|
|
@@ -107,8 +107,8 @@ var import_variablesParams = require("./variablesParams");
|
|
|
107
107
|
var import_context = require("./context");
|
|
108
108
|
var import_autoFlowError = require("./autoFlowError");
|
|
109
109
|
var import_parsePathnameToViewParams = require("./parsePathnameToViewParams");
|
|
110
|
+
var import_openViewRouteState = require("./openViewRouteState");
|
|
110
111
|
var import_dateVariable = require("./dateVariable");
|
|
111
|
-
var import_safeGlobals = require("./safeGlobals");
|
|
112
112
|
var import_runjsValue = require("./runjsValue");
|
|
113
113
|
var import_resolveRunJSObjectValues = require("./resolveRunJSObjectValues");
|
|
114
114
|
var import_runjsTemplateCompat = require("./runjsTemplateCompat");
|
|
@@ -126,6 +126,7 @@ var import_randomId = require("./randomId");
|
|
|
126
126
|
FlowExitAllException,
|
|
127
127
|
FlowExitException,
|
|
128
128
|
MENU_KEYS,
|
|
129
|
+
RUNJS_OPEN_VIEW_ROUTE_STATE,
|
|
129
130
|
buildRecordMeta,
|
|
130
131
|
clearAutoFlowError,
|
|
131
132
|
collectContextParamsForTemplate,
|
|
@@ -135,15 +136,14 @@ var import_randomId = require("./randomId");
|
|
|
135
136
|
createCollectionContextMeta,
|
|
136
137
|
createCurrentRecordMetaFactory,
|
|
137
138
|
createEphemeralContext,
|
|
139
|
+
createOpenViewRouteState,
|
|
138
140
|
createRecordMetaFactory,
|
|
139
141
|
createRecordResolveOnServerWithLocal,
|
|
140
|
-
createSafeDocument,
|
|
141
|
-
createSafeNavigator,
|
|
142
|
-
createSafeRunJSGlobals,
|
|
143
|
-
createSafeWindow,
|
|
144
142
|
decodeBase64Url,
|
|
143
|
+
decodeOpenViewRouteState,
|
|
145
144
|
defineAction,
|
|
146
145
|
encodeBase64Url,
|
|
146
|
+
encodeOpenViewRouteState,
|
|
147
147
|
escapeT,
|
|
148
148
|
extractPropertyPath,
|
|
149
149
|
extractUsedVariableNames,
|
|
@@ -159,6 +159,7 @@ var import_randomId = require("./randomId");
|
|
|
159
159
|
isCtxDateExpression,
|
|
160
160
|
isCtxDatePathPrefix,
|
|
161
161
|
isInheritedFrom,
|
|
162
|
+
isOpenViewRouteStateToken,
|
|
162
163
|
isRunJSValue,
|
|
163
164
|
isVariableExpression,
|
|
164
165
|
normalizeRunJSValue,
|
|
@@ -177,7 +178,6 @@ var import_randomId = require("./randomId");
|
|
|
177
178
|
resolveStepDisabledInSettings,
|
|
178
179
|
resolveStepUiSchema,
|
|
179
180
|
resolveUiMode,
|
|
180
|
-
runjsWithSafeGlobals,
|
|
181
181
|
serializeCtxDateValue,
|
|
182
182
|
setAutoFlowError,
|
|
183
183
|
setupRuntimeContextSteps,
|
|
@@ -17,6 +17,7 @@ type DirtyKeyOptions = {
|
|
|
17
17
|
export declare const createLoadedPageCache: () => {
|
|
18
18
|
getDirtyKeyForModel(model?: FlowModel | null, options?: DirtyKeyOptions): string | undefined;
|
|
19
19
|
markDirty(key?: string): void;
|
|
20
|
+
markDirtyForOptions(options?: LoadedPageOptions): void;
|
|
20
21
|
shouldBypass(options?: LoadedPageOptions, isFlowSettingsEnabled?: () => boolean): boolean;
|
|
21
22
|
clear(options?: LoadedPageOptions): void;
|
|
22
23
|
mountModelToParent: <T extends FlowModel<import("..").DefaultStructure> = FlowModel<import("..").DefaultStructure>>(model: T, forceReplace?: boolean) => T;
|
|
@@ -113,6 +113,12 @@ const createLoadedPageCache = /* @__PURE__ */ __name(() => {
|
|
|
113
113
|
dirtyKeys.add(key);
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
+
markDirtyForOptions(options) {
|
|
117
|
+
const key = getLoadedPageKey(options);
|
|
118
|
+
if (key) {
|
|
119
|
+
dirtyKeys.add(key);
|
|
120
|
+
}
|
|
121
|
+
},
|
|
116
122
|
shouldBypass(options, isFlowSettingsEnabled) {
|
|
117
123
|
const key = getLoadedPageKey(options);
|
|
118
124
|
if (!key || !dirtyKeys.has(key)) {
|
|
@@ -0,0 +1,28 @@
|
|
|
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
|
+
declare const OPEN_VIEW_ROUTE_MODES: readonly ["drawer", "dialog", "embed"];
|
|
10
|
+
declare const OPEN_VIEW_ROUTE_SIZES: readonly ["small", "medium", "large"];
|
|
11
|
+
export type OpenViewRouteMode = (typeof OPEN_VIEW_ROUTE_MODES)[number];
|
|
12
|
+
export type OpenViewRouteSize = (typeof OPEN_VIEW_ROUTE_SIZES)[number];
|
|
13
|
+
export type OpenViewRouteState = {
|
|
14
|
+
mode?: OpenViewRouteMode;
|
|
15
|
+
size?: OpenViewRouteSize;
|
|
16
|
+
};
|
|
17
|
+
export declare const RUNJS_OPEN_VIEW_ROUTE_STATE: unique symbol;
|
|
18
|
+
export declare function createOpenViewRouteState(input?: {
|
|
19
|
+
mode?: unknown;
|
|
20
|
+
size?: unknown;
|
|
21
|
+
}): OpenViewRouteState | undefined;
|
|
22
|
+
export declare function isOpenViewRouteStateToken(value: unknown): value is string;
|
|
23
|
+
export declare function encodeOpenViewRouteState(viewUid: string, input?: {
|
|
24
|
+
mode?: unknown;
|
|
25
|
+
size?: unknown;
|
|
26
|
+
}): string;
|
|
27
|
+
export declare function decodeOpenViewRouteState(viewUid: string, token: unknown): OpenViewRouteState;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,125 @@
|
|
|
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 openViewRouteState_exports = {};
|
|
29
|
+
__export(openViewRouteState_exports, {
|
|
30
|
+
RUNJS_OPEN_VIEW_ROUTE_STATE: () => RUNJS_OPEN_VIEW_ROUTE_STATE,
|
|
31
|
+
createOpenViewRouteState: () => createOpenViewRouteState,
|
|
32
|
+
decodeOpenViewRouteState: () => decodeOpenViewRouteState,
|
|
33
|
+
encodeOpenViewRouteState: () => encodeOpenViewRouteState,
|
|
34
|
+
isOpenViewRouteStateToken: () => isOpenViewRouteStateToken
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(openViewRouteState_exports);
|
|
37
|
+
const OPEN_VIEW_ROUTE_MODES = ["drawer", "dialog", "embed"];
|
|
38
|
+
const OPEN_VIEW_ROUTE_SIZES = ["small", "medium", "large"];
|
|
39
|
+
const OPEN_VIEW_ROUTE_STATE_TOKEN_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
40
|
+
const OPEN_VIEW_ROUTE_STATE_TOKEN_LENGTH = 8;
|
|
41
|
+
const RUNJS_OPEN_VIEW_ROUTE_STATE = Symbol.for("nocobase.runjs.openViewRouteState");
|
|
42
|
+
function isOpenViewRouteMode(value) {
|
|
43
|
+
return typeof value === "string" && OPEN_VIEW_ROUTE_MODES.includes(value);
|
|
44
|
+
}
|
|
45
|
+
__name(isOpenViewRouteMode, "isOpenViewRouteMode");
|
|
46
|
+
function isOpenViewRouteSize(value) {
|
|
47
|
+
return typeof value === "string" && OPEN_VIEW_ROUTE_SIZES.includes(value);
|
|
48
|
+
}
|
|
49
|
+
__name(isOpenViewRouteSize, "isOpenViewRouteSize");
|
|
50
|
+
function createOpenViewRouteState(input) {
|
|
51
|
+
const state = {};
|
|
52
|
+
if (isOpenViewRouteMode(input == null ? void 0 : input.mode)) {
|
|
53
|
+
state.mode = input.mode;
|
|
54
|
+
}
|
|
55
|
+
if (isOpenViewRouteSize(input == null ? void 0 : input.size)) {
|
|
56
|
+
state.size = input.size;
|
|
57
|
+
}
|
|
58
|
+
return state.mode || state.size ? state : void 0;
|
|
59
|
+
}
|
|
60
|
+
__name(createOpenViewRouteState, "createOpenViewRouteState");
|
|
61
|
+
function hashString(value) {
|
|
62
|
+
let hash = 2166136261;
|
|
63
|
+
for (let i = 0; i < value.length; i++) {
|
|
64
|
+
hash ^= value.charCodeAt(i);
|
|
65
|
+
hash = Math.imul(hash, 16777619);
|
|
66
|
+
}
|
|
67
|
+
return hash >>> 0;
|
|
68
|
+
}
|
|
69
|
+
__name(hashString, "hashString");
|
|
70
|
+
function stateToCode(state) {
|
|
71
|
+
const modeIndex = state.mode ? OPEN_VIEW_ROUTE_MODES.indexOf(state.mode) + 1 : 0;
|
|
72
|
+
const sizeIndex = state.size ? OPEN_VIEW_ROUTE_SIZES.indexOf(state.size) + 1 : 0;
|
|
73
|
+
const code = modeIndex * 4 + sizeIndex;
|
|
74
|
+
return code > 0 ? code : void 0;
|
|
75
|
+
}
|
|
76
|
+
__name(stateToCode, "stateToCode");
|
|
77
|
+
function codeToState(code) {
|
|
78
|
+
const modeIndex = Math.floor(code / 4);
|
|
79
|
+
const sizeIndex = code % 4;
|
|
80
|
+
return createOpenViewRouteState({
|
|
81
|
+
mode: modeIndex ? OPEN_VIEW_ROUTE_MODES[modeIndex - 1] : void 0,
|
|
82
|
+
size: sizeIndex ? OPEN_VIEW_ROUTE_SIZES[sizeIndex - 1] : void 0
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
__name(codeToState, "codeToState");
|
|
86
|
+
function tokenForCode(viewUid, code) {
|
|
87
|
+
let seed = hashString(`${viewUid}:${code}`);
|
|
88
|
+
let token = "";
|
|
89
|
+
for (let i = 0; i < OPEN_VIEW_ROUTE_STATE_TOKEN_LENGTH; i++) {
|
|
90
|
+
seed = Math.imul(seed ^ code + i * 17, 16777619) >>> 0;
|
|
91
|
+
token += OPEN_VIEW_ROUTE_STATE_TOKEN_ALPHABET[seed % OPEN_VIEW_ROUTE_STATE_TOKEN_ALPHABET.length];
|
|
92
|
+
}
|
|
93
|
+
return token;
|
|
94
|
+
}
|
|
95
|
+
__name(tokenForCode, "tokenForCode");
|
|
96
|
+
function isOpenViewRouteStateToken(value) {
|
|
97
|
+
return typeof value === "string" && value.length === OPEN_VIEW_ROUTE_STATE_TOKEN_LENGTH && [...value].every((char) => OPEN_VIEW_ROUTE_STATE_TOKEN_ALPHABET.includes(char));
|
|
98
|
+
}
|
|
99
|
+
__name(isOpenViewRouteStateToken, "isOpenViewRouteStateToken");
|
|
100
|
+
function encodeOpenViewRouteState(viewUid, input) {
|
|
101
|
+
const state = createOpenViewRouteState(input);
|
|
102
|
+
const code = state ? stateToCode(state) : void 0;
|
|
103
|
+
return code ? tokenForCode(viewUid, code) : void 0;
|
|
104
|
+
}
|
|
105
|
+
__name(encodeOpenViewRouteState, "encodeOpenViewRouteState");
|
|
106
|
+
function decodeOpenViewRouteState(viewUid, token) {
|
|
107
|
+
if (!isOpenViewRouteStateToken(token)) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
for (let code = 1; code < 16; code++) {
|
|
111
|
+
if (tokenForCode(viewUid, code) === token) {
|
|
112
|
+
return codeToState(code);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
__name(decodeOpenViewRouteState, "decodeOpenViewRouteState");
|
|
118
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
119
|
+
0 && (module.exports = {
|
|
120
|
+
RUNJS_OPEN_VIEW_ROUTE_STATE,
|
|
121
|
+
createOpenViewRouteState,
|
|
122
|
+
decodeOpenViewRouteState,
|
|
123
|
+
encodeOpenViewRouteState,
|
|
124
|
+
isOpenViewRouteStateToken
|
|
125
|
+
});
|
|
@@ -6,6 +6,7 @@
|
|
|
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
|
+
import { type OpenViewRouteState } from './openViewRouteState';
|
|
9
10
|
export interface ViewParam {
|
|
10
11
|
/** 视图唯一标识符,一般为某个 Model 实例的 uid */
|
|
11
12
|
viewUid: string;
|
|
@@ -15,6 +16,8 @@ export interface ViewParam {
|
|
|
15
16
|
filterByTk?: string | Record<string, string | number>;
|
|
16
17
|
/** source Id */
|
|
17
18
|
sourceId?: string;
|
|
19
|
+
/** RunJS ctx.openView runtime display overrides decoded from URL. */
|
|
20
|
+
openViewRouteState?: OpenViewRouteState;
|
|
18
21
|
}
|
|
19
22
|
export interface ParsePathnameToViewParamsOptions {
|
|
20
23
|
rootPrefix?: string;
|
|
@@ -30,6 +30,7 @@ __export(parsePathnameToViewParams_exports, {
|
|
|
30
30
|
parsePathnameToViewParams: () => parsePathnameToViewParams
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(parsePathnameToViewParams_exports);
|
|
33
|
+
var import_openViewRouteState = require("./openViewRouteState");
|
|
33
34
|
const normalizePathname = /* @__PURE__ */ __name((pathname) => {
|
|
34
35
|
if (!pathname || pathname === "/") {
|
|
35
36
|
return "/";
|
|
@@ -77,7 +78,23 @@ const parsePathnameToViewParams = /* @__PURE__ */ __name((pathname, options = {}
|
|
|
77
78
|
} else {
|
|
78
79
|
break;
|
|
79
80
|
}
|
|
80
|
-
} else if (currentView
|
|
81
|
+
} else if (currentView) {
|
|
82
|
+
if (segment === "opts") {
|
|
83
|
+
if (i + 1 < segments.length) {
|
|
84
|
+
const routeState = (0, import_openViewRouteState.decodeOpenViewRouteState)(currentView.viewUid, segments[i + 1]);
|
|
85
|
+
if (routeState) {
|
|
86
|
+
currentView.openViewRouteState = routeState;
|
|
87
|
+
}
|
|
88
|
+
i += 2;
|
|
89
|
+
} else {
|
|
90
|
+
i++;
|
|
91
|
+
}
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (i + 1 >= segments.length) {
|
|
95
|
+
i++;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
81
98
|
const rawValue = segments[i + 1];
|
|
82
99
|
let decoded = rawValue;
|
|
83
100
|
try {
|
|
@@ -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;
|
|
@@ -32,6 +32,7 @@ __export(ViewNavigation_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(ViewNavigation_exports);
|
|
34
34
|
var import_reactive = require("../reactive");
|
|
35
|
+
var import_utils = require("../utils");
|
|
35
36
|
function encodeFilterByTk(val) {
|
|
36
37
|
if (val === void 0 || val === null) return "";
|
|
37
38
|
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
@@ -63,6 +64,10 @@ function generatePathnameFromViewParams(viewParams, options = {}) {
|
|
|
63
64
|
segments.push("view");
|
|
64
65
|
}
|
|
65
66
|
segments.push(viewParam.viewUid);
|
|
67
|
+
const openViewRouteStateToken = (0, import_utils.encodeOpenViewRouteState)(viewParam.viewUid, viewParam.openViewRouteState);
|
|
68
|
+
if (openViewRouteStateToken) {
|
|
69
|
+
segments.push("opts", openViewRouteStateToken);
|
|
70
|
+
}
|
|
66
71
|
if (viewParam.tabUid) {
|
|
67
72
|
segments.push("tab", viewParam.tabUid);
|
|
68
73
|
}
|
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.11",
|
|
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.11",
|
|
12
|
+
"@nocobase/shared": "2.2.0-beta.11",
|
|
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": "8dab25af2bb83a81da68158d0dcf836f96103d61"
|
|
41
41
|
}
|
package/src/JSRunner.ts
CHANGED
|
@@ -39,6 +39,117 @@ export function shouldPreprocessRunJSTemplates(
|
|
|
39
39
|
return options?.version !== 'v2';
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
const RUNJS_BROWSER_GLOBAL_NAMES = [
|
|
43
|
+
'fetch',
|
|
44
|
+
'localStorage',
|
|
45
|
+
'sessionStorage',
|
|
46
|
+
'XMLHttpRequest',
|
|
47
|
+
'WebSocket',
|
|
48
|
+
'Worker',
|
|
49
|
+
'SharedWorker',
|
|
50
|
+
'ServiceWorker',
|
|
51
|
+
'BroadcastChannel',
|
|
52
|
+
'EventSource',
|
|
53
|
+
'indexedDB',
|
|
54
|
+
'caches',
|
|
55
|
+
'Function',
|
|
56
|
+
'eval',
|
|
57
|
+
'globalThis',
|
|
58
|
+
'Intl',
|
|
59
|
+
'Blob',
|
|
60
|
+
'URL',
|
|
61
|
+
'location',
|
|
62
|
+
] as const;
|
|
63
|
+
|
|
64
|
+
export const RUNJS_ALLOWED_BARE_GLOBAL_NAMES = [
|
|
65
|
+
'ctx',
|
|
66
|
+
'console',
|
|
67
|
+
'window',
|
|
68
|
+
'document',
|
|
69
|
+
'navigator',
|
|
70
|
+
'setTimeout',
|
|
71
|
+
'clearTimeout',
|
|
72
|
+
'setInterval',
|
|
73
|
+
'clearInterval',
|
|
74
|
+
'Array',
|
|
75
|
+
'ArrayBuffer',
|
|
76
|
+
'BigInt',
|
|
77
|
+
'BigInt64Array',
|
|
78
|
+
'BigUint64Array',
|
|
79
|
+
'Boolean',
|
|
80
|
+
'DataView',
|
|
81
|
+
'Date',
|
|
82
|
+
'Error',
|
|
83
|
+
'EvalError',
|
|
84
|
+
'FinalizationRegistry',
|
|
85
|
+
'Float32Array',
|
|
86
|
+
'Float64Array',
|
|
87
|
+
'Int8Array',
|
|
88
|
+
'Int16Array',
|
|
89
|
+
'Int32Array',
|
|
90
|
+
'Map',
|
|
91
|
+
'Math',
|
|
92
|
+
'Number',
|
|
93
|
+
'Object',
|
|
94
|
+
'Promise',
|
|
95
|
+
'Proxy',
|
|
96
|
+
'RangeError',
|
|
97
|
+
'ReferenceError',
|
|
98
|
+
'Reflect',
|
|
99
|
+
'RegExp',
|
|
100
|
+
'Set',
|
|
101
|
+
'String',
|
|
102
|
+
'Symbol',
|
|
103
|
+
'SyntaxError',
|
|
104
|
+
'TypeError',
|
|
105
|
+
'URIError',
|
|
106
|
+
'Uint8Array',
|
|
107
|
+
'Uint8ClampedArray',
|
|
108
|
+
'Uint16Array',
|
|
109
|
+
'Uint32Array',
|
|
110
|
+
'WeakMap',
|
|
111
|
+
'WeakRef',
|
|
112
|
+
'WeakSet',
|
|
113
|
+
'JSON',
|
|
114
|
+
'decodeURI',
|
|
115
|
+
'decodeURIComponent',
|
|
116
|
+
'encodeURI',
|
|
117
|
+
'encodeURIComponent',
|
|
118
|
+
'isFinite',
|
|
119
|
+
'isNaN',
|
|
120
|
+
'parseFloat',
|
|
121
|
+
'parseInt',
|
|
122
|
+
'undefined',
|
|
123
|
+
'NaN',
|
|
124
|
+
'Infinity',
|
|
125
|
+
...RUNJS_BROWSER_GLOBAL_NAMES,
|
|
126
|
+
] as const;
|
|
127
|
+
|
|
128
|
+
function collectRunJSBrowserGlobals(providedGlobals: Record<string, unknown> = {}) {
|
|
129
|
+
const windowGlobal = providedGlobals.window;
|
|
130
|
+
if (!windowGlobal || typeof windowGlobal !== 'object') {
|
|
131
|
+
return {};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const windowRecord = windowGlobal as Record<string, unknown>;
|
|
135
|
+
const globals: Record<string, unknown> = {};
|
|
136
|
+
RUNJS_BROWSER_GLOBAL_NAMES.forEach((name) => {
|
|
137
|
+
if (Object.prototype.hasOwnProperty.call(providedGlobals, name)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const value = windowRecord[name];
|
|
142
|
+
if (typeof value === 'undefined') {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
globals[name] = name === 'fetch' && typeof value === 'function' ? value.bind(windowGlobal) : value;
|
|
146
|
+
} catch {
|
|
147
|
+
// Ignore browser globals that cannot be read in the current environment.
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return globals;
|
|
151
|
+
}
|
|
152
|
+
|
|
42
153
|
// Heuristic: detect likely bare `{{ctx.xxx}}` usage in executable positions (not quoted string literals).
|
|
43
154
|
const BARE_CTX_TEMPLATE_RE = /(^|[=(:,[\s)])(\{\{\s*(ctx(?:\.|\[|\?\.)[^}]*)\s*\}\})/m;
|
|
44
155
|
|
|
@@ -98,31 +209,7 @@ export class JSRunner {
|
|
|
98
209
|
};
|
|
99
210
|
|
|
100
211
|
const providedGlobals = options.globals || {};
|
|
101
|
-
const liftedGlobals
|
|
102
|
-
|
|
103
|
-
// Auto-lift selected globals from safe window into top-level sandbox globals
|
|
104
|
-
// so user code can access them directly (e.g. `new Blob(...)`).
|
|
105
|
-
if (!Object.prototype.hasOwnProperty.call(providedGlobals, 'Blob')) {
|
|
106
|
-
try {
|
|
107
|
-
const blobCtor = (providedGlobals as any).window?.Blob;
|
|
108
|
-
if (typeof blobCtor !== 'undefined') {
|
|
109
|
-
liftedGlobals.Blob = blobCtor;
|
|
110
|
-
}
|
|
111
|
-
} catch {
|
|
112
|
-
// ignore when window proxy blocks property access
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (!Object.prototype.hasOwnProperty.call(providedGlobals, 'URL')) {
|
|
117
|
-
try {
|
|
118
|
-
const urlCtor = (providedGlobals as any).window?.URL;
|
|
119
|
-
if (typeof urlCtor !== 'undefined') {
|
|
120
|
-
liftedGlobals.URL = urlCtor;
|
|
121
|
-
}
|
|
122
|
-
} catch {
|
|
123
|
-
// ignore when window proxy blocks property access
|
|
124
|
-
}
|
|
125
|
-
}
|
|
212
|
+
const liftedGlobals = collectRunJSBrowserGlobals(providedGlobals);
|
|
126
213
|
|
|
127
214
|
this.globals = {
|
|
128
215
|
console,
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
11
11
|
import { JSRunner, shouldPreprocessRunJSTemplates } from '../JSRunner';
|
|
12
|
-
import { createSafeWindow } from '../utils';
|
|
13
12
|
|
|
14
13
|
describe('JSRunner', () => {
|
|
15
14
|
let originalSearch: string;
|
|
@@ -68,7 +67,7 @@ describe('JSRunner', () => {
|
|
|
68
67
|
|
|
69
68
|
const runner = new JSRunner({
|
|
70
69
|
globals: {
|
|
71
|
-
window
|
|
70
|
+
window,
|
|
72
71
|
},
|
|
73
72
|
});
|
|
74
73
|
|
|
@@ -84,7 +83,7 @@ describe('JSRunner', () => {
|
|
|
84
83
|
|
|
85
84
|
const runner = new JSRunner({
|
|
86
85
|
globals: {
|
|
87
|
-
window
|
|
86
|
+
window,
|
|
88
87
|
Blob: explicitBlob,
|
|
89
88
|
},
|
|
90
89
|
});
|
|
@@ -97,7 +96,7 @@ describe('JSRunner', () => {
|
|
|
97
96
|
it('auto-lifts URL from injected window to top-level globals', async () => {
|
|
98
97
|
const runner = new JSRunner({
|
|
99
98
|
globals: {
|
|
100
|
-
window
|
|
99
|
+
window,
|
|
101
100
|
},
|
|
102
101
|
});
|
|
103
102
|
|
|
@@ -114,7 +113,7 @@ describe('JSRunner', () => {
|
|
|
114
113
|
|
|
115
114
|
const runner = new JSRunner({
|
|
116
115
|
globals: {
|
|
117
|
-
window
|
|
116
|
+
window,
|
|
118
117
|
URL: explicitURL,
|
|
119
118
|
},
|
|
120
119
|
});
|