UNPKG

@nocobase/flow-engine

Version:

A standalone flow engine for NocoBase, managing workflows, models, and actions.

1,256 lines (1,255 loc) 51.4 kB
/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __typeError = (msg) => { throw TypeError(msg); }; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg); var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj)); var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value); var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value); var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method); var flowContext_exports = {}; __export(flowContext_exports, { FlowContext: () => FlowContext, FlowEngineContext: () => FlowEngineContext, FlowForkModelContext: () => FlowForkModelContext, FlowModelContext: () => FlowModelContext, FlowRunjsContext: () => FlowRunjsContext, FlowRuntimeContext: () => FlowRuntimeContext }); module.exports = __toCommonJS(flowContext_exports); var import_reactive = require("@formily/reactive"); var antd = __toESM(require("antd")); var import_lodash = __toESM(require("lodash")); var import_qs = __toESM(require("qs")); var import_react = __toESM(require("react")); var import_Acl = require("./acl/Acl"); var import_ContextPathProxy = require("./ContextPathProxy"); var import_data_source = require("./data-source"); var import_flowEngine = require("./flowEngine"); var import_flowI18n = require("./flowI18n"); var import_JSRunner = require("./JSRunner"); var import_models = require("./models"); var import_resources = require("./resources"); var import_utils = require("./utils"); var import_exceptions = require("./utils/exceptions"); var import_params_resolvers = require("./utils/params-resolvers"); var import_serverContextParams = require("./utils/serverContextParams"); var _proxy, _FlowContext_instances, createChildNodes_fn, findMetaByPath_fn, findMetaInDelegatesDeep_fn, findMetaInProperty_fn, resolvePathInMeta_fn, resolvePathInMetaAsync_fn, buildParentTitles_fn, toTreeNode_fn; function isRecordRefLike(val) { return !!(val && typeof val === "object" && "collection" in val && "filterByTk" in val); } __name(isRecordRefLike, "isRecordRefLike"); function filterBuilderOutputByPaths(built, neededPaths) { if (!neededPaths || neededPaths.length === 0) return void 0; if (isRecordRefLike(built)) return built; if (built && typeof built === "object" && !Array.isArray(built)) { const out = {}; for (const [k, v] of Object.entries(built)) { const hit = neededPaths.some((p) => p === k || p.startsWith(`${k}.`) || p.startsWith(`${k}[`)); if (hit) out[k] = v; } return out; } return void 0; } __name(filterBuilderOutputByPaths, "filterBuilderOutputByPaths"); const _FlowContext = class _FlowContext { constructor() { __privateAdd(this, _FlowContext_instances); __publicField(this, "_props", {}); __publicField(this, "_methods", {}); __publicField(this, "_cache", {}); __publicField(this, "_observableCache", import_reactive.observable.shallow({})); __publicField(this, "_delegates", []); __publicField(this, "_pending", {}); __privateAdd(this, _proxy, null); __publicField(this, "_metaNodeCache", /* @__PURE__ */ new WeakMap()); return this.createProxy(); } createProxy() { if (__privateGet(this, _proxy)) { return __privateGet(this, _proxy); } __privateSet(this, _proxy, new Proxy(this, { get: /* @__PURE__ */ __name((target, key, receiver) => { if (typeof key === "string") { if (Reflect.has(target, key)) { const val = Reflect.get(target, key, receiver); if (typeof val === "function") return val.bind(target); return val; } if (Object.prototype.hasOwnProperty.call(target._props, key)) { return target._getOwnProperty(key, this.createProxy()); } if (Object.prototype.hasOwnProperty.call(target._methods, key)) { return target._getOwnMethod(key, this.createProxy()); } const found = this._findInDelegates(target._delegates, key); if (found !== void 0) return found.result; return void 0; } return Reflect.get(target, key, receiver); }, "get"), has: /* @__PURE__ */ __name((target, key) => { if (typeof key === "string") { if (Reflect.has(target, key)) return true; if (Object.prototype.hasOwnProperty.call(target._props, key)) return true; if (Object.prototype.hasOwnProperty.call(target._methods, key)) return true; if (this._hasInDelegates(target._delegates, key)) return true; } return Reflect.has(target, key); }, "has") })); return __privateGet(this, _proxy); } defineProperty(key, options) { var _a; if (this._props[key] && ((_a = this._props[key]) == null ? void 0 : _a.once)) { return; } const oldOptions = this._props[key]; if (oldOptions == null ? void 0 : oldOptions.meta) { this._clearMetaNodeCacheFor(oldOptions.meta); } this._props[key] = options; delete this._observableCache[key]; delete this._cache[key]; Object.defineProperty(this, key, { configurable: true, enumerable: true, get: /* @__PURE__ */ __name(() => this._getOwnProperty(key, this.createProxy()), "get") }); } defineMethod(name, fn, des) { this._methods[name] = fn; Object.defineProperty(this, name, { configurable: true, enumerable: false, writable: false, value: fn.bind(this.createProxy()) }); } removeCache(key) { if (key in this._observableCache) { delete this._observableCache[key]; return true; } if (key in this._cache) { delete this._cache[key]; return true; } if (key in this._pending) { delete this._pending[key]; return true; } for (const delegate of this._delegates) { if (delegate.removeCache(key)) { return true; } } } delegate(ctx) { if (!(ctx instanceof _FlowContext)) { throw new Error("Delegate must be an instance of FlowContext"); } if (this._delegates.includes(ctx)) { console.warn(`[FlowContext] delegate - skip duplicate delegate: ${this._delegates.length}`); return; } this._delegates.unshift(ctx); } addDelegate(ctx) { if (!(ctx instanceof _FlowContext)) { throw new Error("Delegate must be an instance of FlowContext"); } if (!this._delegates.includes(ctx)) { this._delegates.unshift(ctx); } } clearDelegates() { this._delegates = []; this._metaNodeCache = /* @__PURE__ */ new WeakMap(); } removeDelegate(ctx) { if (!(ctx instanceof _FlowContext)) { throw new Error("Delegate must be an instance of FlowContext"); } const index = this._delegates.indexOf(ctx); if (index !== -1) { this._delegates.splice(index, 1); } } /** * 清除特定 meta 对象的缓存 */ _clearMetaNodeCacheFor(meta) { this._metaNodeCache.delete(meta); } has(key) { return !!this._props[key]; } /** * 获取属性元数据树 * 返回的 MetaTreeNode 中可能包含异步的延迟加载逻辑 * @param value 可选参数,指定要获取的属性路径,格式: "{{ ctx.propertyName }}" * @returns MetaTreeNode[] 根级属性的元数据树,或指定路径的子树 * * @example * // 同步调用,获取完整 meta tree * const metaTree = flowContext.getPropertyMetaTree(); * * // 获取指定属性的子树 * const subTree = flowContext.getPropertyMetaTree("{{ ctx.user }}"); * * // 获取多层级属性的子树 * const profileTree = flowContext.getPropertyMetaTree("{{ ctx.user.profile }}"); */ getPropertyMetaTree(value, options) { const metaMap = this._getPropertiesMeta(); if (value) { const propertyPath = (0, import_utils.extractPropertyPath)(value); if (propertyPath && propertyPath.length > 0) { const loadChildrenFrom = /* @__PURE__ */ __name(async (metaOrFactory, fullPath, finalKey) => { try { const meta = typeof metaOrFactory === "function" ? await metaOrFactory() : metaOrFactory; if (!(meta == null ? void 0 : meta.properties)) return []; let props = meta.properties; if (typeof props === "function") { const resolved = await props(); meta.properties = resolved; props = resolved; } const childNodes = __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, props, fullPath, [], meta); return Array.isArray(childNodes) ? childNodes : await childNodes(); } catch (error) { console.warn(`Failed to load meta for ${finalKey}:`, error); return []; } }, "loadChildrenFrom"); const targetMeta = __privateMethod(this, _FlowContext_instances, findMetaByPath_fn).call(this, propertyPath); if (targetMeta) { const [finalKey, metaOrFactory, fullPath] = targetMeta; const depth = propertyPath.length; if (depth === 1) { if (typeof metaOrFactory === "function") { return () => loadChildrenFrom(metaOrFactory, fullPath, finalKey); } if (metaOrFactory.properties) { if (typeof metaOrFactory.properties === "function") { return () => loadChildrenFrom(metaOrFactory, fullPath, finalKey); } const childNodes = __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, metaOrFactory.properties, fullPath, [], metaOrFactory); return Array.isArray(childNodes) ? childNodes : []; } return []; } if (typeof metaOrFactory === "function") { if (options == null ? void 0 : options.flatten) { return () => loadChildrenFrom(metaOrFactory, fullPath, finalKey); } const parentTitles = __privateMethod(this, _FlowContext_instances, buildParentTitles_fn).call(this, fullPath); return [__privateMethod(this, _FlowContext_instances, toTreeNode_fn).call(this, finalKey, metaOrFactory, fullPath, parentTitles)]; } if (metaOrFactory.properties) { const parentTitles = [...__privateMethod(this, _FlowContext_instances, buildParentTitles_fn).call(this, fullPath), metaOrFactory.title]; const childNodes = __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, metaOrFactory.properties, fullPath, parentTitles, metaOrFactory); return Array.isArray(childNodes) ? childNodes : []; } return []; } return []; } else if (propertyPath === null) { console.warn( `[FlowContext] getPropertyMetaTree - unsupported value format: "${value}". Only "{{ ctx.propertyName }}" format is supported. Returning empty meta tree.` ); return []; } } const sorted = Object.entries(metaMap).sort(([, a], [, b]) => { const sa = (typeof a === "function" ? a.sort : a == null ? void 0 : a.sort) ?? 0; const sb = (typeof b === "function" ? b.sort : b == null ? void 0 : b.sort) ?? 0; return sb - sa; }); return sorted.map(([key, metaOrFactory]) => __privateMethod(this, _FlowContext_instances, toTreeNode_fn).call(this, key, metaOrFactory, [key], [])); } _getPropertiesMeta() { const metaMap = {}; for (const delegate of this._delegates) { Object.assign(metaMap, delegate._getPropertiesMeta()); } for (const [key, options] of Object.entries(this._props)) { if (options.meta) { metaMap[key] = typeof options.meta === "function" ? options.meta : options.meta; } } return metaMap; } // 只查找自身 _props _getOwnProperty(key, currentContext) { const options = this._props[key]; if (!options) return void 0; if ("value" in options) { return options.value; } if (options.get) { if (options.cache === false) { return options.get(currentContext); } const cacheKey = options.observable ? "_observableCache" : "_cache"; if (key in this[cacheKey]) { return this[cacheKey][key]; } if (this._pending[key]) return this._pending[key]; const result = options.get(this.createProxy()); const isPromise = typeof result === "object" && result !== null && typeof result.then === "function" || typeof result === "function" && typeof result.then === "function"; if (isPromise) { this._pending[key] = result.then( (v) => { this[cacheKey][key] = v; delete this._pending[key]; return v; }, (err) => { delete this._pending[key]; throw err; } ); return this._pending[key]; } this[cacheKey][key] = result; return result; } return void 0; } // 只查找自身 _methods _getOwnMethod(key, flowContext) { const fn = this._methods[key]; if (typeof fn === "function") { return fn.bind(flowContext); } return fn; } _findPropertyInDelegates(delegates, key) { for (const delegate of delegates) { if (Object.prototype.hasOwnProperty.call(delegate._props, key)) { return delegate._props[key]; } const found = this._findPropertyInDelegates(delegate._delegates, key); if (found !== void 0) return found; } return void 0; } _findInDelegates(delegates, key) { for (const delegate of delegates) { if (Object.prototype.hasOwnProperty.call(delegate._props, key)) { return { result: delegate._getOwnProperty(key, this.createProxy()) }; } if (Object.prototype.hasOwnProperty.call(delegate._methods, key)) { return { result: delegate._getOwnMethod(key, this.createProxy()) }; } const found = this._findInDelegates(delegate._delegates, key); if (found !== void 0) return found; } return void 0; } // 递归查找委托链 _hasInDelegates(delegates, key) { for (const delegate of delegates) { if (Object.prototype.hasOwnProperty.call(delegate._props, key)) return true; if (Object.prototype.hasOwnProperty.call(delegate._methods, key)) return true; if (this._hasInDelegates(delegate._delegates, key)) return true; } return false; } /** * 获取属性定义选项(包含代理链)。 * * - 优先查找当前上下文自身通过 defineProperty 注册的属性定义 * - 若自身不存在,则沿委托链(delegates)向上查找第一个命中的定义 * * @param key 顶层属性名(例如 'user'、'view') * @returns 属性定义选项,或 undefined(未定义) */ getPropertyOptions(key) { if (Object.prototype.hasOwnProperty.call(this._props, key)) { return this._props[key]; } return this._findPropertyInDelegates(this._delegates, key); } }; _proxy = new WeakMap(); _FlowContext_instances = new WeakSet(); createChildNodes_fn = /* @__PURE__ */ __name(function(properties, parentPaths = [], parentTitles = [], parentMeta) { return typeof properties === "function" ? async () => { const resolved = await properties(); if (parentMeta) { parentMeta.properties = resolved; } const entries = Object.entries(resolved); entries.sort(([, a], [, b]) => ((b == null ? void 0 : b.sort) ?? 0) - ((a == null ? void 0 : a.sort) ?? 0)); return entries.map(([name, meta]) => __privateMethod(this, _FlowContext_instances, toTreeNode_fn).call(this, name, meta, [...parentPaths, name], parentTitles)); } : Object.entries(properties).sort(([, a], [, b]) => ((b == null ? void 0 : b.sort) ?? 0) - ((a == null ? void 0 : a.sort) ?? 0)).map(([name, meta]) => __privateMethod(this, _FlowContext_instances, toTreeNode_fn).call(this, name, meta, [...parentPaths, name], parentTitles)); }, "#createChildNodes"); /** * 根据属性路径查找对应的 meta * @param propertyPath 属性路径数组,例如 ["aaa", "bbb"] * @returns [finalKey, metaOrFactory, fullPath] 或 null */ findMetaByPath_fn = /* @__PURE__ */ __name(function(propertyPath) { if (propertyPath.length === 0) return null; const [firstKey, ...remainingPath] = propertyPath; const ownProperty = this._props[firstKey]; if (ownProperty == null ? void 0 : ownProperty.meta) { return __privateMethod(this, _FlowContext_instances, findMetaInProperty_fn).call(this, firstKey, ownProperty.meta, remainingPath, [firstKey]); } const deepMeta = __privateMethod(this, _FlowContext_instances, findMetaInDelegatesDeep_fn).call(this, this._delegates, firstKey); if (deepMeta) { return __privateMethod(this, _FlowContext_instances, findMetaInProperty_fn).call(this, firstKey, deepMeta, remainingPath, [firstKey]); } return null; }, "#findMetaByPath"); /** * 递归在委托链中查找指定 key 的 meta(只返回 metaOrFactory,不解析路径)。 */ findMetaInDelegatesDeep_fn = /* @__PURE__ */ __name(function(delegates, key) { for (const delegate of delegates) { const prop = delegate._props[key]; if (prop == null ? void 0 : prop.meta) return prop.meta; const deeper = __privateMethod(this, _FlowContext_instances, findMetaInDelegatesDeep_fn).call(this, delegate._delegates, key); if (deeper) return deeper; } return null; }, "#findMetaInDelegatesDeep"); /** * 在给定属性的 meta 中查找剩余路径 */ findMetaInProperty_fn = /* @__PURE__ */ __name(function(currentKey, metaOrFactory, remainingPath, currentPath) { if (remainingPath.length === 0) { return [currentKey, metaOrFactory, currentPath]; } if (typeof metaOrFactory === "function") { const finalKey = remainingPath[remainingPath.length - 1]; const finalPath = [...currentPath, ...remainingPath]; const wrappedFactory = /* @__PURE__ */ __name(async () => { const resolvedMeta = await metaOrFactory(); const result = await __privateMethod(this, _FlowContext_instances, resolvePathInMetaAsync_fn).call(this, resolvedMeta, remainingPath); return result; }, "wrappedFactory"); return [finalKey, wrappedFactory, finalPath]; } if (metaOrFactory.properties) { const [nextKey, ...restPath] = remainingPath; const nextPath = [...currentPath, nextKey]; if (typeof metaOrFactory.properties === "function") { const finalKey = remainingPath[remainingPath.length - 1]; const finalPath = [...currentPath, ...remainingPath]; const wrappedFactory = /* @__PURE__ */ __name(async () => { const propertiesFactory = metaOrFactory.properties; const resolvedProperties = await propertiesFactory(); metaOrFactory.properties = resolvedProperties; const startMeta = resolvedProperties[nextKey]; if (!startMeta) { throw new Error(`Property ${nextKey} not found in resolved properties`); } const result = await __privateMethod(this, _FlowContext_instances, resolvePathInMetaAsync_fn).call(this, startMeta, restPath); return result; }, "wrappedFactory"); return [finalKey, wrappedFactory, finalPath]; } const nextMeta = metaOrFactory.properties[nextKey]; if (nextMeta) { return __privateMethod(this, _FlowContext_instances, findMetaInProperty_fn).call(this, nextKey, nextMeta, restPath, nextPath); } } return null; }, "#findMetaInProperty"); /** * 在给定的 meta 中递归解析路径 */ resolvePathInMeta_fn = /* @__PURE__ */ __name(function(meta, path) { if (path.length === 0) { return meta; } let current = meta; for (const key of path) { const properties = import_lodash.default.get(current, "properties"); if (!properties || typeof properties === "function") { return null; } current = import_lodash.default.get(properties, key); if (!current) { return null; } } return current; }, "#resolvePathInMeta"); resolvePathInMetaAsync_fn = /* @__PURE__ */ __name(async function(meta, path) { if (path.length === 0) return meta; let current = meta; for (const key of path) { let properties = import_lodash.default.get(current, "properties"); if (!properties) { throw new Error(`Property path not found: ${path.join(".")}`); } if (typeof properties === "function") { const resolved = await properties(); current.properties = resolved; properties = resolved; } const next = properties[key]; if (!next) { throw new Error(`Property ${key} not found while resolving path: ${path.join(".")}`); } current = next; } return current; }, "#resolvePathInMetaAsync"); /** * 构建 parentTitles 数组,通过递归查找每个路径层级对应的 meta title * @param propertyPath 属性路径数组,例如 ['aaa', 'bbb', 'ccc'] * @param excludeLastLevel 是否排除最后一层,默认为 true(parentTitles 不包含当前节点) * @returns string[] 父级标题数组 */ buildParentTitles_fn = /* @__PURE__ */ __name(function(propertyPath, excludeLastLevel = true) { if (propertyPath.length === 0) return []; const pathToProcess = excludeLastLevel ? propertyPath.slice(0, -1) : propertyPath; if (pathToProcess.length === 0) return []; const parentTitles = []; let currentMetas = this._getPropertiesMeta(); for (let i = 0; i < pathToProcess.length; i++) { const currentKey = pathToProcess[i]; const currentMeta = currentMetas[currentKey]; if (!currentMeta || typeof currentMeta === "function") { parentTitles.push(currentKey); break; } parentTitles.push(currentMeta.title || currentKey); if (i < pathToProcess.length - 1 && currentMeta.properties && typeof currentMeta.properties !== "function") { currentMetas = currentMeta.properties; } else if (i < pathToProcess.length - 1) { for (let j = i + 1; j < pathToProcess.length; j++) { parentTitles.push(pathToProcess[j]); } break; } } return parentTitles; }, "#buildParentTitles"); toTreeNode_fn = /* @__PURE__ */ __name(function(name, metaOrFactory, paths = [name], parentTitles = []) { const cached = this._metaNodeCache.get(metaOrFactory); if (cached) { cached.paths = paths; cached.parentTitles = parentTitles.length > 0 ? parentTitles : void 0; return cached; } let node; const computeDisabledFromMeta = /* @__PURE__ */ __name((m) => { if (!m) return { disabled: false }; const disabledVal = typeof m.disabled === "function" ? m.disabled() : m.disabled; const reason = typeof m.disabledReason === "function" ? m.disabledReason() : m.disabledReason; return { disabled: !!disabledVal, reason }; }, "computeDisabledFromMeta"); if (typeof metaOrFactory === "function") { const initialTitle = name; const hasChildrenHint = metaOrFactory.hasChildren; node = { name, title: metaOrFactory.title || initialTitle, // 初始使用 name 作为 title type: "object", // 初始类型 interface: void 0, uiSchema: void 0, paths, parentTitles: parentTitles.length > 0 ? parentTitles : void 0, disabled: /* @__PURE__ */ __name(() => { const maybe = metaOrFactory(); if (maybe && typeof maybe["then"] === "function") return false; return computeDisabledFromMeta(maybe).disabled; }, "disabled"), disabledReason: /* @__PURE__ */ __name(() => { const maybe = metaOrFactory(); if (maybe && typeof maybe["then"] === "function") return void 0; return computeDisabledFromMeta(maybe).reason; }, "disabledReason"), // 注意:即便 hasChildren === false,也只是“没有子节点”的 UI 提示; // 节点自身依然通过 meta 工厂保持惰性特性(需要时可解析出 title/type 等)。 // 这里仅在 hasChildren !== false 时,提供子节点的懒加载逻辑。 children: hasChildrenHint === false ? void 0 : async () => { try { const meta = await metaOrFactory(); const finalTitle = (meta == null ? void 0 : meta.title) || name; node.title = finalTitle; node.type = meta == null ? void 0 : meta.type; node.interface = meta == null ? void 0 : meta.interface; node.uiSchema = meta == null ? void 0 : meta.uiSchema; if (!(meta == null ? void 0 : meta.properties)) return []; const childNodes = __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, meta.properties, paths, [...parentTitles, finalTitle], meta); const resolvedChildren = Array.isArray(childNodes) ? childNodes : await childNodes(); node.children = resolvedChildren; return resolvedChildren; } catch (error) { console.warn(`Failed to load meta for ${name}:`, error); return []; } } }; } else { const nodeTitle = metaOrFactory.title; const { disabled, reason } = computeDisabledFromMeta(metaOrFactory); node = { name, title: nodeTitle, type: metaOrFactory.type, interface: metaOrFactory.interface, uiSchema: metaOrFactory.uiSchema, paths, parentTitles: parentTitles.length > 0 ? parentTitles : void 0, disabled, disabledReason: reason, children: metaOrFactory.properties ? __privateMethod(this, _FlowContext_instances, createChildNodes_fn).call(this, metaOrFactory.properties, paths, [...parentTitles, nodeTitle], metaOrFactory) : void 0 }; } this._metaNodeCache.set(metaOrFactory, node); return node; }, "#toTreeNode"); __name(_FlowContext, "FlowContext"); let FlowContext = _FlowContext; const _FlowRunjsContext = class _FlowRunjsContext extends FlowContext { constructor(delegate) { super(); this.addDelegate(delegate); this.defineProperty("React", { value: import_react.default }); this.defineProperty("antd", { value: antd }); this.defineMethod( "dispatchModelEvent", async (modelOrUid, eventName, inputArgs) => { var _a, _b; let model = null; if (typeof modelOrUid === "string") { model = await this.engine.loadModel({ uid: modelOrUid }); } else if (modelOrUid instanceof import_models.FlowModel) { model = modelOrUid; } if (model) { model.context.addDelegate(this); model.dispatchEvent(eventName, { navigation: false, ...(_b = (_a = this.model) == null ? void 0 : _a["getInputArgs"]) == null ? void 0 : _b.call(_a), ...inputArgs }); } else { this.message.error(this.t("Model with ID {{uid}} not found", { uid: modelOrUid })); } } ); } }; __name(_FlowRunjsContext, "FlowRunjsContext"); let FlowRunjsContext = _FlowRunjsContext; const _BaseFlowEngineContext = class _BaseFlowEngineContext extends FlowContext { }; __name(_BaseFlowEngineContext, "BaseFlowEngineContext"); let BaseFlowEngineContext = _BaseFlowEngineContext; const _BaseFlowModelContext = class _BaseFlowModelContext extends BaseFlowEngineContext { }; __name(_BaseFlowModelContext, "BaseFlowModelContext"); let BaseFlowModelContext = _BaseFlowModelContext; const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContext { // public dataSourceManager: DataSourceManager; constructor(engine) { if (!(engine instanceof import_flowEngine.FlowEngine)) { throw new Error("Invalid FlowEngine instance"); } super(); this.engine = engine; this.engine = engine; const dataSourceManager = new import_data_source.DataSourceManager(); dataSourceManager.setFlowEngine(this.engine); const mainDataSource = new import_data_source.DataSource({ key: "main", displayName: "Main" }); dataSourceManager.addDataSource(mainDataSource); this.defineProperty("engine", { value: this.engine }); this.defineProperty("sql", { get: /* @__PURE__ */ __name(() => new import_resources.FlowSQLRepository(this), "get") }); this.defineProperty("dataSourceManager", { value: dataSourceManager }); const i18n = new import_flowI18n.FlowI18n(this); this.defineMethod("t", (keyOrTemplate, options) => { return i18n.translate(keyOrTemplate, options); }); this.defineMethod("runjs", async (code, variables, options) => { const mergedGlobals = { ...(options == null ? void 0 : options.globals) || {}, ...variables || {} }; const runner = this.createJSRunner({ ...options || {}, globals: mergedGlobals }); return runner.run(code); }); this.defineMethod("renderJson", function(template) { return this.resolveJsonTemplate(template); }); this.defineMethod("resolveJsonTemplate", async function(template) { var _a, _b; const used = (0, import_utils.extractUsedVariablePaths)(template); const usedVarNames = Object.keys(used || {}); if (!usedVarNames.length) { return (0, import_utils.resolveExpressions)(template, this); } const serverVarPaths = {}; for (const varName of usedVarNames) { const paths = used[varName] || []; const opt = this.getPropertyOptions(varName); const mark = opt == null ? void 0 : opt.resolveOnServer; if (mark === true) { serverVarPaths[varName] = paths; } else if (typeof mark === "function") { const filtered = paths.filter((p) => { try { return !!mark(p); } catch (_2) { return false; } }); if (filtered.length) serverVarPaths[varName] = filtered; } } const needServer = Object.keys(serverVarPaths).length > 0; let serverResolved = template; if (needServer) { const collectFromMeta = /* @__PURE__ */ __name(async () => { var _a2; const out = {}; try { const metas = (_a2 = this._getPropertiesMeta) == null ? void 0 : _a2.call(this); if (!metas || typeof metas !== "object") return out; for (const [key, metaOrFactory] of Object.entries(metas)) { if (!serverVarPaths[key]) continue; try { let meta; if (typeof metaOrFactory === "function") { const fn = metaOrFactory; meta = await fn(); } else { meta = metaOrFactory; } if (!meta || typeof meta !== "object") continue; const builder = meta.buildVariablesParams; if (typeof builder !== "function") continue; const built = await builder(this); if (!built) continue; const neededPaths = serverVarPaths[key] || []; const filtered = filterBuilderOutputByPaths(built, neededPaths); if (filtered && (typeof filtered !== "object" || Object.keys(filtered).length)) { out[key] = filtered; } } catch (_2) { } } } catch (_2) { } return out; }, "collectFromMeta"); const inputFromMeta = await collectFromMeta(); const autoInput = { ...inputFromMeta }; const autoContextParams = Object.keys(autoInput).length ? (0, import_serverContextParams.buildServerContextParams)(this, autoInput) : void 0; if (this.api) { try { serverResolved = await (0, import_params_resolvers.enqueueVariablesResolve)(this, { template, contextParams: autoContextParams || {} }); } catch (e) { (_b = (_a = this.logger) == null ? void 0 : _a.warn) == null ? void 0 : _b.call(_a, { err: e }, "variables:resolve failed, fallback to client-only"); serverResolved = template; } } } return (0, import_utils.resolveExpressions)(serverResolved, this); }); this.defineProperty("requirejs", { get: /* @__PURE__ */ __name(() => { var _a, _b; return (_b = (_a = this.app) == null ? void 0 : _a.requirejs) == null ? void 0 : _b.requirejs; }, "get") }); this.defineProperty("token", { get: /* @__PURE__ */ __name(() => { var _a, _b; return (_b = (_a = this.api) == null ? void 0 : _a.auth) == null ? void 0 : _b.token; }, "get"), cache: false, // 注意:使用惰性 meta 工厂,避免在 i18n 尚未注入时提前求值导致无法翻译 meta: Object.assign(() => ({ type: "string", title: this.t("API Token"), sort: 980 }), { title: "API Token", sort: 980, hasChildren: false }) }); this.defineProperty("role", { get: /* @__PURE__ */ __name(() => { var _a, _b; return (_b = (_a = this.api) == null ? void 0 : _a.auth) == null ? void 0 : _b.role; }, "get"), cache: false, // 注意:使用惰性 meta 工厂,避免在 i18n 尚未注入时提前求值导致无法翻译 meta: Object.assign(() => ({ type: "string", title: this.t("Current role"), sort: 990 }), { title: (0, import_utils.escapeT)("Current role"), sort: 990, hasChildren: false }) }); this.defineProperty("urlSearchParams", { // 不缓存,确保随 URL 变化实时生效 cache: false, get: /* @__PURE__ */ __name(() => { var _a; const search = ((_a = this.location) == null ? void 0 : _a.search) || ""; const str = search.startsWith("?") ? search.slice(1) : search; return import_qs.default.parse(str) || {}; }, "get"), // 变量选择器中的元信息与动态子项 meta: Object.assign( () => ({ type: "object", title: this.t("URL search params"), sort: 970, disabled: /* @__PURE__ */ __name(() => { var _a; const search = ((_a = this.location) == null ? void 0 : _a.search) || ""; const str = search.startsWith("?") ? search.slice(1) : search; const params = import_qs.default.parse(str) || {}; return Object.keys(params).length === 0; }, "disabled"), disabledReason: /* @__PURE__ */ __name(() => this.t( "The value of this variable is derived from the query string of the page URL. This variable can only be used normally when the page has a query string." ), "disabledReason"), properties: /* @__PURE__ */ __name(async () => { var _a; const search = ((_a = this.location) == null ? void 0 : _a.search) || ""; const str = search.startsWith("?") ? search.slice(1) : search; const params = import_qs.default.parse(str) || {}; const props = {}; for (const key of Object.keys(params)) { props[key] = { type: "string", title: key }; } return props; }, "properties") }), { title: (0, import_utils.escapeT)("URL search params"), sort: 970, hasChildren: true } ) }); this.defineProperty("logger", { get: /* @__PURE__ */ __name(() => { return this.engine.logger.child({ module: "flow-engine" }); }, "get") }); this.defineProperty("auth", { get: /* @__PURE__ */ __name(() => ({ roleName: this.api.auth.role, locale: this.api.auth.locale, token: this.api.auth.token, user: this.user }), "get") }); this.defineMethod("loadCSS", async (url) => { return new Promise((resolve, reject) => { const existingLink = document.querySelector(`link[href="${url}"]`); if (existingLink) { resolve(null); return; } const link = document.createElement("link"); link.rel = "stylesheet"; link.href = url; link.onload = () => resolve(null); link.onerror = () => reject(new Error(`Failed to load CSS: ${url}`)); document.head.appendChild(link); }); }); this.defineMethod("requireAsync", async (url) => { return new Promise((resolve, reject) => { if (!this.requirejs) { reject(new Error("requirejs is not available")); return; } this.requirejs( [url], (...args) => { resolve(args[0]); }, reject ); }); }); this.defineMethod("createJSRunner", function(options) { const runCtx = new FlowRunjsContext(this.createProxy()); return new import_JSRunner.JSRunner({ ...options, globals: { ctx: runCtx, window: (0, import_utils.createSafeWindow)(), document: (0, import_utils.createSafeDocument)(), ...options == null ? void 0 : options.globals } }); }); this.defineMethod("copyToClipboard", async (text) => { const content = String(text ?? ""); try { if (typeof navigator !== "undefined" && navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(content); return; } } catch (e) { } return new Promise((resolve, reject) => { try { const ta = document.createElement("textarea"); ta.value = content; ta.setAttribute("readonly", ""); ta.style.position = "fixed"; ta.style.top = "-9999px"; document.body.appendChild(ta); ta.focus(); ta.select(); const ok = document.execCommand("copy"); document.body.removeChild(ta); if (ok) resolve(); else reject(new Error("execCommand copy failed")); } catch (err) { reject(err); } }); }); this.defineMethod("buildServerContextParams", function(input) { return (0, import_serverContextParams.buildServerContextParams)(this, input); }); this.defineMethod("getAction", function(name) { return this.engine.getAction(name); }); this.defineMethod("getActions", function() { return this.engine.getActions(); }); this.defineMethod("getEvents", function() { return this.engine.getEvents(); }); this.defineMethod( "runAction", async function(actionName, params) { const def = this.engine.getAction(actionName); const ctx = this.createProxy(); if (!def) { throw new Error(`Action '${actionName}' not found.`); } const defaultParams = await (0, import_utils.resolveDefaultParams)(def.defaultParams, ctx); let combinedParams = { ...defaultParams || {}, ...params || {} }; let useRawParams = def.useRawParams; if (typeof useRawParams === "function") { useRawParams = await useRawParams(ctx); } if (!useRawParams) { combinedParams = await ctx.resolveJsonTemplate(combinedParams); } if (!def.handler) { throw new Error(`Action '${actionName}' has no handler.`); } return def.handler(ctx, combinedParams); } ); this.defineProperty("acl", { get: /* @__PURE__ */ __name(() => { const acl = new import_Acl.ACL(this.engine); return acl; }, "get") }); this.defineMethod("aclCheck", function(params) { return this.acl.aclCheck(params); }); this.defineMethod("createResource", function(resourceType) { return this.engine.createResource(resourceType, { context: this.createProxy() }); }); } }; __name(_FlowEngineContext, "FlowEngineContext"); let FlowEngineContext = _FlowEngineContext; const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext { constructor(model) { if (!(model instanceof import_models.FlowModel)) { throw new Error("Invalid FlowModel instance"); } super(); this.addDelegate(model.flowEngine.context); this.defineMethod("onRefReady", (ref, cb, timeout) => { this.engine.reactView.onRefReady(ref, cb, timeout); }); this.defineMethod("runjs", async (code, variables, options) => { const runner = this.createJSRunner({ globals: variables, version: options == null ? void 0 : options.version }); return runner.run(code); }); this.defineProperty("model", { value: model }); this.defineProperty("ref", { get: /* @__PURE__ */ __name(() => { this.model["_refCreated"] = true; return (0, import_react.createRef)(); }, "get") }); this.defineMethod("openView", async function(uid, options) { var _a, _b, _c, _d, _e, _f, _g; const opts = { ...options }; if (opts.defineProperties || opts.defineMethod) { opts.navigation = false; } let model2 = null; model2 = await this.engine.loadModel({ uid }); if (!model2) { model2 = this.engine.createModel({ uid, // 注意: 新建的 model 应该使用 ${parentModel.uid}-xxx 形式的 uid use: "PopupActionModel", parentId: this.model.uid, subType: "object", subKey: uid, stepParams: { popupSettings: { openView: { ...import_lodash.default.pick(opts, ["dataSourceKey", "collectionName", "associationName"]) } } } }); await model2.save(); } if ((_b = (_a = model2.getStepParams("popupSettings")) == null ? void 0 : _a.openView) == null ? void 0 : _b.dataSourceKey) { model2.setStepParams("popupSettings", { openView: { ...(_c = model2.getStepParams("popupSettings")) == null ? void 0 : _c.openView, ...import_lodash.default.pick(opts, ["dataSourceKey", "collectionName", "associationName"]) } }); await model2.save(); } const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((_e = (_d = model2.stepParams) == null ? void 0 : _d.popupSettings) == null ? void 0 : _e.openView) ? model2.uid : this.model.uid); const parentView = this.view; const pendingType = (opts == null ? void 0 : opts.isMobileLayout) ? "embed" : (opts == null ? void 0 : opts.mode) || "drawer"; const pendingInputArgs = { ...opts, viewUid, navigation: opts.navigation }; pendingInputArgs.filterByTk = pendingInputArgs.filterByTk || ((_f = this.inputArgs) == null ? void 0 : _f.filterByTk); pendingInputArgs.sourceId = pendingInputArgs.sourceId || ((_g = this.inputArgs) == null ? void 0 : _g.sourceId); const pendingView = { type: pendingType, inputArgs: pendingInputArgs, navigation: parentView == null ? void 0 : parentView.navigation, preventClose: !!(opts == null ? void 0 : opts.preventClose), engineCtx: this.engine.context }; model2.context.defineProperty("view", { value: pendingView }); await model2.dispatchEvent("click", { // navigation: false, // TODO: 路由模式有bug,不支持多层同样viewId的弹窗,因此这里默认先用false // ...this.model?.['getInputArgs']?.(), // 避免部分关系字段信息丢失, 仿照 ClickableCollectionField 做法 ...opts }); model2.context.defineProperty("view", { value: void 0 }); }); this.defineMethod("getEvents", function() { return this.model.getEvents(); }); this.defineMethod("getAction", function(name) { return this.model.getAction(name); }); this.defineMethod("getActions", function() { return this.model.getActions(); }); this.defineMethod( "runAction", async function(actionName, params) { const def = this.model.getAction(actionName); const ctx = this.createProxy(); if (!def) { throw new Error(`Action '${actionName}' not found.`); } const defaultParams = await (0, import_utils.resolveDefaultParams)(def.defaultParams, ctx); let combinedParams = { ...defaultParams || {}, ...params || {} }; let useRawParams = def.useRawParams; if (typeof useRawParams === "function") { useRawParams = await useRawParams(ctx); } if (!useRawParams) { combinedParams = await ctx.resolveJsonTemplate(combinedParams); } if (!def.handler) { throw new Error(`Action '${actionName}' has no handler.`); } return def.handler(ctx, combinedParams); } ); } }; __name(_FlowModelContext, "FlowModelContext"); let FlowModelContext = _FlowModelContext; const _FlowForkModelContext = class _FlowForkModelContext extends BaseFlowModelContext { constructor(master, fork) { if (!(master instanceof import_models.FlowModel)) { throw new Error("Invalid FlowModel instance"); } super(); this.master = master; this.fork = fork; this.addDelegate(this.master.context); this.defineMethod("onRefReady", (ref, cb, timeout) => { this.engine.reactView.onRefReady(ref, cb, timeout); }); this.defineProperty("model", { get: /* @__PURE__ */ __name(() => this.fork, "get") }); this.defineProperty("ref", { get: /* @__PURE__ */ __name(() => { this.fork["_refCreated"] = true; return (0, import_react.createRef)(); }, "get") }); this.defineMethod("runjs", async (code, variables, options) => { const runner = this.createJSRunner({ globals: variables, version: options == null ? void 0 : options.version }); return runner.run(code); }); } }; __name(_FlowForkModelContext, "FlowForkModelContext"); let FlowForkModelContext = _FlowForkModelContext; const _FlowRuntimeContext = class _FlowRuntimeContext extends BaseFlowModelContext { constructor(model, flowKey, _mode = "runtime") { super(); this.model = model; this.flowKey = flowKey; this._mode = _mode; this.addDelegate(this.model.context); this.defineMethod("getStepParams", (stepKey) => { return model.getStepParams(flowKey, stepKey) || {}; }); this.defineMethod("setStepParams", (stepKey, params) => { return model.setStepParams(flowKey, stepKey, params); }); this.defineMethod("getStepResults", (stepKey) => { return import_lodash.default.get(this.steps, [stepKey, "result"]); }); this.defineMethod( "useResource", (className) => { if (model.context.has("resource")) { console.warn(`[FlowRuntimeContext] useResource - resource already defined in context: ${className}`); return; } model.context.defineProperty("resource", { get: /* @__PURE__ */ __name(() => { return this.createResource(className); }, "get") }); if (!model["resource"]) { model["resource"] = model.context.resource; } } ); this.defineProperty("resource", { get: /* @__PURE__ */ __name(() => model["resource"] || model.context["resource"], "get"), cache: false }); this.defineMethod("onRefReady", (ref, cb, timeout) => { this.engine.reactView.onRefReady(ref, cb, timeout); }); this.defineMethod("runjs", async (code, variables, options) => { const runner = this.createJSRunner({ globals: variables, version: options == null ? void 0 : options.version }); return runner.run(code); }); } stepResults = {}; _getOwnProperty(key) { if (this.mode === "runtime") { return super._getOwnProperty(key, this.createProxy()); } const options = this._props[key]; if (!options) return void 0; if ("value" in options) { return import_ContextPathProxy.ContextPathProxy.create()[key]; } if (options.get) { if (options.cache === false) { return import_ContextPathProxy.ContextPathProxy.create()[key]; } const cacheKey = options.observable ? "_observableCache" : "_cache"; if (!(key in this[cacheKey])) { this[cacheKey][key] = import_ContextPathProxy.ContextPathProxy.create()[key]; } return this[cacheKey][key]; } return void 0; } exit() { throw new import_utils.FlowExitException(this.flowKey, this.model.uid); } exitAll() { throw new import_exceptions.FlowExitAllException(this.flowKey, this.model.uid); } get mode() { return this._mode; } }; __name(_FlowRuntimeCo