@nocobase/plugin-flow-engine 2.0.0-alpha.7 → 2.0.0-alpha.8

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.
@@ -8,14 +8,14 @@
8
8
  */
9
9
 
10
10
  module.exports = {
11
- "@nocobase/client": "2.0.0-alpha.7",
11
+ "@nocobase/client": "2.0.0-alpha.8",
12
12
  "lodash": "4.17.21",
13
- "@nocobase/database": "2.0.0-alpha.7",
14
- "@nocobase/data-source-manager": "2.0.0-alpha.7",
15
- "@nocobase/resourcer": "2.0.0-alpha.7",
16
- "@nocobase/server": "2.0.0-alpha.7",
17
- "@nocobase/cache": "2.0.0-alpha.7",
18
- "@nocobase/utils": "2.0.0-alpha.7",
19
- "@nocobase/plugin-localization": "2.0.0-alpha.7",
20
- "@nocobase/actions": "2.0.0-alpha.7"
13
+ "@nocobase/database": "2.0.0-alpha.8",
14
+ "@nocobase/data-source-manager": "2.0.0-alpha.8",
15
+ "@nocobase/resourcer": "2.0.0-alpha.8",
16
+ "@nocobase/server": "2.0.0-alpha.8",
17
+ "@nocobase/cache": "2.0.0-alpha.8",
18
+ "@nocobase/utils": "2.0.0-alpha.8",
19
+ "@nocobase/plugin-localization": "2.0.0-alpha.8",
20
+ "@nocobase/actions": "2.0.0-alpha.8"
21
21
  };
