@nocobase/plugin-flow-engine 3.0.0-alpha.5 → 3.0.0-alpha.7

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 (50) hide show
  1. package/dist/externalVersion.js +9 -9
  2. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  3. package/dist/node_modules/acorn/package.json +1 -1
  4. package/dist/node_modules/acorn-jsx/package.json +1 -1
  5. package/dist/node_modules/acorn-walk/package.json +1 -1
  6. package/dist/node_modules/ses/package.json +1 -1
  7. package/dist/node_modules/zod/package.json +1 -1
  8. package/dist/server/flow-surfaces/builder.js +5 -0
  9. package/dist/server/flow-surfaces/catalog.js +27 -8
  10. package/dist/server/flow-surfaces/configure-options.js +17 -1
  11. package/dist/server/flow-surfaces/service-utils.d.ts +1 -0
  12. package/dist/server/flow-surfaces/service-utils.js +17 -0
  13. package/dist/server/flow-surfaces/service.js +9 -0
  14. package/dist/server/index.d.ts +2 -0
  15. package/dist/server/index.js +7 -0
  16. package/dist/server/plugin.d.ts +11 -0
  17. package/dist/server/plugin.js +85 -3
  18. package/dist/server/repository.d.ts +8 -0
  19. package/dist/server/repository.js +29 -0
  20. package/dist/server/template/context-keys.d.ts +14 -0
  21. package/dist/server/template/context-keys.js +86 -0
  22. package/dist/server/template/contexts.d.ts +5 -8
  23. package/dist/server/template/contexts.js +43 -51
  24. package/dist/server/template/resolver.d.ts +5 -13
  25. package/dist/server/template/resolver.js +188 -257
  26. package/dist/server/template/variable-expression.d.ts +72 -0
  27. package/dist/server/template/variable-expression.js +597 -0
  28. package/dist/server/variables/allow-list.d.ts +48 -0
  29. package/dist/server/variables/allow-list.js +374 -0
  30. package/dist/server/variables/form-item-record-slot-resolvers.d.ts +10 -0
  31. package/dist/server/variables/form-item-record-slot-resolvers.js +280 -0
  32. package/dist/server/variables/record-bindings.d.ts +42 -0
  33. package/dist/server/variables/record-bindings.js +196 -0
  34. package/dist/server/variables/record-projection.d.ts +10 -0
  35. package/dist/server/variables/record-projection.js +140 -0
  36. package/dist/server/variables/record-slot-policy.d.ts +23 -0
  37. package/dist/server/variables/record-slot-policy.js +100 -0
  38. package/dist/server/variables/record-slot-resolvers.d.ts +46 -0
  39. package/dist/server/variables/record-slot-resolvers.js +115 -0
  40. package/dist/server/variables/records.d.ts +47 -1
  41. package/dist/server/variables/records.js +279 -5
  42. package/dist/server/variables/registry.d.ts +33 -10
  43. package/dist/server/variables/registry.js +197 -362
  44. package/dist/server/variables/resolve.d.ts +18 -2
  45. package/dist/server/variables/resolve.js +79 -13
  46. package/dist/server/variables/runjs-variable-dependencies.d.ts +21 -0
  47. package/dist/server/variables/runjs-variable-dependencies.js +313 -0
  48. package/dist/server/variables/utils.d.ts +3 -6
  49. package/dist/server/variables/utils.js +50 -111
  50. package/package.json +2 -2
