@nocobase/plugin-workflow 1.5.0-beta.27 → 1.5.0-beta.28
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/externalVersion.js +11 -11
- package/dist/locale/zh-CN.json +5 -5
- 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 +4 -4
- package/dist/server/Plugin.js +67 -34
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +1 -1
- package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +17 -12
- package/package.json +3 -3
package/dist/externalVersion.js
CHANGED
|
@@ -11,24 +11,24 @@ module.exports = {
|
|
|
11
11
|
"react": "18.2.0",
|
|
12
12
|
"@formily/core": "2.3.0",
|
|
13
13
|
"@formily/react": "2.3.0",
|
|
14
|
-
"@nocobase/client": "1.5.0-beta.
|
|
15
|
-
"@nocobase/utils": "1.5.0-beta.
|
|
14
|
+
"@nocobase/client": "1.5.0-beta.28",
|
|
15
|
+
"@nocobase/utils": "1.5.0-beta.28",
|
|
16
16
|
"antd": "5.12.8",
|
|
17
17
|
"@ant-design/icons": "5.2.6",
|
|
18
18
|
"react-router-dom": "6.21.0",
|
|
19
19
|
"react-i18next": "11.18.6",
|
|
20
20
|
"@formily/shared": "2.3.2",
|
|
21
21
|
"lodash": "4.17.21",
|
|
22
|
-
"
|
|
23
|
-
"@nocobase/
|
|
24
|
-
"@nocobase/
|
|
25
|
-
"@nocobase/
|
|
26
|
-
"@nocobase/
|
|
27
|
-
"@nocobase/
|
|
22
|
+
"sequelize": "6.35.2",
|
|
23
|
+
"@nocobase/database": "1.5.0-beta.28",
|
|
24
|
+
"@nocobase/server": "1.5.0-beta.28",
|
|
25
|
+
"@nocobase/logger": "1.5.0-beta.28",
|
|
26
|
+
"@nocobase/actions": "1.5.0-beta.28",
|
|
27
|
+
"@nocobase/data-source-manager": "1.5.0-beta.28",
|
|
28
|
+
"@nocobase/evaluators": "1.5.0-beta.28",
|
|
28
29
|
"@formily/antd-v5": "1.1.9",
|
|
29
30
|
"@formily/reactive": "2.3.0",
|
|
30
31
|
"dayjs": "1.11.10",
|
|
31
|
-
"
|
|
32
|
-
"@nocobase/
|
|
33
|
-
"@nocobase/test": "1.5.0-beta.27"
|
|
32
|
+
"@nocobase/plugin-workflow-test": "1.5.0-beta.28",
|
|
33
|
+
"@nocobase/test": "1.5.0-beta.28"
|
|
34
34
|
};
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -157,19 +157,19 @@
|
|
|
157
157
|
"Node type": "节点类型",
|
|
158
158
|
"Unknown node": "未知节点",
|
|
159
159
|
"Node with unknown type will cause error. Please delete it or check plugin which provide this type.": "未知类型的节点会导致错误,请删除或检查提供该类型的插件。",
|
|
160
|
-
"Calculation": "
|
|
161
|
-
"Calculation engine": "
|
|
160
|
+
"Calculation": "计算",
|
|
161
|
+
"Calculation engine": "计算引擎",
|
|
162
162
|
"Basic": "基础",
|
|
163
|
-
"Calculation expression": "
|
|
163
|
+
"Calculation expression": "计算表达式",
|
|
164
164
|
"Expression syntax error": "表达式语法错误",
|
|
165
165
|
"Syntax references: ": "语法参考:",
|
|
166
|
-
"Calculation result": "
|
|
166
|
+
"Calculation result": "计算结果",
|
|
167
167
|
"True": "真",
|
|
168
168
|
"False": "假",
|
|
169
169
|
"concat": "连接",
|
|
170
170
|
"Condition": "条件判断",
|
|
171
171
|
"Based on boolean result of the calculation to determine whether to \"continue\" or \"exit\" the process, or continue on different branches of \"yes\" and \"no\".":
|
|
172
|
-
"
|
|
172
|
+
"基于计算结果的真假来决定“继续”或“退出”流程,或者在“是”与“否”的分支上分别继续。",
|
|
173
173
|
"Mode": "模式",
|
|
174
174
|
"Continue when \"Yes\"": "“是”则继续",
|
|
175
175
|
"Branch into \"Yes\" and \"No\"": "“是”和“否”分别继续",
|
|
@@ -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":"2025-01-
|
|
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":"2025-01-14T08:42:50.531Z"}
|
|
@@ -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":"2025-01-
|
|
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":"2025-01-14T08:42:50.127Z"}
|
package/dist/server/Plugin.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
import { Transactionable } from '
|
|
9
|
+
import { Transactionable } from 'sequelize';
|
|
10
10
|
import { Plugin } from '@nocobase/server';
|
|
11
11
|
import { Registry } from '@nocobase/utils';
|
|
12
12
|
import { Logger } from '@nocobase/logger';
|
|
@@ -42,7 +42,7 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
42
42
|
/**
|
|
43
43
|
* @experimental
|
|
44
44
|
*/
|
|
45
|
-
getLogger(workflowId
|
|
45
|
+
getLogger(workflowId?: ID): Logger;
|
|
46
46
|
/**
|
|
47
47
|
* @experimental
|
|
48
48
|
* @param {WorkflowModel} workflow
|
|
@@ -70,11 +70,11 @@ export default class PluginWorkflowServer extends Plugin {
|
|
|
70
70
|
* Start a deferred execution
|
|
71
71
|
* @experimental
|
|
72
72
|
*/
|
|
73
|
-
start(execution: ExecutionModel): void
|
|
74
|
-
createProcessor(execution: ExecutionModel, options?: {}): Processor;
|
|
73
|
+
start(execution: ExecutionModel): Promise<void>;
|
|
75
74
|
private createExecution;
|
|
76
75
|
private prepare;
|
|
77
76
|
private dispatch;
|
|
77
|
+
createProcessor(execution: ExecutionModel, options?: {}): Processor;
|
|
78
78
|
private process;
|
|
79
79
|
execute(workflow: WorkflowModel, context: Context, options?: EventOptions): Promise<void | Processor>;
|
|
80
80
|
/**
|
package/dist/server/Plugin.js
CHANGED
|
@@ -41,6 +41,7 @@ __export(Plugin_exports, {
|
|
|
41
41
|
module.exports = __toCommonJS(Plugin_exports);
|
|
42
42
|
var import_path = __toESM(require("path"));
|
|
43
43
|
var import_crypto = require("crypto");
|
|
44
|
+
var import_sequelize = require("sequelize");
|
|
44
45
|
var import_lru_cache = __toESM(require("lru-cache"));
|
|
45
46
|
var import_database = require("@nocobase/database");
|
|
46
47
|
var import_server = require("@nocobase/server");
|
|
@@ -126,7 +127,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
126
127
|
/**
|
|
127
128
|
* @experimental
|
|
128
129
|
*/
|
|
129
|
-
getLogger(workflowId) {
|
|
130
|
+
getLogger(workflowId = "dispatcher") {
|
|
130
131
|
const now = /* @__PURE__ */ new Date();
|
|
131
132
|
const date = `${now.getFullYear()}-${`0${now.getMonth() + 1}`.slice(-2)}-${`0${now.getDate()}`.slice(-2)}`;
|
|
132
133
|
const key = `${date}-${workflowId}}`;
|
|
@@ -256,7 +257,6 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
256
257
|
(model, { transaction }) => this.toggle(model, false, { transaction })
|
|
257
258
|
);
|
|
258
259
|
this.app.on("afterStart", async () => {
|
|
259
|
-
this.app.setMaintainingMessage("check for not started executions");
|
|
260
260
|
this.ready = true;
|
|
261
261
|
const collection = db.getCollection("workflows");
|
|
262
262
|
const workflows = await collection.repository.find({
|
|
@@ -266,12 +266,14 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
266
266
|
this.toggle(workflow, true, { silent: true });
|
|
267
267
|
});
|
|
268
268
|
this.checker = setInterval(() => {
|
|
269
|
+
this.getLogger("dispatcher").info(`(cycling) check for queueing executions`);
|
|
269
270
|
this.dispatch();
|
|
270
271
|
}, 3e5);
|
|
271
272
|
this.app.on("workflow:dispatch", () => {
|
|
272
273
|
this.app.logger.info("workflow:dispatch");
|
|
273
274
|
this.dispatch();
|
|
274
275
|
});
|
|
276
|
+
this.getLogger("dispatcher").info("(starting) check for queueing executions");
|
|
275
277
|
this.dispatch();
|
|
276
278
|
});
|
|
277
279
|
this.app.on("beforeStop", async () => {
|
|
@@ -331,6 +333,15 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
331
333
|
logger.warn(`workflow ${workflow.id} is not enabled, event will be ignored`);
|
|
332
334
|
return;
|
|
333
335
|
}
|
|
336
|
+
const duplicated = this.events.find(([w, c, { eventKey }]) => {
|
|
337
|
+
if (eventKey && options.eventKey) {
|
|
338
|
+
return eventKey === options.eventKey;
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
if (duplicated) {
|
|
342
|
+
logger.warn(`event of workflow ${workflow.id} is duplicated (${options.eventKey}), event will be ignored`);
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
334
345
|
if (context == null) {
|
|
335
346
|
logger.warn(`workflow ${workflow.id} event data context is null, event will be ignored`);
|
|
336
347
|
return;
|
|
@@ -344,6 +355,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
344
355
|
logger.info(`new event triggered, now events: ${this.events.length}`);
|
|
345
356
|
logger.debug(`event data:`, { context });
|
|
346
357
|
if (this.events.length > 1) {
|
|
358
|
+
logger.info(`new event is pending to be prepared after previous preparation is finished`);
|
|
347
359
|
return;
|
|
348
360
|
}
|
|
349
361
|
setTimeout(this.prepare);
|
|
@@ -371,22 +383,25 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
371
383
|
`execution (${job.execution.id}) resuming from job (${job.id}) added to pending list`
|
|
372
384
|
);
|
|
373
385
|
this.pending.push([job.execution, job]);
|
|
386
|
+
if (this.executing) {
|
|
387
|
+
await this.executing;
|
|
388
|
+
}
|
|
374
389
|
this.dispatch();
|
|
375
390
|
}
|
|
376
391
|
/**
|
|
377
392
|
* Start a deferred execution
|
|
378
393
|
* @experimental
|
|
379
394
|
*/
|
|
380
|
-
start(execution) {
|
|
395
|
+
async start(execution) {
|
|
381
396
|
if (execution.status !== import_constants.EXECUTION_STATUS.STARTED) {
|
|
382
397
|
return;
|
|
383
398
|
}
|
|
384
399
|
this.pending.push([execution]);
|
|
400
|
+
if (this.executing) {
|
|
401
|
+
await this.executing;
|
|
402
|
+
}
|
|
385
403
|
this.dispatch();
|
|
386
404
|
}
|
|
387
|
-
createProcessor(execution, options = {}) {
|
|
388
|
-
return new import_Processor.default(execution, { ...options, plugin: this });
|
|
389
|
-
}
|
|
390
405
|
async createExecution(workflow, context, options) {
|
|
391
406
|
const { deferred } = options;
|
|
392
407
|
const transaction = await this.useDataSourceTransaction("main", options.transaction, true);
|
|
@@ -445,7 +460,7 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
445
460
|
const event = this.events.shift();
|
|
446
461
|
this.eventsCount = this.events.length;
|
|
447
462
|
if (!event) {
|
|
448
|
-
this.getLogger("dispatcher").
|
|
463
|
+
this.getLogger("dispatcher").info(`events queue is empty, no need to prepare`);
|
|
449
464
|
return;
|
|
450
465
|
}
|
|
451
466
|
const logger = this.getLogger(event[0].id);
|
|
@@ -478,38 +493,56 @@ class PluginWorkflowServer extends import_server.Plugin {
|
|
|
478
493
|
}
|
|
479
494
|
this.executing = (async () => {
|
|
480
495
|
let next = null;
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
"workflow.enabled": true,
|
|
490
|
-
"workflow.id": {
|
|
491
|
-
[import_database.Op.not]: null
|
|
492
|
-
}
|
|
496
|
+
if (this.pending.length) {
|
|
497
|
+
next = this.pending.shift();
|
|
498
|
+
this.getLogger(next[0].workflowId).info(`pending execution (${next[0].id}) ready to process`);
|
|
499
|
+
} else {
|
|
500
|
+
try {
|
|
501
|
+
await this.db.sequelize.transaction(
|
|
502
|
+
{
|
|
503
|
+
isolationLevel: this.db.options.dialect === "sqlite" ? [][0] : import_sequelize.Transaction.ISOLATION_LEVELS.REPEATABLE_READ
|
|
493
504
|
},
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
505
|
+
async (transaction) => {
|
|
506
|
+
const execution = await this.db.getRepository("executions").findOne({
|
|
507
|
+
filter: {
|
|
508
|
+
status: import_constants.EXECUTION_STATUS.QUEUEING,
|
|
509
|
+
"workflow.enabled": true
|
|
510
|
+
},
|
|
511
|
+
sort: "id",
|
|
512
|
+
transaction
|
|
513
|
+
});
|
|
514
|
+
if (execution) {
|
|
515
|
+
this.getLogger(execution.workflowId).info(`execution (${execution.id}) fetched from db`);
|
|
516
|
+
await execution.update(
|
|
517
|
+
{
|
|
518
|
+
status: import_constants.EXECUTION_STATUS.STARTED
|
|
519
|
+
},
|
|
520
|
+
{ transaction }
|
|
521
|
+
);
|
|
522
|
+
execution.workflow = this.enabledCache.get(execution.workflowId);
|
|
523
|
+
next = [execution];
|
|
524
|
+
} else {
|
|
525
|
+
this.getLogger("dispatcher").info(`no execution in db queued to process`);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
);
|
|
529
|
+
} catch (error) {
|
|
530
|
+
this.getLogger("dispatcher").error(`fetching execution from db failed: ${error.message}`, { error });
|
|
509
531
|
}
|
|
510
532
|
}
|
|
533
|
+
if (next) {
|
|
534
|
+
await this.process(...next);
|
|
535
|
+
}
|
|
536
|
+
this.executing = null;
|
|
537
|
+
if (next) {
|
|
538
|
+
this.getLogger("dispatcher").info(`last process finished, will do another dispatch`);
|
|
539
|
+
this.dispatch();
|
|
540
|
+
}
|
|
511
541
|
})();
|
|
512
542
|
}
|
|
543
|
+
createProcessor(execution, options = {}) {
|
|
544
|
+
return new import_Processor.default(execution, { ...options, plugin: this });
|
|
545
|
+
}
|
|
513
546
|
async process(execution, job, options = {}) {
|
|
514
547
|
var _a, _b;
|
|
515
548
|
if (execution.status === import_constants.EXECUTION_STATUS.QUEUEING) {
|
|
@@ -30,7 +30,7 @@ export default class DateFieldScheduleTrigger {
|
|
|
30
30
|
constructor(workflow: Plugin);
|
|
31
31
|
reload(): Promise<void>;
|
|
32
32
|
inspect(workflows: WorkflowModel[]): void;
|
|
33
|
-
loadRecordsToSchedule({ config: { collection, limit, startsOn, repeat, endsOn }, allExecuted }: WorkflowModel, currentDate: Date): Promise<import("@nocobase/database").Model<any, any>[]>;
|
|
33
|
+
loadRecordsToSchedule({ id, config: { collection, limit, startsOn, repeat, endsOn }, allExecuted }: WorkflowModel, currentDate: Date): Promise<import("@nocobase/database").Model<any, any>[]>;
|
|
34
34
|
getRecordNextTime(workflow: WorkflowModel, record: any, nextSecond?: boolean): any;
|
|
35
35
|
schedule(workflow: WorkflowModel, record: any, nextTime: any, toggle?: boolean, options?: {}): Promise<void>;
|
|
36
36
|
trigger(workflow: WorkflowModel, record: any, nextTime: any, { transaction }?: Transactionable): Promise<void>;
|
|
@@ -131,6 +131,7 @@ class DateFieldScheduleTrigger {
|
|
|
131
131
|
const now = /* @__PURE__ */ new Date();
|
|
132
132
|
workflows.forEach(async (workflow) => {
|
|
133
133
|
const records = await this.loadRecordsToSchedule(workflow, now);
|
|
134
|
+
this.workflow.getLogger(workflow.id).info(`[Schedule on date field] ${records.length} records to schedule`);
|
|
134
135
|
records.forEach((record) => {
|
|
135
136
|
const nextTime = this.getRecordNextTime(workflow, record);
|
|
136
137
|
this.schedule(workflow, record, nextTime, Boolean(nextTime));
|
|
@@ -144,17 +145,20 @@ class DateFieldScheduleTrigger {
|
|
|
144
145
|
// b. repeat in range (number or cron):
|
|
145
146
|
// i. endsOn after now -> yes
|
|
146
147
|
// ii. endsOn before now -> no
|
|
147
|
-
async loadRecordsToSchedule({ config: { collection, limit, startsOn, repeat, endsOn }, allExecuted }, currentDate) {
|
|
148
|
+
async loadRecordsToSchedule({ id, config: { collection, limit, startsOn, repeat, endsOn }, allExecuted }, currentDate) {
|
|
148
149
|
const { dataSourceManager } = this.workflow.app;
|
|
149
150
|
if (limit && allExecuted >= limit) {
|
|
151
|
+
this.workflow.getLogger(id).warn(`[Schedule on date field] limit reached (all executed ${allExecuted})`);
|
|
150
152
|
return [];
|
|
151
153
|
}
|
|
152
154
|
if (!startsOn) {
|
|
155
|
+
this.workflow.getLogger(id).warn(`[Schedule on date field] "startsOn" is not configured`);
|
|
153
156
|
return [];
|
|
154
157
|
}
|
|
155
158
|
const timestamp = currentDate.getTime();
|
|
156
159
|
const startTimestamp = getOnTimestampWithOffset(startsOn, currentDate);
|
|
157
160
|
if (!startTimestamp) {
|
|
161
|
+
this.workflow.getLogger(id).warn(`[Schedule on date field] "startsOn.field" is not configured`);
|
|
158
162
|
return [];
|
|
159
163
|
}
|
|
160
164
|
const [dataSourceName, collectionName] = (0, import_data_source_manager.parseCollectionName)(collection);
|
|
@@ -193,21 +197,21 @@ class DateFieldScheduleTrigger {
|
|
|
193
197
|
}
|
|
194
198
|
}
|
|
195
199
|
if (endsOn) {
|
|
196
|
-
const now = /* @__PURE__ */ new Date();
|
|
197
|
-
const endTimestamp = getOnTimestampWithOffset(endsOn, now);
|
|
198
|
-
if (!endTimestamp) {
|
|
199
|
-
return [];
|
|
200
|
-
}
|
|
201
200
|
if (typeof endsOn === "string") {
|
|
202
|
-
if (
|
|
201
|
+
if ((0, import_utils.parseDateWithoutMs)(endsOn) <= timestamp) {
|
|
203
202
|
return [];
|
|
204
203
|
}
|
|
205
204
|
} else {
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
const endTimestamp = getOnTimestampWithOffset(endsOn, currentDate);
|
|
206
|
+
if (endTimestamp) {
|
|
207
|
+
conditions.push({
|
|
208
|
+
[endsOn.field]: {
|
|
209
|
+
[import_database.Op.gte]: new Date(endTimestamp)
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
this.workflow.getLogger(id).warn(`[Schedule on date field] "endsOn.field" is not configured`);
|
|
214
|
+
}
|
|
211
215
|
}
|
|
212
216
|
}
|
|
213
217
|
} else {
|
|
@@ -217,6 +221,7 @@ class DateFieldScheduleTrigger {
|
|
|
217
221
|
}
|
|
218
222
|
});
|
|
219
223
|
}
|
|
224
|
+
this.workflow.getLogger(id).debug(`[Schedule on date field] conditions: `, { conditions });
|
|
220
225
|
return model.findAll({
|
|
221
226
|
where: {
|
|
222
227
|
[import_database.Op.and]: conditions
|
package/package.json
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
"displayName.zh-CN": "工作流",
|
|
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
|
"description.zh-CN": "一个强大的 BPM 工具,为业务自动化提供基础支持,并且可任意扩展更多的触发器和节点。",
|
|
7
|
-
"version": "1.5.0-beta.
|
|
7
|
+
"version": "1.5.0-beta.28",
|
|
8
8
|
"license": "AGPL-3.0",
|
|
9
9
|
"main": "./dist/server/index.js",
|
|
10
10
|
"homepage": "https://docs.nocobase.com/handbook/workflow",
|
|
11
11
|
"homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/workflow",
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nocobase/plugin-workflow-test": "1.5.0-beta.
|
|
13
|
+
"@nocobase/plugin-workflow-test": "1.5.0-beta.28"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@ant-design/icons": "5.x",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@nocobase/test": "1.x",
|
|
45
45
|
"@nocobase/utils": "1.x"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "51948b3d451eabe1ca31e8f56bce32e84eba57ec",
|
|
48
48
|
"keywords": [
|
|
49
49
|
"Workflow"
|
|
50
50
|
]
|