@tachybase/module-workflow 1.5.1 → 1.6.0

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 (40) hide show
  1. package/dist/client/WorkflowCategoriesProvider.d.ts +4 -0
  2. package/dist/client/components/WorkflowCategoryColumn.d.ts +8 -0
  3. package/dist/client/components/index.d.ts +2 -0
  4. package/dist/client/hooks/index.d.ts +2 -0
  5. package/dist/client/hooks/useDumpAction.d.ts +7 -0
  6. package/dist/client/hooks/useRevisionAction.d.ts +7 -0
  7. package/dist/client/index.d.ts +2 -0
  8. package/dist/client/index.js +56 -56
  9. package/dist/client/schemas/workflows.d.ts +5 -0
  10. package/dist/client/utils.d.ts +2 -2
  11. package/dist/externalVersion.js +4 -4
  12. package/dist/locale/en-US.json +2 -0
  13. package/dist/locale/es-ES.json +2 -0
  14. package/dist/locale/fr-FR.json +2 -0
  15. package/dist/locale/ja-JP.json +2 -0
  16. package/dist/locale/ko_KR.json +2 -0
  17. package/dist/locale/pt-BR.json +2 -0
  18. package/dist/locale/ru-RU.json +2 -0
  19. package/dist/locale/tr-TR.json +2 -0
  20. package/dist/locale/zh-CN.json +2 -0
  21. package/dist/node_modules/@babel/core/package.json +1 -1
  22. package/dist/node_modules/@babel/preset-env/package.json +1 -1
  23. package/dist/node_modules/@babel/preset-react/package.json +1 -1
  24. package/dist/node_modules/@babel/preset-typescript/package.json +1 -1
  25. package/dist/node_modules/cron-parser/package.json +1 -1
  26. package/dist/node_modules/form-data/package.json +1 -1
  27. package/dist/node_modules/jsonata/package.json +1 -1
  28. package/dist/node_modules/lru-cache/package.json +1 -1
  29. package/dist/node_modules/mime-types/package.json +1 -1
  30. package/dist/node_modules/qrcode/package.json +1 -1
  31. package/dist/server/actions/executions.d.ts +1 -1
  32. package/dist/server/actions/executions.js +15 -3
  33. package/dist/server/actions/workflows.d.ts +11 -2
  34. package/dist/server/actions/workflows.helpers.d.ts +55 -0
  35. package/dist/server/actions/workflows.helpers.js +167 -0
  36. package/dist/server/actions/workflows.js +56 -7
  37. package/dist/server/utils.d.ts +16 -0
  38. package/dist/server/utils.js +33 -2
  39. package/package.json +7 -7
  40. package/dist/client/provider/EventSourceProvider.d.ts +0 -7
