@tachybase/module-workflow 1.5.1 → 1.6.1

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 (75) hide show
  1. package/dist/client/WorkflowCategoriesProvider.d.ts +4 -0
  2. package/dist/client/components/ColletionTreeSelect.d.ts +16 -0
  3. package/dist/client/components/EnabledStatusFilter.d.ts +2 -0
  4. package/dist/client/components/WorkflowCategoryColumn.d.ts +8 -0
  5. package/dist/client/components/index.d.ts +3 -0
  6. package/dist/client/features/script/Script.instruction.d.ts +136 -0
  7. package/dist/client/features/script/ScriptCodeEditor.d.ts +9 -0
  8. package/dist/client/features/script/SyncRemoteCodeButton.d.ts +6 -0
  9. package/dist/client/features/trigger-instruction/TriggerInstruction.d.ts +164 -5
  10. package/dist/client/hooks/index.d.ts +2 -0
  11. package/dist/client/hooks/useDumpAction.d.ts +7 -0
  12. package/dist/client/hooks/useRevisionAction.d.ts +7 -0
  13. package/dist/client/index.d.ts +2 -0
  14. package/dist/client/index.js +85 -59
  15. package/dist/client/nodes/select.d.ts +235 -0
  16. package/dist/client/schemas/workflows.d.ts +5 -0
  17. package/dist/client/utils.d.ts +2 -2
  18. package/dist/externalVersion.js +9 -9
  19. package/dist/locale/en-US.json +49 -1
  20. package/dist/locale/es-ES.json +19 -1
  21. package/dist/locale/fr-FR.json +18 -0
  22. package/dist/locale/ja-JP.json +19 -1
  23. package/dist/locale/ko_KR.json +19 -1
  24. package/dist/locale/pt-BR.json +19 -1
  25. package/dist/locale/ru-RU.json +20 -2
  26. package/dist/locale/tr-TR.json +20 -2
  27. package/dist/locale/zh-CN.json +52 -1
  28. package/dist/node_modules/@babel/core/lib/index.js +77 -77
  29. package/dist/node_modules/@babel/core/node_modules/.bin/parser +4 -4
  30. package/dist/node_modules/@babel/core/package.json +1 -1
  31. package/dist/node_modules/@babel/preset-env/lib/index.js +88 -88
  32. package/dist/node_modules/@babel/preset-env/package.json +1 -1
  33. package/dist/node_modules/@babel/preset-react/lib/index.js +80 -80
  34. package/dist/node_modules/@babel/preset-react/package.json +1 -1
  35. package/dist/node_modules/@babel/preset-typescript/lib/index.js +77 -77
  36. package/dist/node_modules/@babel/preset-typescript/package.json +1 -1
  37. package/dist/node_modules/cron-parser/package.json +1 -1
  38. package/dist/node_modules/form-data/package.json +1 -1
  39. package/dist/node_modules/jsonata/package.json +1 -1
  40. package/dist/node_modules/lru-cache/package.json +1 -1
  41. package/dist/node_modules/mime-types/package.json +1 -1
  42. package/dist/node_modules/qrcode/package.json +1 -1
  43. package/dist/server/Plugin.js +57 -1
  44. package/dist/server/actions/executions.d.ts +3 -3
  45. package/dist/server/actions/executions.js +42 -30
  46. package/dist/server/actions/index.js +3 -2
  47. package/dist/server/actions/nodes.d.ts +13 -6
  48. package/dist/server/actions/nodes.js +160 -34
  49. package/dist/server/actions/workflows.d.ts +17 -8
  50. package/dist/server/actions/workflows.helpers.d.ts +55 -0
  51. package/dist/server/actions/workflows.helpers.js +167 -0
  52. package/dist/server/actions/workflows.js +118 -69
  53. package/dist/server/features/interception/RequestInterceptionTrigger.d.ts +1 -1
  54. package/dist/server/features/interception/RequestInterceptionTrigger.js +12 -12
  55. package/dist/server/features/manual/actions.d.ts +1 -1
  56. package/dist/server/features/manual/actions.js +12 -12
  57. package/dist/server/features/notice/actions.js +19 -19
  58. package/dist/server/features/notice/plugin.js +0 -3
  59. package/dist/server/features/omni-trigger/CustomActionTrigger.d.ts +2 -2
  60. package/dist/server/features/omni-trigger/CustomActionTrigger.js +27 -27
  61. package/dist/server/features/script/script.instruction.js +146 -4
  62. package/dist/server/features/trigger-instruction/TriggerInstruction.d.ts +4 -0
  63. package/dist/server/features/trigger-instruction/TriggerInstruction.js +71 -5
  64. package/dist/server/instructions/SelectInstruction.d.ts +13 -0
  65. package/dist/server/instructions/SelectInstruction.js +126 -0
  66. package/dist/server/services/remote-code-fetcher.d.ts +48 -0
  67. package/dist/server/services/remote-code-fetcher.js +370 -0
  68. package/dist/server/utils/get-remote-code-fetcher.d.ts +7 -0
  69. package/dist/server/utils/get-remote-code-fetcher.js +39 -0
  70. package/dist/server/utils.d.ts +16 -0
  71. package/dist/server/utils.js +33 -2
  72. package/package.json +12 -12
  73. package/dist/client/provider/EventSourceProvider.d.ts +0 -7
  74. package/dist/server/features/trigger-instruction/index.d.ts +0 -0
  75. package/dist/server/features/trigger-instruction/index.js +0 -0
