@nocobase/plugin-flow-engine 2.0.0-alpha.2
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/LICENSE +661 -0
- package/README.md +29 -0
- package/build.config.ts +22 -0
- package/client.d.ts +2 -0
- package/client.js +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.js +10 -0
- package/dist/externalVersion.js +21 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +48 -0
- package/dist/locale/en-US.json +61 -0
- package/dist/locale/index.d.ts +141 -0
- package/dist/locale/index.js +79 -0
- package/dist/locale/zh-CN.json +61 -0
- package/dist/node_modules/ses/LICENSE +201 -0
- package/dist/node_modules/ses/LICENSE-aura +16 -0
- package/dist/node_modules/ses/LICENSE-caja +13 -0
- package/dist/node_modules/ses/LICENSE-corejs +19 -0
- package/dist/node_modules/ses/LICENSE-v8 +9 -0
- package/dist/node_modules/ses/assert-shim.js +1 -0
- package/dist/node_modules/ses/compartment-shim.js +1 -0
- package/dist/node_modules/ses/console-shim.js +1 -0
- package/dist/node_modules/ses/dist/lockdown.cjs +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.js +13912 -0
- package/dist/node_modules/ses/dist/lockdown.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/ses-hermes.cjs +13912 -0
- package/dist/node_modules/ses/dist/ses.cjs +1 -0
- package/dist/node_modules/ses/dist/ses.umd.js +13912 -0
- package/dist/node_modules/ses/dist/ses.umd.min.js +1 -0
- package/dist/node_modules/ses/dist/types.d.cts +606 -0
- package/dist/node_modules/ses/index.js +18 -0
- package/dist/node_modules/ses/lockdown-shim.js +1 -0
- package/dist/node_modules/ses/lockdown.js +1 -0
- package/dist/node_modules/ses/package.json +1 -0
- package/dist/node_modules/ses/src/assert-shim.js +4 -0
- package/dist/node_modules/ses/src/assert-sloppy-mode.js +11 -0
- package/dist/node_modules/ses/src/cauterize-property.js +69 -0
- package/dist/node_modules/ses/src/commons.js +425 -0
- package/dist/node_modules/ses/src/compartment-evaluate.js +93 -0
- package/dist/node_modules/ses/src/compartment-shim.js +22 -0
- package/dist/node_modules/ses/src/compartment.js +477 -0
- package/dist/node_modules/ses/src/console-shim.js +50 -0
- package/dist/node_modules/ses/src/enable-property-overrides.js +211 -0
- package/dist/node_modules/ses/src/enablements.js +244 -0
- package/dist/node_modules/ses/src/error/assert.js +584 -0
- package/dist/node_modules/ses/src/error/console.js +541 -0
- package/dist/node_modules/ses/src/error/fatal-assert.js +54 -0
- package/dist/node_modules/ses/src/error/internal-types.js +98 -0
- package/dist/node_modules/ses/src/error/note-log-args.js +77 -0
- package/dist/node_modules/ses/src/error/stringify-utils.js +195 -0
- package/dist/node_modules/ses/src/error/tame-console.js +197 -0
- package/dist/node_modules/ses/src/error/tame-error-constructor.js +284 -0
- package/dist/node_modules/ses/src/error/tame-v8-error-constructor.js +386 -0
- package/dist/node_modules/ses/src/error/types.js +59 -0
- package/dist/node_modules/ses/src/error/unhandled-rejection.js +122 -0
- package/dist/node_modules/ses/src/eval-scope.js +89 -0
- package/dist/node_modules/ses/src/get-anonymous-intrinsics.js +181 -0
- package/dist/node_modules/ses/src/get-source-url.js +50 -0
- package/dist/node_modules/ses/src/global-object.js +175 -0
- package/dist/node_modules/ses/src/intrinsics.js +192 -0
- package/dist/node_modules/ses/src/lockdown-shim.js +37 -0
- package/dist/node_modules/ses/src/lockdown.js +558 -0
- package/dist/node_modules/ses/src/make-eval-function.js +28 -0
- package/dist/node_modules/ses/src/make-evaluate.js +110 -0
- package/dist/node_modules/ses/src/make-function-constructor.js +79 -0
- package/dist/node_modules/ses/src/make-hardener.js +275 -0
- package/dist/node_modules/ses/src/make-safe-evaluator.js +112 -0
- package/dist/node_modules/ses/src/module-instance.js +497 -0
- package/dist/node_modules/ses/src/module-link.js +159 -0
- package/dist/node_modules/ses/src/module-load.js +719 -0
- package/dist/node_modules/ses/src/module-proxy.js +200 -0
- package/dist/node_modules/ses/src/permits-intrinsics.js +291 -0
- package/dist/node_modules/ses/src/permits.js +1761 -0
- package/dist/node_modules/ses/src/reporting-types.d.ts +13 -0
- package/dist/node_modules/ses/src/reporting.js +105 -0
- package/dist/node_modules/ses/src/scope-constants.js +180 -0
- package/dist/node_modules/ses/src/shim-arraybuffer-transfer.js +85 -0
- package/dist/node_modules/ses/src/sloppy-globals-scope-terminator.js +61 -0
- package/dist/node_modules/ses/src/strict-scope-terminator.js +99 -0
- package/dist/node_modules/ses/src/tame-date-constructor.js +127 -0
- package/dist/node_modules/ses/src/tame-domains.js +41 -0
- package/dist/node_modules/ses/src/tame-faux-data-properties.js +210 -0
- package/dist/node_modules/ses/src/tame-function-constructors.js +140 -0
- package/dist/node_modules/ses/src/tame-function-tostring.js +50 -0
- package/dist/node_modules/ses/src/tame-harden.js +29 -0
- package/dist/node_modules/ses/src/tame-locale-methods.js +78 -0
- package/dist/node_modules/ses/src/tame-math-object.js +41 -0
- package/dist/node_modules/ses/src/tame-module-source.js +51 -0
- package/dist/node_modules/ses/src/tame-regenerator-runtime.js +29 -0
- package/dist/node_modules/ses/src/tame-regexp-constructor.js +65 -0
- package/dist/node_modules/ses/src/tame-symbol-constructor.js +64 -0
- package/dist/node_modules/ses/src/transforms.js +267 -0
- package/dist/node_modules/ses/tools.js +25 -0
- package/dist/node_modules/ses/types.d.ts +606 -0
- package/dist/server/actions/ui-schema-action.d.ts +27 -0
- package/dist/server/actions/ui-schema-action.js +118 -0
- package/dist/server/collections/flowModelTreePath.d.ts +11 -0
- package/dist/server/collections/flowModelTreePath.js +74 -0
- package/dist/server/collections/flowModels.d.ts +11 -0
- package/dist/server/collections/flowModels.js +57 -0
- package/dist/server/collections/flowsql.d.ts +10 -0
- package/dist/server/collections/flowsql.js +51 -0
- package/dist/server/dao/ui_schema_node_dao.d.ts +26 -0
- package/dist/server/dao/ui_schema_node_dao.js +24 -0
- package/dist/server/helper.d.ts +8 -0
- package/dist/server/helper.js +9 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +42 -0
- package/dist/server/model.d.ts +12 -0
- package/dist/server/model.js +38 -0
- package/dist/server/plugin.d.ts +26 -0
- package/dist/server/plugin.js +270 -0
- package/dist/server/repository.d.ts +116 -0
- package/dist/server/repository.js +1209 -0
- package/dist/server/server.d.ts +16 -0
- package/dist/server/server.js +198 -0
- package/dist/server/template/contexts.d.ts +73 -0
- package/dist/server/template/contexts.js +233 -0
- package/dist/server/template/resolver.d.ts +30 -0
- package/dist/server/template/resolver.js +225 -0
- package/dist/server/variables/registry.d.ts +42 -0
- package/dist/server/variables/registry.js +299 -0
- package/package.json +28 -0
- package/server.d.ts +2 -0
- package/server.js +1 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
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
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var resolver_exports = {};
|
|
38
|
+
__export(resolver_exports, {
|
|
39
|
+
preprocessExpression: () => preprocessExpression,
|
|
40
|
+
resolveJsonTemplate: () => resolveJsonTemplate
|
|
41
|
+
});
|
|
42
|
+
module.exports = __toCommonJS(resolver_exports);
|
|
43
|
+
var import_ses = require("ses");
|
|
44
|
+
var import_lodash = __toESM(require("lodash"));
|
|
45
|
+
async function resolveJsonTemplate(template, ctx) {
|
|
46
|
+
const compile = async (source) => {
|
|
47
|
+
if (typeof source === "string" && /\{\{.*?\}\}/.test(source)) {
|
|
48
|
+
return await replacePlaceholders(source, ctx);
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(source)) return Promise.all(source.map(compile));
|
|
51
|
+
if (source && typeof source === "object") {
|
|
52
|
+
const out = {};
|
|
53
|
+
for (const [k, v] of Object.entries(source)) out[k] = await compile(v);
|
|
54
|
+
return out;
|
|
55
|
+
}
|
|
56
|
+
return source;
|
|
57
|
+
};
|
|
58
|
+
return compile(template);
|
|
59
|
+
}
|
|
60
|
+
async function replacePlaceholders(input, ctx) {
|
|
61
|
+
const single = input.match(/^\{\{\s*(.+)\s*\}\}$/);
|
|
62
|
+
if (single) {
|
|
63
|
+
const val = await evaluate(single[1], ctx);
|
|
64
|
+
return typeof val === "undefined" ? input : val;
|
|
65
|
+
}
|
|
66
|
+
const regex = /\{\{\s*(.+?)\s*\}\}/g;
|
|
67
|
+
let result = input;
|
|
68
|
+
const matches = [...input.matchAll(regex)];
|
|
69
|
+
for (const [full, inner] of matches) {
|
|
70
|
+
const value = await evaluate(inner, ctx);
|
|
71
|
+
if (typeof value !== "undefined") {
|
|
72
|
+
const replacement = typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
73
|
+
result = result.replace(full, replacement);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
async function evaluate(expr, ctx) {
|
|
79
|
+
try {
|
|
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_$]*)*)$/);
|
|
82
|
+
if (dotOnly) {
|
|
83
|
+
const path = dotOnly[1];
|
|
84
|
+
const segs = path.split(".");
|
|
85
|
+
const first = segs.shift();
|
|
86
|
+
const base = await ctx[first];
|
|
87
|
+
if (!segs.length) return base;
|
|
88
|
+
return await asyncGetValuesByPath(base, segs.join("."));
|
|
89
|
+
}
|
|
90
|
+
const transformed = preprocessExpression(raw);
|
|
91
|
+
const compartment = new Compartment({
|
|
92
|
+
ctx,
|
|
93
|
+
__get: (varName, path) => getAtPath(ctx, varName, path),
|
|
94
|
+
console
|
|
95
|
+
});
|
|
96
|
+
const wrapped = `(async () => { try { return ${transformed}; } catch (e) { return undefined; } })()`;
|
|
97
|
+
return await compartment.evaluate(wrapped);
|
|
98
|
+
} catch (_2) {
|
|
99
|
+
return void 0;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async function getAtPath(ctx, varName, path) {
|
|
103
|
+
try {
|
|
104
|
+
let current = await ctx[varName];
|
|
105
|
+
if (!path) return current;
|
|
106
|
+
const norm = String(path || "").replace(/^\./, "");
|
|
107
|
+
const segments = import_lodash.default.toPath(norm);
|
|
108
|
+
for (const seg of segments) {
|
|
109
|
+
if (current == null) return void 0;
|
|
110
|
+
let val = current[seg];
|
|
111
|
+
if (val && typeof val["then"] === "function") {
|
|
112
|
+
val = await val;
|
|
113
|
+
}
|
|
114
|
+
current = val;
|
|
115
|
+
}
|
|
116
|
+
return current;
|
|
117
|
+
} catch (_2) {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async function asyncGetValuesByPath(obj, path, defaultValue) {
|
|
122
|
+
try {
|
|
123
|
+
let currentValue = await obj;
|
|
124
|
+
if (!currentValue) return defaultValue;
|
|
125
|
+
const keys = String(path || "").split(".");
|
|
126
|
+
let result = [];
|
|
127
|
+
let shouldReturnArray = false;
|
|
128
|
+
for (let i = 0; i < keys.length; i++) {
|
|
129
|
+
const key = keys[i];
|
|
130
|
+
if (Array.isArray(currentValue)) {
|
|
131
|
+
shouldReturnArray = true;
|
|
132
|
+
const rest = keys.slice(i).join(".");
|
|
133
|
+
const parts = await Promise.all(currentValue.map((el) => asyncGetValuesByPath(el, rest, defaultValue)));
|
|
134
|
+
for (const p of parts) {
|
|
135
|
+
if (Array.isArray(p)) result.push(...p);
|
|
136
|
+
else if (typeof p !== "undefined") result.push(p);
|
|
137
|
+
}
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
let val = currentValue == null ? void 0 : currentValue[key];
|
|
141
|
+
if (val && typeof val.then === "function") {
|
|
142
|
+
val = await val;
|
|
143
|
+
}
|
|
144
|
+
currentValue = val;
|
|
145
|
+
if (i === keys.length - 1) {
|
|
146
|
+
result.push(currentValue);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
result = result.filter((item) => typeof item !== "undefined");
|
|
150
|
+
if (result.length === 0) return defaultValue;
|
|
151
|
+
if (shouldReturnArray) return result.filter((item) => item !== null);
|
|
152
|
+
return result[0];
|
|
153
|
+
} catch (_2) {
|
|
154
|
+
return defaultValue;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function preprocessExpression(expression) {
|
|
158
|
+
let out = "";
|
|
159
|
+
let i = 0;
|
|
160
|
+
const n = expression.length;
|
|
161
|
+
while (i < n) {
|
|
162
|
+
const dotIdx = expression.indexOf("ctx.", i);
|
|
163
|
+
const brkIdx = expression.indexOf("ctx[", i);
|
|
164
|
+
let idx = -1;
|
|
165
|
+
if (dotIdx === -1) idx = brkIdx;
|
|
166
|
+
else if (brkIdx === -1) idx = dotIdx;
|
|
167
|
+
else idx = Math.min(dotIdx, brkIdx);
|
|
168
|
+
if (idx === -1) {
|
|
169
|
+
out += expression.slice(i);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
out += expression.slice(i, idx);
|
|
173
|
+
let j = idx + 3;
|
|
174
|
+
let varName = null;
|
|
175
|
+
let pathStr = "";
|
|
176
|
+
if (expression[j] === ".") {
|
|
177
|
+
j += 1;
|
|
178
|
+
const varMatch = /^[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(expression.slice(j));
|
|
179
|
+
if (!varMatch) {
|
|
180
|
+
out += "ctx.";
|
|
181
|
+
i = j;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
varName = varMatch[0];
|
|
185
|
+
j += varName.length;
|
|
186
|
+
} else if (expression[j] === "[") {
|
|
187
|
+
const m = /^\[("((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)')\]/.exec(expression.slice(j));
|
|
188
|
+
if (!m) {
|
|
189
|
+
out += "ctx[";
|
|
190
|
+
i = j;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
varName = m[2] ?? m[3];
|
|
194
|
+
j += m[0].length;
|
|
195
|
+
} else {
|
|
196
|
+
out += expression.slice(idx, idx + 3);
|
|
197
|
+
i = idx + 3;
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
200
|
+
while (j < n) {
|
|
201
|
+
if (expression[j] === ".") {
|
|
202
|
+
const m = /^\.[a-zA-Z_$][a-zA-Z0-9_$]*/.exec(expression.slice(j));
|
|
203
|
+
if (!m) break;
|
|
204
|
+
pathStr += m[0];
|
|
205
|
+
j += m[0].length;
|
|
206
|
+
} else if (expression[j] === "[") {
|
|
207
|
+
const m = /^(\[(?:\d+|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\])/.exec(expression.slice(j));
|
|
208
|
+
if (!m) break;
|
|
209
|
+
pathStr += m[1];
|
|
210
|
+
j += m[1].length;
|
|
211
|
+
} else {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const argPath = pathStr ? `, ${JSON.stringify(pathStr)}` : "";
|
|
216
|
+
out += `(await __get(${JSON.stringify(varName)}${argPath}))`;
|
|
217
|
+
i = j;
|
|
218
|
+
}
|
|
219
|
+
return out;
|
|
220
|
+
}
|
|
221
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
222
|
+
0 && (module.exports = {
|
|
223
|
+
preprocessExpression,
|
|
224
|
+
resolveJsonTemplate
|
|
225
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { HttpRequestContext } from '../template/contexts';
|
|
10
|
+
import { ResourcerContext } from '@nocobase/resourcer';
|
|
11
|
+
export type JSONValue = string | {
|
|
12
|
+
[key: string]: JSONValue;
|
|
13
|
+
} | JSONValue[];
|
|
14
|
+
export type VarScope = 'global' | 'request';
|
|
15
|
+
export interface RequiredParamSpec {
|
|
16
|
+
name: string;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
defaultValue?: any;
|
|
19
|
+
}
|
|
20
|
+
export interface VariableDef {
|
|
21
|
+
name: string;
|
|
22
|
+
scope: VarScope;
|
|
23
|
+
requiredParams?: RequiredParamSpec[];
|
|
24
|
+
attach: (ctx: HttpRequestContext, koaCtx: ResourcerContext, params?: any, usage?: VarUsage) => Promise<void> | void;
|
|
25
|
+
}
|
|
26
|
+
export type VarUsage = {
|
|
27
|
+
[varName: string]: string[];
|
|
28
|
+
};
|
|
29
|
+
declare class VariableRegistry {
|
|
30
|
+
private vars;
|
|
31
|
+
register(def: VariableDef): void;
|
|
32
|
+
get(name: string): VariableDef;
|
|
33
|
+
list(): VariableDef[];
|
|
34
|
+
extractUsage(template: JSONValue): VarUsage;
|
|
35
|
+
validate(template: JSONValue, contextParams: any): {
|
|
36
|
+
ok: boolean;
|
|
37
|
+
missing?: string[];
|
|
38
|
+
};
|
|
39
|
+
attachUsedVariables(ctx: HttpRequestContext, koaCtx: ResourcerContext, template: JSONValue, contextParams: any): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
export declare const variables: VariableRegistry;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __create = Object.create;
|
|
11
|
+
var __defProp = Object.defineProperty;
|
|
12
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
13
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
15
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
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
|
+
));
|
|
36
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var registry_exports = {};
|
|
38
|
+
__export(registry_exports, {
|
|
39
|
+
variables: () => variables
|
|
40
|
+
});
|
|
41
|
+
module.exports = __toCommonJS(registry_exports);
|
|
42
|
+
var import_lodash = __toESM(require("lodash"));
|
|
43
|
+
var import_contexts = require("../template/contexts");
|
|
44
|
+
var import_utils = require("@nocobase/utils");
|
|
45
|
+
class VariableRegistry {
|
|
46
|
+
vars = /* @__PURE__ */ new Map();
|
|
47
|
+
register(def) {
|
|
48
|
+
this.vars.set(def.name, def);
|
|
49
|
+
}
|
|
50
|
+
get(name) {
|
|
51
|
+
return this.vars.get(name);
|
|
52
|
+
}
|
|
53
|
+
list() {
|
|
54
|
+
return Array.from(this.vars.values());
|
|
55
|
+
}
|
|
56
|
+
extractUsage(template) {
|
|
57
|
+
return (0, import_utils.extractUsedVariablePaths)(template);
|
|
58
|
+
}
|
|
59
|
+
validate(template, contextParams) {
|
|
60
|
+
var _a;
|
|
61
|
+
const usage = this.extractUsage(template);
|
|
62
|
+
const missing = [];
|
|
63
|
+
for (const varName of Object.keys(usage)) {
|
|
64
|
+
const def = this.get(varName);
|
|
65
|
+
if (!((_a = def == null ? void 0 : def.requiredParams) == null ? void 0 : _a.length)) continue;
|
|
66
|
+
const params = import_lodash.default.get(contextParams, varName);
|
|
67
|
+
for (const spec of def.requiredParams) {
|
|
68
|
+
if (!spec.required) continue;
|
|
69
|
+
if (params && typeof params[spec.name] !== "undefined") continue;
|
|
70
|
+
missing.push(`contextParams.${varName}.${spec.name}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return { ok: missing.length === 0, missing: missing.length ? missing : void 0 };
|
|
74
|
+
}
|
|
75
|
+
async attachUsedVariables(ctx, koaCtx, template, contextParams) {
|
|
76
|
+
const usage = this.extractUsage(template);
|
|
77
|
+
for (const varName of Object.keys(usage)) {
|
|
78
|
+
const def = this.get(varName);
|
|
79
|
+
const params = import_lodash.default.get(contextParams, varName);
|
|
80
|
+
if (def) {
|
|
81
|
+
await def.attach(ctx, koaCtx, params, { [varName]: usage[varName] });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
attachGenericRecordVariables(ctx, koaCtx, usage, contextParams);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const GLOBAL_KEY = "__ncbVarRegistry__";
|
|
88
|
+
const g = typeof globalThis !== "undefined" ? globalThis : global;
|
|
89
|
+
if (!g[GLOBAL_KEY]) {
|
|
90
|
+
g[GLOBAL_KEY] = new VariableRegistry();
|
|
91
|
+
}
|
|
92
|
+
const variables = g[GLOBAL_KEY];
|
|
93
|
+
function inferSelectsFromUsage(paths = [], params) {
|
|
94
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
95
|
+
return { generatedAppends: void 0, generatedFields: void 0 };
|
|
96
|
+
}
|
|
97
|
+
const appendSet = /* @__PURE__ */ new Set();
|
|
98
|
+
const fieldSet = /* @__PURE__ */ new Set();
|
|
99
|
+
for (let path of paths) {
|
|
100
|
+
if (!path) continue;
|
|
101
|
+
while (/^\[(\d+)\](\.|$)/.test(path)) {
|
|
102
|
+
path = path.replace(/^\[(\d+)\]\.?/, "");
|
|
103
|
+
}
|
|
104
|
+
if (!path) continue;
|
|
105
|
+
let first = "";
|
|
106
|
+
let rest = "";
|
|
107
|
+
const mStr = path.match(/^\[(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)')\](.*)$/);
|
|
108
|
+
if (mStr) {
|
|
109
|
+
first = (mStr[1] ?? mStr[2]) || "";
|
|
110
|
+
rest = mStr[3] || "";
|
|
111
|
+
} else {
|
|
112
|
+
const m = path.match(/^([^.[]+)([\s\S]*)$/);
|
|
113
|
+
first = (m == null ? void 0 : m[1]) ?? "";
|
|
114
|
+
rest = (m == null ? void 0 : m[2]) ?? "";
|
|
115
|
+
}
|
|
116
|
+
if (!first) continue;
|
|
117
|
+
const hasDeep = rest.includes(".") || rest.includes("[");
|
|
118
|
+
if (hasDeep) appendSet.add(first);
|
|
119
|
+
else fieldSet.add(first);
|
|
120
|
+
}
|
|
121
|
+
const generatedAppends = appendSet.size ? Array.from(appendSet) : void 0;
|
|
122
|
+
const generatedFields = fieldSet.size ? Array.from(fieldSet) : void 0;
|
|
123
|
+
return { generatedAppends, generatedFields };
|
|
124
|
+
}
|
|
125
|
+
async function fetchRecordWithRequestCache(koaCtx, dataSourceKey, collection, filterByTk, fields, appends) {
|
|
126
|
+
try {
|
|
127
|
+
const kctx = koaCtx;
|
|
128
|
+
if (!kctx.state) kctx.state = {};
|
|
129
|
+
if (!kctx.state["__varResolveBatchCache"]) {
|
|
130
|
+
kctx.state["__varResolveBatchCache"] = /* @__PURE__ */ new Map();
|
|
131
|
+
}
|
|
132
|
+
const cache = kctx.state.__varResolveBatchCache || null;
|
|
133
|
+
const ds = koaCtx.app.dataSourceManager.get(dataSourceKey || "main");
|
|
134
|
+
const cm = ds.collectionManager;
|
|
135
|
+
if (!(cm == null ? void 0 : cm.db)) return void 0;
|
|
136
|
+
const repo = cm.db.getRepository(collection);
|
|
137
|
+
const keyObj = {
|
|
138
|
+
ds: dataSourceKey || "main",
|
|
139
|
+
c: collection,
|
|
140
|
+
tk: filterByTk,
|
|
141
|
+
f: Array.isArray(fields) ? [...fields].sort() : void 0,
|
|
142
|
+
a: Array.isArray(appends) ? [...appends].sort() : void 0
|
|
143
|
+
};
|
|
144
|
+
const key = JSON.stringify(keyObj);
|
|
145
|
+
if (cache) {
|
|
146
|
+
if (cache.has(key)) return cache.get(key);
|
|
147
|
+
const needFields = Array.isArray(fields) ? new Set(fields) : void 0;
|
|
148
|
+
const needAppends = Array.isArray(appends) ? new Set(appends) : void 0;
|
|
149
|
+
let fallbackAny = void 0;
|
|
150
|
+
for (const [cacheKey, cacheVal] of cache.entries()) {
|
|
151
|
+
const parsed = JSON.parse(cacheKey);
|
|
152
|
+
if (!parsed || parsed.ds !== keyObj.ds || parsed.c !== keyObj.c || parsed.tk !== keyObj.tk) continue;
|
|
153
|
+
const cachedFields = Array.isArray(parsed.f) ? new Set(parsed.f) : void 0;
|
|
154
|
+
const cachedAppends = Array.isArray(parsed.a) ? new Set(parsed.a) : void 0;
|
|
155
|
+
const fieldsOk = !needFields || cachedFields && [...needFields].every((x) => cachedFields.has(x));
|
|
156
|
+
const appendsOk = !needAppends || cachedAppends && [...needAppends].every((x) => cachedAppends.has(x));
|
|
157
|
+
if (fieldsOk && appendsOk) return cacheVal;
|
|
158
|
+
if (typeof fallbackAny === "undefined") fallbackAny = cacheVal;
|
|
159
|
+
}
|
|
160
|
+
if (typeof fallbackAny !== "undefined") return fallbackAny;
|
|
161
|
+
}
|
|
162
|
+
const tk = filterByTk;
|
|
163
|
+
const rec = await repo.findOne({
|
|
164
|
+
filterByTk: tk,
|
|
165
|
+
fields,
|
|
166
|
+
appends
|
|
167
|
+
});
|
|
168
|
+
const json = rec ? rec.toJSON() : void 0;
|
|
169
|
+
if (cache) cache.set(key, json);
|
|
170
|
+
return json;
|
|
171
|
+
} catch (_2) {
|
|
172
|
+
return void 0;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function isRecordParams(val) {
|
|
176
|
+
return val && typeof val === "object" && "collection" in val && "filterByTk" in val;
|
|
177
|
+
}
|
|
178
|
+
function attachGenericRecordVariables(flowCtx, koaCtx, usage, contextParams) {
|
|
179
|
+
const parseIndexSegment = (segment) => {
|
|
180
|
+
const m = segment.match(/^\[(\d+)\]$/);
|
|
181
|
+
return m ? m[1] : void 0;
|
|
182
|
+
};
|
|
183
|
+
for (const varName of Object.keys(usage)) {
|
|
184
|
+
const usedPaths = usage[varName] || [];
|
|
185
|
+
const topParams = import_lodash.default.get(contextParams, varName);
|
|
186
|
+
if (isRecordParams(topParams)) {
|
|
187
|
+
const { generatedAppends, generatedFields } = inferSelectsFromUsage(usedPaths, topParams);
|
|
188
|
+
flowCtx.defineProperty(varName, {
|
|
189
|
+
get: async () => {
|
|
190
|
+
const dataSourceKey = (topParams == null ? void 0 : topParams.dataSourceKey) || "main";
|
|
191
|
+
return await fetchRecordWithRequestCache(
|
|
192
|
+
koaCtx,
|
|
193
|
+
dataSourceKey,
|
|
194
|
+
topParams.collection,
|
|
195
|
+
topParams.filterByTk,
|
|
196
|
+
generatedFields,
|
|
197
|
+
generatedAppends
|
|
198
|
+
);
|
|
199
|
+
},
|
|
200
|
+
cache: true
|
|
201
|
+
});
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
const segmentMap = /* @__PURE__ */ new Map();
|
|
205
|
+
const splitHead = (path) => {
|
|
206
|
+
if (!path) return { seg: "", remainder: "" };
|
|
207
|
+
const mIdx = path.match(/^\[(\d+)\](?:\.(.*))?$/);
|
|
208
|
+
if (mIdx) {
|
|
209
|
+
return { seg: `[${mIdx[1]}]`, remainder: mIdx[2] || "" };
|
|
210
|
+
}
|
|
211
|
+
const m = path.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)(\[(?:\d+|"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')\])?(?:\.(.*))?$/);
|
|
212
|
+
if (m) {
|
|
213
|
+
const seg2 = m[1];
|
|
214
|
+
const idxPart = m[2] || "";
|
|
215
|
+
const tail = m[3] || "";
|
|
216
|
+
const remainder = (idxPart ? `${idxPart}${tail ? `.${tail}` : ""}` : tail) || "";
|
|
217
|
+
return { seg: seg2, remainder };
|
|
218
|
+
}
|
|
219
|
+
const [seg, ...rest] = path.split(".");
|
|
220
|
+
return { seg, remainder: rest.join(".") };
|
|
221
|
+
};
|
|
222
|
+
for (const p of usedPaths) {
|
|
223
|
+
if (!p) continue;
|
|
224
|
+
const { seg, remainder } = splitHead(p);
|
|
225
|
+
if (!seg) continue;
|
|
226
|
+
const arr = segmentMap.get(seg) || [];
|
|
227
|
+
arr.push(remainder);
|
|
228
|
+
segmentMap.set(seg, arr);
|
|
229
|
+
}
|
|
230
|
+
const segEntries = Array.from(segmentMap.entries());
|
|
231
|
+
const recordChildren = segEntries.filter(([seg]) => {
|
|
232
|
+
const idx = parseIndexSegment(seg);
|
|
233
|
+
const nestedObj = import_lodash.default.get(contextParams, [varName, seg]) ?? (idx ? import_lodash.default.get(contextParams, [varName, idx]) : void 0);
|
|
234
|
+
const dotted = (contextParams || {})[`${varName}.${seg}`] ?? (idx ? (contextParams || {})[`${varName}.${idx}`] : void 0);
|
|
235
|
+
return isRecordParams(nestedObj) || isRecordParams(dotted);
|
|
236
|
+
});
|
|
237
|
+
if (!recordChildren.length) continue;
|
|
238
|
+
flowCtx.defineProperty(varName, {
|
|
239
|
+
get: () => {
|
|
240
|
+
const subContext = new import_contexts.ServerBaseContext();
|
|
241
|
+
for (const [seg, remainders] of recordChildren) {
|
|
242
|
+
const idx = parseIndexSegment(seg);
|
|
243
|
+
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);
|
|
244
|
+
let effRemainders = remainders.filter((r) => !!r);
|
|
245
|
+
if (!effRemainders.length) {
|
|
246
|
+
const all = usedPaths.map(
|
|
247
|
+
(p) => p.startsWith(`${seg}.`) ? p.slice(seg.length + 1) : p.startsWith(`${seg}[`) ? p.slice(seg.length) : ""
|
|
248
|
+
).filter((x) => !!x);
|
|
249
|
+
if (all.length) effRemainders = all;
|
|
250
|
+
}
|
|
251
|
+
const { generatedAppends, generatedFields } = inferSelectsFromUsage(effRemainders, recordParams);
|
|
252
|
+
const definitionKey = idx ?? seg;
|
|
253
|
+
subContext.defineProperty(definitionKey, {
|
|
254
|
+
get: async () => {
|
|
255
|
+
const dataSourceKey = (recordParams == null ? void 0 : recordParams.dataSourceKey) || "main";
|
|
256
|
+
return await fetchRecordWithRequestCache(
|
|
257
|
+
koaCtx,
|
|
258
|
+
dataSourceKey,
|
|
259
|
+
recordParams.collection,
|
|
260
|
+
recordParams.filterByTk,
|
|
261
|
+
generatedFields,
|
|
262
|
+
generatedAppends
|
|
263
|
+
);
|
|
264
|
+
},
|
|
265
|
+
cache: true
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return subContext.createProxy();
|
|
269
|
+
},
|
|
270
|
+
cache: true
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function registerBuiltInVariables(reg) {
|
|
275
|
+
reg.register({
|
|
276
|
+
name: "user",
|
|
277
|
+
scope: "request",
|
|
278
|
+
// no requiredParams: frontend will not pass context params for user
|
|
279
|
+
attach: (flowCtx, koaCtx, _params, usage) => {
|
|
280
|
+
const paths = (usage == null ? void 0 : usage["user"]) || [];
|
|
281
|
+
const { generatedAppends, generatedFields } = inferSelectsFromUsage(paths);
|
|
282
|
+
flowCtx.defineProperty("user", {
|
|
283
|
+
get: async () => {
|
|
284
|
+
var _a;
|
|
285
|
+
const authObj = koaCtx.auth;
|
|
286
|
+
const uid = (_a = authObj == null ? void 0 : authObj.user) == null ? void 0 : _a.id;
|
|
287
|
+
if (typeof uid === "undefined" || uid === null) return void 0;
|
|
288
|
+
return await fetchRecordWithRequestCache(koaCtx, "main", "users", uid, generatedFields, generatedAppends);
|
|
289
|
+
},
|
|
290
|
+
cache: true
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
registerBuiltInVariables(variables);
|
|
296
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
297
|
+
0 && (module.exports = {
|
|
298
|
+
variables
|
|
299
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nocobase/plugin-flow-engine",
|
|
3
|
+
"displayName": "Flow engine",
|
|
4
|
+
"displayName.zh-CN": "前端流引擎",
|
|
5
|
+
"description": "",
|
|
6
|
+
"description.zh-CN": "",
|
|
7
|
+
"version": "2.0.0-alpha.2",
|
|
8
|
+
"main": "./dist/server/index.js",
|
|
9
|
+
"license": "AGPL-3.0",
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"antd": "5.x",
|
|
12
|
+
"cronstrue": "^2.11.0",
|
|
13
|
+
"koa-send": "^5.0.1",
|
|
14
|
+
"koa-static": "^5.0.0"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"ses": "^1.14.0"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@nocobase/client": "2.x",
|
|
21
|
+
"@nocobase/database": "2.x",
|
|
22
|
+
"@nocobase/plugin-localization": "2.x",
|
|
23
|
+
"@nocobase/server": "2.x",
|
|
24
|
+
"@nocobase/test": "2.x",
|
|
25
|
+
"@nocobase/utils": "2.x"
|
|
26
|
+
},
|
|
27
|
+
"gitHead": "1322f486b248bef53ed8c8f42f0a39dfd02125fd"
|
|
28
|
+
}
|
package/server.d.ts
ADDED
package/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./dist/server/index.js');
|