@@ -0,0 +1,167 @@
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 __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var workflows_helpers_exports = {};
29
+ __export(workflows_helpers_exports, {
30
+ getCategoriesForWorkflow: () => getCategoriesForWorkflow,
31
+ getEventSourceNameForWorkflow: () => getEventSourceNameForWorkflow,
32
+ getLatestExecutedTimeForWorkflow: () => getLatestExecutedTimeForWorkflow,
33
+ getWorkflowData: () => getWorkflowData,
34
+ setCategories: () => setCategories,
35
+ setEventSourceName: () => setEventSourceName,
36
+ setLatestExecutedTime: () => setLatestExecutedTime
37
+ });
38
+ module.exports = __toCommonJS(workflows_helpers_exports);
39
+ var import_dayjs = __toESM(require("dayjs"));
40
+ function getWorkflowData(workflow) {
41
+ return workflow && typeof workflow.toJSON === "function" ? workflow.toJSON() : workflow;
42
+ }
43
+ async function getLatestExecutedTimeForWorkflow(context, workflowId, workflowKey) {
44
+ if (!workflowId && !workflowKey) {
45
+ return null;
46
+ }
47
+ try {
48
+ const ExecutionRepo = context.db.getRepository("executions");
49
+ const filter = {};
50
+ if (workflowId) {
51
+ filter.workflowId = workflowId;
52
+ } else if (workflowKey) {
53
+ filter.key = workflowKey;
54
+ }
55
+ const latestExecution = await ExecutionRepo.findOne({
56
+ filter,
57
+ fields: ["id", "key", "createdAt", "workflowId"],
58
+ sort: ["-createdAt"],
59
+ context
60
+ });
61
+ return (latestExecution == null ? void 0 : latestExecution.createdAt) ? (0, import_dayjs.default)(latestExecution.createdAt).utc().toISOString() : null;
62
+ } catch (error) {
63
+ context.log.error("Failed to fetch latest executed time:", error);
64
+ return null;
65
+ }
66
+ }
67
+ function setLatestExecutedTime(row, executedTime) {
68
+ row.latestExecutedTime = executedTime;
69
+ if (row && typeof row.setDataValue === "function") {
70
+ row.setDataValue("latestExecutedTime", executedTime);
71
+ }
72
+ }
73
+ async function getEventSourceNameForWorkflow(context, workflowKey) {
74
+ if (!workflowKey) {
75
+ return null;
76
+ }
77
+ try {
78
+ const WebhookRepo = context.db.getRepository("webhooks");
79
+ const eventSource = await WebhookRepo.findOne({
80
+ filter: { workflowKey },
81
+ fields: ["id", "name"],
82
+ context
83
+ });
84
+ return (eventSource == null ? void 0 : eventSource.name) || null;
85
+ } catch (error) {
86
+ context.log.error("Failed to fetch event source name:", error);
87
+ return null;
88
+ }
89
+ }
90
+ function setEventSourceName(row, eventSourceName) {
91
+ row.eventSourceName = eventSourceName;
92
+ if (row && typeof row.setDataValue === "function") {
93
+ row.setDataValue("eventSourceName", eventSourceName);
94
+ }
95
+ }
96
+ async function getCategoriesForWorkflow(context, workflow, workflowKey) {
97
+ var _a;
98
+ if (workflow) {
99
+ const workflowData = workflow && typeof workflow.toJSON === "function" ? workflow.toJSON() : workflow;
100
+ if ((workflowData == null ? void 0 : workflowData.category) && Array.isArray(workflowData.category)) {
101
+ return workflowData.category.map((cat) => {
102
+ const data = cat && typeof cat.toJSON === "function" ? cat.toJSON() : cat;
103
+ return {
104
+ id: data == null ? void 0 : data.id,
105
+ name: data == null ? void 0 : data.name,
106
+ color: data == null ? void 0 : data.color
107
+ };
108
+ });
109
+ }
110
+ }
111
+ const key = workflowKey || workflow && ((_a = getWorkflowData(workflow)) == null ? void 0 : _a.key);
112
+ if (!key) {
113
+ return null;
114
+ }
115
+ try {
116
+ const WorkflowCategoryRepo = context.db.getRepository("workflowCategory");
117
+ const CategoryRepo = context.db.getRepository("workflowCategories");
118
+ const workflowCategories = await WorkflowCategoryRepo.find({
119
+ filter: { workflowKey: key },
120
+ fields: ["categoryId"],
121
+ context
122
+ });
123
+ if (!workflowCategories || workflowCategories.length === 0) {
124
+ return [];
125
+ }
126
+ const categoryIds = workflowCategories.map((wc) => {
127
+ const data = wc && typeof wc.toJSON === "function" ? wc.toJSON() : wc;
128
+ return data == null ? void 0 : data.categoryId;
129
+ }).filter(Boolean);
130
+ if (categoryIds.length === 0) {
131
+ return [];
132
+ }
133
+ const categories = await CategoryRepo.find({
134
+ filter: { id: categoryIds },
135
+ fields: ["id", "name", "color"],
136
+ sort: ["sort"],
137
+ context
138
+ });
139
+ return categories.map((cat) => {
140
+ const data = cat && typeof cat.toJSON === "function" ? cat.toJSON() : cat;
141
+ return {
142
+ id: data == null ? void 0 : data.id,
143
+ name: data == null ? void 0 : data.name,
144
+ color: data == null ? void 0 : data.color
145
+ };
146
+ });
147
+ } catch (error) {
148
+ context.log.error("Failed to fetch categories:", error);
149
+ return null;
150
+ }
151
+ }
152
+ function setCategories(row, categories) {
153
+ row.category = categories || [];
154
+ if (row && typeof row.setDataValue === "function") {
155
+ row.setDataValue("category", categories || []);
156
+ }
157
+ }
158
+ // Annotate the CommonJS export names for ESM import in node:
159
+ 0 && (module.exports = {
160
+ getCategoriesForWorkflow,
161
+ getEventSourceNameForWorkflow,
162
+ getLatestExecutedTimeForWorkflow,
163
+ getWorkflowData,
164
+ setCategories,
165
+ setEventSourceName,
166
+ setLatestExecutedTime
167
+ });
@@ -29,6 +29,7 @@ var workflows_exports = {};
29
29
  __export(workflows_exports, {
30
30
  destroy: () => destroy,
31
31
  dump: () => dump,
32
+ listExtended: () => listExtended,
32
33
  load: () => load,
33
34
  moveWorkflow: () => moveWorkflow,
34
35
  retry: () => retry,
@@ -41,6 +42,28 @@ __export(workflows_exports, {
41
42
  module.exports = __toCommonJS(workflows_exports);
42
43
  var import_server = require("@tego/server");
43
44
  var import_Plugin = __toESM(require("../Plugin"));
45
+ var import_utils = require("../utils");
46
+ var import_workflows = require("./workflows.helpers");
47
+ async function listExtended(context, next) {
48
+ var _a;
49
+ await import_server.actions.list(context, next);
50
+ if (((_a = context.body) == null ? void 0 : _a.rows) && Array.isArray(context.body.rows) && context.body.rows.length > 0) {
51
+ const workflows = context.body.rows;
52
+ for (let index = 0; index < workflows.length; index++) {
53
+ const workflow = workflows[index];
54
+ const row = context.body.rows[index];
55
+ if (!row) continue;
56
+ const workflowData = (0, import_workflows.getWorkflowData)(workflow);
57
+ const executedTime = await (0, import_workflows.getLatestExecutedTimeForWorkflow)(context, workflowData == null ? void 0 : workflowData.id, workflowData == null ? void 0 : workflowData.key);
58
+ (0, import_workflows.setLatestExecutedTime)(row, executedTime);
59
+ const eventSourceName = await (0, import_workflows.getEventSourceNameForWorkflow)(context, workflowData == null ? void 0 : workflowData.key);
60
+ (0, import_workflows.setEventSourceName)(row, eventSourceName);
61
+ const categories = await (0, import_workflows.getCategoriesForWorkflow)(context, workflow, workflowData == null ? void 0 : workflowData.key);
62
+ (0, import_workflows.setCategories)(row, categories);
63
+ }
64
+ }
65
+ return context;
66
+ }
44
67
  async function update(context, next) {
45
68
  const repository = import_server.utils.getRepositoryFromParams(context);
46
69
  const { filterByTk, values } = context.action.params;
@@ -198,19 +221,30 @@ async function test(context, next) {
198
221
  appends: ["nodes"],
199
222
  context
200
223
  });
201
- const result = await plugin.trigger(
224
+ if (!workflow) {
225
+ return context.throw(404, "Workflow not found");
226
+ }
227
+ const execution = await (0, import_utils.triggerWorkflowAndGetExecution)(
228
+ plugin,
202
229
  workflow,
203
230
  {
204
231
  data: values.data || {},
205
232
  user: ((_a = context == null ? void 0 : context.state) == null ? void 0 : _a.currentUser) || {}
206
233
  },
207
- { httpContext: context }
234
+ { httpContext: context, transaction: context.transaction },
235
+ context.db
208
236
  );
209
- context.app.logger.info(result);
237
+ if (!execution) {
238
+ context.state.messages.push({
239
+ message: context.t("Failed to create execution", { ns: "workflow" })
240
+ });
241
+ return context.throw(500, "Failed to create execution");
242
+ }
210
243
  context.state.messages.push({
211
244
  message: context.t("Test execution ended", { ns: "workflow" })
212
245
  });
213
- context.body = result.execution;
246
+ context.body = execution;
247
+ await next();
214
248
  }
215
249
  async function revision(context, next) {
216
250
  const plugin = context.app.getPlugin(import_Plugin.default);
@@ -308,10 +342,24 @@ async function retry(context, next) {
308
342
  });
309
343
  }
310
344
  try {
311
- const result = await plugin.trigger(workflow, execution.context, { httpContext: context });
312
- context.app.logger.info(result);
345
+ const newExecution = await (0, import_utils.triggerWorkflowAndGetExecution)(
346
+ plugin,
347
+ workflow,
348
+ execution.context,
349
+ { httpContext: context, transaction: context.transaction },
350
+ context.db
351
+ );
352
+ if (!newExecution) {
353
+ context.state.messages.push({
354
+ message: context.t("Failed to create execution", { ns: "workflow" })
355
+ });
356
+ context.body = {
357
+ error: context.t("Failed to create execution", { ns: "workflow" })
358
+ };
359
+ return await next();
360
+ }
313
361
  context.state.messages.push({ message: context.t("Execute ended", { ns: "workflow" }) });
314
- context.body = result.execution;
362
+ context.body = newExecution;
315
363
  } catch (error) {
316
364
  context.app.logger.error(`Failed to retry execution ${execution.id}: ${error.message}`);
317
365
  context.state.messages.push({
@@ -428,6 +476,7 @@ async function moveWorkflow(ctx, next) {
428
476
  0 && (module.exports = {
429
477
  destroy,
430
478
  dump,
479
+ listExtended,
431
480
  load,
432
481
  moveWorkflow,
433
482
  retry,
@@ -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.0",
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"
@@ -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.0",
45
+ "@tachybase/module-error-handler": "1.6.0",
46
+ "@tachybase/module-collection": "1.6.0",
47
+ "@tachybase/module-ui-schema": "1.6.0",
48
+ "@tachybase/module-user": "1.6.0",
49
+ "@tachybase/plugin-workflow-test": "1.6.0"
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
- };