@nocobase/flow-engine 2.2.0-beta.1 → 2.2.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/lib/JSRunner.d.ts +1 -0
  2. package/lib/JSRunner.js +110 -20
  3. package/lib/components/FieldModelRenderer.js +44 -31
  4. package/lib/components/MobilePopup.js +28 -10
  5. package/lib/components/MobilePopup.style.js +27 -6
  6. package/lib/components/dnd/index.js +9 -2
  7. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +86 -32
  8. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +20 -0
  9. package/lib/flowContext.d.ts +1 -1
  10. package/lib/flowContext.js +97 -42
  11. package/lib/flowEngine.js +6 -0
  12. package/lib/flowSettings.d.ts +5 -1
  13. package/lib/flowSettings.js +70 -0
  14. package/lib/locale/en-US.json +1 -0
  15. package/lib/locale/index.d.ts +2 -0
  16. package/lib/locale/zh-CN.json +1 -0
  17. package/lib/resources/apiResource.js +2 -1
  18. package/lib/resources/baseRecordResource.js +6 -17
  19. package/lib/resources/multiRecordResource.js +13 -3
  20. package/lib/resources/singleRecordResource.js +7 -2
  21. package/lib/runjs-context/helpers.js +12 -5
  22. package/lib/types.d.ts +12 -0
  23. package/lib/utils/dataSourceDirty.d.ts +20 -0
  24. package/lib/utils/dataSourceDirty.js +139 -0
  25. package/lib/utils/dirtyAwareApiClient.d.ts +11 -0
  26. package/lib/utils/dirtyAwareApiClient.js +378 -0
  27. package/lib/utils/index.d.ts +1 -1
  28. package/lib/utils/index.js +11 -11
  29. package/lib/utils/loadedPageCache.d.ts +1 -0
  30. package/lib/utils/loadedPageCache.js +6 -0
  31. package/lib/utils/openViewRouteState.d.ts +28 -0
  32. package/lib/utils/openViewRouteState.js +125 -0
  33. package/lib/utils/parsePathnameToViewParams.d.ts +3 -0
  34. package/lib/utils/parsePathnameToViewParams.js +18 -1
  35. package/lib/utils/resolveRunJSObjectValues.js +3 -2
  36. package/lib/utils/runjsModuleLoader.js +0 -30
  37. package/lib/views/ViewNavigation.js +5 -0
  38. package/package.json +4 -4
  39. package/src/JSRunner.ts +112 -25
  40. package/src/__tests__/JSRunner.test.ts +4 -5
  41. package/src/__tests__/flowContext.test.ts +154 -0
  42. package/src/__tests__/flowEngine.dataSourceDirty.test.ts +51 -0
  43. package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
  44. package/src/__tests__/flowSettings.test.ts +72 -0
  45. package/src/__tests__/runjsRuntimeFeatures.test.ts +15 -2
  46. package/src/__tests__/viewScopedFlowEngine.test.ts +72 -6
  47. package/src/components/FieldModelRenderer.tsx +50 -36
  48. package/src/components/MobilePopup.style.ts +34 -7
  49. package/src/components/MobilePopup.tsx +30 -10
  50. package/src/components/__tests__/FieldModelRenderer.test.tsx +165 -0
  51. package/src/components/__tests__/MobilePopup.style.test.tsx +103 -0
  52. package/src/components/__tests__/MobilePopup.test.tsx +109 -0
  53. package/src/components/dnd/index.tsx +11 -2
  54. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +105 -35
  55. package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +381 -12
  56. package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +28 -0
  57. package/src/flowContext.ts +104 -36
  58. package/src/flowEngine.ts +6 -0
  59. package/src/flowSettings.ts +85 -1
  60. package/src/locale/en-US.json +1 -0
  61. package/src/locale/zh-CN.json +1 -0
  62. package/src/resources/apiResource.ts +2 -1
  63. package/src/resources/baseRecordResource.ts +6 -23
  64. package/src/resources/multiRecordResource.ts +13 -3
  65. package/src/resources/singleRecordResource.ts +6 -1
  66. package/src/runjs-context/helpers.ts +12 -6
  67. package/src/types.ts +14 -0
  68. package/src/utils/__tests__/dirtyAwareApiClient.test.ts +392 -0
  69. package/src/utils/__tests__/openViewRouteState.test.ts +40 -0
  70. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +36 -0
  71. package/src/utils/dataSourceDirty.ts +126 -0
  72. package/src/utils/dirtyAwareApiClient.ts +430 -0
  73. package/src/utils/index.ts +10 -9
  74. package/src/utils/loadedPageCache.ts +7 -0
  75. package/src/utils/openViewRouteState.ts +107 -0
  76. package/src/utils/parsePathnameToViewParams.ts +23 -1
  77. package/src/utils/resolveRunJSObjectValues.ts +5 -2
  78. package/src/utils/runjsModuleLoader.ts +0 -32
  79. package/src/views/ViewNavigation.ts +6 -1
  80. package/src/views/__tests__/ViewNavigation.test.ts +15 -0
  81. package/lib/utils/safeGlobals.d.ts +0 -28
  82. package/lib/utils/safeGlobals.js +0 -367
  83. package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +0 -38
  84. package/src/utils/__tests__/safeGlobals.test.ts +0 -106
  85. package/src/utils/safeGlobals.ts +0 -406