@@ -0,0 +1,370 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
8
+ var __typeError = (msg) => {
9
+ throw TypeError(msg);
10
+ };
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+ var __copyProps = (to, from, except, desc) => {
18
+ if (from && typeof from === "object" || typeof from === "function") {
19
+ for (let key of __getOwnPropNames(from))
20
+ if (!__hasOwnProp.call(to, key) && key !== except)
21
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
22
+ }
23
+ return to;
24
+ };
25
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
26
+ // If the importer is in node compatibility mode or this is not an ESM
27
+ // file that has been converted to a CommonJS file using a Babel-
28
+ // compatible transform (i.e. "__esModule" has not been set), then set
29
+ // "default" to the CommonJS "module.exports" for node compatibility.
30
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
31
+ mod
32
+ ));
33
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
+ var __decoratorStart = (base) => [, , , __create((base == null ? void 0 : base[__knownSymbol("metadata")]) ?? null)];
35
+ var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
36
+ var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
37
+ var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
38
+ var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
39
+ var __runInitializers = (array, flags, self, value) => {
40
+ for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
41
+ return value;
42
+ };
43
+ var __decorateElement = (array, flags, name, decorators, target, extra) => {
44
+ var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
45
+ var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
46
+ var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
47
+ var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
48
+ return __privateGet(this, extra);
49
+ }, set [name](x) {
50
+ return __privateSet(this, extra, x);
51
+ } }, name));
52
+ k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
53
+ for (var i = decorators.length - 1; i >= 0; i--) {
54
+ ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
55
+ if (k) {
56
+ ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
57
+ if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
58
+ if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
59
+ }
60
+ it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
61
+ if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
62
+ else if (typeof it !== "object" || it === null) __typeError("Object expected");
63
+ else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
64
+ }
65
+ return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
66
+ };
67
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
68
+ var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
69
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
70
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
71
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
72
+ var remote_code_fetcher_exports = {};
73
+ __export(remote_code_fetcher_exports, {
74
+ WorkflowRemoteCodeFetcher: () => WorkflowRemoteCodeFetcher
75
+ });
76
+ module.exports = __toCommonJS(remote_code_fetcher_exports);
77
+ var import_node_http = __toESM(require("node:http"));
78
+ var import_node_https = __toESM(require("node:https"));
79
+ var import_node_url = require("node:url");
80
+ var import_server = require("@tego/server");
81
+ var _logger_dec, _WorkflowRemoteCodeFetcher_decorators, _init;
82
+ _WorkflowRemoteCodeFetcher_decorators = [(0, import_server.Service)()], _logger_dec = [(0, import_server.InjectLog)()];
83
+ class WorkflowRemoteCodeFetcher {
84
+ constructor() {
85
+ this.logger = __runInitializers(_init, 8, this), __runInitializers(_init, 11, this);
86
+ }
87
+ /**
88
+ * 从 CDN 获取代码
89
+ * @param url 代码 URL
90
+ * @param timeout 超时时间(毫秒)
91
+ * @param authType 认证类型: 'none' | 'token' | 'basic'
92
+ * @param authToken Bearer Token 或 Basic Auth 的密码
93
+ * @param authUsername Basic Auth 的用户名
94
+ */
95
+ async fetchFromCDN(url, timeout = 1e4, authType, authToken, authUsername) {
96
+ return new Promise((resolve, reject) => {
97
+ const urlObj = new import_node_url.URL(url);
98
+ const client = urlObj.protocol === "https:" ? import_node_https.default : import_node_http.default;
99
+ this.logger.info(`Fetching from URL: ${url}${authType && authType !== "none" ? ` (with ${authType} auth)` : ""}`);
100
+ const headers = {
101
+ "User-Agent": "TegoWorkflow/1.0"
102
+ };
103
+ if (authType === "token" && authToken) {
104
+ headers["Authorization"] = `Bearer ${authToken}`;
105
+ this.logger.info(`Using Bearer Token authentication (token length: ${authToken.length})`);
106
+ } else if (authType === "basic" && authUsername && authToken) {
107
+ const credentials = Buffer.from(`${authUsername}:${authToken}`).toString("base64");
108
+ headers["Authorization"] = `Basic ${credentials}`;
109
+ this.logger.info(`Using Basic Auth authentication (username: ${authUsername})`);
110
+ } else if (authType && authType !== "none") {
111
+ this.logger.warn(`Auth type is ${authType} but missing required credentials`);
112
+ }
113
+ const request = client.get(
114
+ {
115
+ hostname: urlObj.hostname,
116
+ port: urlObj.port || (urlObj.protocol === "https:" ? 443 : 80),
117
+ path: urlObj.pathname + urlObj.search,
118
+ headers,
119
+ timeout
120
+ },
121
+ (res) => {
122
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
123
+ const redirectUrl = res.headers.location.startsWith("http") ? res.headers.location : `${urlObj.protocol}//${urlObj.hostname}${res.headers.location}`;
124
+ this.logger.info(`Following redirect from ${url} to ${redirectUrl}`);
125
+ request.destroy();
126
+ return this.fetchFromCDN(redirectUrl, timeout, authType, authToken, authUsername).then(resolve).catch(reject);
127
+ }
128
+ if (res.statusCode !== 200) {
129
+ const errorMsg = `Failed to fetch from URL: HTTP ${res.statusCode}. URL: ${url}`;
130
+ this.logger.error(errorMsg);
131
+ reject(new Error(errorMsg));
132
+ return;
133
+ }
134
+ let data = "";
135
+ res.on("data", (chunk) => {
136
+ data += chunk;
137
+ });
138
+ res.on("end", () => {
139
+ this.logger.info(`Successfully fetched ${data.length} bytes from ${url}`);
140
+ resolve(data);
141
+ });
142
+ }
143
+ );
144
+ request.on("error", (error) => {
145
+ const errorMsg = `Failed to fetch from URL: ${error.message}. URL: ${url}`;
146
+ this.logger.error(errorMsg);
147
+ reject(new Error(errorMsg));
148
+ });
149
+ request.on("timeout", () => {
150
+ request.destroy();
151
+ const errorMsg = `Request timeout after ${timeout}ms. URL: ${url}`;
152
+ this.logger.error(errorMsg);
153
+ reject(new Error(errorMsg));
154
+ });
155
+ });
156
+ }
157
+ /**
158
+ * 检测 URL 是否已经是 Raw 文件 URL(可以直接访问)
159
+ */
160
+ isRawFileUrl(url) {
161
+ try {
162
+ const urlObj = new import_node_url.URL(url);
163
+ return urlObj.hostname.includes("raw.githubusercontent.com") || urlObj.pathname.includes("/-/raw/") || urlObj.pathname.includes("/raw/branch/");
164
+ } catch {
165
+ return false;
166
+ }
167
+ }
168
+ /**
169
+ * 从 URL 中解析分支和文件路径
170
+ */
171
+ parseGitUrl(url) {
172
+ try {
173
+ const urlObj = new import_node_url.URL(url);
174
+ const pathParts = urlObj.pathname.split("/").filter(Boolean);
175
+ if (pathParts.length < 2) {
176
+ return null;
177
+ }
178
+ const owner = pathParts[0];
179
+ const repo = pathParts[1];
180
+ let branch;
181
+ let filePath;
182
+ if (urlObj.hostname === "github.com" || urlObj.hostname.includes("github")) {
183
+ const blobIndex = pathParts.findIndex((p) => p === "blob");
184
+ const treeIndex = pathParts.findIndex((p) => p === "tree");
185
+ if (blobIndex !== -1 && blobIndex + 1 < pathParts.length) {
186
+ branch = pathParts[blobIndex + 1];
187
+ if (blobIndex + 2 < pathParts.length) {
188
+ filePath = pathParts.slice(blobIndex + 2).join("/");
189
+ }
190
+ } else if (treeIndex !== -1 && treeIndex + 1 < pathParts.length) {
191
+ branch = pathParts[treeIndex + 1];
192
+ if (treeIndex + 2 < pathParts.length) {
193
+ filePath = pathParts.slice(treeIndex + 2).join("/");
194
+ }
195
+ }
196
+ } else if (urlObj.hostname.includes("gitlab.com") || urlObj.hostname.includes("gitlab")) {
197
+ const dashIndex = pathParts.findIndex((p) => p === "-");
198
+ if (dashIndex !== -1 && dashIndex + 1 < pathParts.length) {
199
+ const nextPart = pathParts[dashIndex + 1];
200
+ if (nextPart === "blob" || nextPart === "tree") {
201
+ if (dashIndex + 2 < pathParts.length) {
202
+ branch = pathParts[dashIndex + 2];
203
+ if (dashIndex + 3 < pathParts.length) {
204
+ filePath = pathParts.slice(dashIndex + 3).join("/");
205
+ }
206
+ }
207
+ }
208
+ }
209
+ } else if (urlObj.pathname.includes("/src/branch/")) {
210
+ const srcIndex = pathParts.findIndex((p) => p === "src");
211
+ if (srcIndex !== -1 && pathParts[srcIndex + 1] === "branch" && srcIndex + 2 < pathParts.length) {
212
+ branch = pathParts[srcIndex + 2];
213
+ if (srcIndex + 3 < pathParts.length) {
214
+ filePath = pathParts.slice(srcIndex + 3).join("/");
215
+ }
216
+ }
217
+ } else if (this.isRawFileUrl(url)) {
218
+ if (pathParts.length >= 3) {
219
+ branch = pathParts[2];
220
+ if (pathParts.length > 3) {
221
+ filePath = pathParts.slice(3).join("/");
222
+ }
223
+ }
224
+ }
225
+ return { owner, repo, branch, filePath };
226
+ } catch {
227
+ return null;
228
+ }
229
+ }
230
+ /**
231
+ * 从 Git 仓库获取代码(通过 Raw 文件 URL)
232
+ */
233
+ async fetchFromGit(url, branch = "main", path, authType, authToken, authUsername) {
234
+ try {
235
+ const urlObj = new import_node_url.URL(url);
236
+ let rawUrl = "";
237
+ if (this.isRawFileUrl(url)) {
238
+ this.logger.info(`URL appears to be a raw file URL, using directly: ${url}`);
239
+ return await this.fetchFromCDN(url, 1e4, authType, authToken, authUsername);
240
+ }
241
+ const parsed = this.parseGitUrl(url);
242
+ const finalBranch = branch || (parsed == null ? void 0 : parsed.branch) || "main";
243
+ const finalPath = path || (parsed == null ? void 0 : parsed.filePath);
244
+ if (urlObj.hostname === "github.com" || urlObj.hostname.includes("github")) {
245
+ const pathParts = urlObj.pathname.split("/").filter(Boolean);
246
+ if (pathParts.length >= 2) {
247
+ const owner = pathParts[0];
248
+ const repo = pathParts[1];
249
+ if (parsed == null ? void 0 : parsed.filePath) {
250
+ rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${finalBranch}/${parsed.filePath}`;
251
+ } else if (finalPath) {
252
+ rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${finalBranch}/${finalPath}`;
253
+ } else {
254
+ const blobIndex = pathParts.findIndex((p) => p === "blob");
255
+ const treeIndex = pathParts.findIndex((p) => p === "tree");
256
+ let filePath;
257
+ if (blobIndex !== -1 && blobIndex + 2 < pathParts.length) {
258
+ filePath = pathParts.slice(blobIndex + 2).join("/");
259
+ } else if (treeIndex !== -1 && treeIndex + 2 < pathParts.length) {
260
+ const possiblePath = pathParts.slice(treeIndex + 2).join("/");
261
+ if (possiblePath.match(/\.(tsx?|jsx?|ts|js)$/)) {
262
+ filePath = possiblePath;
263
+ }
264
+ }
265
+ if (filePath) {
266
+ rawUrl = `https://raw.githubusercontent.com/${owner}/${repo}/${finalBranch}/${filePath}`;
267
+ } else {
268
+ throw new Error(
269
+ `Unable to determine file path from GitHub URL: ${url}. Please ensure the URL points to a specific file (e.g., /blob/branch/path/to/file.tsx) or provide codePath.`
270
+ );
271
+ }
272
+ }
273
+ } else {
274
+ throw new Error(`Invalid GitHub URL format: ${url}`);
275
+ }
276
+ } else if (urlObj.hostname.includes("gitlab.com") || urlObj.hostname.includes("gitlab")) {
277
+ const pathParts = urlObj.pathname.split("/").filter(Boolean);
278
+ if (pathParts.length >= 2) {
279
+ const owner = pathParts[0];
280
+ const repo = pathParts[1];
281
+ if (parsed == null ? void 0 : parsed.filePath) {
282
+ rawUrl = `${urlObj.protocol}//${urlObj.hostname}/${owner}/${repo}/-/raw/${finalBranch}/${parsed.filePath}`;
283
+ } else if (finalPath) {
284
+ rawUrl = `${urlObj.protocol}//${urlObj.hostname}/${owner}/${repo}/-/raw/${finalBranch}/${finalPath}`;
285
+ } else {
286
+ throw new Error(
287
+ `Unable to determine file path from GitLab URL: ${url}. Please ensure the URL points to a specific file or provide codePath.`
288
+ );
289
+ }
290
+ } else {
291
+ throw new Error(`Invalid GitLab URL format: ${url}`);
292
+ }
293
+ } else {
294
+ if (parsed) {
295
+ const { owner, repo } = parsed;
296
+ if (urlObj.pathname.includes("/src/branch/")) {
297
+ const actualPath = finalPath || parsed.filePath;
298
+ if (!actualPath) {
299
+ throw new Error(
300
+ `Unable to determine file path from Gitea URL: ${url}. Please ensure the URL points to a specific file or provide codePath.`
301
+ );
302
+ }
303
+ rawUrl = `${urlObj.protocol}//${urlObj.hostname}/${owner}/${repo}/raw/branch/${finalBranch}/${actualPath}`;
304
+ } else if (finalPath || parsed.filePath) {
305
+ const filePath = finalPath || parsed.filePath;
306
+ rawUrl = `${urlObj.protocol}//${urlObj.hostname}/${owner}/${repo}/-/raw/${finalBranch}/${filePath}`;
307
+ } else {
308
+ throw new Error(
309
+ `Unable to determine file path from URL: ${url}. Please provide codePath or use a URL that points to a specific file.`
310
+ );
311
+ }
312
+ } else {
313
+ if (this.isRawFileUrl(url)) {
314
+ rawUrl = url;
315
+ } else {
316
+ throw new Error(`Invalid Git URL format: ${url}`);
317
+ }
318
+ }
319
+ }
320
+ this.logger.info(`Fetching from Git: ${rawUrl}`);
321
+ return await this.fetchFromCDN(rawUrl, 1e4, authType, authToken, authUsername);
322
+ } catch (error) {
323
+ this.logger.error(`Failed to fetch from Git: ${error instanceof Error ? error.message : String(error)}`);
324
+ throw error;
325
+ }
326
+ }
327
+ /**
328
+ * 获取远程代码
329
+ * @param codeUrl 代码地址
330
+ * @param codeType 代码类型:'cdn' 或 'git'
331
+ * @param codeBranch Git 分支名称(仅 Git 类型需要)
332
+ * @param codePath Git 文件路径(仅 Git 类型需要)
333
+ * @param authType 认证类型: 'none' | 'token' | 'basic'
334
+ * @param authToken Bearer Token 或 Basic Auth 的密码
335
+ * @param authUsername Basic Auth 的用户名
336
+ */
337
+ async fetchCode(codeUrl, codeType, codeBranch, codePath, authType, authToken, authUsername) {
338
+ if (!codeUrl) {
339
+ throw new Error("Code URL is required");
340
+ }
341
+ if (codeType === "cdn") {
342
+ this.logger.info(`Fetching code from CDN: ${codeUrl}`);
343
+ return await this.fetchFromCDN(codeUrl, 1e4, authType, authToken, authUsername);
344
+ } else if (codeType === "git") {
345
+ this.logger.info(`Fetching code from Git: ${codeUrl}, branch: ${codeBranch || "main"}`);
346
+ return await this.fetchFromGit(codeUrl, codeBranch || "main", codePath, authType, authToken, authUsername);
347
+ } else {
348
+ throw new Error(`Unsupported code type: ${codeType}. Must be 'cdn' or 'git'`);
349
+ }
350
+ }
351
+ /**
352
+ * 检查缓存是否有效(默认缓存 1 小时)
353
+ * @param cache 缓存对象,包含 content 和 timestamp
354
+ * @param maxAge 最大缓存时间(毫秒),默认 1 小时 (3600000ms)
355
+ */
356
+ isCacheValid(cache, maxAge = 36e5) {
357
+ if (!cache) {
358
+ return false;
359
+ }
360
+ return Date.now() - cache.timestamp < maxAge;
361
+ }
362
+ }
363
+ _init = __decoratorStart(null);
364
+ __decorateElement(_init, 5, "logger", _logger_dec, WorkflowRemoteCodeFetcher);
365
+ WorkflowRemoteCodeFetcher = __decorateElement(_init, 0, "WorkflowRemoteCodeFetcher", _WorkflowRemoteCodeFetcher_decorators, WorkflowRemoteCodeFetcher);
366
+ __runInitializers(_init, 1, WorkflowRemoteCodeFetcher);
367
+ // Annotate the CommonJS export names for ESM import in node:
368
+ 0 && (module.exports = {
369
+ WorkflowRemoteCodeFetcher
370
+ });
@@ -0,0 +1,7 @@
1
+ import { Application } from '@tego/server';
2
+ import { WorkflowRemoteCodeFetcher } from '../services/remote-code-fetcher';
3
+ /**
4
+ * 获取 WorkflowRemoteCodeFetcher 服务
5
+ * 优先使用 app.container.get,失败时回退到全局 Container.get
6
+ */
7
+ export declare function getRemoteCodeFetcher(app: Application): WorkflowRemoteCodeFetcher | undefined;
@@ -0,0 +1,39 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var get_remote_code_fetcher_exports = {};
19
+ __export(get_remote_code_fetcher_exports, {
20
+ getRemoteCodeFetcher: () => getRemoteCodeFetcher
21
+ });
22
+ module.exports = __toCommonJS(get_remote_code_fetcher_exports);
23
+ var import_server = require("@tego/server");
24
+ var import_remote_code_fetcher = require("../services/remote-code-fetcher");
25
+ function getRemoteCodeFetcher(app) {
26
+ try {
27
+ return app.container.get(import_remote_code_fetcher.WorkflowRemoteCodeFetcher);
28
+ } catch {
29
+ try {
30
+ return import_server.Container.get(import_remote_code_fetcher.WorkflowRemoteCodeFetcher);
31
+ } catch {
32
+ return void 0;
33
+ }
34
+ }
35
+ }
36
+ // Annotate the CommonJS export names for ESM import in node:
37
+ 0 && (module.exports = {
38
+ getRemoteCodeFetcher
39
+ });
@@ -1 +1,17 @@
1
+ import { Database, Transactionable } from '@tego/server';
2
+ import PluginWorkflowServer from './Plugin';
3
+ import { WorkflowModel } from './types';
1
4
  export declare function toJSON(data: any): any;
