@nocobase/plugin-flow-engine 2.3.0-alpha.1 → 2.3.0-beta.10
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.
- package/dist/ai/ai-employees/nathan/prompt.md +2 -0
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/SKILLS.md +1 -0
- package/dist/ai/ai-employees/nathan/skills/frontend-developer/tools/patchJSCode.js +2 -2
- package/dist/ai/docs/runjs/context/ai.md +194 -4
- package/dist/externalVersion.js +9 -9
- package/dist/locale/en-US.json +2 -0
- package/dist/locale/index.d.ts +4 -0
- package/dist/locale/zh-CN.json +2 -0
- package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
- package/dist/node_modules/acorn/package.json +1 -1
- package/dist/node_modules/acorn-jsx/package.json +1 -1
- package/dist/node_modules/acorn-walk/package.json +1 -1
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/flow-surfaces/builder.js +5 -0
- package/dist/server/flow-surfaces/catalog.js +27 -8
- package/dist/server/flow-surfaces/configure-options.js +17 -1
- package/dist/server/flow-surfaces/field-binding-registry.js +9 -8
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +10 -3
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +90 -8
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +2 -2
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +7 -69
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +5 -5
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +56 -23
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +4 -2
- package/dist/server/flow-surfaces/service-utils.d.ts +1 -0
- package/dist/server/flow-surfaces/service-utils.js +17 -0
- package/dist/server/flow-surfaces/service.js +9 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +7 -0
- package/dist/server/plugin.d.ts +13 -0
- package/dist/server/plugin.js +90 -3
- package/dist/server/repository.d.ts +12 -0
- package/dist/server/repository.js +39 -2
- package/dist/server/template/context-keys.d.ts +14 -0
- package/dist/server/template/context-keys.js +86 -0
- package/dist/server/template/contexts.d.ts +5 -8
- package/dist/server/template/contexts.js +43 -51
- package/dist/server/template/resolver.d.ts +5 -13
- package/dist/server/template/resolver.js +188 -257
- package/dist/server/template/variable-expression.d.ts +72 -0
- package/dist/server/template/variable-expression.js +597 -0
- package/dist/server/variables/allow-list.d.ts +49 -0
- package/dist/server/variables/allow-list.js +546 -0
- package/dist/server/variables/form-item-record-slot-resolvers.d.ts +10 -0
- package/dist/server/variables/form-item-record-slot-resolvers.js +297 -0
- package/dist/server/variables/record-bindings.d.ts +42 -0
- package/dist/server/variables/record-bindings.js +196 -0
- package/dist/server/variables/record-projection.d.ts +10 -0
- package/dist/server/variables/record-projection.js +140 -0
- package/dist/server/variables/record-slot-policy.d.ts +23 -0
- package/dist/server/variables/record-slot-policy.js +100 -0
- package/dist/server/variables/record-slot-resolvers.d.ts +46 -0
- package/dist/server/variables/record-slot-resolvers.js +115 -0
- package/dist/server/variables/records.d.ts +49 -2
- package/dist/server/variables/records.js +309 -18
- package/dist/server/variables/registry.d.ts +33 -10
- package/dist/server/variables/registry.js +197 -362
- package/dist/server/variables/resolve.d.ts +20 -2
- package/dist/server/variables/resolve.js +85 -13
- package/dist/server/variables/runjs-variable-dependencies.d.ts +23 -0
- package/dist/server/variables/runjs-variable-dependencies.js +542 -0
- package/dist/server/variables/selects.js +6 -3
- package/dist/server/variables/utils.d.ts +3 -6
- package/dist/server/variables/utils.js +50 -111
- 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
|
-
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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) ||
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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?:
|
|
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?:
|
|
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
|
-
|
|
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):
|
|
35
|
-
validate(template: JSONValue, contextParams:
|
|
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:
|
|
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 {};
|