@nocobase/plugin-workflow 0.19.0-alpha.4 → 0.19.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/components/CheckboxGroupWithTooltip.d.ts +7 -0
- package/dist/client/components/index.d.ts +1 -0
- package/dist/client/index.js +31 -28
- package/dist/client/triggers/index.d.ts +1 -1
- package/dist/externalVersion.js +9 -9
- package/dist/locale/zh-CN.json +10 -2
- package/dist/node_modules/cron-parser/package.json +1 -1
- package/dist/node_modules/lru-cache/package.json +1 -1
- package/dist/server/Plugin.d.ts +1 -1
- package/dist/server/Plugin.js +23 -22
- package/dist/server/Processor.d.ts +1 -0
- package/dist/server/actions/workflows.js +3 -1
- package/dist/server/instructions/CreateInstruction.js +1 -1
- package/dist/server/instructions/DestroyInstruction.js +1 -1
- package/dist/server/instructions/EndInstruction.d.ts +1 -3
- package/dist/server/instructions/EndInstruction.js +8 -4
- package/dist/server/instructions/UpdateInstruction.js +1 -1
- package/dist/server/migrations/20240115220721-add-node-key-to-job.js +0 -1
- package/dist/server/triggers/CollectionTrigger.d.ts +2 -0
- package/dist/server/triggers/CollectionTrigger.js +19 -9
- package/dist/server/triggers/index.d.ts +1 -0
- package/dist/server/triggers/index.js +3 -0
- package/package.json +8 -3
|
@@ -19,7 +19,7 @@ export declare abstract class Trigger {
|
|
|
19
19
|
};
|
|
20
20
|
useInitializers?(config: any): SchemaInitializerItemType | null;
|
|
21
21
|
initializers?: any;
|
|
22
|
-
|
|
22
|
+
isActionTriggerable?: boolean | ((config: object, context?: object) => boolean);
|
|
23
23
|
}
|
|
24
24
|
export declare const TriggerConfig: () => React.JSX.Element;
|
|
25
25
|
export declare function useTrigger(): any;
|
package/dist/externalVersion.js
CHANGED
|
@@ -2,21 +2,21 @@ module.exports = {
|
|
|
2
2
|
"react": "18.2.0",
|
|
3
3
|
"antd": "5.12.8",
|
|
4
4
|
"@ant-design/icons": "5.2.6",
|
|
5
|
-
"@nocobase/client": "0.19.0-alpha.
|
|
5
|
+
"@nocobase/client": "0.19.0-alpha.6",
|
|
6
6
|
"react-router-dom": "6.21.0",
|
|
7
|
-
"@nocobase/utils": "0.19.0-alpha.
|
|
7
|
+
"@nocobase/utils": "0.19.0-alpha.6",
|
|
8
8
|
"react-i18next": "11.18.6",
|
|
9
9
|
"@formily/core": "2.3.0",
|
|
10
10
|
"@formily/react": "2.3.0",
|
|
11
|
-
"@nocobase/database": "0.19.0-alpha.
|
|
12
|
-
"@nocobase/server": "0.19.0-alpha.
|
|
13
|
-
"@nocobase/logger": "0.19.0-alpha.
|
|
14
|
-
"@nocobase/evaluators": "0.19.0-alpha.
|
|
11
|
+
"@nocobase/database": "0.19.0-alpha.6",
|
|
12
|
+
"@nocobase/server": "0.19.0-alpha.6",
|
|
13
|
+
"@nocobase/logger": "0.19.0-alpha.6",
|
|
14
|
+
"@nocobase/evaluators": "0.19.0-alpha.6",
|
|
15
15
|
"lodash": "4.17.21",
|
|
16
16
|
"@formily/antd-v5": "1.1.9",
|
|
17
|
-
"@nocobase/actions": "0.19.0-alpha.
|
|
17
|
+
"@nocobase/actions": "0.19.0-alpha.6",
|
|
18
18
|
"sequelize": "6.35.2",
|
|
19
|
-
"@nocobase/plugin-workflow-test": "0.19.0-alpha.
|
|
20
|
-
"@nocobase/test": "0.19.0-alpha.
|
|
19
|
+
"@nocobase/plugin-workflow-test": "0.19.0-alpha.6",
|
|
20
|
+
"@nocobase/test": "0.19.0-alpha.6",
|
|
21
21
|
"dayjs": "1.11.10"
|
|
22
22
|
};
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -27,10 +27,18 @@
|
|
|
27
27
|
"Trigger time": "触发时间",
|
|
28
28
|
"Triggered at": "触发时间",
|
|
29
29
|
|
|
30
|
+
"Execute mode": "执行模式",
|
|
31
|
+
"Execute workflow asynchronously or synchronously based on trigger type, and could not be changed after created.": "基于触发类型异步或同步执行工作流,创建后不可更改。",
|
|
32
|
+
"Asynchronously": "异步",
|
|
33
|
+
"Synchronously": "同步",
|
|
34
|
+
"Will be executed in the background as a queued task.": "将作为队列任务在后台执行。",
|
|
35
|
+
"For user actions that require immediate feedback. Can not use asynchronous nodes in such mode, and it is not recommended to perform time-consuming operations under synchronous mode.":
|
|
36
|
+
"适用于需要即时反馈的用户操作。不能在此模式下使用异步节点,并且不建议在同步模式下执行耗时的操作。",
|
|
37
|
+
|
|
30
38
|
"Bind workflows": "绑定工作流",
|
|
31
|
-
"Workflow will be triggered after submitting succeeded.": "
|
|
32
|
-
"Workflow will be triggered after saving succeeded.": "保存成功后触发工作流。",
|
|
39
|
+
"Workflow will be triggered before or after submitting succeeded based on workflow type.": "工作流会基于其类型在提交成功之前或之后触发。",
|
|
33
40
|
"Workflow will be triggered directly once the button clicked, without data saving.": "按钮点击后直接触发工作流,但不会保存数据。",
|
|
41
|
+
"Workflow will be triggered before deleting succeeded.": "删除成功之前触发工作流。",
|
|
34
42
|
"Submit to workflow": "提交至工作流",
|
|
35
43
|
"Add workflow": "添加工作流",
|
|
36
44
|
"Select workflow": "选择工作流",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"cron-parser","version":"4.4.0","description":"Node.js library for parsing crontab instructions","main":"lib/parser.js","types":"index.d.ts","typesVersions":{"<4.1":{"*":["types/ts3/*"]}},"directories":{"test":"test"},"scripts":{"test:tsd":"tsd","test:unit":"TZ=UTC tap ./test/*.js","test:cover":"TZ=UTC tap --coverage-report=html ./test/*.js","lint":"eslint .","lint:fix":"eslint --fix .","test":"npm run lint && npm run test:unit && npm run test:tsd"},"repository":{"type":"git","url":"https://github.com/harrisiirak/cron-parser.git"},"keywords":["cron","crontab","parser"],"author":"Harri Siirak","contributors":["Nicholas Clawson","Daniel Prentis <daniel@salsitasoft.com>","Renault John Lecoultre","Richard Astbury <richard.astbury@gmail.com>","Meaglin Wasabi <Meaglin.wasabi@gmail.com>","Mike Kusold <hello@mikekusold.com>","Alex Kit <alex.kit@atmajs.com>","Santiago Gimeno <santiago.gimeno@gmail.com>","Daniel <darc.tec@gmail.com>","Christian Steininger <christian.steininger.cs@gmail.com>","Mykola Piskovyi <m.piskovyi@gmail.com>","Brian Vaughn <brian.david.vaughn@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Yasuhiroki <yasuhiroki.duck@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Brendan Warkentin <faazshift@gmail.com>","Charlie Fish <fishcharlie.code@gmail.com>","Ian Graves <ian+diskimage@iangrav.es>","Andy Thompson <me@andytson.com>","Regev Brody <regevbr@gmail.com>"],"license":"MIT","dependencies":{"luxon":"^1.28.0"},"devDependencies":{"eslint":"^8.2.0","sinon":"^10.0.0","tap":"^16.0.1","tsd":"^0.19.0"},"engines":{"node":">=0.8"},"browser":{"fs":false},"tap":{"check-coverage":false},"tsd":{"directory":"test","compilerOptions":{"lib":["es2017","dom"]}},"_lastModified":"2024-
|
|
1
|
+
{"name":"cron-parser","version":"4.4.0","description":"Node.js library for parsing crontab instructions","main":"lib/parser.js","types":"index.d.ts","typesVersions":{"<4.1":{"*":["types/ts3/*"]}},"directories":{"test":"test"},"scripts":{"test:tsd":"tsd","test:unit":"TZ=UTC tap ./test/*.js","test:cover":"TZ=UTC tap --coverage-report=html ./test/*.js","lint":"eslint .","lint:fix":"eslint --fix .","test":"npm run lint && npm run test:unit && npm run test:tsd"},"repository":{"type":"git","url":"https://github.com/harrisiirak/cron-parser.git"},"keywords":["cron","crontab","parser"],"author":"Harri Siirak","contributors":["Nicholas Clawson","Daniel Prentis <daniel@salsitasoft.com>","Renault John Lecoultre","Richard Astbury <richard.astbury@gmail.com>","Meaglin Wasabi <Meaglin.wasabi@gmail.com>","Mike Kusold <hello@mikekusold.com>","Alex Kit <alex.kit@atmajs.com>","Santiago Gimeno <santiago.gimeno@gmail.com>","Daniel <darc.tec@gmail.com>","Christian Steininger <christian.steininger.cs@gmail.com>","Mykola Piskovyi <m.piskovyi@gmail.com>","Brian Vaughn <brian.david.vaughn@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Yasuhiroki <yasuhiroki.duck@gmail.com>","Nicholas Clawson <nickclaw@gmail.com>","Brendan Warkentin <faazshift@gmail.com>","Charlie Fish <fishcharlie.code@gmail.com>","Ian Graves <ian+diskimage@iangrav.es>","Andy Thompson <me@andytson.com>","Regev Brody <regevbr@gmail.com>"],"license":"MIT","dependencies":{"luxon":"^1.28.0"},"devDependencies":{"eslint":"^8.2.0","sinon":"^10.0.0","tap":"^16.0.1","tsd":"^0.19.0"},"engines":{"node":">=0.8"},"browser":{"fs":false},"tap":{"check-coverage":false},"tsd":{"directory":"test","compilerOptions":{"lib":["es2017","dom"]}},"_lastModified":"2024-02-07T12:21:29.401Z"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"lru-cache","description":"A cache object that deletes the least-recently-used items.","version":"8.0.5","author":"Isaac Z. Schlueter <i@izs.me>","keywords":["mru","lru","cache"],"sideEffects":false,"scripts":{"build":"npm run prepare","preprepare":"rm -rf dist","prepare":"tsc -p tsconfig.json && tsc -p tsconfig-esm.json","postprepare":"bash fixup.sh","pretest":"npm run prepare","presnap":"npm run prepare","test":"c8 tap","snap":"c8 tap","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write .","typedoc":"typedoc --tsconfig tsconfig-esm.json ./src/*.ts","benchmark-results-typedoc":"bash scripts/benchmark-results-typedoc.sh","prebenchmark":"npm run prepare","benchmark":"make -C benchmark","preprofile":"npm run prepare","profile":"make -C benchmark profile"},"main":"./dist/cjs/index-cjs.js","module":"./dist/mjs/index.js","types":"./dist/mjs/index.d.ts","exports":{"./min":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.min.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.min.js"}},".":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index-cjs.js"}}},"repository":"git://github.com/isaacs/node-lru-cache.git","devDependencies":{"@size-limit/preset-small-lib":"^7.0.8","@types/node":"^17.0.31","@types/tap":"^15.0.6","benchmark":"^2.1.4","c8":"^7.11.2","clock-mock":"^1.0.6","esbuild":"^0.17.11","eslint-config-prettier":"^8.5.0","marked":"^4.2.12","mkdirp":"^2.1.5","prettier":"^2.6.2","size-limit":"^7.0.8","tap":"^16.3.4","ts-node":"^10.7.0","tslib":"^2.4.0","typedoc":"^0.23.24","typescript":"^4.6.4"},"license":"ISC","files":["dist"],"engines":{"node":">=16.14"},"prettier":{"semi":false,"printWidth":70,"tabWidth":2,"useTabs":false,"singleQuote":true,"jsxSingleQuote":false,"bracketSameLine":true,"arrowParens":"avoid","endOfLine":"lf"},"tap":{"coverage":false,"node-arg":["--expose-gc","--no-warnings","--loader","ts-node/esm"],"ts":false},"size-limit":[{"path":"./dist/mjs/index.js"}],"_lastModified":"2024-
|
|
1
|
+
{"name":"lru-cache","description":"A cache object that deletes the least-recently-used items.","version":"8.0.5","author":"Isaac Z. Schlueter <i@izs.me>","keywords":["mru","lru","cache"],"sideEffects":false,"scripts":{"build":"npm run prepare","preprepare":"rm -rf dist","prepare":"tsc -p tsconfig.json && tsc -p tsconfig-esm.json","postprepare":"bash fixup.sh","pretest":"npm run prepare","presnap":"npm run prepare","test":"c8 tap","snap":"c8 tap","preversion":"npm test","postversion":"npm publish","prepublishOnly":"git push origin --follow-tags","format":"prettier --write .","typedoc":"typedoc --tsconfig tsconfig-esm.json ./src/*.ts","benchmark-results-typedoc":"bash scripts/benchmark-results-typedoc.sh","prebenchmark":"npm run prepare","benchmark":"make -C benchmark","preprofile":"npm run prepare","profile":"make -C benchmark profile"},"main":"./dist/cjs/index-cjs.js","module":"./dist/mjs/index.js","types":"./dist/mjs/index.d.ts","exports":{"./min":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.min.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index.min.js"}},".":{"import":{"types":"./dist/mjs/index.d.ts","default":"./dist/mjs/index.js"},"require":{"types":"./dist/cjs/index.d.ts","default":"./dist/cjs/index-cjs.js"}}},"repository":"git://github.com/isaacs/node-lru-cache.git","devDependencies":{"@size-limit/preset-small-lib":"^7.0.8","@types/node":"^17.0.31","@types/tap":"^15.0.6","benchmark":"^2.1.4","c8":"^7.11.2","clock-mock":"^1.0.6","esbuild":"^0.17.11","eslint-config-prettier":"^8.5.0","marked":"^4.2.12","mkdirp":"^2.1.5","prettier":"^2.6.2","size-limit":"^7.0.8","tap":"^16.3.4","ts-node":"^10.7.0","tslib":"^2.4.0","typedoc":"^0.23.24","typescript":"^4.6.4"},"license":"ISC","files":["dist"],"engines":{"node":">=16.14"},"prettier":{"semi":false,"printWidth":70,"tabWidth":2,"useTabs":false,"singleQuote":true,"jsxSingleQuote":false,"bracketSameLine":true,"arrowParens":"avoid","endOfLine":"lf"},"tap":{"coverage":false,"node-arg":["--expose-gc","--no-warnings","--loader","ts-node/esm"],"ts":false},"size-limit":[{"path":"./dist/mjs/index.js"}],"_lastModified":"2024-02-07T12:21:29.047Z"}
|
package/dist/server/Plugin.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
33
33
|
load(): Promise<void>;
|
|
34
34
|
toggle(workflow: WorkflowModel, enable?: boolean): void;
|
|
35
35
|
trigger(workflow: WorkflowModel, context: object, options?: {
|
|
36
|
-
|
|
36
|
+
[key: string]: any;
|
|
37
37
|
} & Transactionable): void | Promise<Processor | null>;
|
|
38
38
|
private triggerSync;
|
|
39
39
|
resume(job: any): Promise<void>;
|
package/dist/server/Plugin.js
CHANGED
|
@@ -182,6 +182,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
182
182
|
"workflows.nodes:*",
|
|
183
183
|
"executions:list",
|
|
184
184
|
"executions:get",
|
|
185
|
+
"executions:cancel",
|
|
185
186
|
"flow_nodes:update",
|
|
186
187
|
"flow_nodes:destroy"
|
|
187
188
|
]
|
|
@@ -217,8 +218,8 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
217
218
|
this.dispatch();
|
|
218
219
|
});
|
|
219
220
|
this.app.on("beforeStop", async () => {
|
|
220
|
-
const
|
|
221
|
-
const workflows = await
|
|
221
|
+
const repository = db.getRepository("workflows");
|
|
222
|
+
const workflows = await repository.find({
|
|
222
223
|
filter: { enabled: true }
|
|
223
224
|
});
|
|
224
225
|
workflows.forEach((workflow) => {
|
|
@@ -240,7 +241,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
240
241
|
this.getLogger(workflow.id).error(`trigger type ${workflow.type} of workflow ${workflow.id} is not implemented`);
|
|
241
242
|
return;
|
|
242
243
|
}
|
|
243
|
-
if (
|
|
244
|
+
if (enable ?? workflow.get("enabled")) {
|
|
244
245
|
const prev = workflow.previous();
|
|
245
246
|
if (prev.config) {
|
|
246
247
|
trigger.off({ ...workflow.get(), ...prev });
|
|
@@ -264,7 +265,8 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
264
265
|
if (this.isWorkflowSync(workflow)) {
|
|
265
266
|
return this.triggerSync(workflow, context, options);
|
|
266
267
|
}
|
|
267
|
-
|
|
268
|
+
const { transaction, ...rest } = options;
|
|
269
|
+
this.events.push([workflow, context, rest]);
|
|
268
270
|
this.eventsCount = this.events.length;
|
|
269
271
|
logger.info(`new event triggered, now events: ${this.events.length}`);
|
|
270
272
|
logger.debug(`event data:`, {
|
|
@@ -304,22 +306,15 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
304
306
|
return new import_Processor.default(execution, { ...options, plugin: this });
|
|
305
307
|
}
|
|
306
308
|
async createExecution(workflow, context, options) {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
transaction: options.transaction
|
|
314
|
-
});
|
|
315
|
-
if (existed) {
|
|
316
|
-
this.getLogger(workflow.id).warn(
|
|
317
|
-
`workflow ${workflow.id} has already been triggered in same execution (${options.context.executionId}), and newly triggering will be skipped.`
|
|
318
|
-
);
|
|
319
|
-
return null;
|
|
309
|
+
const { transaction = await this.db.sequelize.transaction() } = options;
|
|
310
|
+
const trigger = this.triggers.get(workflow.type);
|
|
311
|
+
const valid = await trigger.validateEvent(workflow, context, { ...options, transaction });
|
|
312
|
+
if (!valid) {
|
|
313
|
+
if (!options.transaction) {
|
|
314
|
+
await transaction.commit();
|
|
320
315
|
}
|
|
316
|
+
return null;
|
|
321
317
|
}
|
|
322
|
-
const { transaction = await this.db.sequelize.transaction() } = options;
|
|
323
318
|
const execution = await workflow.createExecution(
|
|
324
319
|
{
|
|
325
320
|
context,
|
|
@@ -351,6 +346,9 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
351
346
|
return execution;
|
|
352
347
|
}
|
|
353
348
|
prepare = async () => {
|
|
349
|
+
if (this.executing && this.db.options.dialect === "sqlite") {
|
|
350
|
+
await this.executing;
|
|
351
|
+
}
|
|
354
352
|
const event = this.events.shift();
|
|
355
353
|
this.eventsCount = this.events.length;
|
|
356
354
|
if (!event) {
|
|
@@ -361,7 +359,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
361
359
|
logger.info(`preparing execution for event`);
|
|
362
360
|
try {
|
|
363
361
|
const execution = await this.createExecution(...event);
|
|
364
|
-
if (!this.executing && !this.pending.length) {
|
|
362
|
+
if (execution && !this.executing && !this.pending.length) {
|
|
365
363
|
this.pending.push([execution]);
|
|
366
364
|
}
|
|
367
365
|
} catch (err) {
|
|
@@ -382,6 +380,9 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
382
380
|
this.getLogger("dispatcher").warn(`workflow executing is not finished, new dispatching will be ignored`);
|
|
383
381
|
return;
|
|
384
382
|
}
|
|
383
|
+
if (this.events.length) {
|
|
384
|
+
return this.prepare();
|
|
385
|
+
}
|
|
385
386
|
this.executing = (async () => {
|
|
386
387
|
let next = null;
|
|
387
388
|
if (this.pending.length) {
|
|
@@ -413,12 +414,12 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
413
414
|
}
|
|
414
415
|
})();
|
|
415
416
|
}
|
|
416
|
-
async process(execution, job,
|
|
417
|
+
async process(execution, job, options = {}) {
|
|
417
418
|
var _a, _b;
|
|
418
419
|
if (execution.status === import_constants.EXECUTION_STATUS.QUEUEING) {
|
|
419
|
-
await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction });
|
|
420
|
+
await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction: options.transaction });
|
|
420
421
|
}
|
|
421
|
-
const processor = this.createProcessor(execution,
|
|
422
|
+
const processor = this.createProcessor(execution, options);
|
|
422
423
|
this.getLogger(execution.workflowId).info(`execution (${execution.id}) ${job ? "resuming" : "starting"}...`);
|
|
423
424
|
try {
|
|
424
425
|
await (job ? processor.resume(job) : processor.start());
|
|
@@ -4,6 +4,7 @@ import type Plugin from './Plugin';
|
|
|
4
4
|
import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
|
|
5
5
|
export interface ProcessorOptions extends Transactionable {
|
|
6
6
|
plugin: Plugin;
|
|
7
|
+
[key: string]: any;
|
|
7
8
|
}
|
|
8
9
|
export default class Processor {
|
|
9
10
|
execution: ExecutionModel;
|
|
@@ -96,7 +96,9 @@ async function revision(context, next) {
|
|
|
96
96
|
const revisionData = filter.key ? {
|
|
97
97
|
key: filter.key,
|
|
98
98
|
title: origin.title,
|
|
99
|
-
|
|
99
|
+
triggerTitle: origin.triggerTitle,
|
|
100
|
+
allExecuted: origin.allExecuted,
|
|
101
|
+
sync: origin.sync
|
|
100
102
|
} : values;
|
|
101
103
|
const instance = await repository.create({
|
|
102
104
|
values: {
|
|
@@ -32,7 +32,7 @@ class CreateInstruction extends import__.Instruction {
|
|
|
32
32
|
const created = await repository.create({
|
|
33
33
|
...options,
|
|
34
34
|
context: {
|
|
35
|
-
|
|
35
|
+
stack: Array.from(new Set((processor.execution.context.stack ?? []).concat(processor.execution.id)))
|
|
36
36
|
},
|
|
37
37
|
transaction: processor.transaction
|
|
38
38
|
});
|
|
@@ -31,7 +31,7 @@ class DestroyInstruction extends import__.Instruction {
|
|
|
31
31
|
const result = await repo.destroy({
|
|
32
32
|
...options,
|
|
33
33
|
context: {
|
|
34
|
-
|
|
34
|
+
stack: Array.from(new Set((processor.execution.context.stack ?? []).concat(processor.execution.id)))
|
|
35
35
|
},
|
|
36
36
|
transaction: processor.transaction
|
|
37
37
|
});
|
|
@@ -2,7 +2,5 @@ import Instruction from '.';
|
|
|
2
2
|
import Processor from '../Processor';
|
|
3
3
|
import { FlowNodeModel } from '../types';
|
|
4
4
|
export default class extends Instruction {
|
|
5
|
-
run(node: FlowNodeModel, prevJob: any, processor: Processor): Promise<
|
|
6
|
-
status: number;
|
|
7
|
-
}>;
|
|
5
|
+
run(node: FlowNodeModel, prevJob: any, processor: Processor): Promise<any>;
|
|
8
6
|
}
|
|
@@ -34,9 +34,13 @@ var import__ = __toESM(require("."));
|
|
|
34
34
|
var import_constants = require("../constants");
|
|
35
35
|
class EndInstruction_default extends import__.default {
|
|
36
36
|
async run(node, prevJob, processor) {
|
|
37
|
-
const { endStatus } = node.config;
|
|
38
|
-
|
|
39
|
-
status: endStatus
|
|
40
|
-
|
|
37
|
+
const { endStatus = import_constants.JOB_STATUS.RESOLVED } = node.config;
|
|
38
|
+
await processor.saveJob({
|
|
39
|
+
status: endStatus,
|
|
40
|
+
nodeId: node.id,
|
|
41
|
+
nodeKey: node.key,
|
|
42
|
+
upstreamId: (prevJob == null ? void 0 : prevJob.id) ?? null
|
|
43
|
+
});
|
|
44
|
+
return processor.exit(endStatus);
|
|
41
45
|
}
|
|
42
46
|
}
|
|
@@ -31,7 +31,7 @@ class UpdateInstruction extends import__.Instruction {
|
|
|
31
31
|
const result = await repo.update({
|
|
32
32
|
...options,
|
|
33
33
|
context: {
|
|
34
|
-
|
|
34
|
+
stack: Array.from(new Set((processor.execution.context.stack ?? []).concat(processor.execution.id)))
|
|
35
35
|
},
|
|
36
36
|
transaction: processor.transaction
|
|
37
37
|
});
|
|
@@ -26,7 +26,6 @@ class add_node_key_to_job_default extends import_server.Migration {
|
|
|
26
26
|
on = "afterSync";
|
|
27
27
|
async up() {
|
|
28
28
|
const { db } = this.context;
|
|
29
|
-
const PluginModel = db.getModel("applicationPlugins");
|
|
30
29
|
const JobRepo = db.getRepository("jobs");
|
|
31
30
|
await db.sequelize.transaction(async (transaction) => {
|
|
32
31
|
const jobs = await JobRepo.find({
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Transactionable } from '@nocobase/database';
|
|
1
2
|
import Trigger from '.';
|
|
2
3
|
import type { WorkflowModel } from '../types';
|
|
3
4
|
export interface CollectionChangeTriggerConfig {
|
|
@@ -9,4 +10,5 @@ export default class CollectionTrigger extends Trigger {
|
|
|
9
10
|
events: Map<any, any>;
|
|
10
11
|
on(workflow: WorkflowModel): void;
|
|
11
12
|
off(workflow: WorkflowModel): void;
|
|
13
|
+
validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): Promise<boolean>;
|
|
12
14
|
}
|
|
@@ -89,20 +89,13 @@ async function handler(workflow, data, options) {
|
|
|
89
89
|
if (workflow.sync) {
|
|
90
90
|
await this.workflow.trigger(
|
|
91
91
|
workflow,
|
|
92
|
-
{ data: json },
|
|
92
|
+
{ data: json, stack: context == null ? void 0 : context.stack },
|
|
93
93
|
{
|
|
94
|
-
context,
|
|
95
94
|
transaction
|
|
96
95
|
}
|
|
97
96
|
);
|
|
98
97
|
} else {
|
|
99
|
-
this.workflow.trigger(
|
|
100
|
-
workflow,
|
|
101
|
-
{ data: json },
|
|
102
|
-
{
|
|
103
|
-
context
|
|
104
|
-
}
|
|
105
|
-
);
|
|
98
|
+
this.workflow.trigger(workflow, { data: json, stack: context == null ? void 0 : context.stack });
|
|
106
99
|
}
|
|
107
100
|
}
|
|
108
101
|
class CollectionTrigger extends import__.default {
|
|
@@ -151,4 +144,21 @@ class CollectionTrigger extends import__.default {
|
|
|
151
144
|
}
|
|
152
145
|
}
|
|
153
146
|
}
|
|
147
|
+
async validateEvent(workflow, context, options) {
|
|
148
|
+
if (context.stack) {
|
|
149
|
+
const existed = await workflow.countExecutions({
|
|
150
|
+
where: {
|
|
151
|
+
id: context.stack
|
|
152
|
+
},
|
|
153
|
+
transaction: options.transaction
|
|
154
|
+
});
|
|
155
|
+
if (existed) {
|
|
156
|
+
this.workflow.getLogger(workflow.id).warn(
|
|
157
|
+
`workflow ${workflow.id} has already been triggered in stack executions (${context.stack}), and newly triggering will be skipped.`
|
|
158
|
+
);
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
154
164
|
}
|
|
@@ -6,6 +6,7 @@ export declare abstract class Trigger {
|
|
|
6
6
|
constructor(workflow: Plugin);
|
|
7
7
|
abstract on(workflow: WorkflowModel): void;
|
|
8
8
|
abstract off(workflow: WorkflowModel): void;
|
|
9
|
+
validateEvent(workflow: WorkflowModel, context: any, options: Transactionable): boolean | Promise<boolean>;
|
|
9
10
|
duplicateConfig?(workflow: WorkflowModel, options: Transactionable): object | Promise<object>;
|
|
10
11
|
sync?: boolean;
|
|
11
12
|
}
|
package/package.json
CHANGED
|
@@ -4,11 +4,13 @@
|
|
|
4
4
|
"displayName.zh-CN": "工作流",
|
|
5
5
|
"description": "A powerful workflow plugin designed to support business process management and automation.",
|
|
6
6
|
"description.zh-CN": "工作流插件,为业务流程管理和自动化提供支持。",
|
|
7
|
-
"version": "0.19.0-alpha.
|
|
7
|
+
"version": "0.19.0-alpha.6",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
|
+
"homepage": "https://docs.nocobase.com/plugins/workflow",
|
|
11
|
+
"homepage.zh-CN": "https://docs-cn.nocobase.com/plugins/workflow",
|
|
10
12
|
"dependencies": {
|
|
11
|
-
"@nocobase/plugin-workflow-test": "0.19.0-alpha.
|
|
13
|
+
"@nocobase/plugin-workflow-test": "0.19.0-alpha.6"
|
|
12
14
|
},
|
|
13
15
|
"devDependencies": {
|
|
14
16
|
"@ant-design/icons": "5.x",
|
|
@@ -43,5 +45,8 @@
|
|
|
43
45
|
"@nocobase/test": "0.x",
|
|
44
46
|
"@nocobase/utils": "0.x"
|
|
45
47
|
},
|
|
46
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "2eb524db98c7f4136fe1a9a1b1259cd72cf6635f",
|
|
49
|
+
"keywords": [
|
|
50
|
+
"workflow"
|
|
51
|
+
]
|
|
47
52
|
}
|