5
+ /**
6
+ * 触发工作流并获取新创建的执行记录
7
+ * @param plugin 工作流插件实例
8
+ * @param workflow 工作流模型
9
+ * @param context 触发上下文
10
+ * @param options 选项(包含 httpContext, transaction 等)
11
+ * @param db 数据库实例(用于查询执行记录)
12
+ * @returns 新创建的执行记录,如果创建失败则返回 null
13
+ */
14
+ export declare function triggerWorkflowAndGetExecution(plugin: PluginWorkflowServer, workflow: WorkflowModel, context: object, options: {
15
+ httpContext?: any;
16
+ transaction?: any;
17
+ } & Transactionable, db: Database): Promise<any | null>;
@@ -17,7 +17,8 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var utils_exports = {};
19
19
  __export(utils_exports, {
20
- toJSON: () => toJSON
20
+ toJSON: () => toJSON,
21
+ triggerWorkflowAndGetExecution: () => triggerWorkflowAndGetExecution
21
22
  });
22
23
  module.exports = __toCommonJS(utils_exports);
23
24
  var import_server = require("@tego/server");
@@ -36,7 +37,37 @@ function toJSON(data) {
36
37
  });
37
38
  return result;
38
39
  }
40
+ async function triggerWorkflowAndGetExecution(plugin, workflow, context, options = {}, db) {
41
+ const beforeTriggerTime = /* @__PURE__ */ new Date();
42
+ const result = await plugin.trigger(workflow, context, options);
43
+ let execution;
44
+ if (result && typeof result === "object" && "execution" in result && result.execution) {
45
+ execution = result.execution;
46
+ } else if (!result && !plugin.isWorkflowSync(workflow)) {
47
+ const ExecutionRepo = db.getRepository("executions");
48
+ const maxRetries = 10;
49
+ const retryDelay = 200;
50
+ for (let i = 0; i < maxRetries; i++) {
51
+ await new Promise((resolve) => setTimeout(resolve, retryDelay));
52
+ execution = await ExecutionRepo.findOne({
53
+ filter: {
54
+ key: workflow.key,
55
+ createdAt: {
56
+ [import_server.Op.gte]: beforeTriggerTime
57
+ }
58
+ },
59
+ sort: ["-createdAt"],
60
+ transaction: options.transaction
61
+ });
62
+ if (execution) {
63
+ break;
64
+ }
65
+ }
66
+ }
67
+ return execution || null;
68
+ }
39
69
  // Annotate the CommonJS export names for ESM import in node:
