@nocobase/plugin-workflow 0.16.0-alpha.4 → 0.16.0-alpha.5

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.
@@ -1,23 +1,23 @@
1
1
  module.exports = {
2
2
  "@ant-design/icons": "5.1.4",
3
- "@nocobase/client": "0.16.0-alpha.4",
3
+ "@nocobase/client": "0.16.0-alpha.5",
4
4
  "antd": "5.8.6",
5
5
  "react": "18.2.0",
6
- "@nocobase/utils": "0.16.0-alpha.4",
6
+ "@nocobase/utils": "0.16.0-alpha.5",
7
7
  "react-router-dom": "6.14.1",
8
8
  "react-i18next": "11.18.6",
9
9
  "winston": "3.9.0",
10
- "@nocobase/database": "0.16.0-alpha.4",
11
- "@nocobase/server": "0.16.0-alpha.4",
12
- "@nocobase/logger": "0.16.0-alpha.4",
13
- "@nocobase/evaluators": "0.16.0-alpha.4",
10
+ "@nocobase/database": "0.16.0-alpha.5",
11
+ "@nocobase/server": "0.16.0-alpha.5",
12
+ "@nocobase/logger": "0.16.0-alpha.5",
13
+ "@nocobase/evaluators": "0.16.0-alpha.5",
14
14
  "@formily/react": "2.2.27",
15
15
  "@formily/core": "2.2.27",
16
16
  "@formily/antd-v5": "1.1.7",
17
17
  "lodash": "4.17.21",
18
- "@nocobase/actions": "0.16.0-alpha.4",
18
+ "@nocobase/actions": "0.16.0-alpha.5",
19
19
  "axios": "0.26.1",
20
20
  "sequelize": "6.32.1",
21
21
  "dayjs": "1.11.9",
22
- "@nocobase/resourcer": "0.16.0-alpha.4"
22
+ "@nocobase/resourcer": "0.16.0-alpha.5"
23
23
  };
@@ -54,7 +54,7 @@ declare const _default: {
54
54
  'Preload associations': string;
55
55
  'Please select the associated fields that need to be accessed in subsequent nodes. With more than two levels of to-many associations may cause performance issue, please use with caution.': string;
56
56
  'Schedule event': string;
57
- 'Scheduled job base on time conditions.': string;
57
+ 'Event will be scheduled and triggered base on time conditions.': string;
58
58
  'Trigger mode': string;
59
59
  'Based on certain date': string;
60
60
  'Based on date field of collection': string;
@@ -76,7 +76,7 @@ var zh_CN_default = {
76
76
  "Preload associations": "\u9884\u52A0\u8F7D\u5173\u8054\u6570\u636E",
77
77
  "Please select the associated fields that need to be accessed in subsequent nodes. With more than two levels of to-many associations may cause performance issue, please use with caution.": "\u8BF7\u9009\u4E2D\u9700\u8981\u5728\u540E\u7EED\u8282\u70B9\u4E2D\u88AB\u8BBF\u95EE\u7684\u5173\u7CFB\u5B57\u6BB5\u3002\u8D85\u8FC7\u4E24\u5C42\u7684\u5BF9\u591A\u5173\u8054\u53EF\u80FD\u4F1A\u5BFC\u81F4\u6027\u80FD\u95EE\u9898\uFF0C\u8BF7\u8C28\u614E\u4F7F\u7528\u3002",
78
78
  "Schedule event": "\u5B9A\u65F6\u4EFB\u52A1",
79
- "Scheduled job base on time conditions.": "\u57FA\u4E8E\u65F6\u95F4\u6761\u4EF6\u7684\u8BA1\u5212\u4EFB\u52A1",
79
+ "Event will be scheduled and triggered base on time conditions.": "\u57FA\u4E8E\u65F6\u95F4\u6761\u4EF6\u8FDB\u884C\u5B9A\u65F6\u89E6\u53D1\u7684\u4E8B\u4EF6\u3002",
80
80
  "Trigger mode": "\u89E6\u53D1\u6A21\u5F0F",
81
81
  "Based on certain date": "\u81EA\u5B9A\u4E49\u65F6\u95F4",
82
82
  "Based on date field of collection": "\u6839\u636E\u6570\u636E\u8868\u65F6\u95F4\u5B57\u6BB5",
@@ -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":"2023-11-24T15:25:40.047Z"}
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":"2023-11-30T04:56:25.322Z"}
@@ -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":"2023-11-24T15:25:39.753Z"}
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":"2023-11-30T04:56:25.033Z"}
@@ -252,13 +252,21 @@ class WorkflowPlugin extends import_server.Plugin {
252
252
  },
253
253
  { transaction }
254
254
  );
255
- await workflow.increment("executed", { transaction });
256
- await workflow.constructor.increment("allExecuted", {
257
- where: {
258
- key: workflow.key
255
+ await workflow.increment(["executed", "allExecuted"], { transaction });
256
+ if (this.db.options.dialect !== "postgres") {
257
+ await workflow.reload({ transaction });
258
+ }
259
+ await workflow.constructor.update(
260
+ {
261
+ allExecuted: workflow.allExecuted
259
262
  },
260
- transaction
261
- });
263
+ {
264
+ where: {
265
+ key: workflow.key
266
+ },
267
+ transaction
268
+ }
269
+ );
262
270
  execution2.workflow = workflow;
263
271
  return execution2;
264
272
  });