@@ -0,0 +1,48 @@
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 { ResourcerContext } from '@nocobase/resourcer';
10
+ import { type FlowModelNodeSnapshot } from '../repository';
11
+ import { type AnalyzeTemplateMode, type AnalyzedTemplate, type ResolvePathPolicy } from '../template/variable-expression';
12
+ import type { JSONValue } from '../template/resolver';
13
+ import { type RecordBindingPlan } from './record-bindings';
14
+ import { type RecordSlotPolicies } from './record-slot-policy';
15
+ type AuthorizationResultBase = {
16
+ contextParams: Readonly<Record<string, unknown>>;
17
+ flowModelUid?: string;
18
+ policy: ResolvePathPolicy;
19
+ recordSlotPolicies: RecordSlotPolicies;
20
+ };
21
+ export type AuthorizationResult = AuthorizationResultBase & ({
22
+ allowed: true;
23
+ analysis: AnalyzedTemplate;
24
+ bindingPlan: RecordBindingPlan;
25
+ } | {
26
+ allowed: false;
27
+ analysis?: AnalyzedTemplate;
28
+ });
29
+ export type TemplateAnalysisResult = {
30
+ ok: true;
31
+ analysis: AnalyzedTemplate;
32
+ } | {
33
+ ok: false;
34
+ errorType: string;
35
+ };
36
+ export declare function analyzeVariableTemplateSafely(template: unknown, options?: Readonly<{
37
+ mode?: AnalyzeTemplateMode;
38
+ }>): TemplateAnalysisResult;
39
+ export declare function clearVariableAllowListCache(app?: object): object;
40
+ export declare function hasRecordContextParams(value: unknown): boolean;
41
+ export declare function sanitizeContextParams(value?: Record<string, unknown>): Record<string, unknown>;
42
+ export declare function resolveFlowModelNodeFromRequestRd(ctx: ResourcerContext, rd?: string | number): Promise<FlowModelNodeSnapshot>;
43
+ export declare function authorizeVariablesResolve(ctx: ResourcerContext, options: {
44
+ contextParams?: Record<string, unknown>;
45
+ rd?: string | number;
46
+ template: JSONValue;
47
+ }): Promise<AuthorizationResult>;
48
+ export {};
@@ -0,0 +1,374 @@
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 __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var allow_list_exports = {};
28
+ __export(allow_list_exports, {
29
+ analyzeVariableTemplateSafely: () => analyzeVariableTemplateSafely,
30
+ authorizeVariablesResolve: () => authorizeVariablesResolve,
31
+ clearVariableAllowListCache: () => clearVariableAllowListCache,
32
+ hasRecordContextParams: () => hasRecordContextParams,
33
+ resolveFlowModelNodeFromRequestRd: () => resolveFlowModelNodeFromRequestRd,
34
+ sanitizeContextParams: () => sanitizeContextParams
35
+ });
36
+ module.exports = __toCommonJS(allow_list_exports);
37
+ var import_utils = require("@nocobase/utils");
38
+ var import_variable_expression = require("../template/variable-expression");
39
+ var import_record_bindings = require("./record-bindings");
40
+ var import_record_slot_policy = require("./record-slot-policy");
41
+ var import_registry = require("./registry");
42
+ var import_runjs_variable_dependencies = require("./runjs-variable-dependencies");
43
+ function analyzeVariableTemplateSafely(template, options = {}) {
44
+ let analysis;
45
+ try {
46
+ analysis = (0, import_variable_expression.analyzeVariableTemplate)(template, options);
47
+ } catch (error) {
48
+ return { ok: false, errorType: error instanceof Error ? error.name : typeof error };
49
+ }
50
+ return { ok: true, analysis };
51
+ }
52
+ const MAX_FLOW_MODEL_ANCESTORS = 64;
53
+ function clearVariableAllowListCache(app) {
54
+ return app;
55
+ }
56
+ function isObject(value) {
57
+ return !!value && typeof value === "object" && !Array.isArray(value);
58
+ }
59
+ function isRecordParams(value) {
60
+ return isObject(value) && typeof value.collection === "string" && Object.prototype.hasOwnProperty.call(value, "filterByTk") && (typeof value.dataSourceKey === "undefined" || typeof value.dataSourceKey === "string") && (typeof value.associationName === "undefined" || typeof value.associationName === "string") && (typeof value.fields === "undefined" || Array.isArray(value.fields) && value.fields.every((field) => typeof field === "string")) && (typeof value.appends === "undefined" || Array.isArray(value.appends) && value.appends.every((append) => typeof append === "string"));
61
+ }
62
+ function hasRecordContextParams(value) {
63
+ if (isRecordParams(value)) return true;
64
+ if (Array.isArray(value)) return value.some((item) => hasRecordContextParams(item));
65
+ if (!isObject(value)) return false;
66
+ return Object.values(value).some((item) => hasRecordContextParams(item));
67
+ }
68
+ function sanitizeContextParams(value = {}) {
69
+ const sanitizeStringArray = (input) => Array.isArray(input) && input.every((item) => typeof item === "string") ? input : void 0;
70
+ const sanitize = (input) => {
71
+ if (isRecordParams(input)) {
72
+ const { associationName, collection, filterByTk, dataSourceKey, sourceId } = input;
73
+ const fields = sanitizeStringArray(input.fields);
74
+ const appends = sanitizeStringArray(input.appends);
75
+ return {
76
+ associationName,
77
+ collection,
78
+ filterByTk,
79
+ dataSourceKey,
80
+ sourceId,
81
+ ...fields ? { fields } : {},
82
+ ...appends ? { appends } : {}
83
+ };
84
+ }
85
+ if (Array.isArray(input)) return input.map((item) => sanitize(item));
86
+ if (!isObject(input)) return input;
87
+ const output = {};
88
+ for (const [key, child] of Object.entries(input)) output[key] = sanitize(child);
89
+ return output;
90
+ };
91
+ return sanitize(value);
92
+ }
93
+ function getRequestState(ctx) {
94
+ const request = ctx;
95
+ if (!request.state) request.state = {};
96
+ return request.state;
97
+ }
98
+ function getFlowModelRepository(ctx) {
99
+ return ctx.db.getCollection("flowModels").repository;
100
+ }
101
+ async function getFlowModelNode(ctx, flowModelUid) {
102
+ const state = getRequestState(ctx);
103
+ const cacheKey = "__variableResolveFlowModelCache";
104
+ const cache = state[cacheKey] || /* @__PURE__ */ new Map();
105
+ state[cacheKey] = cache;
106
+ if (cache.has(flowModelUid)) return await cache.get(flowModelUid) || null;
107
+ const load = getFlowModelRepository(ctx).findModelNodeSnapshotById(flowModelUid);
108
+ cache.set(flowModelUid, load);
109
+ const model = await load;
110
+ cache.set(flowModelUid, model);
111
+ return model;
112
+ }
113
+ async function loadFlowModelAncestors(ctx, currentNode) {
114
+ const ancestors = [];
115
+ const seen = /* @__PURE__ */ new Set([currentNode.uid]);
116
+ let parentId = currentNode.parentId;
117
+ while (parentId) {
118
+ if (seen.has(parentId) || ancestors.length >= MAX_FLOW_MODEL_ANCESTORS) {
119
+ throw new Error("Invalid FlowModel ancestor chain");
120
+ }
121
+ seen.add(parentId);
122
+ const parent = await getFlowModelNode(ctx, parentId);
123
+ if (!parent) throw new Error("Missing FlowModel ancestor");
124
+ ancestors.push(parent);
125
+ parentId = parent.parentId;
126
+ }
127
+ return Object.freeze(ancestors);
128
+ }
129
+ function createRecordSlotCompilerOptions(ctx, currentNode) {
130
+ let ancestors;
131
+ return {
132
+ app: ctx.app,
133
+ ctx,
134
+ currentNode,
135
+ getCollection: (dataSourceKey, collection) => {
136
+ var _a, _b, _c;
137
+ return dataSourceKey === "main" ? ctx.db.getCollection(collection) : (_c = (_b = (_a = ctx.app.dataSourceManager.get(dataSourceKey)) == null ? void 0 : _a.collectionManager) == null ? void 0 : _b.getCollection) == null ? void 0 : _c.call(_b, collection);
138
+ },
139
+ loadAncestors: currentNode ? () => {
140
+ ancestors ||= loadFlowModelAncestors(ctx, currentNode);
141
+ return ancestors;
142
+ } : void 0
143
+ };
144
+ }
145
+ async function getFlowModelVariableContract(ctx, flowModelUid) {
146
+ const state = getRequestState(ctx);
147
+ const cacheKey = "__variableResolveContractCache";
148
+ const cache = state[cacheKey] || /* @__PURE__ */ new Map();
149
+ state[cacheKey] = cache;
150
+ if (cache.has(flowModelUid)) return await cache.get(flowModelUid) || null;
151
+ const load = createFlowModelVariableContractFromNode(ctx, flowModelUid);
152
+ cache.set(flowModelUid, load);
153
+ const contract = await load;
154
+ cache.set(flowModelUid, contract);
155
+ return contract;
156
+ }
157
+ async function createFlowModelVariableContractFromNode(ctx, flowModelUid) {
158
+ const node = await getFlowModelNode(ctx, flowModelUid);
159
+ if (!node) return null;
160
+ const prepared = (0, import_runjs_variable_dependencies.prepareFlowModelVariableSource)(node.options);
161
+ const contractSource = prepared.ok ? prepared.runJsTemplates.length ? [prepared.templateSource, ...prepared.runJsTemplates] : prepared.templateSource : {};
162
+ const result = analyzeVariableTemplateSafely(contractSource, { mode: "flow-model" });
163
+ const analysis = result.ok ? result.analysis : (0, import_variable_expression.analyzeVariableTemplate)({}, { mode: "flow-model" });
164
+ return await (0, import_record_slot_policy.createFlowModelVariableContract)(analysis, createRecordSlotCompilerOptions(ctx, node));
165
+ }
166
+ function getCurrentRoleNames(ctx) {
167
+ const state = ctx.state;
168
+ const roleNames = /* @__PURE__ */ new Set();
169
+ const currentRoles = state == null ? void 0 : state.currentRoles;
170
+ if (Array.isArray(currentRoles)) {
171
+ currentRoles.forEach((roleName) => {
172
+ if (typeof roleName === "string" && roleName) roleNames.add(roleName);
173
+ });
174
+ }
175
+ if (typeof (state == null ? void 0 : state.currentRole) === "string" && state.currentRole) roleNames.add(state.currentRole);
176
+ return Array.from(roleNames);
177
+ }
178
+ async function readCurrentRoleAllowsConfigure(ctx) {
179
+ const roleNames = getCurrentRoleNames(ctx);
180
+ if (!roleNames.length) return false;
181
+ if (roleNames.includes("root")) return true;
182
+ const acl = ctx.app.acl;
183
+ if (roleNames.some((roleName) => {
184
+ var _a, _b, _c, _d;
185
+ return ((_d = (_c = (_b = (_a = acl == null ? void 0 : acl.getRole) == null ? void 0 : _a.call(acl, roleName)) == null ? void 0 : _b.getStrategy) == null ? void 0 : _c.call(_b)) == null ? void 0 : _d.allowConfigure) === true;
186
+ })) return true;
187
+ const roles = await ctx.db.getRepository("roles").find({
188
+ filter: { name: roleNames },
189
+ fields: ["name", "allowConfigure"]
190
+ });
191
+ return roles.some(
192
+ (role) => typeof (role == null ? void 0 : role.get) === "function" ? role.get("allowConfigure") === true : (role == null ? void 0 : role.allowConfigure) === true
193
+ );
194
+ }
195
+ async function currentRoleAllowsConfigure(ctx) {
196
+ const state = getRequestState(ctx);
197
+ const cacheKey = "__variableResolveRoleAllowsConfigure";
198
+ const cached = state[cacheKey];
199
+ if (typeof cached === "boolean") return cached;
200
+ if (cached instanceof Promise) return await cached;
201
+ const pending = readCurrentRoleAllowsConfigure(ctx);
202
+ state[cacheKey] = pending;
203
+ const allowed = await pending;
204
+ state[cacheKey] = allowed;
205
+ return allowed;
206
+ }
207
+ function getRequestBearerToken(ctx) {
208
+ var _a, _b;
209
+ const contextWithBearerToken = ctx;
210
+ const token = (_a = contextWithBearerToken.getBearerToken) == null ? void 0 : _a.call(contextWithBearerToken);
211
+ if (token) return token;
212
+ const authorization = typeof ctx.get === "function" ? ctx.get("authorization") || ctx.get("Authorization") : void 0;
213
+ if (typeof authorization !== "string") return "";
214
+ return ((_b = authorization.match(/^Bearer\s+(.+)$/i)) == null ? void 0 : _b[1]) || "";
215
+ }
216
+ function getCurrentRequestRdSessionId(ctx) {
217
+ const state = getRequestState(ctx);
218
+ const cacheKey = "__variableResolveRdSessionId";
219
+ const cached = state[cacheKey];
220
+ if (typeof cached === "string") return cached;
221
+ const sessionId = (0, import_utils.getFlowModelRdSessionId)((0, import_utils.decodeJwtSessionPayload)(getRequestBearerToken(ctx)));
222
+ state[cacheKey] = sessionId;
223
+ return sessionId;
224
+ }
225
+ function resolveFlowModelUidFromRequestRd(ctx, rd) {
226
+ if (typeof rd !== "string" || !rd) return "";
227
+ const state = getRequestState(ctx);
228
+ const cacheKey = "__variableResolveRdUidCache";
229
+ const cache = state[cacheKey] || /* @__PURE__ */ new Map();
230
+ state[cacheKey] = cache;
231
+ if (cache.has(rd)) return cache.get(rd) || "";
232
+ const flowModelUid = (0, import_utils.resolveFlowModelUidFromRd)(rd, getCurrentRequestRdSessionId(ctx)) || "";
233
+ cache.set(rd, flowModelUid);
234
+ return flowModelUid;
235
+ }
236
+ async function resolveFlowModelNodeFromRequestRd(ctx, rd) {
237
+ const flowModelUid = resolveFlowModelUidFromRequestRd(ctx, rd);
238
+ return flowModelUid ? getFlowModelNode(ctx, flowModelUid) : null;
239
+ }
240
+ function createPolicy(allowAll = false, allowedPaths = /* @__PURE__ */ new Set(), unrestrictedVariables = /* @__PURE__ */ new Set()) {
241
+ return { allowAll, allowedPaths, unrestrictedVariables };
242
+ }
243
+ function denied(analysis, contextParams, policy, recordSlotPolicies, flowModelUid) {
244
+ return { allowed: false, analysis, contextParams, flowModelUid, policy, recordSlotPolicies };
245
+ }
246
+ async function createRecordBindingPlan(ctx, contextParams, usage, recordSlotPolicies) {
247
+ return await (0, import_record_bindings.planRecordBindings)({ contextParams, koaCtx: ctx, policies: recordSlotPolicies, usage });
248
+ }
249
+ function recordBindingPlanAllowed(plan) {
250
+ return plan.rejections.length === 0 && plan.bindings.every(import_registry.isSafeRecordBinding);
251
+ }
252
+ async function authorizeVariablesResolve(ctx, options) {
253
+ var _a;
254
+ let contextParams = sanitizeContextParams(options.contextParams || {});
255
+ const flowModelUid = resolveFlowModelUidFromRequestRd(ctx, options.rd);
256
+ const unrestrictedVariables = /* @__PURE__ */ new Set();
257
+ let policy = createPolicy(false, /* @__PURE__ */ new Set(), unrestrictedVariables);
258
+ let recordSlotPolicies = /* @__PURE__ */ new Map();
259
+ const result = analyzeVariableTemplateSafely(options.template, { mode: "untrusted-request" });
260
+ if (!result.ok) {
261
+ contextParams = sanitizeContextParams((0, import_registry.sanitizeRegisteredVariableContextParams)(contextParams));
262
+ return {
263
+ allowed: false,
264
+ contextParams: (await createRecordBindingPlan(ctx, contextParams, {})).contextParams,
265
+ flowModelUid: flowModelUid || void 0,
266
+ policy,
267
+ recordSlotPolicies
268
+ };
269
+ }
270
+ const { analysis } = result;
271
+ if (!analysis.supported) {
272
+ contextParams = sanitizeContextParams((0, import_registry.sanitizeRegisteredVariableContextParams)(contextParams));
273
+ return denied(
274
+ analysis,
275
+ (await createRecordBindingPlan(ctx, contextParams, analysis.usage)).contextParams,
276
+ policy,
277
+ recordSlotPolicies,
278
+ flowModelUid || void 0
279
+ );
280
+ }
281
+ const flowModelRequiredVars = /* @__PURE__ */ new Set();
282
+ for (const [varName, usedPaths] of Object.entries(analysis.usage)) {
283
+ const def = import_registry.variables.get(varName);
284
+ const validation = await ((_a = def == null ? void 0 : def.validateContextParams) == null ? void 0 : _a.call(def, {
285
+ contextParams,
286
+ flowModelUid: flowModelUid || void 0,
287
+ koaCtx: ctx,
288
+ usage: usedPaths,
289
+ varName
290
+ })) || {};
291
+ contextParams = sanitizeContextParams((validation == null ? void 0 : validation.contextParams) || contextParams);
292
+ if ((validation == null ? void 0 : validation.allowed) === false) {
293
+ contextParams = sanitizeContextParams((0, import_registry.sanitizeRegisteredVariableContextParams)(contextParams));
294
+ return denied(
295
+ analysis,
296
+ (await createRecordBindingPlan(ctx, contextParams, analysis.usage)).contextParams,
297
+ policy,
298
+ recordSlotPolicies,
299
+ flowModelUid || void 0
300
+ );
301
+ }
302
+ if ((validation == null ? void 0 : validation.requireFlowModel) === false) unrestrictedVariables.add(varName);
303
+ else flowModelRequiredVars.add(varName);
304
+ }
305
+ contextParams = sanitizeContextParams((0, import_registry.sanitizeRegisteredVariableContextParams)(contextParams));
306
+ let bindingPlan = await createRecordBindingPlan(ctx, contextParams, analysis.usage);
307
+ const configureRole = await currentRoleAllowsConfigure(ctx);
308
+ const currentNode = flowModelUid ? await getFlowModelNode(ctx, flowModelUid) : null;
309
+ if (configureRole) {
310
+ policy = createPolicy(true, /* @__PURE__ */ new Set(), unrestrictedVariables);
311
+ recordSlotPolicies = await (0, import_record_slot_policy.compileRecordSlotPolicies)(
312
+ analysis,
313
+ createRecordSlotCompilerOptions(ctx, currentNode || void 0)
314
+ );
315
+ bindingPlan = await createRecordBindingPlan(ctx, contextParams, analysis.usage, recordSlotPolicies);
316
+ return recordBindingPlanAllowed(bindingPlan) ? {
317
+ allowed: true,
318
+ analysis,
319
+ bindingPlan,
320
+ contextParams: bindingPlan.contextParams,
321
+ ...currentNode ? { flowModelUid: currentNode.uid } : {},
322
+ policy,
323
+ recordSlotPolicies
324
+ } : denied(analysis, bindingPlan.contextParams, policy, recordSlotPolicies, flowModelUid || void 0);
325
+ }
326
+ if (flowModelRequiredVars.size > 0 && !flowModelUid) {
327
+ return denied(analysis, bindingPlan.contextParams, policy, recordSlotPolicies);
328
+ }
329
+ const contract = flowModelUid ? await getFlowModelVariableContract(ctx, flowModelUid) : null;
330
+ const allowedPaths = (contract == null ? void 0 : contract.allowedPaths) || null;
331
+ recordSlotPolicies = (contract == null ? void 0 : contract.recordSlots) || /* @__PURE__ */ new Map();
332
+ policy = createPolicy(false, allowedPaths || /* @__PURE__ */ new Set(), unrestrictedVariables);
333
+ if (flowModelRequiredVars.size > 0 && !allowedPaths) {
334
+ return denied(analysis, bindingPlan.contextParams, policy, recordSlotPolicies, flowModelUid || void 0);
335
+ }
336
+ for (const path of analysis.paths) {
337
+ if (unrestrictedVariables.has(path.varName)) continue;
338
+ if (!(allowedPaths == null ? void 0 : allowedPaths.has(path.canonicalKey))) {
339
+ return denied(analysis, bindingPlan.contextParams, policy, recordSlotPolicies, flowModelUid || void 0);
340
+ }
341
+ }
342
+ if (unrestrictedVariables.size) {
343
+ const requestPolicies = await (0, import_record_slot_policy.compileRecordSlotPolicies)(
344
+ analysis,
345
+ createRecordSlotCompilerOptions(ctx, currentNode || void 0)
346
+ );
347
+ const mergedPolicies = new Map(recordSlotPolicies);
348
+ for (const path of analysis.paths) {
349
+ if (!unrestrictedVariables.has(path.varName)) continue;
350
+ const requestPolicy = requestPolicies.get(path.canonicalKey);
351
+ if (requestPolicy) mergedPolicies.set(path.canonicalKey, requestPolicy);
352
+ }
353
+ recordSlotPolicies = mergedPolicies;
354
+ }
355
+ bindingPlan = await createRecordBindingPlan(ctx, contextParams, analysis.usage, recordSlotPolicies);
356
+ return recordBindingPlanAllowed(bindingPlan) ? {
357
+ allowed: true,
358
+ analysis,
359
+ bindingPlan,
360
+ contextParams: bindingPlan.contextParams,
361
+ flowModelUid: flowModelUid || void 0,
362
+ policy,
363
+ recordSlotPolicies
364
+ } : denied(analysis, bindingPlan.contextParams, policy, recordSlotPolicies, flowModelUid || void 0);
365
+ }
366
+ // Annotate the CommonJS export names for ESM import in node:
367
+ 0 && (module.exports = {
368
+ analyzeVariableTemplateSafely,
369
+ authorizeVariablesResolve,
370
+ clearVariableAllowListCache,
371
+ hasRecordContextParams,
372
+ resolveFlowModelNodeFromRequestRd,
373
+ sanitizeContextParams
374
+ });
@@ -0,0 +1,10 @@
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 { RecordSlotResolverRegistration } from './record-slot-resolvers';
10
+ export declare function createFormItemRecordSlotResolvers(): readonly RecordSlotResolverRegistration[];