@nocobase/plugin-flow-engine 2.3.0-alpha.1 → 2.3.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/ai/ai-employees/nathan/prompt.md +2 -0
  2. package/dist/ai/ai-employees/nathan/skills/frontend-developer/SKILLS.md +1 -0
  3. package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/patchJSCode.js +2 -2
  4. package/dist/ai/docs/runjs/context/ai.md +194 -4
  5. package/dist/externalVersion.js +9 -9
  6. package/dist/locale/en-US.json +2 -0
  7. package/dist/locale/index.d.ts +4 -0
  8. package/dist/locale/zh-CN.json +2 -0
  9. package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
  10. package/dist/node_modules/acorn/package.json +1 -1
  11. package/dist/node_modules/acorn-jsx/package.json +1 -1
  12. package/dist/node_modules/acorn-walk/package.json +1 -1
  13. package/dist/node_modules/ses/package.json +1 -1
  14. package/dist/node_modules/zod/package.json +1 -1
  15. package/dist/server/flow-surfaces/builder.js +5 -0
  16. package/dist/server/flow-surfaces/catalog.js +27 -8
  17. package/dist/server/flow-surfaces/configure-options.js +17 -1
  18. package/dist/server/flow-surfaces/field-binding-registry.js +9 -8
  19. package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +10 -3
  20. package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +90 -8
  21. package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +2 -2
  22. package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +7 -69
  23. package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +5 -5
  24. package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +56 -23
  25. package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +1 -1
  26. package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +4 -2
  27. package/dist/server/flow-surfaces/service-utils.d.ts +1 -0
  28. package/dist/server/flow-surfaces/service-utils.js +17 -0
  29. package/dist/server/flow-surfaces/service.js +9 -0
  30. package/dist/server/index.d.ts +2 -0
  31. package/dist/server/index.js +7 -0
  32. package/dist/server/plugin.d.ts +13 -0
  33. package/dist/server/plugin.js +90 -3
  34. package/dist/server/repository.d.ts +12 -0
  35. package/dist/server/repository.js +39 -2
  36. package/dist/server/template/context-keys.d.ts +14 -0
  37. package/dist/server/template/context-keys.js +86 -0
  38. package/dist/server/template/contexts.d.ts +5 -8
  39. package/dist/server/template/contexts.js +43 -51
  40. package/dist/server/template/resolver.d.ts +5 -13
  41. package/dist/server/template/resolver.js +188 -257
  42. package/dist/server/template/variable-expression.d.ts +72 -0
  43. package/dist/server/template/variable-expression.js +597 -0
  44. package/dist/server/variables/allow-list.d.ts +49 -0
  45. package/dist/server/variables/allow-list.js +546 -0
  46. package/dist/server/variables/form-item-record-slot-resolvers.d.ts +10 -0
  47. package/dist/server/variables/form-item-record-slot-resolvers.js +297 -0
  48. package/dist/server/variables/record-bindings.d.ts +42 -0
  49. package/dist/server/variables/record-bindings.js +196 -0
  50. package/dist/server/variables/record-projection.d.ts +10 -0
  51. package/dist/server/variables/record-projection.js +140 -0
  52. package/dist/server/variables/record-slot-policy.d.ts +23 -0
  53. package/dist/server/variables/record-slot-policy.js +100 -0
  54. package/dist/server/variables/record-slot-resolvers.d.ts +46 -0
  55. package/dist/server/variables/record-slot-resolvers.js +115 -0
  56. package/dist/server/variables/records.d.ts +49 -2
  57. package/dist/server/variables/records.js +309 -18
  58. package/dist/server/variables/registry.d.ts +33 -10
  59. package/dist/server/variables/registry.js +197 -362
  60. package/dist/server/variables/resolve.d.ts +20 -2
  61. package/dist/server/variables/resolve.js +85 -13
  62. package/dist/server/variables/runjs-variable-dependencies.d.ts +23 -0
  63. package/dist/server/variables/runjs-variable-dependencies.js +542 -0
  64. package/dist/server/variables/selects.js +6 -3
  65. package/dist/server/variables/utils.d.ts +3 -6
  66. package/dist/server/variables/utils.js +50 -111
  67. package/package.json +2 -2