@@ -0,0 +1,139 @@
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 dataSourceDirty_exports = {};
29
+ __export(dataSourceDirty_exports, {
30
+ getAffectedResourceNames: () => getAffectedResourceNames,
31
+ getDataSourceKeyFromHeaders: () => getDataSourceKeyFromHeaders,
32
+ getHeaderValue: () => getHeaderValue,
33
+ markDataSourceDirty: () => markDataSourceDirty
34
+ });
35
+ module.exports = __toCommonJS(dataSourceDirty_exports);
36
+ var import_viewEvents = require("../views/viewEvents");
37
+ function getHeaderValue(headers, name) {
38
+ if (!headers || typeof headers !== "object") {
39
+ return void 0;
40
+ }
41
+ const maybeHeaders = headers;
42
+ if (typeof maybeHeaders.get === "function") {
43
+ const value = maybeHeaders.get(name);
44
+ if (value != null && value !== "") {
45
+ return value;
46
+ }
47
+ }
48
+ const lowerName = name.toLowerCase();
49
+ for (const [key, value] of Object.entries(headers)) {
50
+ if (key.toLowerCase() === lowerName) {
51
+ return value;
52
+ }
53
+ }
54
+ return void 0;
55
+ }
56
+ __name(getHeaderValue, "getHeaderValue");
57
+ function getDataSourceKeyFromHeaders(headers) {
58
+ const value = getHeaderValue(headers, "x-data-source");
59
+ if (Array.isArray(value)) {
60
+ return String(value[0] || "main");
61
+ }
62
+ return value == null || value === "" ? "main" : String(value);
63
+ }
64
+ __name(getDataSourceKeyFromHeaders, "getDataSourceKeyFromHeaders");
65
+ function getAffectedResourceNames(resourceName) {
66
+ const name = String(resourceName || "").trim();
67
+ if (!name) {
68
+ return [];
69
+ }
70
+ const names = /* @__PURE__ */ new Set([name]);
71
+ if (name.includes(".")) {
72
+ names.add(name.split(".")[0]);
73
+ }
74
+ return Array.from(names);
75
+ }
76
+ __name(getAffectedResourceNames, "getAffectedResourceNames");
77
+ function getDirtyTargetEngines(engine, includePreviousEngines) {
78
+ if (!includePreviousEngines) {
79
+ return [engine];
80
+ }
81
+ const engines = [];
82
+ const seen = /* @__PURE__ */ new Set();
83
+ let current = engine;
84
+ let guard = 0;
85
+ while (current && guard++ < 50) {
86
+ if (!seen.has(current)) {
87
+ engines.push(current);
88
+ seen.add(current);
89
+ }
90
+ current = current.previousEngine;
91
+ }
92
+ return engines;
93
+ }
94
+ __name(getDirtyTargetEngines, "getDirtyTargetEngines");
95
+ function markDataSourceDirty(options) {
96
+ var _a, _b, _c, _d;
97
+ const { engine, resourceName, includePreviousEngines } = options;
98
+ if (!(engine == null ? void 0 : engine.markDataSourceDirty)) {
99
+ return [];
100
+ }
101
+ const resourceNames = getAffectedResourceNames(resourceName);
102
+ if (!resourceNames.length) {
103
+ return [];
104
+ }
105
+ const dataSourceKey = String(options.dataSourceKey || "main");
106
+ const targetEngines = getDirtyTargetEngines(engine, includePreviousEngines);
107
+ const beforeVersions = /* @__PURE__ */ new Map();
108
+ for (const targetEngine of targetEngines) {
109
+ const versions = /* @__PURE__ */ new Map();
110
+ beforeVersions.set(targetEngine, versions);
111
+ for (const name of resourceNames) {
112
+ versions.set(name, ((_a = targetEngine.getDataSourceDirtyVersion) == null ? void 0 : _a.call(targetEngine, dataSourceKey, name)) || 0);
113
+ }
114
+ }
115
+ for (const targetEngine of targetEngines) {
116
+ const versions = beforeVersions.get(targetEngine);
117
+ for (const name of resourceNames) {
118
+ const before = (versions == null ? void 0 : versions.get(name)) || 0;
119
+ const current = ((_b = targetEngine.getDataSourceDirtyVersion) == null ? void 0 : _b.call(targetEngine, dataSourceKey, name)) || 0;
120
+ if (current !== before) {
121
+ continue;
122
+ }
123
+ targetEngine.markDataSourceDirty(dataSourceKey, name);
124
+ }
125
+ }
126
+ (_d = (_c = engine.emitter) == null ? void 0 : _c.emit) == null ? void 0 : _d.call(_c, import_viewEvents.DATA_SOURCE_DIRTY_EVENT, {
127
+ dataSourceKey,
128
+ resourceNames
129
+ });
130
+ return resourceNames;
131
+ }
132
+ __name(markDataSourceDirty, "markDataSourceDirty");
133
+ // Annotate the CommonJS export names for ESM import in node:
134
+ 0 && (module.exports = {
135
+ getAffectedResourceNames,
136
+ getDataSourceKeyFromHeaders,
137
+ getHeaderValue,
138
+ markDataSourceDirty
139
+ });
@@ -0,0 +1,11 @@
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
+ import type { FlowContext } from '../flowContext';
10
+ export declare const SKIP_DATA_SOURCE_DIRTY = "__nocobaseSkipDataSourceDirty";
11
+ export declare function getDirtyAwareApiClient(value: unknown, context: FlowContext): unknown;
@@ -0,0 +1,378 @@
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 dirtyAwareApiClient_exports = {};
29
+ __export(dirtyAwareApiClient_exports, {
30
+ SKIP_DATA_SOURCE_DIRTY: () => SKIP_DATA_SOURCE_DIRTY,
31
+ getDirtyAwareApiClient: () => getDirtyAwareApiClient
32
+ });
33
+ module.exports = __toCommonJS(dirtyAwareApiClient_exports);
34
+ var import_dataSourceDirty = require("./dataSourceDirty");
35
+ const SKIP_DATA_SOURCE_DIRTY = "__nocobaseSkipDataSourceDirty";
36
+ const dirtyAwareApiClientCache = /* @__PURE__ */ new WeakMap();
37
+ const dirtyAwareApiClientProxies = /* @__PURE__ */ new WeakSet();
38
+ const MUTATING_RESOURCE_ACTIONS = [
39
+ "add",
40
+ "bulkdestroy",
41
+ "bulkupdate",
42
+ "create",
43
+ "delete",
44
+ "destroy",
45
+ "execute",
46
+ "firstorcreate",
47
+ "import",
48
+ "move",
49
+ "remove",
50
+ "save",
51
+ "saveastemplate",
52
+ "set",
53
+ "setfields",
54
+ "submit",
55
+ "update",
56
+ "updateorcreate",
57
+ "upsert"
58
+ ];
59
+ function isApiClientLike(value) {
60
+ if (!value || typeof value !== "object") {
61
+ return false;
62
+ }
63
+ const candidate = value;
64
+ return typeof candidate.resource === "function" && typeof candidate.request === "function";
65
+ }
66
+ __name(isApiClientLike, "isApiClientLike");
67
+ function isMutatingResourceAction(actionName) {
68
+ const normalized = String(actionName || "").trim();
69
+ if (!normalized) {
70
+ return false;
71
+ }
72
+ const baseActionName = normalized.split("/")[0];
73
+ const lowerBaseActionName = baseActionName.toLowerCase();
74
+ return MUTATING_RESOURCE_ACTIONS.some((action) => {
75
+ if (lowerBaseActionName === action) {
76
+ return true;
77
+ }
78
+ if (!lowerBaseActionName.startsWith(action) || baseActionName.length <= action.length) {
79
+ return false;
80
+ }
81
+ const nextChar = baseActionName[action.length];
82
+ return nextChar === "-" || nextChar === "_" || nextChar >= "A" && nextChar <= "Z";
83
+ });
84
+ }
85
+ __name(isMutatingResourceAction, "isMutatingResourceAction");
86
+ function getCurrentOrigin() {
87
+ var _a;
88
+ return typeof window === "undefined" ? void 0 : (_a = window.location) == null ? void 0 : _a.origin;
89
+ }
90
+ __name(getCurrentOrigin, "getCurrentOrigin");
91
+ function parseUrl(value, base) {
92
+ try {
93
+ return new URL(value, base);
94
+ } catch {
95
+ return void 0;
96
+ }
97
+ }
98
+ __name(parseUrl, "parseUrl");
99
+ function stripSearchAndHash(path) {
100
+ const index = path.search(/[?#]/);
101
+ return index === -1 ? path : path.slice(0, index);
102
+ }
103
+ __name(stripSearchAndHash, "stripSearchAndHash");
104
+ function stripKnownApiPrefix(path) {
105
+ const cleanPath = stripSearchAndHash(path).trim();
106
+ if (!cleanPath) {
107
+ return void 0;
108
+ }
109
+ const normalizedPath = cleanPath.replace(/^\/+/, "");
110
+ if (!normalizedPath || normalizedPath === "api") {
111
+ return void 0;
112
+ }
113
+ if (normalizedPath.startsWith("api/")) {
114
+ return normalizedPath.slice("api/".length);
115
+ }
116
+ return normalizedPath;
117
+ }
118
+ __name(stripKnownApiPrefix, "stripKnownApiPrefix");
119
+ function normalizePathname(pathname) {
120
+ return pathname.endsWith("/") ? pathname : `${pathname}/`;
121
+ }
122
+ __name(normalizePathname, "normalizePathname");
123
+ function getAppApiUrl(app) {
124
+ if (!(app == null ? void 0 : app.getApiUrl)) {
125
+ return void 0;
126
+ }
127
+ try {
128
+ return parseUrl(app.getApiUrl(), getCurrentOrigin());
129
+ } catch {
130
+ return void 0;
131
+ }
132
+ }
133
+ __name(getAppApiUrl, "getAppApiUrl");
134
+ function stripConfiguredApiPrefix(path, apiPathname) {
135
+ const cleanPath = stripSearchAndHash(path).trim();
136
+ if (!cleanPath.startsWith("/")) {
137
+ return void 0;
138
+ }
139
+ const apiPath = normalizePathname(apiPathname);
140
+ const requestPath = normalizePathname(cleanPath);
141
+ if (!requestPath.startsWith(apiPath)) {
142
+ return void 0;
143
+ }
144
+ const apiPathWithoutTrailingSlash = apiPath.replace(/\/$/, "");
145
+ return cleanPath.slice(apiPathWithoutTrailingSlash.length).replace(/^\/+/, "") || void 0;
146
+ }
147
+ __name(stripConfiguredApiPrefix, "stripConfiguredApiPrefix");
148
+ function getDirtyResourcePathFromAbsoluteUrl(url, app) {
149
+ if (!["http:", "https:"].includes(url.protocol)) {
150
+ return void 0;
151
+ }
152
+ if (app == null ? void 0 : app.getApiUrl) {
153
+ const apiUrl = getAppApiUrl(app);
154
+ if (!apiUrl || url.origin !== apiUrl.origin) {
155
+ return void 0;
156
+ }
157
+ return stripConfiguredApiPrefix(url.pathname, apiUrl.pathname);
158
+ }
159
+ const currentOrigin = getCurrentOrigin();
160
+ if (!currentOrigin || url.origin !== currentOrigin) {
161
+ return void 0;
162
+ }
163
+ return stripKnownApiPrefix(url.pathname);
164
+ }
165
+ __name(getDirtyResourcePathFromAbsoluteUrl, "getDirtyResourcePathFromAbsoluteUrl");
166
+ function getDirtyResourcePathFromUrl(url, context) {
167
+ if (typeof url !== "string") {
168
+ return void 0;
169
+ }
170
+ const trimmedUrl = url.trim();
171
+ if (!trimmedUrl || trimmedUrl.startsWith("//")) {
172
+ return void 0;
173
+ }
174
+ if (/^https?:\/\//i.test(trimmedUrl)) {
175
+ const parsedUrl = parseUrl(trimmedUrl);
176
+ if (!parsedUrl) {
177
+ return void 0;
178
+ }
179
+ return getDirtyResourcePathFromAbsoluteUrl(parsedUrl, context.app);
180
+ }
181
+ const appApiUrl = getAppApiUrl(context.app);
182
+ const configuredResourcePath = appApiUrl ? stripConfiguredApiPrefix(trimmedUrl, appApiUrl.pathname) : void 0;
183
+ if (configuredResourcePath) {
184
+ return configuredResourcePath;
185
+ }
186
+ return stripKnownApiPrefix(trimmedUrl);
187
+ }
188
+ __name(getDirtyResourcePathFromUrl, "getDirtyResourcePathFromUrl");
189
+ function decodeResourcePathSegment(segment) {
190
+ try {
191
+ return decodeURIComponent(segment);
192
+ } catch {
193
+ return segment;
194
+ }
195
+ }
196
+ __name(decodeResourcePathSegment, "decodeResourcePathSegment");
197
+ function getDataSourceKeyFromResourceOf(resourceOf) {
198
+ const dataSourceKey = String(resourceOf ?? "").trim();
199
+ return dataSourceKey || void 0;
200
+ }
201
+ __name(getDataSourceKeyFromResourceOf, "getDataSourceKeyFromResourceOf");
202
+ function parseResourceActionFromSegments(segments) {
203
+ const resourceSegments = [];
204
+ let actionName;
205
+ let actionSegmentIndex = -1;
206
+ for (let index = 0; index < segments.length; index += 2) {
207
+ const segment = segments[index];
208
+ const actionDelimiterIndex = segment.lastIndexOf(":");
209
+ const resourceSegment = actionDelimiterIndex === -1 ? segment : segment.slice(0, actionDelimiterIndex);
210
+ if (!resourceSegment) {
211
+ return void 0;
212
+ }
213
+ resourceSegments.push(decodeResourcePathSegment(resourceSegment));
214
+ if (actionDelimiterIndex !== -1) {
215
+ actionName = decodeResourcePathSegment(segment.slice(actionDelimiterIndex + 1)).trim();
216
+ actionSegmentIndex = index;
217
+ break;
218
+ }
219
+ }
220
+ if (!actionName || !resourceSegments.length) {
221
+ return void 0;
222
+ }
223
+ if (segments.length > actionSegmentIndex + 2) {
224
+ return void 0;
225
+ }
226
+ return {
227
+ resourceName: resourceSegments.join("."),
228
+ actionName
229
+ };
230
+ }
231
+ __name(parseResourceActionFromSegments, "parseResourceActionFromSegments");
232
+ function parseDirtyResourceActionFromUrl(url, context) {
233
+ const resourcePath = getDirtyResourcePathFromUrl(url, context);
234
+ if (!resourcePath) {
235
+ return void 0;
236
+ }
237
+ const segments = stripSearchAndHash(resourcePath).split("/").filter(Boolean);
238
+ const firstSegment = decodeResourcePathSegment(segments[0] || "");
239
+ if (firstSegment === "dataSources" && segments.length >= 3) {
240
+ const dataSourceKey = getDataSourceKeyFromResourceOf(decodeResourcePathSegment(segments[1]));
241
+ const parsed = parseResourceActionFromSegments(segments.slice(2));
242
+ if (dataSourceKey && parsed) {
243
+ return {
244
+ ...parsed,
245
+ dataSourceKey
246
+ };
247
+ }
248
+ }
249
+ return parseResourceActionFromSegments(segments);
250
+ }
251
+ __name(parseDirtyResourceActionFromUrl, "parseDirtyResourceActionFromUrl");
252
+ function resolveDirtyResourceActionFromResource(resourceName, resourceOf, actionName, context) {
253
+ const normalizedResourceName = resourceName.trim();
254
+ const normalizedActionName = actionName.trim();
255
+ if (!normalizedResourceName || !normalizedActionName) {
256
+ return void 0;
257
+ }
258
+ if (normalizedResourceName.includes("/")) {
259
+ const parsed = parseDirtyResourceActionFromUrl(`${normalizedResourceName}:${normalizedActionName}`, context);
260
+ if (parsed) {
261
+ return parsed;
262
+ }
263
+ }
264
+ const dataSourcesPrefix = "dataSources.";
265
+ if (normalizedResourceName.startsWith(dataSourcesPrefix)) {
266
+ const dataSourceKey = getDataSourceKeyFromResourceOf(resourceOf);
267
+ const nestedResourceName = normalizedResourceName.slice(dataSourcesPrefix.length).trim();
268
+ if (dataSourceKey && nestedResourceName) {
269
+ return {
270
+ dataSourceKey,
271
+ resourceName: nestedResourceName,
272
+ actionName: normalizedActionName
273
+ };
274
+ }
275
+ }
276
+ return {
277
+ resourceName: normalizedResourceName,
278
+ actionName: normalizedActionName
279
+ };
280
+ }
281
+ __name(resolveDirtyResourceActionFromResource, "resolveDirtyResourceActionFromResource");
282
+ function resolveDirtyResourceAction(options, context) {
283
+ const resourceName = typeof (options == null ? void 0 : options.resource) === "string" ? options.resource : void 0;
284
+ const actionName = typeof (options == null ? void 0 : options.action) === "string" ? options.action : void 0;
285
+ if (resourceName && actionName) {
286
+ return resolveDirtyResourceActionFromResource(resourceName, options.resourceOf, actionName, context);
287
+ }
288
+ return parseDirtyResourceActionFromUrl(options == null ? void 0 : options.url, context);
289
+ }
290
+ __name(resolveDirtyResourceAction, "resolveDirtyResourceAction");
291
+ function markResourceActionDataSourceDirty(context, dirtyResourceAction, headers) {
292
+ (0, import_dataSourceDirty.markDataSourceDirty)({
293
+ engine: context.engine,
294
+ dataSourceKey: dirtyResourceAction.dataSourceKey || (0, import_dataSourceDirty.getDataSourceKeyFromHeaders)(headers),
295
+ resourceName: dirtyResourceAction.resourceName,
296
+ includePreviousEngines: true
297
+ });
298
+ }
299
+ __name(markResourceActionDataSourceDirty, "markResourceActionDataSourceDirty");
300
+ function createDirtyAwareResource(context, resource, resourceName, resourceOf, headers) {
301
+ return new Proxy(resource, {
302
+ get(target, prop, receiver) {
303
+ const original = Reflect.get(target, prop, receiver);
304
+ if (typeof prop !== "string" || typeof original !== "function" || !isMutatingResourceAction(prop)) {
305
+ return original;
306
+ }
307
+ const action = original;
308
+ return async (...args) => {
309
+ const result = await action(...args);
310
+ const dirtyResourceAction = resolveDirtyResourceActionFromResource(resourceName, resourceOf, prop, context);
311
+ if (dirtyResourceAction) {
312
+ markResourceActionDataSourceDirty(context, dirtyResourceAction, headers);
313
+ }
314
+ return result;
315
+ };
316
+ }
317
+ });
318
+ }
319
+ __name(createDirtyAwareResource, "createDirtyAwareResource");
320
+ function createDirtyAwareApiClient(api, context) {
321
+ const resource = /* @__PURE__ */ __name((name, of, headers, cancel) => {
322
+ const targetResource = api.resource(name, of, headers, cancel);
323
+ return createDirtyAwareResource(context, targetResource, name, of, headers);
324
+ }, "resource");
325
+ const request = /* @__PURE__ */ __name((config) => {
326
+ const options = config;
327
+ const skipDataSourceDirty = options == null ? void 0 : options[SKIP_DATA_SOURCE_DIRTY];
328
+ const dirtyResourceAction = skipDataSourceDirty ? void 0 : resolveDirtyResourceAction(options, context);
329
+ const { [SKIP_DATA_SOURCE_DIRTY]: _skipDataSourceDirty, ...cleanConfig } = options;
330
+ return api.request(cleanConfig).then((result) => {
331
+ if (dirtyResourceAction && isMutatingResourceAction(dirtyResourceAction.actionName)) {
332
+ markResourceActionDataSourceDirty(context, dirtyResourceAction, options.headers);
333
+ }
334
+ return result;
335
+ });
336
+ }, "request");
337
+ const proxy = new Proxy(api, {
338
+ get(target, prop, receiver) {
339
+ if (prop === "resource") {
340
+ return resource;
341
+ }
342
+ if (prop === "request") {
343
+ return request;
344
+ }
345
+ return Reflect.get(target, prop, receiver);
346
+ }
347
+ });
348
+ dirtyAwareApiClientProxies.add(proxy);
349
+ return proxy;
350
+ }
351
+ __name(createDirtyAwareApiClient, "createDirtyAwareApiClient");
352
+ function getDirtyAwareApiClient(value, context) {
353
+ if (!isApiClientLike(value)) {
354
+ return value;
355
+ }
356
+ if (dirtyAwareApiClientProxies.has(value)) {
357
+ return value;
358
+ }
359
+ const api = value;
360
+ let contextCache = dirtyAwareApiClientCache.get(api);
361
+ if (!contextCache) {
362
+ contextCache = /* @__PURE__ */ new WeakMap();
363
+ dirtyAwareApiClientCache.set(api, contextCache);
364
+ }
365
+ const cached = contextCache.get(context);
366
+ if (cached) {
367
+ return cached;
368
+ }
369
+ const wrapped = createDirtyAwareApiClient(value, context);
370
+ contextCache.set(context, wrapped);
371
+ return wrapped;
372
+ }
373
+ __name(getDirtyAwareApiClient, "getDirtyAwareApiClient");
374
+ // Annotate the CommonJS export names for ESM import in node:
375
+ 0 && (module.exports = {
376
+ SKIP_DATA_SOURCE_DIRTY,
377
+ getDirtyAwareApiClient
378
+ });
@@ -20,8 +20,8 @@ export { buildRecordMeta, collectContextParamsForTemplate, createCurrentRecordMe
20
20
  export { extractPropertyPath, formatPathToVariable, isVariableExpression } from './context';
21
21
  export { clearAutoFlowError, getAutoFlowError, setAutoFlowError, type AutoFlowError } from './autoFlowError';
22
22
  export { parsePathnameToViewParams, type ViewParam } from './parsePathnameToViewParams';
23
+ export { createOpenViewRouteState, decodeOpenViewRouteState, encodeOpenViewRouteState, isOpenViewRouteStateToken, RUNJS_OPEN_VIEW_ROUTE_STATE, type OpenViewRouteMode, type OpenViewRouteSize, type OpenViewRouteState, } from './openViewRouteState';
23
24
  export { decodeBase64Url, encodeBase64Url, isCompleteCtxDatePath, isCtxDatePathPrefix, isCtxDateExpression, parseCtxDateExpression, resolveCtxDatePath, serializeCtxDateValue, } from './dateVariable';
24
- export { createSafeDocument, createSafeWindow, createSafeNavigator, createSafeRunJSGlobals, runjsWithSafeGlobals, } from './safeGlobals';
25
25
  export { isRunJSValue, normalizeRunJSValue, extractUsedVariablePathsFromRunJS, type RunJSValue } from './runjsValue';
26
26
  export { resolveRunJSObjectValues } from './resolveRunJSObjectValues';
27
27
  export { prepareRunJsCode, preprocessRunJsTemplates } from './runjsTemplateCompat';
@@ -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 {};