@@ -179,7 +179,9 @@ class Processor {
179
179
  const { instructions } = this.options.plugin;
180
180
  const instruction = instructions.get(node.type);
181
181
  if (typeof instruction.resume !== "function") {
182
- return Promise.reject(new Error("`resume` should be implemented"));
182
+ return Promise.reject(
183
+ new Error(`"resume" method should be implemented for [${node.type}] instruction of node (#${node.id})`)
184
+ );
183
185
  }
184
186
  return this.exec(instruction.resume.bind(instruction), node, job);
185
187
  }
@@ -75,26 +75,27 @@ ScheduleModes.set(SCHEDULE_MODE.CONSTANT, {
75
75
  const timestamp = now.getTime();
76
76
  const startTime = parseDateWithoutMs(startsOn);
77
77
  if (!startTime || startTime > timestamp) {
78
- return;
78
+ return 0;
79
79
  }
80
80
  if (repeat) {
81
81
  if (typeof repeat === "number") {
82
82
  if (Math.round(timestamp - startTime) % repeat) {
83
- return;
83
+ return 0;
84
84
  }
85
85
  }
86
86
  if (endsOn) {
87
87
  const endTime = parseDateWithoutMs(endsOn);
88
88
  if (!endTime || endTime < timestamp) {
89
- return;
89
+ return 0;
90
90
  }
91
91
  }
92
92
  } else {
93
93
  if (startTime !== timestamp) {
94
- return;
94
+ return 0;
95
95
  }
96
96
  }
97
- return this.plugin.trigger(workflow, { date: now });
97
+ this.plugin.trigger(workflow, { date: now });
98
+ return 1;
98
99
  }
99
100
  });