@@ -7,9 +7,11 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
 
10
+ var __create = Object.create;
10
11
  var __defProp = Object.defineProperty;
11
12
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
13
  var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
13
15
  var __hasOwnProp = Object.prototype.hasOwnProperty;
14
16
  var __export = (target, all) => {
15
17
  for (var name in all)
@@ -23,14 +25,285 @@ var __copyProps = (to, from, except, desc) => {
23
25
  }
24
26
  return to;
25
27
  };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
26
36
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
37
  var records_exports = {};
28
38
  __export(records_exports, {
29
39
  fetchRecordOrRecordsJson: () => fetchRecordOrRecordsJson,
40
+ fetchRecordWithRequestCache: () => fetchRecordWithRequestCache,
41
+ findRecordRequestCacheValue: () => findRecordRequestCacheValue,
30
42
  getExtraKeyFieldsForSelect: () => getExtraKeyFieldsForSelect,
31
- mergeFieldsWithExtras: () => mergeFieldsWithExtras
43
+ getRecordRequestCache: () => getRecordRequestCache,
44
+ isRecordParams: () => isRecordParams,
45
+ mergeFieldsWithExtras: () => mergeFieldsWithExtras,
46
+ prepareRecordQuery: () => prepareRecordQuery,
47
+ resolveRecordTarget: () => resolveRecordTarget,
48
+ setRecordRequestCache: () => setRecordRequestCache
32
49
  });
33
50
  module.exports = __toCommonJS(records_exports);
