@nocobase/plugin-flow-engine 3.0.0-alpha.6 → 3.0.0-alpha.7
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/externalVersion.js +9 -9
- 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/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 +11 -0
- package/dist/server/plugin.js +85 -3
- package/dist/server/repository.d.ts +8 -0
- package/dist/server/repository.js +29 -0
- 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 +48 -0
- package/dist/server/variables/allow-list.js +374 -0
- package/dist/server/variables/form-item-record-slot-resolvers.d.ts +10 -0
- package/dist/server/variables/form-item-record-slot-resolvers.js +280 -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 +47 -1
- package/dist/server/variables/records.js +279 -5
- package/dist/server/variables/registry.d.ts +33 -10
- package/dist/server/variables/registry.js +197 -362
- package/dist/server/variables/resolve.d.ts +18 -2
- package/dist/server/variables/resolve.js +79 -13
- package/dist/server/variables/runjs-variable-dependencies.d.ts +21 -0
- package/dist/server/variables/runjs-variable-dependencies.js +313 -0
- package/dist/server/variables/utils.d.ts +3 -6
- package/dist/server/variables/utils.js +50 -111
- package/package.json +2 -2
|
@@ -37,14 +37,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
37
37
|
var registry_exports = {};
|
|
38
38
|
__export(registry_exports, {
|
|
39
39
|
inferSelectsFromUsage: () => inferSelectsFromUsage,
|
|
40
|
+
isSafeRecordBinding: () => isSafeRecordBinding,
|
|
41
|
+
omitVariableContextParams: () => omitVariableContextParams,
|
|
42
|
+
registerBuiltInVariables: () => registerBuiltInVariables,
|
|
43
|
+
sanitizeRegisteredVariableContextParams: () => sanitizeRegisteredVariableContextParams,
|
|
40
44
|
variables: () => variables
|
|
41
45
|
});
|
|
42
46
|
module.exports = __toCommonJS(registry_exports);
|
|
43
47
|
var import_lodash = __toESM(require("lodash"));
|
|
44
|
-
var import_contexts = require("../template/contexts");
|
|
45
48
|
var import_utils = require("@nocobase/utils");
|
|
46
|
-
var
|
|
49
|
+
var import_context_keys = require("../template/context-keys");
|
|
50
|
+
var import_contexts = require("../template/contexts");
|
|
51
|
+
var import_variable_expression = require("../template/variable-expression");
|
|
52
|
+
var import_record_bindings = require("./record-bindings");
|
|
53
|
+
var import_record_projection = require("./record-projection");
|
|
47
54
|
var import_records = require("./records");
|
|
55
|
+
var import_record_slot_policy = require("./record-slot-policy");
|
|
48
56
|
class VariableRegistry {
|
|
49
57
|
vars = /* @__PURE__ */ new Map();
|
|
50
58
|
register(def) {
|
|
@@ -76,15 +84,31 @@ class VariableRegistry {
|
|
|
76
84
|
return { ok: missing.length === 0, missing: missing.length ? missing : void 0 };
|
|
77
85
|
}
|
|
78
86
|
async attachUsedVariables(ctx, koaCtx, template, contextParams) {
|
|
79
|
-
const usage =
|
|
87
|
+
const usage = (0, import_variable_expression.analyzeVariableTemplate)(template).usage;
|
|
88
|
+
return this.attachUsedVariablesFromUsage(ctx, koaCtx, usage, contextParams);
|
|
89
|
+
}
|
|
90
|
+
async attachUsedVariablesFromUsage(ctx, koaCtx, usage, contextParams) {
|
|
91
|
+
const policies = await (0, import_record_slot_policy.compileRecordSlotPolicies)(
|
|
92
|
+
{ paths: Object.values(usage).flat() },
|
|
93
|
+
{ app: koaCtx.app, ctx: koaCtx }
|
|
94
|
+
);
|
|
95
|
+
const plan = (0, import_record_bindings.planRecordBindings)({
|
|
96
|
+
contextParams,
|
|
97
|
+
koaCtx,
|
|
98
|
+
policies,
|
|
99
|
+
usage
|
|
100
|
+
});
|
|
101
|
+
return this.attachUsedVariablesFromPlan(ctx, koaCtx, usage, await plan);
|
|
102
|
+
}
|
|
103
|
+
async attachUsedVariablesFromPlan(ctx, koaCtx, usage, plan) {
|
|
80
104
|
for (const varName of Object.keys(usage)) {
|
|
81
105
|
const def = this.get(varName);
|
|
82
|
-
const params = import_lodash.default.get(contextParams, varName);
|
|
106
|
+
const params = import_lodash.default.get(plan.contextParams, varName);
|
|
83
107
|
if (def) {
|
|
84
108
|
await def.attach(ctx, koaCtx, params, { [varName]: usage[varName] });
|
|
85
109
|
}
|
|
86
110
|
}
|
|
87
|
-
|
|
111
|
+
attachAuthorizedRecordBindings(ctx, koaCtx, plan.bindings);
|
|
88
112
|
}
|
|
89
113
|
}
|
|
90
114
|
const GLOBAL_KEY = "__ncbVarRegistry__";
|
|
@@ -96,6 +120,29 @@ if (!g[GLOBAL_KEY]) {
|
|
|
96
120
|
g[GLOBAL_KEY] = new VariableRegistry();
|
|
97
121
|
}
|
|
98
122
|
const variables = g[GLOBAL_KEY];
|
|
123
|
+
function omitVariableContextParams(contextParams, varName) {
|
|
124
|
+
if (!contextParams || typeof contextParams !== "object") return {};
|
|
125
|
+
const prefix = `${varName}.`;
|
|
126
|
+
const next = {};
|
|
127
|
+
for (const [key, value] of Object.entries(contextParams)) {
|
|
128
|
+
if (key === varName || key.startsWith(prefix)) continue;
|
|
129
|
+
next[key] = value;
|
|
130
|
+
}
|
|
131
|
+
return next;
|
|
132
|
+
}
|
|
133
|
+
function sanitizeRegisteredVariableContextParams(contextParams, registry = variables) {
|
|
134
|
+
let next = contextParams;
|
|
135
|
+
const defs = typeof registry.list === "function" ? registry.list() : ["user"].map((name) => {
|
|
136
|
+
var _a;
|
|
137
|
+
return (_a = registry.get) == null ? void 0 : _a.call(registry, name);
|
|
138
|
+
}).filter((def) => !!def);
|
|
139
|
+
for (const def of defs) {
|
|
140
|
+
if (def.name === "user") {
|
|
141
|
+
next = omitVariableContextParams(next, def.name);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return next;
|
|
145
|
+
}
|
|
99
146
|
function inferSelectsFromUsage(paths = [], _params) {
|
|
100
147
|
if (!Array.isArray(paths) || paths.length === 0) {
|
|
101
148
|
return { generatedAppends: void 0, generatedFields: void 0 };
|
|
@@ -111,14 +158,23 @@ function inferSelectsFromUsage(paths = [], _params) {
|
|
|
111
158
|
s = s.replace(/^\./, "").replace(/\.$/, "");
|
|
112
159
|
return s;
|
|
113
160
|
};
|
|
114
|
-
for (
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
161
|
+
for (const value of paths) {
|
|
162
|
+
let segments;
|
|
163
|
+
if (Array.isArray(value)) {
|
|
164
|
+
if (value.some((segment) => typeof segment === "string" && segment.includes("."))) {
|
|
165
|
+
return { generatedAppends: void 0, generatedFields: void 0 };
|
|
166
|
+
}
|
|
167
|
+
segments = value.filter((segment) => typeof segment === "string" && !!segment);
|
|
168
|
+
} else {
|
|
169
|
+
let path = value;
|
|
170
|
+
if (!path) continue;
|
|
171
|
+
while (/^\[(\d+)\](\.|$)/.test(path)) {
|
|
172
|
+
path = path.replace(/^\[(\d+)\]\.?/, "");
|
|
173
|
+
}
|
|
174
|
+
const norm = normalizePath(path);
|
|
175
|
+
if (!norm) continue;
|
|
176
|
+
segments = norm.split(".").filter(Boolean);
|
|
118
177
|
}
|
|
119
|
-
const norm = normalizePath(path);
|
|
120
|
-
if (!norm) continue;
|
|
121
|
-
const segments = norm.split(".").filter(Boolean);
|
|
122
178
|
if (segments.length === 0) continue;
|
|
123
179
|
if (segments.length === 1) {
|
|
124
180
|
fieldSet.add(segments[0]);
|
|
@@ -133,345 +189,111 @@ function inferSelectsFromUsage(paths = [], _params) {
|
|
|
133
189
|
const generatedFields = fieldSet.size ? Array.from(fieldSet) : void 0;
|
|
134
190
|
return { generatedAppends, generatedFields };
|
|
135
191
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!kctx.state["__varResolveBatchCache"]) {
|
|
147
|
-
kctx.state["__varResolveBatchCache"] = /* @__PURE__ */ new Map();
|
|
192
|
+
function createRecordProviderNode() {
|
|
193
|
+
return { children: /* @__PURE__ */ new Map() };
|
|
194
|
+
}
|
|
195
|
+
function addRecordProviderBinding(root, binding) {
|
|
196
|
+
let node = root;
|
|
197
|
+
for (const segment of binding.prefix) {
|
|
198
|
+
let child = node.children.get(segment);
|
|
199
|
+
if (!child) {
|
|
200
|
+
child = createRecordProviderNode();
|
|
201
|
+
node.children.set(segment, child);
|
|
148
202
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
full: preferFullRecord ? true : void 0,
|
|
176
|
-
assoc: associationName,
|
|
177
|
-
sid: typeof sourceId === "undefined" ? void 0 : sourceId
|
|
178
|
-
};
|
|
179
|
-
const key = JSON.stringify(keyObj);
|
|
180
|
-
if (cache) {
|
|
181
|
-
if (cache.has(key)) {
|
|
182
|
-
return cache.get(key);
|
|
183
|
-
}
|
|
184
|
-
if (!strictSelects) {
|
|
185
|
-
const needFields = !preferFullRecord && Array.isArray(fieldsWithExtras) ? [...new Set(fieldsWithExtras)] : void 0;
|
|
186
|
-
const needAppends = !preferFullRecord && Array.isArray(appends) ? new Set(appends) : void 0;
|
|
187
|
-
for (const [cacheKey, cacheVal] of cache.entries()) {
|
|
188
|
-
const parsed = JSON.parse(cacheKey);
|
|
189
|
-
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))
|
|
190
|
-
continue;
|
|
191
|
-
const cachedFields = new Set(parsed.f || []);
|
|
192
|
-
const cachedAppends = new Set(parsed.a || []);
|
|
193
|
-
const fieldCoveredByAppends = (fieldPath) => {
|
|
194
|
-
const p = String(fieldPath || "");
|
|
195
|
-
for (const a of cachedAppends) {
|
|
196
|
-
if (!a) continue;
|
|
197
|
-
if (p === a || p.startsWith(a + ".")) return true;
|
|
198
|
-
}
|
|
199
|
-
return false;
|
|
200
|
-
};
|
|
201
|
-
const fieldsOk = needFields ? needFields.every((f) => cachedFields.has(f) || fieldCoveredByAppends(f)) : parsed.f === void 0;
|
|
202
|
-
const appendsOk = !needAppends || [...needAppends].every((a) => cachedAppends.has(a));
|
|
203
|
-
const fullOk = preferFullRecord ? parsed.full === true : true;
|
|
204
|
-
if (fieldsOk && appendsOk && fullOk) {
|
|
205
|
-
return cacheVal;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
203
|
+
node = child;
|
|
204
|
+
}
|
|
205
|
+
if (node.binding) return false;
|
|
206
|
+
node.binding = binding;
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
function isProvidedByDescendant(node, path) {
|
|
210
|
+
let current = node;
|
|
211
|
+
for (const segment of path) {
|
|
212
|
+
const child = current.children.get(segment);
|
|
213
|
+
if (!child) return false;
|
|
214
|
+
if (child.binding) return true;
|
|
215
|
+
current = child;
|
|
216
|
+
}
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
function materializeRecordProvider(node, values, inherited) {
|
|
220
|
+
const base = node.binding ? values.get(node) : inherited;
|
|
221
|
+
if (!node.children.size) return base;
|
|
222
|
+
if (Array.isArray(base)) {
|
|
223
|
+
const result2 = Array.from(node.children.keys()).every(
|
|
224
|
+
(segment) => typeof segment === "number"
|
|
225
|
+
) ? [...base] : Object.assign(/* @__PURE__ */ Object.create(null), base);
|
|
226
|
+
for (const [segment, child] of node.children) {
|
|
227
|
+
if (typeof segment !== "number") continue;
|
|
228
|
+
result2[segment] = materializeRecordProvider(child, values, result2[segment]);
|
|
209
229
|
}
|
|
210
|
-
|
|
211
|
-
filterByTk,
|
|
212
|
-
preferFullRecord,
|
|
213
|
-
fields: fieldsWithExtras,
|
|
214
|
-
appends,
|
|
215
|
-
filterTargetKey,
|
|
216
|
-
pkAttr,
|
|
217
|
-
pkIsValid
|
|
218
|
-
});
|
|
219
|
-
if (cache) cache.set(key, json);
|
|
220
|
-
return json;
|
|
221
|
-
} catch (e) {
|
|
222
|
-
const log = (_e = (_d = koaCtx.app) == null ? void 0 : _d.logger) == null ? void 0 : _e.child({
|
|
223
|
-
module: "plugin-flow-engine",
|
|
224
|
-
submodule: "variables.resolve",
|
|
225
|
-
method: "fetchRecordWithRequestCache"
|
|
226
|
-
});
|
|
227
|
-
const errMsg = e instanceof Error ? e.message : String(e);
|
|
228
|
-
log == null ? void 0 : log.warn("[variables.resolve] fetchRecordWithRequestCache error", {
|
|
229
|
-
ds: dataSourceKey,
|
|
230
|
-
collection,
|
|
231
|
-
tk: filterByTk,
|
|
232
|
-
fields,
|
|
233
|
-
appends,
|
|
234
|
-
error: errMsg
|
|
235
|
-
});
|
|
236
|
-
return void 0;
|
|
230
|
+
return result2;
|
|
237
231
|
}
|
|
232
|
+
const result = import_lodash.default.isPlainObject(base) ? { ...base } : /* @__PURE__ */ Object.create(null);
|
|
233
|
+
for (const [segment, child] of node.children) {
|
|
234
|
+
const key = String(segment);
|
|
235
|
+
result[key] = materializeRecordProvider(child, values, result[key]);
|
|
236
|
+
}
|
|
237
|
+
return result;
|
|
238
238
|
}
|
|
239
|
-
function
|
|
240
|
-
return
|
|
239
|
+
function isSafeRecordBinding(binding) {
|
|
240
|
+
return !(0, import_context_keys.isProtectedServerContextKey)(binding.varName);
|
|
241
241
|
}
|
|
242
|
-
function
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
242
|
+
async function fetchBindingRecord(koaCtx, binding, relativePaths = binding.relativePaths) {
|
|
243
|
+
const strictSelects = Array.isArray(binding.params.fields) || Array.isArray(binding.params.appends);
|
|
244
|
+
let { generatedAppends, generatedFields } = inferSelectsFromUsage(relativePaths);
|
|
245
|
+
if (Array.isArray(binding.params.fields)) generatedFields = binding.params.fields;
|
|
246
|
+
if (Array.isArray(binding.params.appends)) generatedAppends = binding.params.appends;
|
|
247
|
+
const raw = await (0, import_records.fetchRecordWithRequestCache)(
|
|
248
|
+
koaCtx,
|
|
249
|
+
binding.params,
|
|
250
|
+
generatedFields,
|
|
251
|
+
generatedAppends,
|
|
252
|
+
strictSelects,
|
|
253
|
+
binding.preferFullRecord || relativePaths.some((path) => path.some((segment) => typeof segment === "string" && segment.includes(".")))
|
|
254
|
+
);
|
|
255
|
+
return (0, import_record_projection.projectRecord)(raw, relativePaths);
|
|
256
|
+
}
|
|
257
|
+
function attachAuthorizedRecordBindings(flowCtx, koaCtx, bindings) {
|
|
258
|
+
const byVariable = /* @__PURE__ */ new Map();
|
|
259
|
+
const conflicts = /* @__PURE__ */ new Set();
|
|
260
|
+
for (const binding of bindings) {
|
|
261
|
+
if (!isSafeRecordBinding(binding)) continue;
|
|
262
|
+
let root = byVariable.get(binding.varName);
|
|
263
|
+
if (!root) {
|
|
264
|
+
root = createRecordProviderNode();
|
|
265
|
+
byVariable.set(binding.varName, root);
|
|
263
266
|
}
|
|
264
|
-
if (
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
267
|
+
if (!addRecordProviderBinding(root, binding)) conflicts.add(binding.varName);
|
|
268
|
+
}
|
|
269
|
+
for (const [varName, root] of byVariable) {
|
|
270
|
+
if (conflicts.has(varName)) continue;
|
|
271
|
+
const resolveNode = async (node) => {
|
|
272
|
+
const entries = [];
|
|
273
|
+
const collect = (current) => {
|
|
274
|
+
if (current.binding) {
|
|
275
|
+
const paths = current.binding.relativePaths.filter((path) => !isProvidedByDescendant(current, path));
|
|
276
|
+
entries.push([current, fetchBindingRecord(koaCtx, current.binding, paths)]);
|
|
270
277
|
}
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
generatedFields,
|
|
286
|
-
generatedAppends
|
|
287
|
-
);
|
|
288
|
-
const base = await fetchRecordWithRequestCache(
|
|
289
|
-
koaCtx,
|
|
290
|
-
dataSourceKey,
|
|
291
|
-
topParams.collection,
|
|
292
|
-
topParams.filterByTk,
|
|
293
|
-
fixed.fields,
|
|
294
|
-
fixed.appends,
|
|
295
|
-
strictSelects,
|
|
296
|
-
hasDirectRefTop,
|
|
297
|
-
topParams.associationName,
|
|
298
|
-
topParams.sourceId
|
|
299
|
-
);
|
|
300
|
-
if (!deepRecordMap.size) return base;
|
|
301
|
-
const merged = base && typeof base === "object" && !Array.isArray(base) ? { ...base } : {};
|
|
302
|
-
const setClonedPath = (obj, path, value) => {
|
|
303
|
-
const segs = String(path || "").split(".").filter(Boolean);
|
|
304
|
-
if (!segs.length) return;
|
|
305
|
-
if (segs.length === 1) {
|
|
306
|
-
obj[segs[0]] = value;
|
|
307
|
-
return;
|
|
308
|
-
}
|
|
309
|
-
let cur = obj;
|
|
310
|
-
for (let i = 0; i < segs.length - 1; i++) {
|
|
311
|
-
const seg = segs[i];
|
|
312
|
-
const prev = cur[seg];
|
|
313
|
-
const next = prev && typeof prev === "object" && !Array.isArray(prev) ? { ...prev } : {};
|
|
314
|
-
cur[seg] = next;
|
|
315
|
-
cur = next;
|
|
316
|
-
}
|
|
317
|
-
cur[segs[segs.length - 1]] = value;
|
|
318
|
-
};
|
|
319
|
-
const buildNestedPromise = (recordParams, relative) => {
|
|
320
|
-
const subPaths = (usedPaths || []).map((p) => p === relative ? "" : p.startsWith(relative + ".") ? p.slice(relative.length + 1) : "").filter((x) => x !== "");
|
|
321
|
-
const hasDirectRef = (usedPaths || []).some((p) => p === relative);
|
|
322
|
-
const dataSourceKey2 = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
|
|
323
|
-
const strictSelects2 = Array.isArray(recordParams == null ? void 0 : recordParams.fields) || Array.isArray(recordParams == null ? void 0 : recordParams.appends);
|
|
324
|
-
let { generatedAppends: generatedAppends2, generatedFields: generatedFields2 } = inferSelectsFromUsage(subPaths, recordParams);
|
|
325
|
-
if (Array.isArray(recordParams == null ? void 0 : recordParams.fields)) generatedFields2 = recordParams.fields;
|
|
326
|
-
if (Array.isArray(recordParams == null ? void 0 : recordParams.appends)) generatedAppends2 = recordParams.appends;
|
|
327
|
-
const fixed2 = (0, import_selects.adjustSelectsForCollection)(
|
|
328
|
-
koaCtx,
|
|
329
|
-
dataSourceKey2,
|
|
330
|
-
recordParams.collection,
|
|
331
|
-
generatedFields2,
|
|
332
|
-
generatedAppends2
|
|
333
|
-
);
|
|
334
|
-
return fetchRecordWithRequestCache(
|
|
335
|
-
koaCtx,
|
|
336
|
-
dataSourceKey2,
|
|
337
|
-
recordParams.collection,
|
|
338
|
-
recordParams.filterByTk,
|
|
339
|
-
fixed2.fields,
|
|
340
|
-
fixed2.appends,
|
|
341
|
-
strictSelects2,
|
|
342
|
-
hasDirectRef,
|
|
343
|
-
recordParams.associationName,
|
|
344
|
-
recordParams.sourceId
|
|
345
|
-
);
|
|
346
|
-
};
|
|
347
|
-
for (const [relative, recordParams] of deepRecordMap.entries()) {
|
|
348
|
-
setClonedPath(merged, relative, buildNestedPromise(recordParams, relative));
|
|
349
|
-
}
|
|
350
|
-
return merged;
|
|
351
|
-
},
|
|
352
|
-
cache: true
|
|
353
|
-
});
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
356
|
-
const segmentMap = /* @__PURE__ */ new Map();
|
|
357
|
-
const splitHead = (path) => {
|
|
358
|
-
if (!path) return { seg: "", remainder: "" };
|
|
359
|
-
const mIdx = path.match(/^\[(\d+)\](?:\.(.*))?$/);
|
|
360
|
-
if (mIdx) {
|
|
361
|
-
return { seg: `[${mIdx[1]}]`, remainder: mIdx[2] || "" };
|
|
362
|
-
}
|
|
363
|
-
const m = path.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)(\[(?:\d+|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\])?(?:\.(.*))?$/);
|
|
364
|
-
if (m) {
|
|
365
|
-
const seg2 = m[1];
|
|
366
|
-
const idxPart = m[2] || "";
|
|
367
|
-
const tail = m[3] || "";
|
|
368
|
-
const remainder = (idxPart ? `${idxPart}${tail ? `.${tail}` : ""}` : tail) || "";
|
|
369
|
-
return { seg: seg2, remainder };
|
|
278
|
+
for (const child of current.children.values()) collect(child);
|
|
279
|
+
};
|
|
280
|
+
collect(node);
|
|
281
|
+
const values = /* @__PURE__ */ new Map();
|
|
282
|
+
await Promise.all(entries.map(async ([current, pending]) => values.set(current, await pending)));
|
|
283
|
+
return materializeRecordProvider(node, values);
|
|
284
|
+
};
|
|
285
|
+
const createProxy = (node) => {
|
|
286
|
+
const context = new import_contexts.ServerBaseContext();
|
|
287
|
+
for (const [segment, child] of node.children) {
|
|
288
|
+
context.defineProperty(String(segment), {
|
|
289
|
+
get: () => child.binding ? resolveNode(child) : createProxy(child),
|
|
290
|
+
cache: true
|
|
291
|
+
});
|
|
370
292
|
}
|
|
371
|
-
|
|
372
|
-
return { seg, remainder: rest.join(".") };
|
|
293
|
+
return context.createProxy();
|
|
373
294
|
};
|
|
374
|
-
for (const p of usedPaths) {
|
|
375
|
-
if (!p) continue;
|
|
376
|
-
const { seg, remainder } = splitHead(p);
|
|
377
|
-
if (!seg) continue;
|
|
378
|
-
const arr = segmentMap.get(seg) || [];
|
|
379
|
-
arr.push(remainder);
|
|
380
|
-
segmentMap.set(seg, arr);
|
|
381
|
-
}
|
|
382
|
-
const segEntries = Array.from(segmentMap.entries());
|
|
383
|
-
const oneLevelRecordChildren = segEntries.filter(([seg]) => {
|
|
384
|
-
const idx = parseIndexSegment(seg);
|
|
385
|
-
const nestedObj = import_lodash.default.get(contextParams, [varName, seg]) ?? (idx ? import_lodash.default.get(contextParams, [varName, idx]) : void 0);
|
|
386
|
-
const dotted = (contextParams || {})[`${varName}.${seg}`] ?? (idx ? (contextParams || {})[`${varName}.${idx}`] : void 0);
|
|
387
|
-
return isRecordParams(nestedObj) || isRecordParams(dotted);
|
|
388
|
-
});
|
|
389
|
-
if (!oneLevelRecordChildren.length && deepRecordMap.size === 0) continue;
|
|
390
295
|
flowCtx.defineProperty(varName, {
|
|
391
|
-
get: () =>
|
|
392
|
-
const root = new import_contexts.ServerBaseContext();
|
|
393
|
-
const definedFirstLevel = /* @__PURE__ */ new Set();
|
|
394
|
-
const defineRecordGetter = (container, key, recordParams, subPaths = [], preferFull) => {
|
|
395
|
-
const strictSelects = Array.isArray(recordParams == null ? void 0 : recordParams.fields) || Array.isArray(recordParams == null ? void 0 : recordParams.appends);
|
|
396
|
-
let { generatedAppends, generatedFields } = inferSelectsFromUsage(subPaths, recordParams);
|
|
397
|
-
if (Array.isArray(recordParams == null ? void 0 : recordParams.fields)) generatedFields = recordParams.fields;
|
|
398
|
-
if (Array.isArray(recordParams == null ? void 0 : recordParams.appends)) generatedAppends = recordParams.appends;
|
|
399
|
-
container.defineProperty(key, {
|
|
400
|
-
get: async () => {
|
|
401
|
-
const dataSourceKey = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
|
|
402
|
-
const fixed = (0, import_selects.adjustSelectsForCollection)(
|
|
403
|
-
koaCtx,
|
|
404
|
-
dataSourceKey,
|
|
405
|
-
recordParams.collection,
|
|
406
|
-
generatedFields,
|
|
407
|
-
generatedAppends
|
|
408
|
-
);
|
|
409
|
-
return await fetchRecordWithRequestCache(
|
|
410
|
-
koaCtx,
|
|
411
|
-
dataSourceKey,
|
|
412
|
-
recordParams.collection,
|
|
413
|
-
recordParams.filterByTk,
|
|
414
|
-
fixed.fields,
|
|
415
|
-
fixed.appends,
|
|
416
|
-
strictSelects,
|
|
417
|
-
preferFull || ((subPaths == null ? void 0 : subPaths.length) ?? 0) === 0,
|
|
418
|
-
recordParams.associationName,
|
|
419
|
-
recordParams.sourceId
|
|
420
|
-
);
|
|
421
|
-
},
|
|
422
|
-
cache: true
|
|
423
|
-
});
|
|
424
|
-
};
|
|
425
|
-
const subContainers = /* @__PURE__ */ new Map();
|
|
426
|
-
const ensureSubContainer = (parent, key) => {
|
|
427
|
-
let map = subContainers.get(parent);
|
|
428
|
-
if (!map) {
|
|
429
|
-
map = /* @__PURE__ */ new Map();
|
|
430
|
-
subContainers.set(parent, map);
|
|
431
|
-
}
|
|
432
|
-
let child = map.get(key);
|
|
433
|
-
if (!child) {
|
|
434
|
-
const inst = new import_contexts.ServerBaseContext();
|
|
435
|
-
parent.defineProperty(key, { get: () => inst.createProxy(), cache: true });
|
|
436
|
-
map.set(key, inst);
|
|
437
|
-
child = inst;
|
|
438
|
-
}
|
|
439
|
-
return child;
|
|
440
|
-
};
|
|
441
|
-
for (const [seg, remainders] of oneLevelRecordChildren) {
|
|
442
|
-
const idx = parseIndexSegment(seg);
|
|
443
|
-
const recordParams = import_lodash.default.get(contextParams, [varName, seg]) ?? (idx ? import_lodash.default.get(contextParams, [varName, idx]) : void 0) ?? (contextParams || {})[`${varName}.${seg}`] ?? (idx ? (contextParams || {})[`${varName}.${idx}`] : void 0);
|
|
444
|
-
let effRemainders = (remainders || []).filter((r) => !!r);
|
|
445
|
-
if (!effRemainders.length) {
|
|
446
|
-
const all = usedPaths.map(
|
|
447
|
-
(p) => p.startsWith(`${seg}.`) ? p.slice(seg.length + 1) : p.startsWith(`${seg}[`) ? p.slice(seg.length) : ""
|
|
448
|
-
).filter((x) => !!x);
|
|
449
|
-
if (all.length) effRemainders = all;
|
|
450
|
-
}
|
|
451
|
-
const hasDirectRefOne = (usedPaths || []).some((p) => p === seg || !!idx && p === `[${idx}]`);
|
|
452
|
-
defineRecordGetter(root, idx ?? seg, recordParams, effRemainders, hasDirectRefOne);
|
|
453
|
-
definedFirstLevel.add(idx ?? seg);
|
|
454
|
-
}
|
|
455
|
-
for (const [relative, recordParams] of deepRecordMap.entries()) {
|
|
456
|
-
const segs = String(relative).split(".").filter(Boolean);
|
|
457
|
-
if (segs.length === 0) continue;
|
|
458
|
-
const first = segs[0];
|
|
459
|
-
let container;
|
|
460
|
-
if (definedFirstLevel.has(first)) {
|
|
461
|
-
continue;
|
|
462
|
-
} else {
|
|
463
|
-
container = root;
|
|
464
|
-
for (let i = 0; i < segs.length - 1; i++) {
|
|
465
|
-
container = ensureSubContainer(container, segs[i]);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
const leaf = segs[segs.length - 1];
|
|
469
|
-
const subPaths = (usedPaths || []).map((p) => p === relative ? "" : p.startsWith(relative + ".") ? p.slice(relative.length + 1) : "").filter((x) => x !== "");
|
|
470
|
-
const hasDirectRef = (usedPaths || []).some((p) => p === relative);
|
|
471
|
-
defineRecordGetter(container, leaf, recordParams, subPaths, hasDirectRef);
|
|
472
|
-
}
|
|
473
|
-
return root.createProxy();
|
|
474
|
-
},
|
|
296
|
+
get: () => root.binding ? resolveNode(root) : createProxy(root),
|
|
475
297
|
cache: true
|
|
476
298
|
});
|
|
477
299
|
}
|
|
@@ -481,30 +303,39 @@ function registerBuiltInVariables(reg) {
|
|
|
481
303
|
name: "user",
|
|
482
304
|
scope: "request",
|
|
483
305
|
// no requiredParams: frontend will not pass context params for user
|
|
306
|
+
validateContextParams: ({ contextParams }) => ({
|
|
307
|
+
allowed: true,
|
|
308
|
+
contextParams: omitVariableContextParams(contextParams, "user")
|
|
309
|
+
}),
|
|
484
310
|
attach: (flowCtx, koaCtx, _params, usage) => {
|
|
485
|
-
const paths = (usage == null ? void 0 : usage
|
|
311
|
+
const paths = ((usage == null ? void 0 : usage.user) || []).map((path) => path.runtimeSegments);
|
|
486
312
|
const { generatedAppends, generatedFields } = inferSelectsFromUsage(paths);
|
|
487
|
-
flowCtx.defineProperty(
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
);
|
|
313
|
+
flowCtx.defineProperty(
|
|
314
|
+
"user",
|
|
315
|
+
{
|
|
316
|
+
get: async () => {
|
|
317
|
+
var _a;
|
|
318
|
+
const authObj = koaCtx.auth;
|
|
319
|
+
const uid = (_a = authObj == null ? void 0 : authObj.user) == null ? void 0 : _a.id;
|
|
320
|
+
if (typeof uid === "undefined" || uid === null) return void 0;
|
|
321
|
+
return await (0, import_records.fetchRecordWithRequestCache)(
|
|
322
|
+
koaCtx,
|
|
323
|
+
{ collection: "users", dataSourceKey: "main", filterByTk: uid },
|
|
324
|
+
generatedFields,
|
|
325
|
+
generatedAppends,
|
|
326
|
+
false
|
|
327
|
+
);
|
|
328
|
+
},
|
|
329
|
+
cache: true
|
|
505
330
|
},
|
|
506
|
-
|
|
507
|
-
|
|
331
|
+
import_contexts.SERVER_CONTEXT_PROVIDER_TOKEN
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
reg.register({
|
|
336
|
+
name: "popup",
|
|
337
|
+
scope: "request",
|
|
338
|
+
attach: () => {
|
|
508
339
|
}
|
|
509
340
|
});
|
|
510
341
|
}
|
|
@@ -512,5 +343,9 @@ registerBuiltInVariables(variables);
|
|
|
512
343
|
// Annotate the CommonJS export names for ESM import in node:
|
|
513
344
|
0 && (module.exports = {
|
|
514
345
|
inferSelectsFromUsage,
|
|
346
|
+
isSafeRecordBinding,
|
|
347
|
+
omitVariableContextParams,
|
|
348
|
+
registerBuiltInVariables,
|
|
349
|
+
sanitizeRegisteredVariableContextParams,
|
|
515
350
|
variables
|
|
516
351
|
});
|