@nocobase/plugin-flow-engine 2.0.0-beta.11 → 2.0.0-beta.13

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-beta.11",
11
+ "@nocobase/client": "2.0.0-beta.13",
12
12
  "lodash": "4.17.21",
13
- "@nocobase/database": "2.0.0-beta.11",
14
- "@nocobase/data-source-manager": "2.0.0-beta.11",
15
- "@nocobase/resourcer": "2.0.0-beta.11",
16
- "@nocobase/server": "2.0.0-beta.11",
17
- "@nocobase/utils": "2.0.0-beta.11",
18
- "@nocobase/cache": "2.0.0-beta.11",
19
- "@nocobase/plugin-localization": "2.0.0-beta.11",
20
- "@nocobase/actions": "2.0.0-beta.11"
13
+ "@nocobase/database": "2.0.0-beta.13",
14
+ "@nocobase/data-source-manager": "2.0.0-beta.13",
15
+ "@nocobase/resourcer": "2.0.0-beta.13",
16
+ "@nocobase/server": "2.0.0-beta.13",
17
+ "@nocobase/utils": "2.0.0-beta.13",
18
+ "@nocobase/cache": "2.0.0-beta.13",
19
+ "@nocobase/plugin-localization": "2.0.0-beta.13",
20
+ "@nocobase/actions": "2.0.0-beta.13"
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":"2026-01-15T06:43:18.131Z"}
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":"2026-01-19T13:31:50.808Z"}
@@ -78,14 +78,18 @@ async function replacePlaceholders(input, ctx) {
78
78
  async function evaluate(expr, ctx) {
79
79
  try {
80
80
  const raw = expr.trim();
81
- const dotOnly = raw.match(/^ctx\.([a-zA-Z_$][a-zA-Z0-9_$]*(?:\.[a-zA-Z_$][a-zA-Z0-9_$]*)*)$/);
81
+ const dotOnly = raw.match(
82
+ /^ctx\.([a-zA-Z_$][a-zA-Z0-9_$]*)(?:\.([a-zA-Z_$][a-zA-Z0-9_$-]*(?:\.[a-zA-Z_$][a-zA-Z0-9_$-]*)*))?$/
83
+ );
82
84
  if (dotOnly) {
83
- const path = dotOnly[1];
84
- const segs = path.split(".");
85
- const first = segs.shift();
85
+ const first = dotOnly[1];
86
+ const rest = dotOnly[2];
86
87
  const base = await ctx[first];
87
- if (!segs.length) return base;
88
- return await asyncGetValuesByPath(base, segs.join("."));
88
+ if (!rest) return base;
89
+ const resolved = await asyncGetValuesByPath(base, rest);
90
+ if (typeof resolved !== "undefined" || !rest.includes("-")) {
91
+ return resolved;
92
+ }
89
93
  }
90
94
  const transformed = preprocessExpression(raw);
91
95
  const compartment = new Compartment({
@@ -130,8 +130,8 @@ function inferSelectsFromUsage(paths = [], _params) {
130
130
  const generatedFields = fieldSet.size ? Array.from(fieldSet) : void 0;
131
131
  return { generatedAppends, generatedFields };
132
132
  }
133
- async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, filterByTk, fields, appends, preferFullRecord, associationName, sourceId) {
134
- var _a, _b, _c, _d, _e, _f;
133
+ async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, filterByTk, fields, appends, strictSelects, preferFullRecord, associationName, sourceId) {
134
+ var _a, _b, _c, _d, _e;
135
135
  try {
136
136
  const log = (_b = (_a = koaCtx.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.child({
137
137
  module: "plugin-flow-engine",
@@ -151,15 +151,17 @@ async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, fi
151
151
  const modelInfo = (_c = repo.collection) == null ? void 0 : _c.model;
152
152
  const pkAttr = modelInfo == null ? void 0 : modelInfo.primaryKeyAttribute;
153
153
  const pkIsValid = pkAttr && (modelInfo == null ? void 0 : modelInfo.rawAttributes) && Object.prototype.hasOwnProperty.call(modelInfo.rawAttributes, pkAttr);
154
- const filterTargetKey = (_d = repo.collection) == null ? void 0 : _d.filterTargetKey;
155
- const extraKeyFields = (0, import_records.getExtraKeyFieldsForSelect)(filterByTk, {
154
+ const collectionInfo = repo == null ? void 0 : repo.collection;
155
+ const filterTargetKey = collectionInfo == null ? void 0 : collectionInfo.filterTargetKey;
156
+ const extraKeys = (0, import_records.getExtraKeyFieldsForSelect)(filterByTk, {
156
157
  filterTargetKey,
157
158
  pkAttr,
158
159
  pkIsValid,
159
- rawAttributes: modelInfo == null ? void 0 : modelInfo.rawAttributes
160
+ rawAttributes: (modelInfo == null ? void 0 : modelInfo.rawAttributes) || void 0
160
161
  });
161
- const fieldsWithPk = (0, import_records.mergeFieldsWithExtras)(fields, extraKeyFields);
162
- const cacheKeyFields = preferFullRecord && pkIsValid ? void 0 : Array.isArray(fieldsWithPk) ? [...fieldsWithPk].sort() : void 0;
162
+ const effectiveExtras = strictSelects && Array.isArray(extraKeys) && extraKeys.length ? extraKeys.filter((k) => k === pkAttr) : extraKeys;
163
+ const fieldsWithExtras = (0, import_records.mergeFieldsWithExtras)(fields, effectiveExtras);
164
+ const cacheKeyFields = preferFullRecord && pkIsValid ? void 0 : Array.isArray(fieldsWithExtras) ? [...fieldsWithExtras].sort() : void 0;
163
165
  const cacheKeyAppends = preferFullRecord ? void 0 : Array.isArray(appends) ? [...appends].sort() : void 0;
164
166
  const keyObj = {
165
167
  ds: dataSourceKey || "main",
@@ -176,34 +178,36 @@ async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, fi
176
178
  if (cache.has(key)) {
177
179
  return cache.get(key);
178
180
  }
179
- const needFields = !preferFullRecord && Array.isArray(fieldsWithPk) ? [...new Set(fieldsWithPk)] : void 0;
180
- const needAppends = !preferFullRecord && Array.isArray(appends) ? new Set(appends) : void 0;
181
- for (const [cacheKey, cacheVal] of cache.entries()) {
182
- const parsed = JSON.parse(cacheKey);
183
- if (!parsed || parsed.ds !== keyObj.ds || parsed.c !== keyObj.c || parsed.tk !== keyObj.tk || parsed.assoc !== keyObj.assoc || parsed.sid !== keyObj.sid)
184
- continue;
185
- const cachedFields = new Set(parsed.f || []);
186
- const cachedAppends = new Set(parsed.a || []);
187
- const fieldCoveredByAppends = (fieldPath) => {
188
- const p = String(fieldPath || "");
189
- for (const a of cachedAppends) {
190
- if (!a) continue;
191
- if (p === a || p.startsWith(a + ".")) return true;
181
+ if (!strictSelects) {
182
+ const needFields = !preferFullRecord && Array.isArray(fieldsWithExtras) ? [...new Set(fieldsWithExtras)] : void 0;
183
+ const needAppends = !preferFullRecord && Array.isArray(appends) ? new Set(appends) : void 0;
184
+ for (const [cacheKey, cacheVal] of cache.entries()) {
185
+ const parsed = JSON.parse(cacheKey);
186
+ if (!parsed || parsed.ds !== keyObj.ds || parsed.c !== keyObj.c || !import_lodash.default.isEqual(parsed.tk, keyObj.tk) || parsed.assoc !== keyObj.assoc || !import_lodash.default.isEqual(parsed.sid, keyObj.sid))
187
+ continue;
188
+ const cachedFields = new Set(parsed.f || []);
189
+ const cachedAppends = new Set(parsed.a || []);
190
+ const fieldCoveredByAppends = (fieldPath) => {
191
+ const p = String(fieldPath || "");
192
+ for (const a of cachedAppends) {
193
+ if (!a) continue;
194
+ if (p === a || p.startsWith(a + ".")) return true;
195
+ }
196
+ return false;
197
+ };
198
+ const fieldsOk = needFields ? needFields.every((f) => cachedFields.has(f) || fieldCoveredByAppends(f)) : parsed.f === void 0;
199
+ const appendsOk = !needAppends || [...needAppends].every((a) => cachedAppends.has(a));
200
+ const fullOk = preferFullRecord ? parsed.full === true : true;
201
+ if (fieldsOk && appendsOk && fullOk) {
202
+ return cacheVal;
192
203
  }
193
- return false;
194
- };
195
- const fieldsOk = needFields ? needFields.every((f) => cachedFields.has(f) || fieldCoveredByAppends(f)) : parsed.f === void 0;
196
- const appendsOk = !needAppends || [...needAppends].every((a) => cachedAppends.has(a));
197
- const fullOk = preferFullRecord ? parsed.full === true : true;
198
- if (fieldsOk && appendsOk && fullOk) {
199
- return cacheVal;
200
204
  }
201
205
  }
202
206
  }
203
207
  const json = await (0, import_records.fetchRecordOrRecordsJson)(repo, {
204
208
  filterByTk,
205
209
  preferFullRecord,
206
- fields: fieldsWithPk,
210
+ fields: fieldsWithExtras,
207
211
  appends,
208
212
  filterTargetKey,
209
213
  pkAttr,
@@ -212,7 +216,7 @@ async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, fi
212
216
  if (cache) cache.set(key, json);
213
217
  return json;
214
218
  } catch (e) {
215
- const log = (_f = (_e = koaCtx.app) == null ? void 0 : _e.logger) == null ? void 0 : _f.child({
219
+ const log = (_e = (_d = koaCtx.app) == null ? void 0 : _d.logger) == null ? void 0 : _e.child({
216
220
  module: "plugin-flow-engine",
217
221
  submodule: "variables.resolve",
218
222
  method: "fetchRecordWithRequestCache"
@@ -240,12 +244,37 @@ function attachGenericRecordVariables(flowCtx, koaCtx, usage, contextParams) {
240
244
  for (const varName of Object.keys(usage)) {
241
245
  const usedPaths = usage[varName] || [];
242
246
  const topParams = import_lodash.default.get(contextParams, varName);
247
+ const deepRecordMap = /* @__PURE__ */ new Map();
248
+ const cp = contextParams;
249
+ if (cp && typeof cp === "object") {
250
+ const cpRec = cp;
251
+ for (const key of Object.keys(cpRec)) {
252
+ if (!key || key !== varName && !key.startsWith(`${varName}.`)) continue;
253
+ if (key === varName) continue;
254
+ const val = cpRec[key];
255
+ if (!isRecordParams(val)) continue;
256
+ const relative = key.slice(varName.length + 1);
257
+ if (!relative) continue;
258
+ deepRecordMap.set(relative, val);
259
+ }
260
+ }
243
261
  if (isRecordParams(topParams)) {
244
- const { generatedAppends, generatedFields } = inferSelectsFromUsage(usedPaths, topParams);
245
- const hasDirectRefTop = (usedPaths || []).some((p) => p === "");
262
+ const usedPathsForBase = deepRecordMap.size ? (usedPaths || []).filter((p) => {
263
+ if (!p) return true;
264
+ for (const relative of deepRecordMap.keys()) {
265
+ if (!relative) continue;
266
+ if (p === relative || p.startsWith(relative + ".") || p.startsWith(relative + "[")) return false;
267
+ }
268
+ return true;
269
+ }) : usedPaths || [];
270
+ const hasDirectRefTop = usedPathsForBase.some((p) => p === "");
246
271
  flowCtx.defineProperty(varName, {
247
272
  get: async () => {
248
273
  const dataSourceKey = (topParams == null ? void 0 : topParams.dataSourceKey) || "main";
274
+ const strictSelects = Array.isArray(topParams == null ? void 0 : topParams.fields) || Array.isArray(topParams == null ? void 0 : topParams.appends);
275
+ let { generatedAppends, generatedFields } = inferSelectsFromUsage(usedPathsForBase, topParams);
276
+ if (Array.isArray(topParams == null ? void 0 : topParams.fields)) generatedFields = topParams.fields;
277
+ if (Array.isArray(topParams == null ? void 0 : topParams.appends)) generatedAppends = topParams.appends;
249
278
  const fixed = (0, import_selects.adjustSelectsForCollection)(
250
279
  koaCtx,
251
280
  dataSourceKey,
@@ -253,17 +282,69 @@ function attachGenericRecordVariables(flowCtx, koaCtx, usage, contextParams) {
253
282
  generatedFields,
254
283
  generatedAppends
255
284
  );
256
- return await fetchRecordWithRequestCache(
285
+ const base = await fetchRecordWithRequestCache(
257
286
  koaCtx,
258
287
  dataSourceKey,
259
288
  topParams.collection,
260
289
  topParams.filterByTk,
261
290
  fixed.fields,
262
291
  fixed.appends,
292
+ strictSelects,
263
293
  hasDirectRefTop,
264
294
  topParams.associationName,
265
295
  topParams.sourceId
266
296
  );
297
+ if (!deepRecordMap.size) return base;
298
+ const merged = base && typeof base === "object" && !Array.isArray(base) ? { ...base } : {};
299
+ const setClonedPath = (obj, path, value) => {
300
+ const segs = String(path || "").split(".").filter(Boolean);
301
+ if (!segs.length) return;
302
+ if (segs.length === 1) {
303
+ obj[segs[0]] = value;
304
+ return;
305
+ }
306
+ let cur = obj;
307
+ for (let i = 0; i < segs.length - 1; i++) {
308
+ const seg = segs[i];
309
+ const prev = cur[seg];
310
+ const next = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...prev } : {};
311
+ cur[seg] = next;
312
+ cur = next;
313
+ }
314
+ cur[segs[segs.length - 1]] = value;
315
+ };
316
+ const buildNestedPromise = (recordParams, relative) => {
317
+ const subPaths = (usedPaths || []).map((p) => p === relative ? "" : p.startsWith(relative + ".") ? p.slice(relative.length + 1) : "").filter((x) => x !== "");
318
+ const hasDirectRef = (usedPaths || []).some((p) => p === relative);
319
+ const dataSourceKey2 = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
320
+ const strictSelects2 = Array.isArray(recordParams == null ? void 0 : recordParams.fields) || Array.isArray(recordParams == null ? void 0 : recordParams.appends);
321
+ let { generatedAppends: generatedAppends2, generatedFields: generatedFields2 } = inferSelectsFromUsage(subPaths, recordParams);
322
+ if (Array.isArray(recordParams == null ? void 0 : recordParams.fields)) generatedFields2 = recordParams.fields;
323
+ if (Array.isArray(recordParams == null ? void 0 : recordParams.appends)) generatedAppends2 = recordParams.appends;
324
+ const fixed2 = (0, import_selects.adjustSelectsForCollection)(
325
+ koaCtx,
326
+ dataSourceKey2,
327
+ recordParams.collection,
328
+ generatedFields2,
329
+ generatedAppends2
330
+ );
331
+ return fetchRecordWithRequestCache(
332
+ koaCtx,
333
+ dataSourceKey2,
334
+ recordParams.collection,
335
+ recordParams.filterByTk,
336
+ fixed2.fields,
337
+ fixed2.appends,
338
+ strictSelects2,
339
+ hasDirectRef,
340
+ recordParams.associationName,
341
+ recordParams.sourceId
342
+ );
343
+ };
344
+ for (const [relative, recordParams] of deepRecordMap.entries()) {
345
+ setClonedPath(merged, relative, buildNestedPromise(recordParams, relative));
346
+ }
347
+ return merged;
267
348
  },
268
349
  cache: true
269
350
  });
@@ -302,27 +383,16 @@ function attachGenericRecordVariables(flowCtx, koaCtx, usage, contextParams) {
302
383
  const dotted = (contextParams || {})[`${varName}.${seg}`] ?? (idx ? (contextParams || {})[`${varName}.${idx}`] : void 0);
303
384
  return isRecordParams(nestedObj) || isRecordParams(dotted);
304
385
  });
305
- const deepRecordMap = /* @__PURE__ */ new Map();
306
- const cp = contextParams;
307
- if (cp && typeof cp === "object") {
308
- const cpRec = cp;
309
- for (const key of Object.keys(cpRec)) {
310
- if (!key || key !== varName && !key.startsWith(`${varName}.`)) continue;
311
- if (key === varName) continue;
312
- const val = cpRec[key];
313
- if (!isRecordParams(val)) continue;
314
- const relative = key.slice(varName.length + 1);
315
- if (!relative) continue;
316
- deepRecordMap.set(relative, val);
317
- }
318
- }
319
386
  if (!oneLevelRecordChildren.length && deepRecordMap.size === 0) continue;
320
387
  flowCtx.defineProperty(varName, {
321
388
  get: () => {
322
389
  const root = new import_contexts.ServerBaseContext();
323
390
  const definedFirstLevel = /* @__PURE__ */ new Set();
324
391
  const defineRecordGetter = (container, key, recordParams, subPaths = [], preferFull) => {
325
- const { generatedAppends, generatedFields } = inferSelectsFromUsage(subPaths, recordParams);
392
+ const strictSelects = Array.isArray(recordParams == null ? void 0 : recordParams.fields) || Array.isArray(recordParams == null ? void 0 : recordParams.appends);
393
+ let { generatedAppends, generatedFields } = inferSelectsFromUsage(subPaths, recordParams);
394
+ if (Array.isArray(recordParams == null ? void 0 : recordParams.fields)) generatedFields = recordParams.fields;
395
+ if (Array.isArray(recordParams == null ? void 0 : recordParams.appends)) generatedAppends = recordParams.appends;
326
396
  container.defineProperty(key, {
327
397
  get: async () => {
328
398
  const dataSourceKey = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
@@ -340,6 +410,7 @@ function attachGenericRecordVariables(flowCtx, koaCtx, usage, contextParams) {
340
410
  recordParams.filterByTk,
341
411
  fixed.fields,
342
412
  fixed.appends,
413
+ strictSelects,
343
414
  preferFull || ((subPaths == null ? void 0 : subPaths.length) ?? 0) === 0,
344
415
  recordParams.associationName,
345
416
  recordParams.sourceId
@@ -423,6 +494,7 @@ function registerBuiltInVariables(reg) {
423
494
  uid,
424
495
  generatedFields,
425
496
  generatedAppends,
497
+ false,
426
498
  void 0,
427
499
  void 0,
428
500
  void 0
@@ -33,15 +33,28 @@ var import_registry = require("./registry");
33
33
  var import_selects = require("./selects");
34
34
  var import_records = require("./records");
35
35
  async function prefetchRecordsForResolve(koaCtx, items) {
36
- var _a, _b, _c, _d, _e, _f, _g, _h;
36
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
37
37
  try {
38
38
  const log = (_b = (_a = koaCtx.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.child({ module: "plugin-flow-engine", submodule: "variables.prefetch" });
39
39
  const groupMap = /* @__PURE__ */ new Map();
40
- const ensureGroup = (dataSourceKey, collection, filterByTk) => {
41
- const groupKey = JSON.stringify({ ds: dataSourceKey, collection, tk: filterByTk });
40
+ const ensureGroup = (dataSourceKey, collection, filterByTk, strictSelects, opts) => {
41
+ const groupKey = JSON.stringify({
42
+ ds: dataSourceKey,
43
+ collection,
44
+ tk: filterByTk,
45
+ f: Array.isArray(opts == null ? void 0 : opts.fields) ? [...opts.fields].sort() : void 0,
46
+ a: Array.isArray(opts == null ? void 0 : opts.appends) ? [...opts.appends].sort() : void 0
47
+ });
42
48
  let group = groupMap.get(groupKey);
43
49
  if (!group) {
44
- group = { dataSourceKey, collection, filterByTk, fields: /* @__PURE__ */ new Set(), appends: /* @__PURE__ */ new Set() };
50
+ group = {
51
+ dataSourceKey,
52
+ collection,
53
+ filterByTk,
54
+ strictSelects,
55
+ fields: /* @__PURE__ */ new Set(),
56
+ appends: /* @__PURE__ */ new Set()
57
+ };
45
58
  groupMap.set(groupKey, group);
46
59
  }
47
60
  return group;
@@ -70,8 +83,19 @@ async function prefetchRecordsForResolve(koaCtx, items) {
70
83
  const collection = recordParams == null ? void 0 : recordParams.collection;
71
84
  const filterByTk = recordParams == null ? void 0 : recordParams.filterByTk;
72
85
  if (!collection || typeof filterByTk === "undefined") continue;
73
- if (Array.isArray(filterByTk) && filterByTk.length === 0) continue;
74
- const group = ensureGroup(dataSourceKey, collection, filterByTk);
86
+ const explicitFields = recordParams == null ? void 0 : recordParams.fields;
87
+ const explicitAppends = recordParams == null ? void 0 : recordParams.appends;
88
+ const hasExplicit = Array.isArray(explicitFields) || Array.isArray(explicitAppends);
89
+ const group = ensureGroup(dataSourceKey, collection, filterByTk, hasExplicit, {
90
+ fields: hasExplicit ? explicitFields : void 0,
91
+ appends: hasExplicit ? explicitAppends : void 0
92
+ });
93
+ if (hasExplicit) {
94
+ const fixed2 = (0, import_selects.adjustSelectsForCollection)(koaCtx, dataSourceKey, collection, explicitFields, explicitAppends);
95
+ (_c = fixed2.fields) == null ? void 0 : _c.forEach((f) => group.fields.add(f));
96
+ (_d = fixed2.appends) == null ? void 0 : _d.forEach((a) => group.appends.add(a));
97
+ continue;
98
+ }
75
99
  let { generatedAppends, generatedFields } = (0, import_registry.inferSelectsFromUsage)(remainders);
76
100
  const fixed = (0, import_selects.adjustSelectsForCollection)(koaCtx, dataSourceKey, collection, generatedFields, generatedAppends);
77
101
  generatedFields = fixed.fields;
@@ -85,31 +109,31 @@ async function prefetchRecordsForResolve(koaCtx, items) {
85
109
  if (stateObj && !stateObj["__varResolveBatchCache"]) {
86
110
  stateObj["__varResolveBatchCache"] = /* @__PURE__ */ new Map();
87
111
  }
88
- const cache = (_c = koaCtx.state) == null ? void 0 : _c["__varResolveBatchCache"];
89
- for (const { dataSourceKey, collection, filterByTk, fields, appends } of groupMap.values()) {
112
+ const cache = (_e = koaCtx.state) == null ? void 0 : _e["__varResolveBatchCache"];
113
+ for (const { dataSourceKey, collection, filterByTk, strictSelects, fields, appends } of groupMap.values()) {
90
114
  try {
91
115
  const ds = koaCtx.app.dataSourceManager.get(dataSourceKey);
92
116
  const cm = ds.collectionManager;
93
117
  if (!(cm == null ? void 0 : cm.db)) continue;
94
118
  const repo = cm.db.getRepository(collection);
95
- const modelInfo = (_d = repo.collection) == null ? void 0 : _d.model;
119
+ const collectionInfo = repo == null ? void 0 : repo.collection;
120
+ const filterTargetKey = collectionInfo == null ? void 0 : collectionInfo.filterTargetKey;
121
+ const modelInfo = (_f = repo.collection) == null ? void 0 : _f.model;
96
122
  const pkAttr = modelInfo == null ? void 0 : modelInfo.primaryKeyAttribute;
97
- const pkIsValid = pkAttr && (modelInfo == null ? void 0 : modelInfo.rawAttributes) && Object.prototype.hasOwnProperty.call(modelInfo.rawAttributes, pkAttr);
98
- const filterTargetKey = (_e = repo == null ? void 0 : repo.collection) == null ? void 0 : _e.filterTargetKey;
99
- const extraKeyFields = (0, import_records.getExtraKeyFieldsForSelect)(filterByTk, {
123
+ const rawAttributes = (modelInfo == null ? void 0 : modelInfo.rawAttributes) || void 0;
124
+ const pkIsValid = !!(pkAttr && rawAttributes && Object.prototype.hasOwnProperty.call(rawAttributes, pkAttr));
125
+ const fldBase = fields.size ? Array.from(fields).sort() : void 0;
126
+ const extraKeys = (0, import_records.getExtraKeyFieldsForSelect)(filterByTk, {
100
127
  filterTargetKey,
101
128
  pkAttr,
102
129
  pkIsValid,
103
- rawAttributes: modelInfo == null ? void 0 : modelInfo.rawAttributes
130
+ rawAttributes
104
131
  });
105
- if (fields.size && extraKeyFields.length) {
106
- extraKeyFields.forEach((f) => fields.add(f));
107
- }
108
- const fld = fields.size ? Array.from(fields).sort() : void 0;
132
+ const effectiveExtras = strictSelects && Array.isArray(extraKeys) && extraKeys.length ? extraKeys.filter((k) => k === pkAttr) : extraKeys;
133
+ const fld = (0, import_records.mergeFieldsWithExtras)(fldBase, effectiveExtras);
109
134
  const app = appends.size ? Array.from(appends).sort() : void 0;
110
135
  const json = await (0, import_records.fetchRecordOrRecordsJson)(repo, {
111
136
  filterByTk,
112
- preferFullRecord: false,
113
137
  fields: fld,
114
138
  appends: app,
115
139
  filterTargetKey,
@@ -130,7 +154,7 @@ async function prefetchRecordsForResolve(koaCtx, items) {
130
154
  }
131
155
  }
132
156
  } catch (e) {
133
- (_h = (_g = (_f = koaCtx.app) == null ? void 0 : _f.logger) == null ? void 0 : _g.child({ module: "plugin-flow-engine", submodule: "variables.prefetch" })) == null ? void 0 : _h.debug("[variables.resolve] prefetch fatal error", { error: (e == null ? void 0 : e.message) || String(e) });
157
+ (_i = (_h = (_g = koaCtx.app) == null ? void 0 : _g.logger) == null ? void 0 : _h.child({ module: "plugin-flow-engine", submodule: "variables.prefetch" })) == null ? void 0 : _i.debug("[variables.resolve] prefetch fatal error", { error: (e == null ? void 0 : e.message) || String(e) });
134
158
  }
135
159
  }
136
160
  // Annotate the CommonJS export names for ESM import in node:
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-beta.11",
7
+ "version": "2.0.0-beta.13",
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": "a7b36d7c7c42621fb048cd7d82b1e4180b84ab08"
27
+ "gitHead": "3d3db6eb771d20a49559e5f2c0841057196a0c8f"
28
28
  }