51
+ var import_lodash = __toESM(require("lodash"));
52
+ var import_selects = require("./selects");
53
+ function sortIdentityValue(value) {
54
+ if (Array.isArray(value)) return value.map(sortIdentityValue);
55
+ if (!import_lodash.default.isPlainObject(value)) return value;
56
+ return Object.fromEntries(
57
+ Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => [key, sortIdentityValue(child)])
58
+ );
59
+ }
60
+ function getBaseIdentityKey(identity) {
61
+ return JSON.stringify(sortIdentityValue(identity));
62
+ }
63
+ function createCacheMetadata(query) {
64
+ const cacheIdentity = {
65
+ ds: query.ds,
66
+ c: query.c,
67
+ assoc: query.assoc,
68
+ sid: query.sid,
69
+ tk: query.tk
70
+ };
71
+ return {
72
+ appends: query.a ? new Set(query.a) : void 0,
73
+ baseIdentityKey: getBaseIdentityKey(cacheIdentity),
74
+ cacheIdentity,
75
+ fields: query.f ? new Set(query.f) : void 0,
76
+ full: query.full === true
77
+ };
78
+ }
79
+ class RecordRequestCache extends Map {
80
+ keysByBaseIdentity = /* @__PURE__ */ new Map();
81
+ metadataByKey = /* @__PURE__ */ new Map();
82
+ constructor(entries) {
83
+ super();
84
+ entries == null ? void 0 : entries.forEach((value, key) => this.set(key, value));
85
+ }
86
+ set(cacheKey, value) {
87
+ let metadata;
88
+ try {
89
+ metadata = createCacheMetadata(JSON.parse(cacheKey));
90
+ } catch (_2) {
91
+ }
92
+ return this.setWithMetadata(cacheKey, value, metadata);
93
+ }
94
+ setQuery(query, value) {
95
+ return this.setWithMetadata(
96
+ query.cacheKey,
97
+ value,
98
+ createCacheMetadata({
99
+ ...query.cacheIdentity,
100
+ tk: query.filterByTk,
101
+ f: query.fields,
102
+ a: query.appends,
103
+ full: query.preferFullRecord
104
+ })
105
+ );
106
+ }
107
+ delete(cacheKey) {
108
+ this.removeFromIndex(cacheKey);
109
+ return super.delete(cacheKey);
110
+ }
111
+ clear() {
112
+ super.clear();
113
+ this.keysByBaseIdentity.clear();
114
+ this.metadataByKey.clear();
115
+ }
116
+ *candidates(query) {
117
+ const baseIdentityKey = getBaseIdentityKey({
118
+ ...query.cacheIdentity,
119
+ tk: query.filterByTk
120
+ });
121
+ for (const cacheKey of this.keysByBaseIdentity.get(baseIdentityKey) || []) {
122
+ const metadata = this.metadataByKey.get(cacheKey);
123
+ if (metadata && super.has(cacheKey)) yield [metadata, super.get(cacheKey)];
124
+ }
125
+ }
126
+ setWithMetadata(cacheKey, value, metadata) {
127
+ this.removeFromIndex(cacheKey);
128
+ super.set(cacheKey, value);
129
+ if (!metadata) return this;
130
+ this.metadataByKey.set(cacheKey, metadata);
131
+ let keys = this.keysByBaseIdentity.get(metadata.baseIdentityKey);
132
+ if (!keys) {
133
+ keys = /* @__PURE__ */ new Set();
134
+ this.keysByBaseIdentity.set(metadata.baseIdentityKey, keys);
135
+ }
136
+ keys.add(cacheKey);
137
+ return this;
138
+ }
139
+ removeFromIndex(cacheKey) {
140
+ const metadata = this.metadataByKey.get(cacheKey);
141
+ if (!metadata) return;
142
+ const keys = this.keysByBaseIdentity.get(metadata.baseIdentityKey);
143
+ keys == null ? void 0 : keys.delete(cacheKey);
144
+ if (!(keys == null ? void 0 : keys.size)) this.keysByBaseIdentity.delete(metadata.baseIdentityKey);
145
+ this.metadataByKey.delete(cacheKey);
146
+ }
147
+ }
148
+ function isRecordParams(value) {
149
+ return !!value && typeof value === "object" && typeof value.collection === "string" && Object.prototype.hasOwnProperty.call(value, "filterByTk");
150
+ }
151
+ function resolveRecordTarget(koaCtx, params) {
152
+ var _a, _b, _c, _d, _e, _f;
153
+ const dataSourceKey = params.dataSourceKey || "main";
154
+ const usesAssociation = !!(params.associationName && typeof params.sourceId !== "undefined");
155
+ const associationSourceCollection = usesAssociation ? (_a = params.associationName) == null ? void 0 : _a.split(".")[0] : void 0;
156
+ const context = koaCtx;
157
+ if (!context.state) context.state = {};
158
+ const targets = context.state.__varResolveRecordTargets ??= /* @__PURE__ */ new Map();
159
+ const requestKey = JSON.stringify({
160
+ ds: dataSourceKey,
161
+ c: params.collection,
162
+ assoc: usesAssociation ? params.associationName : void 0,
163
+ sid: usesAssociation ? params.sourceId : void 0
164
+ });
165
+ if (targets.has(requestKey)) return targets.get(requestKey);
166
+ const ds = koaCtx.app.dataSourceManager.get(dataSourceKey);
167
+ const cm = ds.collectionManager;
168
+ let repository;
169
+ if (typeof cm.getRepository === "function") {
170
+ repository = usesAssociation ? cm.getRepository(params.associationName, params.sourceId) : cm.getRepository(params.collection);
171
+ } else if (typeof ((_b = cm.db) == null ? void 0 : _b.getRepository) === "function") {
172
+ repository = usesAssociation ? cm.db.getRepository(params.associationName, params.sourceId) : cm.db.getRepository(params.collection);
173
+ }
174
+ if (!repository) {
175
+ targets.set(requestKey, void 0);
176
+ return void 0;
177
+ }
178
+ const repositoryMetadata = repository;
179
+ let collection = repositoryMetadata.targetCollection || repositoryMetadata.collection;
180
+ if (!usesAssociation && !collection) {
181
+ collection = (typeof cm.getCollection === "function" ? cm.getCollection(params.collection) : (_d = (_c = cm.db) == null ? void 0 : _c.getCollection) == null ? void 0 : _d.call(_c, params.collection)) || { name: params.collection };
182
+ }
183
+ if (!collection) {
184
+ targets.set(requestKey, void 0);
185
+ return void 0;
186
+ }
187
+ if (usesAssociation && (!collection.name || collection.name !== params.collection && associationSourceCollection !== params.collection)) {
188
+ targets.set(requestKey, void 0);
189
+ return void 0;
190
+ }
191
+ const rawAttributes = (_e = collection.model) == null ? void 0 : _e.rawAttributes;
192
+ const pkAttr = (_f = collection.model) == null ? void 0 : _f.primaryKeyAttribute;
193
+ const pkIsValid = !!(pkAttr && rawAttributes && Object.prototype.hasOwnProperty.call(rawAttributes, pkAttr));
194
+ const collectionName = collection.name || params.associationName || params.collection;
195
+ const target = {
196
+ repository,
197
+ dataSourceKey,
198
+ collection,
199
+ collectionName,
200
+ filterTargetKey: collection.filterTargetKey,
201
+ pkAttr,
202
+ pkIsValid,
203
+ rawAttributes,
204
+ cacheIdentity: {
205
+ ds: dataSourceKey,
206
+ c: collectionName,
207
+ assoc: usesAssociation ? params.associationName : void 0,
208
+ sid: usesAssociation ? params.sourceId : void 0
209
+ }
210
+ };
211
+ targets.set(requestKey, target);
212
+ return target;
213
+ }
214
+ function prepareRecordQuery(koaCtx, target, filterByTk, fields, appends, strictSelects = false, preferFullRecord = false) {
215
+ var _a;
216
+ const adjusted = (0, import_selects.adjustSelectsForCollection)(koaCtx, target.dataSourceKey, target.collectionName, fields, appends);
217
+ const extraKeys = getExtraKeyFieldsForSelect(filterByTk, target);
218
+ const selectedFields = mergeFieldsWithExtras(
219
+ strictSelects && Array.isArray(fields) ? adjusted.fields || [] : adjusted.fields,
220
+ extraKeys
221
+ );
222
+ const queryFields = preferFullRecord ? void 0 : selectedFields == null ? void 0 : selectedFields.slice().sort();
223
+ const queryAppends = preferFullRecord ? void 0 : (_a = adjusted.appends) == null ? void 0 : _a.slice().sort();
224
+ const cacheKey = JSON.stringify({
225
+ ...target.cacheIdentity,
226
+ tk: filterByTk,
227
+ f: queryFields,
228
+ a: queryAppends,
229
+ full: preferFullRecord || void 0,
230
+ strict: strictSelects || void 0
231
+ });
232
+ return {
233
+ ...target,
234
+ filterByTk,
235
+ fields: queryFields,
236
+ appends: queryAppends,
237
+ preferFullRecord,
238
+ strictSelects,
239
+ cacheKey
240
+ };
241
+ }
242
+ function getRecordRequestCache(koaCtx) {
243
+ const context = koaCtx;
244
+ if (!context.state) context.state = {};
245
+ const existing = context.state.__varResolveBatchCache;
246
+ if (existing instanceof RecordRequestCache) return existing;
247
+ const cache = new RecordRequestCache(existing instanceof Map ? existing : void 0);
248
+ context.state.__varResolveBatchCache = cache;
249
+ return cache;
250
+ }
251
+ function setRecordRequestCache(cache, query, value) {
252
+ if (cache instanceof RecordRequestCache) return cache.setQuery(query, value);
253
+ return cache.set(query.cacheKey, value);
254
+ }
255
+ function cachedQueryCovers(query, cached) {
256
+ if (cached.cacheIdentity.ds !== query.cacheIdentity.ds || cached.cacheIdentity.c !== query.cacheIdentity.c || cached.cacheIdentity.assoc !== query.cacheIdentity.assoc || !import_lodash.default.isEqual(cached.cacheIdentity.sid, query.cacheIdentity.sid) || !import_lodash.default.isEqual(cached.cacheIdentity.tk, query.filterByTk)) {
257
+ return false;
258
+ }
259
+ if (cached.full) return true;
260
+ if (query.preferFullRecord) return false;
261
+ const cachedFields = cached.fields || /* @__PURE__ */ new Set();
262
+ const cachedAppends = cached.appends || /* @__PURE__ */ new Set();
263
+ const fieldCovered = (field) => cachedFields.has(field) || [...cachedAppends].some((append) => field === append || field.startsWith(`${append}.`));
264
+ return (query.fields ? query.fields.every(fieldCovered) : cached.fields === void 0) && (!query.appends || query.appends.every((append) => cachedAppends.has(append)));
265
+ }
266
+ function findRecordRequestCacheValue(cache, query) {
267
+ if (cache.has(query.cacheKey)) return { hit: true, value: cache.get(query.cacheKey) };
268
+ if (cache instanceof RecordRequestCache) {
269
+ for (const [metadata, value] of cache.candidates(query)) {
270
+ if (cachedQueryCovers(query, metadata)) return { hit: true, value };
271
+ }
272
+ }
273
+ return { hit: false, value: void 0 };
274
+ }
275
+ async function fetchRecordWithRequestCache(koaCtx, params, fields, appends, strictSelects = false, preferFullRecord = false) {
276
+ var _a, _b, _c;
277
+ try {
278
+ const target = resolveRecordTarget(koaCtx, params);
279
+ if (!target) return void 0;
280
+ const query = prepareRecordQuery(
281
+ koaCtx,
282
+ target,
283
+ params.filterByTk,
284
+ fields,
285
+ appends,
286
+ strictSelects,
287
+ preferFullRecord
288
+ );
289
+ const cache = getRecordRequestCache(koaCtx);
290
+ const cached = findRecordRequestCacheValue(cache, query);
291
+ if (cached.hit) return cached.value;
292
+ const value = await fetchRecordOrRecordsJson(query.repository, query, koaCtx);
293
+ setRecordRequestCache(cache, query, value);
294
+ return value;
295
+ } catch (error) {
296
+ (_c = (_b = (_a = koaCtx.app) == null ? void 0 : _a.logger) == null ? void 0 : _b.child({ module: "plugin-flow-engine", submodule: "variables.resolve", method: "fetchRecordWithRequestCache" })) == null ? void 0 : _c.warn("[variables.resolve] fetchRecordWithRequestCache error", {
297
+ ds: params.dataSourceKey || "main",
298
+ collection: params.collection,
299
+ tk: params.filterByTk,
300
+ fields,
301
+ appends,
302
+ error: error instanceof Error ? error.message : String(error)
303
+ });
304
+ return void 0;
305
+ }
306
+ }
34
307
  function uniqStrings(list) {
35
308
  return Array.from(new Set(list));
36
309
  }