@@ -1 +1 @@
1
- {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2025-10-12T02:36:40.415Z"}
1
+ {"name":"ses","version":"1.14.0","description":"Hardened JavaScript for Fearless Cooperation","keywords":["lockdown","harden","Compartment","assert","security","confinement","isolation","object capabilities","ocaps","secure execution","third-party code","prototype pollution","supply-chain attack","plugin"],"author":"Agoric","license":"Apache-2.0","homepage":"https://github.com/Agoric/SES-shim/tree/master/packages/ses#readme","repository":{"type":"git","url":"git+https://github.com/endojs/endo.git","directory":"packages/ses"},"bugs":{"url":"https://github.com/endojs/endo/issues"},"type":"module","main":"./dist/ses.cjs","module":"./index.js","unpkg":"./dist/ses.umd.js","types":"./types.d.ts","exports":{".":{"import":{"types":"./types.d.ts","xs":"./src-xs/index.js","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./lockdown":{"import":{"types":"./types.d.ts","default":"./index.js"},"require":{"types":"./dist/types.d.cts","default":"./dist/ses.cjs"}},"./hermes":{"require":{"types":"./dist/types.d.cts","default":"./dist/ses-hermes.cjs"}},"./tools.js":"./tools.js","./assert-shim.js":"./assert-shim.js","./lockdown-shim.js":{"xs":"./src-xs/lockdown-shim.js","default":"./lockdown-shim.js"},"./compartment-shim.js":{"xs":"./src-xs/compartment-shim.js","default":"./compartment-shim.js"},"./console-shim.js":"./console-shim.js","./package.json":"./package.json"},"scripts":{"build:vanilla":"node scripts/bundle.js","build:hermes":"node scripts/bundle.js hermes","build":"yarn build:vanilla && yarn build:hermes","clean":"rm -rf dist","cover":"c8 ava","demo":"python3 -m http.server","lint":"yarn lint:types && yarn lint:eslint","lint-fix":"eslint --fix .","lint:eslint":"eslint .","lint:types":"tsc","prepare":"npm run clean && npm run build","qt":"ava","test":"tsd && ava","test:hermes":"./scripts/hermes-test.sh","test:xs":"xst dist/ses.umd.js test/_lockdown-safe.js && node scripts/generate-test-xs.js && xst tmp/test-xs.js && rm -rf tmp","postpack":"git clean -fX \"*.d.ts*\" \"*.d.cts*\" \"*.d.mts*\" \"*.tsbuildinfo\""},"dependencies":{"@endo/cache-map":"^1.1.0","@endo/env-options":"^1.1.11","@endo/immutable-arraybuffer":"^1.1.2"},"devDependencies":{"@babel/generator":"^7.26.3","@babel/parser":"~7.26.2","@babel/traverse":"~7.25.9","@babel/types":"~7.26.0","@endo/compartment-mapper":"^1.6.3","@endo/module-source":"^1.3.3","@endo/test262-runner":"^0.1.48","@types/babel__traverse":"^7.20.5","ava":"^6.1.3","babel-eslint":"^10.1.0","c8":"^7.14.0","core-js":"^3.31.0","eslint":"^8.57.1","eslint-config-airbnb-base":"^15.0.0","eslint-config-prettier":"^9.1.0","eslint-plugin-eslint-comments":"^3.2.0","eslint-plugin-import":"^2.31.0","hermes-engine-cli":"^0.12.0","prettier":"^3.5.3","terser":"^5.16.6","tsd":"^0.31.2","typescript":"~5.8.3"},"files":["./*.d.ts","./*.js","./*.map","LICENSE*","SECURITY*","dist","lib","src","tools"],"publishConfig":{"access":"public"},"eslintConfig":{"extends":["plugin:@endo/ses"]},"ava":{"files":["test/**/*.test.*"],"timeout":"2m"},"typeCoverage":{"atLeast":81.17},"gitHead":"9815aea9541f241389d2135c6097a7442bdffa17","_lastModified":"2025-10-14T08:39:40.438Z"}
@@ -12,7 +12,6 @@ export declare class PluginFlowEngineServer extends PluginUISchemaStorageServer
12
12
  afterAdd(): Promise<void>;
13
13
  beforeLoad(): Promise<void>;
14
14
  getDatabaseByDataSourceKey(dataSourceKey?: string): import("@nocobase/database").default;
15
- private prefetchRecordsForResolve;
16
15
  transformSQL(template: string): {
17
16
  sql: string;
18
17
  bind: {};
@@ -44,6 +44,7 @@ var import_server2 = __toESM(require("./server"));
44
44
  var import_contexts = require("./template/contexts");
45
45
  var import_resolver = require("./template/resolver");
46
46
  var import_registry = require("./variables/registry");
47
+ var import_utils = require("./variables/utils");
47
48
  class PluginFlowEngineServer extends import_server2.default {
48
49
  globalContext;
49
50
  async afterAdd() {
@@ -59,86 +60,6 @@ class PluginFlowEngineServer extends import_server2.default {
59
60
  }
60
61
  return cm.db;
61
62
  }
62
- // 预取:构建“同记录”的字段/关联并集,一次查询写入 ctx.state.__varResolveBatchCache,供后续解析复用
63
- async prefetchRecordsForResolve(koaCtx, items) {
64
- var _a;
65
- try {
66
- const groupMap = /* @__PURE__ */ new Map();
67
- const ensureGroup = (dataSourceKey, collection, filterByTk) => {
68
- const groupKey = JSON.stringify({ ds: dataSourceKey, collection, tk: filterByTk });
69
- let group = groupMap.get(groupKey);
70
- if (!group) {
71
- group = { dataSourceKey, collection, filterByTk, fields: /* @__PURE__ */ new Set(), appends: /* @__PURE__ */ new Set() };
72
- groupMap.set(groupKey, group);
73
- }
74
- return group;
75
- };
76
- const normalizeNestedSeg = (segment) => /^\d+$/.test(segment) ? `[${segment}]` : segment;
77
- const toFirstSeg = (path) => {
78
- const m = path.match(/^([^.[]+|\[[^\]]+\])([\s\S]*)$/);
79
- const segment = m ? m[1] : "";
80
- const rest = m ? m[2] : "";
81
- return { segment, hasDeep: rest.includes(".") || rest.includes("[") || rest.length > 0 };
82
- };
83
- for (const it of items) {
84
- const template = (it == null ? void 0 : it.template) ?? {};
85
- const contextParams = (it == null ? void 0 : it.contextParams) || {};
86
- const usage = import_registry.variables.extractUsage(template);
87
- for (const [cpKey, recordParams] of Object.entries(contextParams)) {
88
- const parts = String(cpKey).split(".");
89
- const varName = parts[0];
90
- const nestedSeg = parts.slice(1).join(".");
91
- const paths = (usage == null ? void 0 : usage[varName]) || [];
92
- if (!paths.length) continue;
93
- const segNorm = nestedSeg ? normalizeNestedSeg(nestedSeg) : "";
94
- const remainders = [];
95
- for (const p of paths) {
96
- if (!segNorm) remainders.push(p);
97
- else if (p === segNorm) remainders.push("");
98
- else if (p.startsWith(`${segNorm}.`) || p.startsWith(`${segNorm}[`))
99
- remainders.push(p.slice(segNorm.length + 1));
100
- }
101
- if (!remainders.length) continue;
102
- const dataSourceKey = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
103
- const collection = recordParams == null ? void 0 : recordParams.collection;
104
- const filterByTk = recordParams == null ? void 0 : recordParams.filterByTk;
105
- if (!collection || typeof filterByTk === "undefined") continue;
106
- const group = ensureGroup(dataSourceKey, collection, filterByTk);
107
- for (const r of remainders) {
108
- const { segment, hasDeep } = toFirstSeg(r);
109
- if (!segment) continue;
110
- const key = segment.replace(/^\[(.+)\]$/, "$1");
111
- if (hasDeep) group.appends.add(key);
112
- else group.fields.add(key);
113
- }
114
- }
115
- }
116
- if (!groupMap.size) return;
117
- const stateObj = koaCtx.state;
118
- if (stateObj && !stateObj["__varResolveBatchCache"]) {
119
- stateObj["__varResolveBatchCache"] = /* @__PURE__ */ new Map();
120
- }
121
- const cache = (_a = koaCtx.state) == null ? void 0 : _a["__varResolveBatchCache"];
122
- for (const { dataSourceKey, collection, filterByTk, fields, appends } of groupMap.values()) {
123
- try {
124
- const dataSource = this.app.dataSourceManager.get(dataSourceKey);
125
- const cm = dataSource.collectionManager;
126
- if (!(cm == null ? void 0 : cm.db)) continue;
127
- const repo = cm.db.getRepository(collection);
128
- const fld = fields.size ? Array.from(fields) : void 0;
129
- const app = appends.size ? Array.from(appends) : void 0;
130
- const rec = await repo.findOne({ filterByTk, fields: fld, appends: app });
131
- const json = rec ? rec.toJSON() : void 0;
132
- if (cache) {
133
- const key = JSON.stringify({ ds: dataSourceKey, c: collection, tk: filterByTk, f: fld, a: app });
134
- cache.set(key, json);
135
- }
136
- } catch {
137
- }
138
- }
139
- } catch {
140
- }
141
- }
142
63
  transformSQL(template) {
143
64
  let index = 1;
144
65
  const bind = {};
@@ -167,7 +88,7 @@ class PluginFlowEngineServer extends import_server2.default {
167
88
  const values = typeof (raw == null ? void 0 : raw.values) !== "undefined" ? raw.values : raw;
168
89
  if (Array.isArray(values == null ? void 0 : values.batch)) {
169
90
  const batchItems = values.batch;
170
- await this.prefetchRecordsForResolve(
91
+ await (0, import_utils.prefetchRecordsForResolve)(
171
92
  ctx,
172
93
  batchItems.map((it) => ({
173
94
  template: it.template,
@@ -196,7 +117,7 @@ class PluginFlowEngineServer extends import_server2.default {
196
117
  }
197
118
  const template = values.template;
198
119
  const contextParams = (values == null ? void 0 : values.contextParams) || {};
199
- await this.prefetchRecordsForResolve(ctx, [{ template, contextParams }]);
120
+ await (0, import_utils.prefetchRecordsForResolve)(ctx, [{ template, contextParams }]);
200
121
  const requestCtx = new import_contexts.HttpRequestContext(ctx);
201
122
  requestCtx.delegate(this.globalContext);
202
123
  await import_registry.variables.attachUsedVariables(requestCtx, ctx, template, contextParams);
@@ -39,4 +39,14 @@ declare class VariableRegistry {
39
39
  attachUsedVariables(ctx: HttpRequestContext, koaCtx: ResourcerContext, template: JSONValue, contextParams: any): Promise<void>;
40
40
  }
41
41
  export declare const variables: VariableRegistry;
42
+ /** 仅测试使用:重置变量注册表为内置默认集 */
43
+ /**
44
+ * 从使用路径推断查询所需的 fields 与 appends。
45
+ * @param paths 使用到的子路径数组
46
+ * @param params 显式参数(仅用于兼容签名)
47
+ */
48
+ export declare function inferSelectsFromUsage(paths?: string[], _params?: unknown): {
49
+ generatedAppends?: string[];
50
+ generatedFields?: string[];
51
+ };
42
52
  export {};
@@ -36,6 +36,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
36
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
37
  var registry_exports = {};
38
38
  __export(registry_exports, {
39
+ inferSelectsFromUsage: () => inferSelectsFromUsage,
39
40
  variables: () => variables
40
41
  });
41
42
  module.exports = __toCommonJS(registry_exports);
@@ -90,40 +91,51 @@ if (!g[GLOBAL_KEY]) {
90
91
  g[GLOBAL_KEY] = new VariableRegistry();
91
92
  }
92
93
  const variables = g[GLOBAL_KEY];
93
- function inferSelectsFromUsage(paths = [], params) {
94
+ function inferSelectsFromUsage(paths = [], _params) {
94
95
  if (!Array.isArray(paths) || paths.length === 0) {
95
96
  return { generatedAppends: void 0, generatedFields: void 0 };
96
97
  }
97
98
  const appendSet = /* @__PURE__ */ new Set();
98
99
  const fieldSet = /* @__PURE__ */ new Set();
100
+ const normalizePath = (raw) => {
101
+ if (!raw) return "";
102
+ let s = String(raw);
103
+ s = s.replace(/\[(?:\d+)\]/g, "");
104
+ s = s.replace(/\[(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)')\]/g, (_m, g1, g2) => `.${g1 || g2}`);
105
+ s = s.replace(/\.\.+/g, ".");
106
+ s = s.replace(/^\./, "").replace(/\.$/, "");
107
+ return s;
108
+ };
99
109
  for (let path of paths) {
100
110
  if (!path) continue;
101
111
  while (/^\[(\d+)\](\.|$)/.test(path)) {
102
112
  path = path.replace(/^\[(\d+)\]\.?/, "");
103
113
  }
104
- if (!path) continue;
105
- let first = "";
106
- let rest = "";
107
- const mStr = path.match(/^\[(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)')\](.*)$/);
108
- if (mStr) {
109
- first = (mStr[1] ?? mStr[2]) || "";
110
- rest = mStr[3] || "";
111
- } else {
112
- const m = path.match(/^([^.[]+)([\s\S]*)$/);
113
- first = (m == null ? void 0 : m[1]) ?? "";
114
- rest = (m == null ? void 0 : m[2]) ?? "";
114
+ const norm = normalizePath(path);
115
+ if (!norm) continue;
116
+ const segments = norm.split(".").filter(Boolean);
117
+ if (segments.length === 0) continue;
118
+ if (segments.length === 1) {
119
+ fieldSet.add(segments[0]);
120
+ continue;
115
121
  }
116
- if (!first) continue;
117
- const hasDeep = rest.includes(".") || rest.includes("[");
118
- if (hasDeep) appendSet.add(first);
119
- else fieldSet.add(first);
122
+ for (let i = 0; i < segments.length - 1; i++) {
123
+ appendSet.add(segments.slice(0, i + 1).join("."));
124
+ }
125
+ fieldSet.add(segments.join("."));
120
126
  }
121
127
  const generatedAppends = appendSet.size ? Array.from(appendSet) : void 0;
122
128
  const generatedFields = fieldSet.size ? Array.from(fieldSet) : void 0;
123
129
  return { generatedAppends, generatedFields };
124
130
  }
125
131
  async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, filterByTk, fields, appends) {
132
+ var _a, _b, _c, _d;
126
133
  try {
134
+ const log = (_b = (_a = koaCtx.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.child({
135
+ module: "plugin-flow-engine",
136
+ submodule: "variables.resolve",
137
+ method: "fetchRecordWithRequestCache"
138
+ });
127
139
  const kctx = koaCtx;
128
140
  if (!kctx.state) kctx.state = {};
129
141
  if (!kctx.state["__varResolveBatchCache"]) {
@@ -143,32 +155,53 @@ async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, fi
143
155
  };
144
156
  const key = JSON.stringify(keyObj);
145
157
  if (cache) {
146
- if (cache.has(key)) return cache.get(key);
147
- const needFields = Array.isArray(fields) ? new Set(fields) : void 0;
158
+ if (cache.has(key)) {
159
+ return cache.get(key);
160
+ }
161
+ const needFields = Array.isArray(fields) ? [...new Set(fields)] : void 0;
148
162
  const needAppends = Array.isArray(appends) ? new Set(appends) : void 0;
149
- let fallbackAny = void 0;
150
163
  for (const [cacheKey, cacheVal] of cache.entries()) {
151
164
  const parsed = JSON.parse(cacheKey);
152
165
  if (!parsed || parsed.ds !== keyObj.ds || parsed.c !== keyObj.c || parsed.tk !== keyObj.tk) continue;
153
- const cachedFields = Array.isArray(parsed.f) ? new Set(parsed.f) : void 0;
154
- const cachedAppends = Array.isArray(parsed.a) ? new Set(parsed.a) : void 0;
155
- const fieldsOk = !needFields || cachedFields && [...needFields].every((x) => cachedFields.has(x));
156
- const appendsOk = !needAppends || cachedAppends && [...needAppends].every((x) => cachedAppends.has(x));
157
- if (fieldsOk && appendsOk) return cacheVal;
158
- if (typeof fallbackAny === "undefined") fallbackAny = cacheVal;
166
+ const cachedFields = new Set(parsed.f || []);
167
+ const cachedAppends = new Set(parsed.a || []);
168
+ const fieldCoveredByAppends = (fieldPath) => {
169
+ const p = String(fieldPath || "");
170
+ for (const a of cachedAppends) {
171
+ if (!a) continue;
172
+ if (p === a || p.startsWith(a + ".")) return true;
173
+ }
174
+ return false;
175
+ };
176
+ const fieldsOk = !needFields || needFields.every((f) => cachedFields.has(f) || fieldCoveredByAppends(f));
177
+ const appendsOk = !needAppends || [...needAppends].every((a) => cachedAppends.has(a));
178
+ if (fieldsOk && appendsOk) {
179
+ return cacheVal;
180
+ }
159
181
  }
160
- if (typeof fallbackAny !== "undefined") return fallbackAny;
161
182
  }
162
- const tk = filterByTk;
163
183
  const rec = await repo.findOne({
164
- filterByTk: tk,
184
+ filterByTk,
165
185
  fields,
166
186
  appends
167
187
  });
168
188
  const json = rec ? rec.toJSON() : void 0;
169
189
  if (cache) cache.set(key, json);
170
190
  return json;
171
- } catch (_2) {
191
+ } catch (e) {
192
+ const log = (_d = (_c = koaCtx.app) == null ? void 0 : _c.logger) == null ? void 0 : _d.child({
193
+ module: "plugin-flow-engine",
194
+ submodule: "variables.resolve",
195
+ method: "fetchRecordWithRequestCache"
196
+ });
197
+ log == null ? void 0 : log.debug("[variables.resolve] fetchRecordWithRequestCache error", {
198
+ ds: dataSourceKey,
199
+ collection,
200
+ tk: filterByTk,
201
+ fields,
202
+ appends,
203
+ error: (e == null ? void 0 : e.message) || String(e)
204
+ });
172
205
  return void 0;
173
206
  }
174
207
  }
@@ -295,5 +328,6 @@ function registerBuiltInVariables(reg) {
295
328
  registerBuiltInVariables(variables);
296
329
  // Annotate the CommonJS export names for ESM import in node:
297
330
  0 && (module.exports = {
331
+ inferSelectsFromUsage,
298
332
  variables
299
333
  });
@@ -0,0 +1,17 @@
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 { JSONValue } from '../template/resolver';
11
+ /**
12
+ * 预取:构建“同记录”的字段/关联并集,一次查询写入 ctx.state.__varResolveBatchCache,供后续解析复用
13
+ */
14
+ export declare function prefetchRecordsForResolve(koaCtx: ResourcerContext, items: Array<{
15
+ template: JSONValue;
16
+ contextParams?: Record<string, unknown>;
17
+ }>): Promise<void>;
@@ -0,0 +1,113 @@
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 utils_exports = {};
28
+ __export(utils_exports, {
29
+ prefetchRecordsForResolve: () => prefetchRecordsForResolve
30
+ });
31
+ module.exports = __toCommonJS(utils_exports);
32
+ var import_registry = require("./registry");
33
+ async function prefetchRecordsForResolve(koaCtx, items) {
34
+ var _a, _b, _c, _d, _e, _f;
35
+ try {
36
+ const log = (_b = (_a = koaCtx.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.child({ module: "plugin-flow-engine", submodule: "variables.prefetch" });
37
+ const groupMap = /* @__PURE__ */ new Map();
38
+ const ensureGroup = (dataSourceKey, collection, filterByTk) => {
39
+ const groupKey = JSON.stringify({ ds: dataSourceKey, collection, tk: filterByTk });
40
+ let group = groupMap.get(groupKey);
41
+ if (!group) {
42
+ group = { dataSourceKey, collection, filterByTk, fields: /* @__PURE__ */ new Set(), appends: /* @__PURE__ */ new Set() };
43
+ groupMap.set(groupKey, group);
44
+ }
45
+ return group;
46
+ };
47
+ const normalizeNestedSeg = (segment) => /^\d+$/.test(segment) ? `[${segment}]` : segment;
48
+ for (const it of items) {
49
+ const template = (it == null ? void 0 : it.template) ?? {};
50
+ const contextParams = (it == null ? void 0 : it.contextParams) || {};
51
+ const usage = import_registry.variables.extractUsage(template);
52
+ for (const [cpKey, recordParams] of Object.entries(contextParams)) {
53
+ const parts = String(cpKey).split(".");
54
+ const varName = parts[0];
55
+ const nestedSeg = parts.slice(1).join(".");
56
+ const paths = (usage == null ? void 0 : usage[varName]) || [];
57
+ if (!paths.length) continue;
58
+ const segNorm = nestedSeg ? normalizeNestedSeg(nestedSeg) : "";
59
+ const remainders = [];
60
+ for (const p of paths) {
61
+ if (!segNorm) remainders.push(p);
62
+ else if (p === segNorm) remainders.push("");
63
+ else if (p.startsWith(`${segNorm}.`) || p.startsWith(`${segNorm}[`))
64
+ remainders.push(p.slice(segNorm.length + 1));
65
+ }
66
+ if (!remainders.length) continue;
67
+ const dataSourceKey = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
68
+ const collection = recordParams == null ? void 0 : recordParams.collection;
69
+ const filterByTk = recordParams == null ? void 0 : recordParams.filterByTk;
70
+ if (!collection || typeof filterByTk === "undefined") continue;
71
+ const group = ensureGroup(dataSourceKey, collection, filterByTk);
72
+ const { generatedAppends, generatedFields } = (0, import_registry.inferSelectsFromUsage)(remainders);
73
+ if (generatedFields == null ? void 0 : generatedFields.length) generatedFields.forEach((f) => group.fields.add(f));
74
+ if (generatedAppends == null ? void 0 : generatedAppends.length) generatedAppends.forEach((a) => group.appends.add(a));
75
+ }
76
+ }
77
+ if (!groupMap.size) return;
78
+ const stateObj = koaCtx.state;
79
+ if (stateObj && !stateObj["__varResolveBatchCache"]) {
80
+ stateObj["__varResolveBatchCache"] = /* @__PURE__ */ new Map();
81
+ }
82
+ const cache = (_c = koaCtx.state) == null ? void 0 : _c["__varResolveBatchCache"];
83
+ for (const { dataSourceKey, collection, filterByTk, fields, appends } of groupMap.values()) {
84
+ try {
85
+ const ds = koaCtx.app.dataSourceManager.get(dataSourceKey);
86
+ const cm = ds.collectionManager;
87
+ if (!(cm == null ? void 0 : cm.db)) continue;
88
+ const repo = cm.db.getRepository(collection);
89
+ const fld = fields.size ? Array.from(fields).sort() : void 0;
90
+ const app = appends.size ? Array.from(appends).sort() : void 0;
91
+ const rec = await repo.findOne({ filterByTk, fields: fld, appends: app });
92
+ const json = rec ? rec.toJSON() : void 0;
93
+ if (cache) {
94
+ const key = JSON.stringify({ ds: dataSourceKey, c: collection, tk: filterByTk, f: fld, a: app });
95
+ cache.set(key, json);
96
+ }
97
+ } catch (e) {
98
+ log == null ? void 0 : log.debug("[variables.resolve] prefetch query error", {
99
+ ds: dataSourceKey,
100
+ collection,
101
+ tk: filterByTk,
102
+ error: (e == null ? void 0 : e.message) || String(e)
103
+ });
104
+ }
105
+ }
106
+ } catch (e) {
107
+ (_f = (_e = (_d = koaCtx.app) == null ? void 0 : _d.logger) == null ? void 0 : _e.child({ module: "plugin-flow-engine", submodule: "variables.prefetch" })) == null ? void 0 : _f.debug("[variables.resolve] prefetch fatal error", { error: (e == null ? void 0 : e.message) || String(e) });
108
+ }
109
+ }
110
+ // Annotate the CommonJS export names for ESM import in node:
111
+ 0 && (module.exports = {
112
+ prefetchRecordsForResolve
113
+ });
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "displayName.zh-CN": "前端流引擎",
5
5
  "description": "",
6
6
  "description.zh-CN": "",
7
- "version": "2.0.0-alpha.7",
7
+ "version": "2.0.0-alpha.8",
8
8
  "main": "./dist/server/index.js",
9
9
  "license": "AGPL-3.0",
10
10
  "devDependencies": {
@@ -24,5 +24,5 @@
24
24
  "@nocobase/test": "2.x",
25
25
  "@nocobase/utils": "2.x"
26
26
  },
27
- "gitHead": "cb012f93256f534472d3ae56e075839ca1675779"
27
+ "gitHead": "ff91246a3914c72dc1f4000d85df10a16798ff78"
28
28
  }