100
101
  function getOnTimestampWithOffset(on, now) {
@@ -207,12 +208,12 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
207
208
  if (repeat) {
208
209
  const tsFn = DialectTimestampFnMap[db.options.dialect];
209
210
  if (typeof repeat === "number" && repeat > this.cacheCycle && tsFn) {
210
- conditions.push(
211
- (0, import_database.where)(
212
- (0, import_database.fn)("MOD", (0, import_database.literal)(`${Math.round(timestamp / 1e3)} - ${tsFn(startsOn.field)}`), Math.round(repeat / 1e3)),
213
- { [import_database.Op.lt]: Math.round(this.cacheCycle / 1e3) }
214
- )
211
+ const modExp = (0, import_database.fn)(
212
+ "MOD",
213
+ (0, import_database.literal)(`${Math.round(timestamp / 1e3)} - ${tsFn(startsOn.field)}`),
214
+ Math.round(repeat / 1e3)
215
215
  );
216
+ conditions.push((0, import_database.where)(modExp, { [import_database.Op.lt]: Math.round(this.cacheCycle / 1e3) }));
216
217
  }
217
218
  if (endsOn) {
218
219
  const endTimestamp = getOnTimestampWithOffset(endsOn, now);
@@ -249,7 +250,7 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
249
250
  const timestamp = now.getTime();
250
251
  const startTimestamp = getOnTimestampWithOffset(startsOn, now);
251
252
  if (!startTimestamp) {
252
- return false;
253
+ return 0;
253
254
  }
254
255
  const conditions = [
255
256
  {
@@ -266,21 +267,21 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
266
267
  });
267
268
  const tsFn = DialectTimestampFnMap[this.plugin.app.db.options.dialect];
268
269
  if (typeof repeat === "number" && tsFn) {
269
- conditions.push(
270
- (0, import_database.where)(
271
- (0, import_database.fn)("MOD", (0, import_database.literal)(`${Math.round(timestamp / 1e3)} - ${tsFn(startsOn.field)}`), Math.round(repeat / 1e3)),
272
- { [import_database.Op.eq]: 0 }
273
- )
270
+ const modExp = (0, import_database.fn)(
271
+ "MOD",
272
+ (0, import_database.literal)(`${Math.round(timestamp / 1e3)} - ${tsFn(startsOn.field)}`),
273
+ Math.round(repeat / 1e3)
274
274
  );
275
+ conditions.push((0, import_database.where)(modExp, { [import_database.Op.eq]: 0 }));
275
276
  }
276
277
  if (endsOn) {
277
278
  const endTimestamp = getOnTimestampWithOffset(endsOn, now);
278
279
  if (!endTimestamp) {
279
- return false;
280
+ return 0;
280
281
  }
281
282
  if (typeof endsOn === "string") {
282
283
  if (endTimestamp <= timestamp) {
283
- return false;
284
+ return 0;
284
285
  }
285
286
  } else {
286
287
  conditions.push({
@@ -299,10 +300,13 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
299
300
  }
300
301
  const repo = this.plugin.app.db.getRepository(collection);
301
302
  const instances = await repo.find({
302
- filter: {
303
- $and: conditions
303
+ where: {
304
+ [import_database.Op.and]: conditions
304
305
  },
305
- appends
306
+ appends,
307
+ ...workflow.config.limit ? {
308
+ limit: Math.max(workflow.config.limit - workflow.allExecuted, 0)
309
+ } : {}
306
310
  });
307
311
  instances.forEach((item) => {
308
312
  this.plugin.trigger(workflow, {
@@ -310,6 +314,7 @@ ScheduleModes.set(SCHEDULE_MODE.COLLECTION_FIELD, {
310
314
  data: item.toJSON()
311
315
  });
312
316
  });
317
+ return instances.length;
313
318
  }
314
319
  });
315
320
  function matchNext(workflow, now, range = this.cacheCycle) {
@@ -362,7 +367,8 @@ class ScheduleTrigger extends import__.Trigger {
362
367
  });
363
368
  }
364
369
  init() {
365
- if (this.plugin.app.getPlugin("multi-app-share-collection").enabled && this.plugin.app.name !== "main") {
370
+ var _a;
371
+ if (((_a = this.plugin.app.getPlugin("multi-app-share-collection")) == null ? void 0 : _a.enabled) && this.plugin.app.name !== "main") {
366
372
  return;
367
373
  }
368
374
  if (this.timer) {
@@ -405,19 +411,9 @@ class ScheduleTrigger extends import__.Trigger {
405
411
  );
406
412
  }
407
413
  async reload() {
408
- const WorkflowModel = this.plugin.app.db.getCollection("workflows").model;
409
- const workflows = await WorkflowModel.findAll({
410
- where: { enabled: true, type: "schedule" },
411
- include: [
412
- {
413
- association: "executions",
414
- attributes: ["id", "createdAt"],
415
- separate: true,
416
- limit: 1,
417
- order: [["createdAt", "DESC"]]
418
- }
419
- ],
420
- group: ["id"]
414
+ const WorkflowRepo = this.plugin.app.db.getRepository("workflows");
415
+ const workflows = await WorkflowRepo.find({
416
+ filter: { enabled: true, type: "schedule" }
421
417
  });
422
418
  this.cache = /* @__PURE__ */ new Map();
423
419
  this.inspect(workflows);
package/package.json CHANGED
@@ -4,7 +4,7 @@
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.16.0-alpha.4",
7
+ "version": "0.16.0-alpha.5",
8
8
  "license": "AGPL-3.0",
9
9
  "main": "./dist/server/index.js",
10
10
  "devDependencies": {
@@ -41,5 +41,5 @@
41
41
  "@nocobase/test": "0.x",
42
42
  "@nocobase/utils": "0.x"
43
43
  },
44
- "gitHead": "98d65186a22281e59209d11a6756712a62667c07"
44
+ "gitHead": "3badd2569e4658023897fa381ac4dd30e64d5bce"
45
45
  }