@nocobase/plugin-workflow 0.10.1-alpha.1 → 0.11.1-alpha.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.
- package/client.d.ts +2 -3
- package/client.js +1 -30
- package/lib/client/AddButton.js +13 -11
- package/lib/client/Branch.js +10 -8
- package/lib/client/CanvasContent.js +12 -10
- package/lib/client/ExecutionCanvas.js +37 -33
- package/lib/client/ExecutionPage.js +4 -9
- package/lib/client/WorkflowCanvas.js +18 -15
- package/lib/client/WorkflowPage.js +4 -9
- package/lib/client/WorkflowProvider.js +1 -40
- package/lib/client/components/CollectionBlockInitializer.js +3 -3
- package/lib/client/components/CollectionFieldset.d.ts +1 -1
- package/lib/client/components/CollectionFieldset.js +15 -16
- package/lib/client/components/Duration.js +5 -5
- package/lib/client/components/DynamicExpression.d.ts +3 -3
- package/lib/client/components/FieldsSelect.d.ts +1 -1
- package/lib/client/components/FieldsSelect.js +10 -7
- package/lib/client/components/NodeDescription.js +45 -31
- package/lib/client/components/RadioWithTooltip.js +13 -20
- package/lib/client/components/ValueBlock.js +14 -21
- package/lib/client/components/renderEngineReference.js +1 -8
- package/lib/client/index.d.ts +12 -4
- package/lib/client/index.js +78 -15
- package/lib/client/locale/zh-CN.d.ts +5 -1
- package/lib/client/locale/zh-CN.js +6 -2
- package/lib/client/nodes/aggregate.d.ts +8 -3
- package/lib/client/nodes/aggregate.js +5 -4
- package/lib/client/nodes/calculation.d.ts +6 -4
- package/lib/client/nodes/calculation.js +22 -28
- package/lib/client/nodes/condition.d.ts +2 -10
- package/lib/client/nodes/condition.js +19 -37
- package/lib/client/nodes/create.d.ts +5 -6
- package/lib/client/nodes/create.js +1 -3
- package/lib/client/nodes/destroy.d.ts +1 -1
- package/lib/client/nodes/index.d.ts +2 -3
- package/lib/client/nodes/index.js +95 -102
- package/lib/client/nodes/loop.d.ts +1 -1
- package/lib/client/nodes/loop.js +46 -54
- package/lib/client/nodes/manual/FormBlockInitializer.js +6 -5
- package/lib/client/nodes/manual/ModeConfig.js +23 -30
- package/lib/client/nodes/manual/SchemaConfig.d.ts +4 -5
- package/lib/client/nodes/manual/SchemaConfig.js +180 -25
- package/lib/client/nodes/manual/WorkflowTodo.js +95 -110
- package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.d.ts +2 -5
- package/lib/client/nodes/manual/WorkflowTodoBlockInitializer.js +6 -5
- package/lib/client/nodes/manual/forms/create.js +8 -1
- package/lib/client/nodes/manual/forms/custom.js +22 -22
- package/lib/client/nodes/manual/forms/update.js +8 -1
- package/lib/client/nodes/manual/index.d.ts +6 -1
- package/lib/client/nodes/manual/index.js +5 -4
- package/lib/client/nodes/parallel.js +23 -20
- package/lib/client/nodes/query.d.ts +3 -5
- package/lib/client/nodes/query.js +1 -3
- package/lib/client/nodes/request.d.ts +2 -2
- package/lib/client/nodes/request.js +7 -7
- package/lib/client/nodes/sql.d.ts +26 -0
- package/lib/client/{triggers/schedule/DateFieldsSelect.js → nodes/sql.js} +37 -46
- package/lib/client/nodes/update.d.ts +2 -2
- package/lib/client/nodes/update.js +1 -1
- package/lib/client/schemas/collection.d.ts +3 -4
- package/lib/client/schemas/collection.js +11 -17
- package/lib/client/style.d.ts +18 -13
- package/lib/client/style.js +315 -292
- package/lib/client/triggers/collection.d.ts +13 -13
- package/lib/client/triggers/collection.js +5 -1
- package/lib/client/triggers/index.d.ts +3 -4
- package/lib/client/triggers/index.js +51 -53
- package/lib/client/triggers/schedule/EndsByField.js +11 -11
- package/lib/client/triggers/schedule/OnField.js +45 -33
- package/lib/client/triggers/schedule/RepeatField.js +4 -4
- package/lib/client/triggers/schedule/ScheduleConfig.js +24 -31
- package/lib/client/triggers/schedule/index.d.ts +1 -1
- package/lib/client/triggers/schedule/index.js +32 -20
- package/lib/client/variable.d.ts +31 -13
- package/lib/client/variable.js +44 -29
- package/lib/server/Plugin.d.ts +3 -6
- package/lib/server/Plugin.js +15 -12
- package/lib/server/Processor.d.ts +3 -5
- package/lib/server/Processor.js +2 -2
- package/lib/server/actions/nodes.js +7 -7
- package/lib/server/fields/expression-field.d.ts +1 -2
- package/lib/server/fields/expression-field.js +1 -8
- package/lib/server/functions/index.d.ts +2 -3
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +12 -0
- package/lib/server/instructions/aggregate.d.ts +1 -1
- package/lib/server/instructions/aggregate.js +5 -5
- package/lib/server/instructions/condition.d.ts +2 -1
- package/lib/server/instructions/create.d.ts +2 -2
- package/lib/server/instructions/create.js +13 -13
- package/lib/server/instructions/delay.d.ts +3 -3
- package/lib/server/instructions/delay.js +66 -64
- package/lib/server/instructions/destroy.d.ts +1 -1
- package/lib/server/instructions/index.d.ts +5 -5
- package/lib/server/instructions/index.js +1 -1
- package/lib/server/instructions/loop.d.ts +1 -2
- package/lib/server/instructions/manual/actions.js +19 -7
- package/lib/server/instructions/manual/forms/create.js +7 -1
- package/lib/server/instructions/manual/forms/index.d.ts +1 -1
- package/lib/server/instructions/manual/forms/update.js +7 -1
- package/lib/server/instructions/manual/index.d.ts +1 -1
- package/lib/server/instructions/parallel.d.ts +1 -2
- package/lib/server/instructions/query.d.ts +1 -1
- package/lib/server/instructions/query.js +8 -1
- package/lib/server/instructions/request.d.ts +3 -3
- package/lib/server/instructions/request.js +5 -2
- package/lib/server/instructions/sql.d.ts +12 -0
- package/lib/server/instructions/sql.js +34 -0
- package/lib/server/instructions/update.d.ts +1 -1
- package/lib/server/migrations/20230221071831-calculation-expression.js +1 -1
- package/lib/server/migrations/20230221121203-condition-calculation.js +1 -1
- package/lib/server/migrations/20230221162902-jsonb-to-json.js +7 -7
- package/lib/server/migrations/20230411034722-manual-multi-form.js +1 -8
- package/lib/server/migrations/20230710115902-manual-action-values.d.ts +4 -0
- package/lib/server/migrations/20230710115902-manual-action-values.js +97 -0
- package/lib/server/triggers/collection.d.ts +1 -1
- package/lib/server/triggers/collection.js +15 -13
- package/lib/server/triggers/index.d.ts +1 -1
- package/lib/server/triggers/schedule.d.ts +1 -1
- package/lib/server/triggers/schedule.js +18 -18
- package/lib/server/{models → types}/Execution.d.ts +2 -3
- package/lib/server/{models → types}/FlowNode.d.ts +1 -2
- package/lib/server/{models → types}/Job.d.ts +1 -2
- package/lib/server/{models → types}/Workflow.d.ts +1 -2
- package/lib/server/types/index.d.ts +4 -0
- package/lib/server/types/index.js +5 -0
- package/lib/server/utils.d.ts +2 -0
- package/lib/server/utils.js +21 -0
- package/package.json +39 -18
- package/server.d.ts +2 -3
- package/server.js +1 -30
- package/src/client/AddButton.tsx +111 -0
- package/src/client/Branch.tsx +37 -0
- package/src/client/CanvasContent.tsx +25 -0
- package/src/client/ExecutionCanvas.tsx +166 -0
- package/src/client/ExecutionLink.tsx +16 -0
- package/src/client/ExecutionPage.tsx +45 -0
- package/src/client/ExecutionResourceProvider.tsx +21 -0
- package/src/client/FlowContext.ts +7 -0
- package/src/client/WorkflowCanvas.tsx +221 -0
- package/src/client/WorkflowLink.tsx +16 -0
- package/src/client/WorkflowPage.tsx +52 -0
- package/src/client/WorkflowProvider.tsx +84 -0
- package/src/client/components/CollectionBlockInitializer.tsx +71 -0
- package/src/client/components/CollectionFieldset.tsx +160 -0
- package/src/client/components/Duration.tsx +45 -0
- package/src/client/components/DynamicExpression.tsx +53 -0
- package/src/client/components/FieldsSelect.tsx +32 -0
- package/src/client/components/FilterDynamicComponent.tsx +15 -0
- package/src/client/components/NodeDescription.tsx +51 -0
- package/src/client/components/NullRender.tsx +3 -0
- package/src/client/components/OpenDrawer.tsx +24 -0
- package/src/client/components/RadioWithTooltip.tsx +38 -0
- package/src/client/components/ValueBlock.tsx +67 -0
- package/src/client/components/renderEngineReference.tsx +30 -0
- package/src/client/constants.tsx +91 -0
- package/src/client/index.tsx +51 -0
- package/src/client/interfaces/expression.tsx +25 -0
- package/src/client/locale/en-US.ts +136 -0
- package/src/client/locale/es-ES.ts +129 -0
- package/src/client/locale/index.ts +18 -0
- package/src/client/locale/ja-JP.ts +90 -0
- package/src/client/locale/pt-BR.ts +136 -0
- package/src/client/locale/ru-RU.ts +90 -0
- package/src/client/locale/tr-TR.ts +90 -0
- package/src/client/locale/zh-CN.ts +248 -0
- package/src/client/nodes/aggregate.tsx +327 -0
- package/src/client/nodes/calculation.tsx +216 -0
- package/src/client/nodes/condition.tsx +463 -0
- package/src/client/nodes/create.tsx +85 -0
- package/src/client/nodes/delay.tsx +37 -0
- package/src/client/nodes/destroy.tsx +34 -0
- package/src/client/nodes/index.tsx +485 -0
- package/src/client/nodes/loop.tsx +144 -0
- package/src/client/nodes/manual/AssigneesSelect.tsx +33 -0
- package/src/client/nodes/manual/DetailsBlockProvider.tsx +80 -0
- package/src/client/nodes/manual/FormBlockInitializer.tsx +69 -0
- package/src/client/nodes/manual/FormBlockProvider.tsx +75 -0
- package/src/client/nodes/manual/ModeConfig.tsx +84 -0
- package/src/client/nodes/manual/SchemaConfig.tsx +509 -0
- package/src/client/nodes/manual/WorkflowTodo.tsx +607 -0
- package/src/client/nodes/manual/WorkflowTodoBlockInitializer.tsx +28 -0
- package/src/client/nodes/manual/forms/create.tsx +92 -0
- package/src/client/nodes/manual/forms/custom.tsx +392 -0
- package/src/client/nodes/manual/forms/update.tsx +134 -0
- package/src/client/nodes/manual/index.tsx +162 -0
- package/src/client/nodes/manual/utils.ts +28 -0
- package/src/client/nodes/parallel.tsx +138 -0
- package/src/client/nodes/query.tsx +88 -0
- package/src/client/nodes/request.tsx +185 -0
- package/src/client/nodes/sql.tsx +37 -0
- package/src/client/nodes/update.tsx +99 -0
- package/src/client/schemas/collection.ts +75 -0
- package/src/client/schemas/executions.tsx +169 -0
- package/src/client/schemas/workflows.ts +364 -0
- package/src/client/style.tsx +347 -0
- package/src/client/triggers/collection.tsx +190 -0
- package/src/client/triggers/index.tsx +311 -0
- package/src/client/triggers/schedule/EndsByField.tsx +40 -0
- package/src/client/triggers/schedule/OnField.tsx +64 -0
- package/src/client/triggers/schedule/RepeatField.tsx +116 -0
- package/src/client/triggers/schedule/ScheduleConfig.tsx +227 -0
- package/src/client/triggers/schedule/constants.ts +4 -0
- package/src/client/triggers/schedule/index.tsx +78 -0
- package/src/client/triggers/schedule/locale/Cron.zh-CN.ts +79 -0
- package/src/client/utils.ts +36 -0
- package/src/client/variable.tsx +318 -0
- package/src/index.ts +1 -0
- package/src/server/Plugin.ts +355 -0
- package/src/server/Processor.ts +354 -0
- package/src/server/__tests__/Plugin.test.ts +398 -0
- package/src/server/__tests__/Processor.test.ts +474 -0
- package/src/server/__tests__/actions/workflows.test.ts +419 -0
- package/src/server/__tests__/collections/categories.ts +27 -0
- package/src/server/__tests__/collections/comments.ts +24 -0
- package/src/server/__tests__/collections/posts.ts +42 -0
- package/src/server/__tests__/collections/replies.ts +9 -0
- package/src/server/__tests__/collections/tags.ts +15 -0
- package/src/server/__tests__/index.ts +89 -0
- package/src/server/__tests__/instructions/aggregate.test.ts +294 -0
- package/src/server/__tests__/instructions/calculation.test.ts +265 -0
- package/src/server/__tests__/instructions/condition.test.ts +335 -0
- package/src/server/__tests__/instructions/create.test.ts +129 -0
- package/src/server/__tests__/instructions/delay.test.ts +182 -0
- package/src/server/__tests__/instructions/destroy.test.ts +58 -0
- package/src/server/__tests__/instructions/loop.test.ts +331 -0
- package/src/server/__tests__/instructions/manual.test.ts +1173 -0
- package/src/server/__tests__/instructions/parallel.test.ts +445 -0
- package/src/server/__tests__/instructions/query.test.ts +359 -0
- package/src/server/__tests__/instructions/request.test.ts +247 -0
- package/src/server/__tests__/instructions/sql.test.ts +162 -0
- package/src/server/__tests__/instructions/update.test.ts +189 -0
- package/src/server/__tests__/triggers/collection.test.ts +333 -0
- package/src/server/__tests__/triggers/schedule.test.ts +369 -0
- package/src/server/actions/index.ts +25 -0
- package/src/server/actions/nodes.ts +214 -0
- package/src/server/actions/workflows.ts +178 -0
- package/src/server/collections/executions.ts +35 -0
- package/src/server/collections/flow_nodes.ts +54 -0
- package/src/server/collections/jobs.ts +31 -0
- package/src/server/collections/workflows.ts +88 -0
- package/src/server/constants.ts +26 -0
- package/src/server/fields/expression-field.ts +11 -0
- package/src/server/fields/index.ts +7 -0
- package/src/server/functions/index.ts +16 -0
- package/src/server/index.ts +6 -0
- package/src/server/instructions/aggregate.ts +42 -0
- package/src/server/instructions/calculation.ts +41 -0
- package/src/server/instructions/condition.ts +172 -0
- package/src/server/instructions/create.ts +39 -0
- package/src/server/instructions/delay.ts +105 -0
- package/src/server/instructions/destroy.ts +23 -0
- package/src/server/instructions/index.ts +64 -0
- package/src/server/instructions/loop.ts +99 -0
- package/src/server/instructions/manual/actions.ts +91 -0
- package/src/server/instructions/manual/collecions/jobs.ts +17 -0
- package/src/server/instructions/manual/collecions/users.ts +15 -0
- package/src/server/instructions/manual/collecions/users_jobs.ts +50 -0
- package/src/server/instructions/manual/forms/create.ts +23 -0
- package/src/server/instructions/manual/forms/index.ts +12 -0
- package/src/server/instructions/manual/forms/update.ts +23 -0
- package/src/server/instructions/manual/index.ts +184 -0
- package/src/server/instructions/parallel.ts +121 -0
- package/src/server/instructions/query.ts +42 -0
- package/src/server/instructions/request.ts +88 -0
- package/src/server/instructions/sql.ts +25 -0
- package/src/server/instructions/update.ts +24 -0
- package/src/server/migrations/20221129153547-calculation-variables.ts +64 -0
- package/src/server/migrations/20230221032941-change-request-body-type.ts +76 -0
- package/src/server/migrations/20230221071831-calculation-expression.ts +102 -0
- package/src/server/migrations/20230221121203-condition-calculation.ts +82 -0
- package/src/server/migrations/20230221162902-jsonb-to-json.ts +51 -0
- package/src/server/migrations/20230411034722-manual-multi-form.ts +282 -0
- package/src/server/migrations/20230612021134-manual-collection-block.ts +138 -0
- package/src/server/migrations/20230710115902-manual-action-values.ts +78 -0
- package/src/server/triggers/collection.ts +146 -0
- package/src/server/triggers/index.ts +22 -0
- package/src/server/triggers/schedule.ts +567 -0
- package/src/server/types/Execution.ts +26 -0
- package/src/server/types/FlowNode.ts +21 -0
- package/src/server/types/Job.ts +18 -0
- package/src/server/types/Workflow.ts +36 -0
- package/src/server/types/index.ts +4 -0
- package/src/server/utils.ts +17 -0
- package/lib/client/triggers/schedule/DateFieldsSelect.d.ts +0 -2
- /package/lib/server/{models → types}/Execution.js +0 -0
- /package/lib/server/{models → types}/FlowNode.js +0 -0
- /package/lib/server/{models → types}/Job.js +0 -0
- /package/lib/server/{models → types}/Workflow.js +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
import Database from '@nocobase/database';
|
|
2
|
+
import { Application } from '@nocobase/server';
|
|
3
|
+
import { getApp, sleep } from '.';
|
|
4
|
+
import { BRANCH_INDEX, EXECUTION_STATUS, JOB_STATUS } from '../constants';
|
|
5
|
+
|
|
6
|
+
describe('workflow > Processor', () => {
|
|
7
|
+
let app: Application;
|
|
8
|
+
let db: Database;
|
|
9
|
+
let PostRepo;
|
|
10
|
+
let WorkflowModel;
|
|
11
|
+
let workflow;
|
|
12
|
+
let plugin;
|
|
13
|
+
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
app = await getApp();
|
|
16
|
+
plugin = app.pm.get('workflow');
|
|
17
|
+
|
|
18
|
+
db = app.db;
|
|
19
|
+
WorkflowModel = db.getCollection('workflows').model;
|
|
20
|
+
PostRepo = db.getCollection('posts').repository;
|
|
21
|
+
|
|
22
|
+
workflow = await WorkflowModel.create({
|
|
23
|
+
enabled: true,
|
|
24
|
+
type: 'collection',
|
|
25
|
+
config: {
|
|
26
|
+
mode: 1,
|
|
27
|
+
collection: 'posts',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterEach(() => db.close());
|
|
33
|
+
|
|
34
|
+
describe('base', () => {
|
|
35
|
+
it('empty workflow without any nodes', async () => {
|
|
36
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
37
|
+
|
|
38
|
+
await sleep(500);
|
|
39
|
+
|
|
40
|
+
const [execution] = await workflow.getExecutions();
|
|
41
|
+
expect(execution.context.data.title).toEqual(post.title);
|
|
42
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('execute resolved workflow', async () => {
|
|
46
|
+
await workflow.createNode({
|
|
47
|
+
type: 'echo',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
51
|
+
|
|
52
|
+
await sleep(500);
|
|
53
|
+
|
|
54
|
+
const [execution] = await workflow.getExecutions();
|
|
55
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
56
|
+
|
|
57
|
+
// expect(execution.start()).rejects.toThrow();
|
|
58
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
59
|
+
const jobs = await execution.getJobs();
|
|
60
|
+
expect(jobs.length).toEqual(1);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('workflow with single simple node', async () => {
|
|
64
|
+
await workflow.createNode({
|
|
65
|
+
type: 'echo',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
69
|
+
|
|
70
|
+
await sleep(500);
|
|
71
|
+
|
|
72
|
+
const [execution] = await workflow.getExecutions();
|
|
73
|
+
expect(execution.context.data.title).toEqual(post.title);
|
|
74
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
75
|
+
|
|
76
|
+
const jobs = await execution.getJobs();
|
|
77
|
+
expect(jobs.length).toEqual(1);
|
|
78
|
+
const { status, result } = jobs[0].get();
|
|
79
|
+
expect(status).toEqual(JOB_STATUS.RESOLVED);
|
|
80
|
+
expect(result).toMatchObject({ data: JSON.parse(JSON.stringify(post.toJSON())) });
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('workflow with multiple simple nodes', async () => {
|
|
84
|
+
const n1 = await workflow.createNode({
|
|
85
|
+
title: 'echo 1',
|
|
86
|
+
type: 'echo',
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const n2 = await workflow.createNode({
|
|
90
|
+
title: 'echo 2',
|
|
91
|
+
type: 'echo',
|
|
92
|
+
upstreamId: n1.id,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
await n1.setDownstream(n2);
|
|
96
|
+
|
|
97
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
98
|
+
|
|
99
|
+
await sleep(500);
|
|
100
|
+
|
|
101
|
+
const [execution] = await workflow.getExecutions();
|
|
102
|
+
expect(execution.context.data.title).toEqual(post.title);
|
|
103
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
104
|
+
|
|
105
|
+
const jobs = await execution.getJobs();
|
|
106
|
+
expect(jobs.length).toEqual(2);
|
|
107
|
+
const { status, result } = jobs[1].get();
|
|
108
|
+
expect(status).toEqual(JOB_STATUS.RESOLVED);
|
|
109
|
+
expect(result).toMatchObject({ data: JSON.parse(JSON.stringify(post.toJSON())) });
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('workflow with error node', async () => {
|
|
113
|
+
await workflow.createNode({
|
|
114
|
+
type: 'error',
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
118
|
+
|
|
119
|
+
await sleep(500);
|
|
120
|
+
|
|
121
|
+
const [execution] = await workflow.getExecutions();
|
|
122
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.ERROR);
|
|
123
|
+
|
|
124
|
+
const jobs = await execution.getJobs();
|
|
125
|
+
expect(jobs.length).toEqual(1);
|
|
126
|
+
const { status, result } = jobs[0].get();
|
|
127
|
+
expect(status).toEqual(JOB_STATUS.ERROR);
|
|
128
|
+
expect(result.message).toBe('definite error');
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('workflow with customized success node', async () => {
|
|
132
|
+
await workflow.createNode({
|
|
133
|
+
type: 'customizedSuccess',
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
137
|
+
|
|
138
|
+
await sleep(500);
|
|
139
|
+
|
|
140
|
+
const [execution] = await workflow.getExecutions();
|
|
141
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
142
|
+
|
|
143
|
+
const jobs = await execution.getJobs();
|
|
144
|
+
expect(jobs.length).toEqual(1);
|
|
145
|
+
const { status, result } = jobs[0].get();
|
|
146
|
+
expect(status).toEqual(100);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('workflow with customized error node', async () => {
|
|
150
|
+
await workflow.createNode({
|
|
151
|
+
type: 'customizedError',
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
155
|
+
|
|
156
|
+
await sleep(500);
|
|
157
|
+
|
|
158
|
+
const [execution] = await workflow.getExecutions();
|
|
159
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.FAILED);
|
|
160
|
+
|
|
161
|
+
const jobs = await execution.getJobs();
|
|
162
|
+
expect(jobs.length).toEqual(1);
|
|
163
|
+
const { status, result } = jobs[0].get();
|
|
164
|
+
expect(status).toEqual(-100);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
describe('manual nodes', () => {
|
|
169
|
+
it('manual node should suspend execution, and could be manually resume', async () => {
|
|
170
|
+
const n1 = await workflow.createNode({
|
|
171
|
+
type: 'manual',
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const n2 = await workflow.createNode({
|
|
175
|
+
type: 'echo',
|
|
176
|
+
upstreamId: n1.id,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
await n1.setDownstream(n2);
|
|
180
|
+
|
|
181
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
182
|
+
|
|
183
|
+
await sleep(500);
|
|
184
|
+
|
|
185
|
+
const [execution] = await workflow.getExecutions();
|
|
186
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
187
|
+
const [pending] = await execution.getJobs();
|
|
188
|
+
expect(pending.status).toEqual(JOB_STATUS.PENDING);
|
|
189
|
+
expect(pending.result).toEqual(null);
|
|
190
|
+
|
|
191
|
+
pending.set({
|
|
192
|
+
status: JOB_STATUS.RESOLVED,
|
|
193
|
+
result: 123,
|
|
194
|
+
});
|
|
195
|
+
pending.execution = execution;
|
|
196
|
+
await plugin.resume(pending);
|
|
197
|
+
|
|
198
|
+
await sleep(500);
|
|
199
|
+
|
|
200
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
201
|
+
|
|
202
|
+
const jobs = await execution.getJobs({ order: [['id', 'ASC']] });
|
|
203
|
+
expect(jobs.length).toEqual(2);
|
|
204
|
+
expect(jobs[0].status).toEqual(JOB_STATUS.RESOLVED);
|
|
205
|
+
expect(jobs[0].result).toEqual(123);
|
|
206
|
+
expect(jobs[1].status).toEqual(JOB_STATUS.RESOLVED);
|
|
207
|
+
expect(jobs[1].result).toEqual(123);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('manual node should suspend execution, resuming with error should end execution', async () => {
|
|
211
|
+
const n1 = await workflow.createNode({
|
|
212
|
+
type: 'prompt->error',
|
|
213
|
+
});
|
|
214
|
+
const n2 = await workflow.createNode({
|
|
215
|
+
type: 'echo',
|
|
216
|
+
upstreamId: n1.id,
|
|
217
|
+
});
|
|
218
|
+
await n1.setDownstream(n2);
|
|
219
|
+
|
|
220
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
221
|
+
|
|
222
|
+
await sleep(500);
|
|
223
|
+
|
|
224
|
+
const [execution] = await workflow.getExecutions();
|
|
225
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
226
|
+
const [pending] = await execution.getJobs();
|
|
227
|
+
expect(pending.status).toEqual(JOB_STATUS.PENDING);
|
|
228
|
+
expect(pending.result).toEqual(null);
|
|
229
|
+
|
|
230
|
+
pending.set('result', 123);
|
|
231
|
+
pending.execution = execution;
|
|
232
|
+
await plugin.resume(pending);
|
|
233
|
+
|
|
234
|
+
await sleep(500);
|
|
235
|
+
|
|
236
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.ERROR);
|
|
237
|
+
|
|
238
|
+
const jobs = await execution.getJobs();
|
|
239
|
+
expect(jobs.length).toEqual(1);
|
|
240
|
+
expect(jobs[0].status).toEqual(JOB_STATUS.ERROR);
|
|
241
|
+
expect(jobs[0].result.message).toEqual('input failed');
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
describe('branch: condition', () => {
|
|
246
|
+
it('condition node link to different downstreams', async () => {
|
|
247
|
+
const n1 = await workflow.createNode({
|
|
248
|
+
type: 'condition',
|
|
249
|
+
// no config means always true
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
const n2 = await workflow.createNode({
|
|
253
|
+
type: 'echo',
|
|
254
|
+
branchIndex: BRANCH_INDEX.ON_TRUE,
|
|
255
|
+
upstreamId: n1.id,
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
await workflow.createNode({
|
|
259
|
+
type: 'echo',
|
|
260
|
+
branchIndex: BRANCH_INDEX.ON_FALSE,
|
|
261
|
+
upstreamId: n1.id,
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
265
|
+
|
|
266
|
+
await sleep(500);
|
|
267
|
+
|
|
268
|
+
const [execution] = await workflow.getExecutions();
|
|
269
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
270
|
+
|
|
271
|
+
const jobs = await execution.getJobs({ order: [['id', 'ASC']] });
|
|
272
|
+
expect(jobs.length).toEqual(2);
|
|
273
|
+
expect(jobs[0].nodeId).toEqual(n1.id);
|
|
274
|
+
expect(jobs[1].nodeId).toEqual(n2.id);
|
|
275
|
+
expect(jobs[1].result).toEqual(true);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('suspend downstream in condition branch, then go on', async () => {
|
|
279
|
+
const n1 = await workflow.createNode({
|
|
280
|
+
type: 'condition',
|
|
281
|
+
// no config means always true
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
const n2 = await workflow.createNode({
|
|
285
|
+
type: 'manual',
|
|
286
|
+
branchIndex: BRANCH_INDEX.ON_TRUE,
|
|
287
|
+
upstreamId: n1.id,
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
const n3 = await workflow.createNode({
|
|
291
|
+
type: 'echo',
|
|
292
|
+
upstreamId: n1.id,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
await n1.setDownstream(n3);
|
|
296
|
+
|
|
297
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
298
|
+
|
|
299
|
+
await sleep(500);
|
|
300
|
+
|
|
301
|
+
const [execution] = await workflow.getExecutions();
|
|
302
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
303
|
+
|
|
304
|
+
const [pending] = await execution.getJobs({ where: { nodeId: n2.id } });
|
|
305
|
+
pending.set({
|
|
306
|
+
status: JOB_STATUS.RESOLVED,
|
|
307
|
+
result: 123,
|
|
308
|
+
});
|
|
309
|
+
pending.execution = execution;
|
|
310
|
+
await plugin.resume(pending);
|
|
311
|
+
|
|
312
|
+
await sleep(500);
|
|
313
|
+
|
|
314
|
+
const jobs = await execution.getJobs();
|
|
315
|
+
expect(jobs.length).toEqual(3);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('resume error downstream in condition branch, should error', async () => {
|
|
319
|
+
const n1 = await workflow.createNode({
|
|
320
|
+
type: 'condition',
|
|
321
|
+
// no config means always true
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
const n2 = await workflow.createNode({
|
|
325
|
+
type: 'prompt->error',
|
|
326
|
+
branchIndex: BRANCH_INDEX.ON_TRUE,
|
|
327
|
+
upstreamId: n1.id,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
const n3 = await workflow.createNode({
|
|
331
|
+
type: 'echo',
|
|
332
|
+
upstreamId: n1.id,
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
await n1.setDownstream(n3);
|
|
336
|
+
|
|
337
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
338
|
+
|
|
339
|
+
await sleep(500);
|
|
340
|
+
|
|
341
|
+
const [execution] = await workflow.getExecutions();
|
|
342
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
343
|
+
|
|
344
|
+
const [pending] = await execution.getJobs({ where: { nodeId: n2.id } });
|
|
345
|
+
pending.set('result', 123);
|
|
346
|
+
pending.execution = execution;
|
|
347
|
+
await plugin.resume(pending);
|
|
348
|
+
|
|
349
|
+
await sleep(500);
|
|
350
|
+
|
|
351
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.ERROR);
|
|
352
|
+
|
|
353
|
+
const jobs = await execution.getJobs();
|
|
354
|
+
expect(jobs.length).toEqual(2);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
describe('branch: mixed', () => {
|
|
359
|
+
it('condition branches contains parallel', async () => {
|
|
360
|
+
const n1 = await workflow.createNode({
|
|
361
|
+
type: 'condition',
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
const n2 = await workflow.createNode({
|
|
365
|
+
type: 'parallel',
|
|
366
|
+
branchIndex: BRANCH_INDEX.ON_TRUE,
|
|
367
|
+
upstreamId: n1.id,
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
const n3 = await workflow.createNode({
|
|
371
|
+
type: 'manual',
|
|
372
|
+
upstreamId: n2.id,
|
|
373
|
+
branchIndex: 0,
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
const n4 = await workflow.createNode({
|
|
377
|
+
title: 'parallel echo',
|
|
378
|
+
type: 'echo',
|
|
379
|
+
upstreamId: n2.id,
|
|
380
|
+
branchIndex: 1,
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
const n5 = await workflow.createNode({
|
|
384
|
+
title: 'last echo',
|
|
385
|
+
type: 'echo',
|
|
386
|
+
upstreamId: n1.id,
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
await n1.setDownstream(n5);
|
|
390
|
+
|
|
391
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
392
|
+
|
|
393
|
+
await sleep(500);
|
|
394
|
+
|
|
395
|
+
const [execution] = await workflow.getExecutions();
|
|
396
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
397
|
+
|
|
398
|
+
const pendingJobs = await execution.getJobs();
|
|
399
|
+
expect(pendingJobs.length).toBe(4);
|
|
400
|
+
|
|
401
|
+
const pending = pendingJobs.find((item) => item.nodeId === n3.id);
|
|
402
|
+
pending.set({
|
|
403
|
+
status: JOB_STATUS.RESOLVED,
|
|
404
|
+
result: 123,
|
|
405
|
+
});
|
|
406
|
+
pending.execution = execution;
|
|
407
|
+
await plugin.resume(pending);
|
|
408
|
+
|
|
409
|
+
await sleep(500);
|
|
410
|
+
|
|
411
|
+
expect(execution.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
412
|
+
const jobs = await execution.getJobs({ order: [['id', 'ASC']] });
|
|
413
|
+
expect(jobs.length).toEqual(5);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
it('parallel branches contains condition', async () => {
|
|
417
|
+
const n1 = await workflow.createNode({
|
|
418
|
+
type: 'parallel',
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
const n2 = await workflow.createNode({
|
|
422
|
+
type: 'manual',
|
|
423
|
+
upstreamId: n1.id,
|
|
424
|
+
branchIndex: 0,
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
const n3 = await workflow.createNode({
|
|
428
|
+
type: 'condition',
|
|
429
|
+
upstreamId: n1.id,
|
|
430
|
+
branchIndex: 1,
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
const n4 = await workflow.createNode({
|
|
434
|
+
title: 'condition echo',
|
|
435
|
+
type: 'echo',
|
|
436
|
+
upstreamId: n3.id,
|
|
437
|
+
branchIndex: BRANCH_INDEX.ON_TRUE,
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
const n5 = await workflow.createNode({
|
|
441
|
+
title: 'last echo',
|
|
442
|
+
type: 'echo',
|
|
443
|
+
upstreamId: n1.id,
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
await n1.setDownstream(n5);
|
|
447
|
+
|
|
448
|
+
const post = await PostRepo.create({ values: { title: 't1' } });
|
|
449
|
+
|
|
450
|
+
await sleep(500);
|
|
451
|
+
|
|
452
|
+
const [e1] = await workflow.getExecutions();
|
|
453
|
+
expect(e1.status).toEqual(EXECUTION_STATUS.STARTED);
|
|
454
|
+
|
|
455
|
+
const pendingJobs = await e1.getJobs();
|
|
456
|
+
expect(pendingJobs.length).toBe(4);
|
|
457
|
+
|
|
458
|
+
const pending = pendingJobs.find((item) => item.nodeId === n2.id);
|
|
459
|
+
pending.set({
|
|
460
|
+
status: JOB_STATUS.RESOLVED,
|
|
461
|
+
result: 123,
|
|
462
|
+
});
|
|
463
|
+
pending.execution = e1;
|
|
464
|
+
await plugin.resume(pending);
|
|
465
|
+
|
|
466
|
+
await sleep(500);
|
|
467
|
+
|
|
468
|
+
const [e2] = await workflow.getExecutions();
|
|
469
|
+
expect(e2.status).toEqual(EXECUTION_STATUS.RESOLVED);
|
|
470
|
+
const jobs = await e2.getJobs({ order: [['id', 'ASC']] });
|
|
471
|
+
expect(jobs.length).toEqual(5);
|
|
472
|
+
});
|
|
473
|
+
});
|
|
474
|
+
});
|