40
70
  0 && (module.exports = {
41
- toJSON
71
+ toJSON,
72
+ triggerWorkflowAndGetExecution
42
73
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tachybase/module-workflow",
3
3
  "displayName": "Workflow",
4
- "version": "1.5.1",
4
+ "version": "1.6.1",
5
5
  "description": "A powerful BPM tool that provides foundational support for business automation, with the capability to extend unlimited triggers and nodes.",
6
6
  "keywords": [
7
7
  "Workflow"
@@ -9,17 +9,17 @@
9
9
  "license": "Apache-2.0",
10
10
  "main": "./dist/server/index.js",
11
11
  "devDependencies": {
12
- "@ant-design/icons": "^5.6.1",
12
+ "@ant-design/icons": "^6.1.0",
13
13
  "@babel/core": "7.27.4",
14
14
  "@babel/parser": "7.27.5",
15
15
  "@babel/preset-env": "7.27.2",
16
16
  "@babel/preset-react": "7.27.1",
17
17
  "@babel/preset-typescript": "7.27.1",
18
18
  "@dnd-kit/core": "^6.3.1",
19
- "@tachybase/schema": "1.3.52",
20
- "@tachybase/test": "1.3.52",
21
- "@tego/client": "1.3.52",
22
- "@tego/server": "1.3.52",
19
+ "@tachybase/schema": "1.6.0-alpha.9",
20
+ "@tachybase/test": "1.6.0-alpha.9",
21
+ "@tego/client": "1.6.0-alpha.9",
22
+ "@tego/server": "1.6.0-alpha.9",
23
23
  "@types/babel__core": "7.20.5",
24
24
  "@types/ejs": "^3.1.5",
25
25
  "@types/file-saver": "^2.0.7",
@@ -41,12 +41,12 @@
41
41
  "react-js-cron": "^3.2.0",
42
42
  "react-router-dom": "6.28.1",
43
43
  "sequelize": "6.37.5",
44
- "@tachybase/module-error-handler": "1.5.1",
45
- "@tachybase/client": "1.5.1",
46
- "@tachybase/module-collection": "1.5.1",
47
- "@tachybase/module-ui-schema": "1.5.1",
48
- "@tachybase/module-user": "1.5.1",
49
- "@tachybase/plugin-workflow-test": "1.5.1"
44
+ "@tachybase/client": "1.6.1",
45
+ "@tachybase/module-error-handler": "1.6.1",
46
+ "@tachybase/module-collection": "1.6.1",
47
+ "@tachybase/module-ui-schema": "1.6.1",
48
+ "@tachybase/module-user": "1.6.1",
49
+ "@tachybase/plugin-workflow-test": "1.6.1"
50
50
  },
51
51
  "description.zh-CN": "一个强大的 BPM 工具,为业务自动化提供基础支持,并且可任意扩展更多的触发器和节点。",
52
52
  "displayName.zh-CN": "工作流",
@@ -1,7 +0,0 @@
1
- export declare const EventSourceContext: import("react").Context<{
2
- eventSourceList: any[];
3
- }>;
4
- export declare const EventSourceProvider: (props: any) => import("react/jsx-runtime").JSX.Element;
5
- export declare const useEventSourceContext: () => {
6
- eventSourceList: any[];
7
- };
File without changes