@@ -49,18 +322,16 @@ function getExtraKeyFieldsForSelect(filterByTk, options) {
49
322
  }
50
323
  if (Array.isArray(filterByTk) && filterByTk.length > 0) {
51
324
  const tkKeys = typeof options.filterTargetKey === "string" ? [options.filterTargetKey] : Array.isArray(options.filterTargetKey) ? options.filterTargetKey : [];
52
- if (options.rawAttributes) {
53
- for (const k of tkKeys) {
54
- if (k && Object.prototype.hasOwnProperty.call(options.rawAttributes, k)) {
55
- extra.push(k);
56
- }
325
+ for (const k of tkKeys) {
326
+ if (k && (!options.rawAttributes || Object.prototype.hasOwnProperty.call(options.rawAttributes, k))) {
327
+ extra.push(k);
57
328
  }
58
329
  }
59
330
  }
60
331
  return uniqStrings(extra);
61
332
  }
62
333
  function mergeFieldsWithExtras(fields, extras = []) {
63
- if (!Array.isArray(fields) || fields.length === 0 || extras.length === 0) return fields;
334
+ if (!Array.isArray(fields) || extras.length === 0) return fields;
64
335
  return uniqStrings([...fields, ...extras]);
65
336
  }
66
337
  function toJsonRecord(record) {
@@ -72,6 +343,20 @@ function toJsonArray(rows) {
72
343
  if (!Array.isArray(rows)) return [];
73
344
  return rows.map(toJsonRecord);
74
345
  }
346
+ function createRecordRepositoryContext(context, params) {
347
+ var _a;
348
+ if (!((_a = context.action) == null ? void 0 : _a.params)) return context;
349
+ const repositoryContext = Object.create(context);
350
+ const repositoryAction = Object.create(context.action);
351
+ repositoryAction.params = {
352
+ ...context.action.params,
353
+ filterByTk: params.filterByTk,
354
+ fields: params.fields,
355
+ appends: params.appends
356
+ };
357
+ repositoryContext.action = repositoryAction;
358
+ return repositoryContext;
359
+ }
75
360
  function reorderRecordsByFilterByTk(records, filterByTk, options) {
76
361
  if (!Array.isArray(filterByTk) || filterByTk.length === 0) return records;
77
362
  if (!isPrimitiveTkArray(filterByTk)) return records;
@@ -79,7 +364,7 @@ function reorderRecordsByFilterByTk(records, filterByTk, options) {
79
364
  if (!orderKey) return records;
80
365
  const map = /* @__PURE__ */ new Map();
81
366
  for (const rec of records || []) {
82
- const k = rec == null ? void 0 : rec[orderKey];
367
+ const k = rec && typeof rec === "object" ? rec[orderKey] : void 0;
83
368
  if (typeof k !== "undefined" && k !== null) {
84
369
  map.set(String(k), rec);
85
370
  }
@@ -95,31 +380,37 @@ function reorderRecordsByFilterByTk(records, filterByTk, options) {
95
380
  }
96
381
  }
97
382
  for (const rec of records || []) {
98
- const k = rec == null ? void 0 : rec[orderKey];
383
+ const k = rec && typeof rec === "object" ? rec[orderKey] : void 0;
99
384
  const ks = typeof k === "undefined" || k === null ? void 0 : String(k);
100
385
  if (!ks || used.has(ks)) continue;
101
386
  ordered.push(rec);
102
387
  }
103
388
  return ordered;
104
389
  }
105
- async function fetchRecordOrRecordsJson(repo, params) {
390
+ async function fetchRecordOrRecordsJson(repo, params, context) {
106
391
  const { filterByTk, preferFullRecord, fields, appends } = params;
392
+ if (Array.isArray(filterByTk) && filterByTk.length === 0) return [];
393
+ const query = preferFullRecord ? { filterByTk } : { filterByTk, fields, appends };
394
+ const repositoryContext = createRecordRepositoryContext(context, query);
395
+ const repositoryOptions = { ...query, context: repositoryContext };
107
396
  if (Array.isArray(filterByTk)) {
108
- if (filterByTk.length === 0) return [];
109
- const rows = await repo.find(
110
- preferFullRecord ? { filterByTk } : { filterByTk, fields, appends }
111
- );
397
+ const rows = await repo.find(repositoryOptions);
112
398
  const jsonArr = toJsonArray(rows);
113
399
  return reorderRecordsByFilterByTk(jsonArr, filterByTk, params);
114
400
  }
115
- const rec = await repo.findOne(
116
- preferFullRecord ? { filterByTk } : { filterByTk, fields, appends }
117
- );
401
+ const rec = await repo.findOne(repositoryOptions);
118
402
  return rec ? toJsonRecord(rec) : void 0;
119
403
  }
120
404
  // Annotate the CommonJS export names for ESM import in node:
121
405
  0 && (module.exports = {
122
406
  fetchRecordOrRecordsJson,
407
+ fetchRecordWithRequestCache,
408
+ findRecordRequestCacheValue,
123
409
  getExtraKeyFieldsForSelect,
124
- mergeFieldsWithExtras
410
+ getRecordRequestCache,
411
+ isRecordParams,
412
+ mergeFieldsWithExtras,
413
+ prepareRecordQuery,
414
+ resolveRecordTarget,
415
+ setRecordRequestCache
125
416
  });
@@ -6,8 +6,10 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import { HttpRequestContext } from '../template/contexts';
10
9
  import { ResourcerContext } from '@nocobase/resourcer';
10
+ import { HttpRequestContext } from '../template/contexts';
11
+ import { type PathSegment, type VariablePathRef } from '../template/variable-expression';
12
+ import { type AuthorizedRecordBinding, type RecordBindingPlan } from './record-bindings';
11
13
  export type JSONValue = string | {
12
14
  [key: string]: JSONValue;
13
15
  } | JSONValue[];
@@ -15,38 +17,59 @@ export type VarScope = 'global' | 'request';
15
17
  export interface RequiredParamSpec {
16
18
  name: string;
17
19
  required?: boolean;
18
- defaultValue?: any;
20
+ defaultValue?: unknown;
19
21
  }
22
+ export type ValidateContextParamsOptions = {
23
+ contextParams: Record<string, unknown>;
24
+ flowModelUid?: string;
25
+ koaCtx: ResourcerContext;
26
+ usage: readonly VariablePathRef[];
27
+ varName: string;
28
+ };
29
+ export type ValidateContextParamsResult = {
30
+ allowed?: boolean;
31
+ contextParams?: Record<string, unknown>;
32
+ requireFlowModel?: boolean;
33
+ };
20
34
  export interface VariableDef {
21
35
  name: string;
22
36
  scope: VarScope;
23
37
  requiredParams?: RequiredParamSpec[];
24
- attach: (ctx: HttpRequestContext, koaCtx: ResourcerContext, params?: any, usage?: VarUsage) => Promise<void> | void;
38
+ attach: (ctx: HttpRequestContext, koaCtx: ResourcerContext, params?: unknown, usage?: VarUsage) => Promise<void> | void;
39
+ validateContextParams?: (options: ValidateContextParamsOptions) => Promise<ValidateContextParamsResult | void> | ValidateContextParamsResult | void;
25
40
  }
26
- export type VarUsage = {
27
- [varName: string]: string[];
28
- };
41
+ export type VarUsage = Readonly<Record<string, readonly VariablePathRef[]>>;
42
+ type LegacyVarUsage = Record<string, string[]>;
29
43
  declare class VariableRegistry {
30
44
  private vars;
31
45
  register(def: VariableDef): void;
32
46
  get(name: string): VariableDef;
33
47
  list(): VariableDef[];
34
- extractUsage(template: JSONValue): VarUsage;
35
- validate(template: JSONValue, contextParams: any): {
48
+ extractUsage(template: JSONValue): LegacyVarUsage;
49
+ validate(template: JSONValue, contextParams: unknown): {
36
50
  ok: boolean;
37
51
  missing?: string[];
38
52
  };
39
- attachUsedVariables(ctx: HttpRequestContext, koaCtx: ResourcerContext, template: JSONValue, contextParams: any): Promise<void>;
53
+ attachUsedVariables(ctx: HttpRequestContext, koaCtx: ResourcerContext, template: JSONValue, contextParams: Record<string, unknown>): Promise<void>;
54
+ attachUsedVariablesFromUsage(ctx: HttpRequestContext, koaCtx: ResourcerContext, usage: VarUsage, contextParams: Record<string, unknown>): Promise<void>;
55
+ attachUsedVariablesFromPlan(ctx: HttpRequestContext, koaCtx: ResourcerContext, usage: VarUsage, plan: RecordBindingPlan): Promise<void>;
40
56
  }
41
57
  export declare const variables: VariableRegistry;
42
58
  /** 仅测试使用:重置变量注册表为内置默认集 */
59
+ export declare function omitVariableContextParams(contextParams: Record<string, unknown>, varName: string): Record<string, unknown>;
60
+ export declare function sanitizeRegisteredVariableContextParams(contextParams: Record<string, unknown>, registry?: {
61
+ get?: (name: string) => VariableDef | undefined;
62
+ list?: () => VariableDef[];
63
+ }): Record<string, unknown>;
43
64
  /**
44
65
  * 从使用路径推断查询所需的 fields 与 appends。
45
66
  * @param paths 使用到的子路径数组
46
67
  * @param params 显式参数(仅用于兼容签名)
47
68
  */
48
- export declare function inferSelectsFromUsage(paths?: string[], _params?: unknown): {
69
+ export declare function inferSelectsFromUsage(paths?: readonly (string | readonly PathSegment[])[], _params?: unknown): {
49
70
  generatedAppends?: string[];
50
71
  generatedFields?: string[];
51
72
  };
73
+ export declare function isSafeRecordBinding(binding: AuthorizedRecordBinding): boolean;
74
+ export declare function registerBuiltInVariables(reg: VariableRegistry): void;
52
75
  export {};