@nocobase/plugin-workflow 1.5.0-beta.2 → 1.5.0-beta.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/client/5ed8ff0f70ed5911.js +10 -0
  2. package/dist/client/739d458621edf81f.js +10 -0
  3. package/dist/client/92877729dbcede8f.js +10 -0
  4. package/dist/client/components/TriggerCollectionRecordSelect.d.ts +10 -0
  5. package/dist/client/components/index.d.ts +1 -0
  6. package/dist/client/constants.d.ts +1 -0
  7. package/dist/client/e7b9d67c6a964bec.js +10 -0
  8. package/dist/client/index.js +1 -566
  9. package/dist/client/triggers/collection.d.ts +14 -0
  10. package/dist/client/triggers/index.d.ts +3 -3
  11. package/dist/client/triggers/schedule/ScheduleModes.d.ts +167 -0
  12. package/dist/client/triggers/schedule/TriggerScheduleConfig.d.ts +10 -0
  13. package/dist/client/triggers/schedule/index.d.ts +11 -0
  14. package/dist/externalVersion.js +10 -10
  15. package/dist/locale/zh-CN.json +14 -0
  16. package/dist/node_modules/cron-parser/package.json +1 -1
  17. package/dist/node_modules/lru-cache/package.json +1 -1
  18. package/dist/server/Plugin.d.ts +6 -2
  19. package/dist/server/Plugin.js +70 -46
  20. package/dist/server/Processor.d.ts +4 -0
  21. package/dist/server/Processor.js +13 -5
  22. package/dist/server/actions/workflows.d.ts +5 -0
  23. package/dist/server/actions/workflows.js +56 -61
  24. package/dist/server/collections/workflows.js +2 -2
  25. package/dist/server/index.d.ts +1 -1
  26. package/dist/server/index.js +2 -0
  27. package/dist/server/repositories/WorkflowRepository.d.ts +12 -0
  28. package/dist/server/repositories/WorkflowRepository.js +112 -0
  29. package/dist/server/triggers/CollectionTrigger.d.ts +9 -1
  30. package/dist/server/triggers/CollectionTrigger.js +76 -57
  31. package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.d.ts +1 -1
  32. package/dist/server/triggers/ScheduleTrigger/DateFieldScheduleTrigger.js +8 -5
  33. package/dist/server/triggers/ScheduleTrigger/index.d.ts +2 -0
  34. package/dist/server/triggers/ScheduleTrigger/index.js +4 -0
  35. package/dist/server/triggers/index.d.ts +4 -2
  36. package/dist/server/triggers/index.js +4 -0
  37. package/package.json +3 -3
@@ -10,6 +10,7 @@
10
10
  import { SchemaInitializerItemType, useCollectionDataSource } from '@nocobase/client';
11
11
  import { useWorkflowAnyExecuted } from '../hooks';
12
12
  import { Trigger } from '.';
13
+ import { TriggerCollectionRecordSelect } from '../components/TriggerCollectionRecordSelect';
13
14
  declare function useVariables(config: any, options: any): import("../variable").VariableOption[];
14
15
  export default class extends Trigger {
15
16
  title: string;
@@ -117,7 +118,20 @@ export default class extends Trigger {
117
118
  };
118
119
  components: {
119
120
  FieldsSelect: import("react").MemoExoticComponent<import("@formily/reactive-react").ReactFC<Omit<any, "ref">>>;
121
+ TriggerCollectionRecordSelect: typeof TriggerCollectionRecordSelect;
120
122
  };
123
+ triggerFieldset: {
124
+ data: {
125
+ type: string;
126
+ title: string;
127
+ description: string;
128
+ 'x-decorator': string;
129
+ 'x-component': string;
130
+ default: any;
131
+ required: boolean;
132
+ };
133
+ };
134
+ validate(values: any): any;
121
135
  useVariables: typeof useVariables;
122
136
  useInitializers(config: any): SchemaInitializerItemType | null;
123
137
  }
@@ -15,9 +15,9 @@ export declare abstract class Trigger {
15
15
  title: string;
16
16
  description?: string;
17
17
  useVariables?(config: Record<string, any>, options?: UseVariableOptions): VariableOption[];
18
- fieldset: {
19
- [key: string]: ISchema;
20
- };
18
+ fieldset: Record<string, ISchema>;
19
+ triggerFieldset?: Record<string, ISchema>;
20
+ validate(config: Record<string, any>): boolean;
21
21
  view?: ISchema;
22
22
  scope?: {
23
23
  [key: string]: any;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ export declare const ScheduleModes: {
10
+ [x: number]: {
11
+ fieldset: {
12
+ startsOn: {
13
+ type: string;
14
+ title: string;
15
+ 'x-decorator': string;
16
+ 'x-component': string;
17
+ 'x-component-props': {
18
+ showTime: boolean;
19
+ };
20
+ required: boolean;
21
+ 'x-reactions'?: undefined;
22
+ };
23
+ repeat: {
24
+ type: string;
25
+ title: string;
26
+ 'x-decorator': string;
27
+ 'x-component': string;
28
+ 'x-reactions': {
29
+ target: string;
30
+ fulfill: {
31
+ state: {
32
+ visible: string;
33
+ };
34
+ };
35
+ }[];
36
+ };
37
+ endsOn: {
38
+ type: string;
39
+ title: string;
40
+ 'x-decorator': string;
41
+ 'x-component': string;
42
+ 'x-component-props': {
43
+ showTime: boolean;
44
+ };
45
+ };
46
+ limit: {
47
+ type: string;
48
+ title: string;
49
+ 'x-decorator': string;
50
+ 'x-component': string;
51
+ 'x-component-props': {
52
+ placeholder: string;
53
+ min: number;
54
+ };
55
+ };
56
+ collection?: undefined;
57
+ appends?: undefined;
58
+ };
59
+ triggerFieldset: {
60
+ date: {
61
+ type: string;
62
+ title: string;
63
+ 'x-decorator': string;
64
+ 'x-component': string;
65
+ 'x-component-props': {
66
+ showTime: boolean;
67
+ placeholder: string;
68
+ };
69
+ };
70
+ data?: undefined;
71
+ };
72
+ } | {
73
+ fieldset: {
74
+ collection: {
75
+ 'x-component-props': {
76
+ dataSourceFilter(item: any): any;
77
+ };
78
+ 'x-reactions': any[];
79
+ type: string;
80
+ title: string;
81
+ required: boolean;
82
+ 'x-decorator': string;
83
+ 'x-component': string;
84
+ };
85
+ startsOn: {
86
+ type: string;
87
+ title: string;
88
+ 'x-decorator': string;
89
+ 'x-component': string;
90
+ 'x-reactions': {
91
+ target: string;
92
+ fulfill: {
93
+ state: {
94
+ visible: string;
95
+ };
96
+ };
97
+ }[];
98
+ required: boolean;
99
+ 'x-component-props'?: undefined;
100
+ };
101
+ repeat: {
102
+ type: string;
103
+ title: string;
104
+ 'x-decorator': string;
105
+ 'x-component': string;
106
+ 'x-reactions': {
107
+ target: string;
108
+ fulfill: {
109
+ state: {
110
+ visible: string;
111
+ };
112
+ };
113
+ }[];
114
+ };
115
+ endsOn: {
116
+ type: string;
117
+ title: string;
118
+ 'x-decorator': string;
119
+ 'x-component': string;
120
+ 'x-component-props'?: undefined;
121
+ };
122
+ limit: {
123
+ type: string;
124
+ title: string;
125
+ 'x-decorator': string;
126
+ 'x-component': string;
127
+ 'x-component-props': {
128
+ placeholder: string;
129
+ min: number;
130
+ };
131
+ };
132
+ appends: {
133
+ 'x-reactions': {
134
+ dependencies: string[];
135
+ fulfill: {
136
+ state: {
137
+ visible: string;
138
+ };
139
+ };
140
+ }[];
141
+ type: string;
142
+ title: string;
143
+ description: string;
144
+ 'x-decorator': string;
145
+ 'x-component': string;
146
+ 'x-component-props': {
147
+ title: string;
148
+ multiple: boolean;
149
+ useCollection(): any;
150
+ };
151
+ };
152
+ };
153
+ triggerFieldset: {
154
+ data: {
155
+ type: string;
156
+ title: string;
157
+ description: string;
158
+ 'x-decorator': string;
159
+ 'x-component': string;
160
+ default: any;
161
+ required: boolean;
162
+ };
163
+ date?: undefined;
164
+ };
165
+ validate(config: any): any;
166
+ };
167
+ };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import React from 'react';
10
+ export declare function TriggerScheduleConfig(): React.JSX.Element;
@@ -9,6 +9,8 @@
9
9
  /// <reference types="react" />
10
10
  import { SchemaInitializerItemType, useCollectionDataSource } from '@nocobase/client';
11
11
  import { Trigger } from '..';
12
+ import { TriggerScheduleConfig } from './TriggerScheduleConfig';
13
+ import { TriggerCollectionRecordSelect } from '../../components/TriggerCollectionRecordSelect';
12
14
  declare function useVariables(config: any, opts: any): any[];
13
15
  export default class extends Trigger {
14
16
  sync: boolean;
@@ -21,11 +23,20 @@ export default class extends Trigger {
21
23
  'x-component-props': {};
22
24
  };
23
25
  };
26
+ triggerFieldset: {
27
+ proxy: {
28
+ type: string;
29
+ 'x-component': string;
30
+ };
31
+ };
32
+ validate(config: any): any;
24
33
  scope: {
25
34
  useCollectionDataSource: typeof useCollectionDataSource;
26
35
  };
27
36
  components: {
28
37
  ScheduleConfig: () => import("react").JSX.Element;
38
+ TriggerScheduleConfig: typeof TriggerScheduleConfig;
39
+ TriggerCollectionRecordSelect: typeof TriggerCollectionRecordSelect;
29
40
  };
30
41
  useVariables: typeof useVariables;
31
42
  useInitializers(config: any): SchemaInitializerItemType | null;
@@ -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.2",
15
- "@nocobase/utils": "1.5.0-beta.2",
14
+ "@nocobase/client": "1.5.0-beta.21",
15
+ "@nocobase/utils": "1.5.0-beta.21",
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
- "@nocobase/database": "1.5.0-beta.2",
23
- "@nocobase/server": "1.5.0-beta.2",
24
- "@nocobase/logger": "1.5.0-beta.2",
25
- "@nocobase/evaluators": "1.5.0-beta.2",
22
+ "@nocobase/database": "1.5.0-beta.21",
23
+ "@nocobase/server": "1.5.0-beta.21",
24
+ "@nocobase/logger": "1.5.0-beta.21",
25
+ "@nocobase/actions": "1.5.0-beta.21",
26
+ "@nocobase/data-source-manager": "1.5.0-beta.21",
27
+ "@nocobase/evaluators": "1.5.0-beta.21",
26
28
  "@formily/antd-v5": "1.1.9",
27
29
  "@formily/reactive": "2.3.0",
28
- "@nocobase/actions": "1.5.0-beta.2",
29
30
  "dayjs": "1.11.10",
30
- "@nocobase/data-source-manager": "1.5.0-beta.2",
31
31
  "sequelize": "6.35.2",
32
- "@nocobase/plugin-workflow-test": "1.5.0-beta.2",
33
- "@nocobase/test": "1.5.0-beta.2"
32
+ "@nocobase/plugin-workflow-test": "1.5.0-beta.21",
33
+ "@nocobase/test": "1.5.0-beta.21"
34
34
  };
@@ -16,6 +16,15 @@
16
16
  "Duplicate": "复制",
17
17
  "Duplicate to new workflow": "复制为新工作流",
18
18
  "Delete a main version will cause all other revisions to be deleted too.": "删除主版本将导致其他版本一并被删除。",
19
+ "Execute manually": "手动执行",
20
+ "The trigger is not configured correctly, please check the trigger configuration.": "触发器配置不正确,请检查触发器配置。",
21
+ "This type of trigger has not been supported to be executed manually.": "该类型的触发器暂未支持手动执行。",
22
+ "Trigger variables need to be filled for executing.": "执行需要填写触发器变量。",
23
+ "A new version will be created automatically after execution if current version is not executed.": "如果当前版本还未执行过,将在执行后自动创建一个新版本。",
24
+ "This will perform all the actions configured in the workflow. Are you sure you want to continue?": "将按照工作流中配置的所有操作执行,确定继续吗?",
25
+ "Automatically create a new version after execution": "执行后自动创建新版本",
26
+ "Workflow executed, the result status is <1>{{statusText}}</1><2>View the execution</2>": "工作流已执行,结果状态为 <1>{{statusText}}</1><2>查看执行详情</2>",
27
+
19
28
  "Loading": "加载中",
20
29
  "Load failed": "加载失败",
21
30
  "Use transaction": "启用事务",
@@ -64,6 +73,8 @@
64
73
  "Preload associations": "预加载关联数据",
65
74
  "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.":
66
75
  "请选中需要在后续节点中被访问的关系字段。超过两层的对多关联可能会导致性能问题,请谨慎使用。",
76
+ "Choose a record of the collection to trigger.": "选择数据表中的一行记录来触发。",
77
+
67
78
  "Schedule event": "定时任务",
68
79
  "Triggered according to preset time conditions. Suitable for one-time or periodic tasks, such as sending notifications and cleaning data on a schedule.": "按预设的时间条件定时触发。适用于一次性或周期性的任务,如定时发送通知、清理数据等。",
69
80
  "Trigger mode": "触发模式",
@@ -92,6 +103,9 @@
92
103
  "By field": "数据表字段",
93
104
  "By custom date": "自定义时间",
94
105
  "Advanced": "高级模式",
106
+ "Execute on": "执行时间",
107
+ "Current time": "当前时间",
108
+
95
109
  "End": "结束",
96
110
  "Node result": "节点数据",
97
111
  "Variable key of node": "节点变量标识",
@@ -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-12-06T09:00:37.111Z"}
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-03T00:43:40.041Z"}
@@ -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-12-06T09:00:36.725Z"}
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-03T00:43:39.648Z"}
@@ -15,11 +15,13 @@ import { CustomFunction } from './functions';
15
15
  import Trigger from './triggers';
16
16
  import { InstructionInterface } from './instructions';
17
17
  import type { ExecutionModel, WorkflowModel } from './types';
18
+ import { Context } from '@nocobase/actions';
18
19
  type ID = number | string;
19
- type EventOptions = {
20
+ export type EventOptions = {
20
21
  eventKey?: string;
21
22
  context?: any;
22
23
  deferred?: boolean;
24
+ manually?: boolean;
23
25
  [key: string]: any;
24
26
  } & Transactionable;
25
27
  export default class PluginWorkflowServer extends Plugin {
@@ -36,7 +38,7 @@ export default class PluginWorkflowServer extends Plugin {
36
38
  private meter;
37
39
  private checker;
38
40
  private onBeforeSave;
39
- onSync(message: any): Promise<void>;
41
+ handleSyncMessage(message: any): Promise<void>;
40
42
  /**
41
43
  * @experimental
42
44
  */
@@ -55,6 +57,7 @@ export default class PluginWorkflowServer extends Plugin {
55
57
  }): void;
56
58
  private initTriggers;
57
59
  private initInstructions;
60
+ beforeLoad(): Promise<void>;
58
61
  /**
59
62
  * @internal
60
63
  */
@@ -73,6 +76,7 @@ export default class PluginWorkflowServer extends Plugin {
73
76
  private prepare;
74
77
  private dispatch;
75
78
  private process;
79
+ execute(workflow: WorkflowModel, context: Context, options?: EventOptions): Promise<void | Processor>;
76
80
  /**
77
81
  * @experimental
78
82
  * @param {string} dataSourceName
@@ -58,6 +58,7 @@ var import_CreateInstruction = __toESM(require("./instructions/CreateInstruction
58
58
  var import_DestroyInstruction = __toESM(require("./instructions/DestroyInstruction"));
59
59
  var import_QueryInstruction = __toESM(require("./instructions/QueryInstruction"));
60
60
  var import_UpdateInstruction = __toESM(require("./instructions/UpdateInstruction"));
61
+ var import_WorkflowRepository = __toESM(require("./repositories/WorkflowRepository"));
61
62
  class PluginWorkflowServer extends import_server.Plugin {
62
63
  instructions = new import_utils.Registry();
63
64
  triggers = new import_utils.Registry();
@@ -71,23 +72,10 @@ class PluginWorkflowServer extends import_server.Plugin {
71
72
  loggerCache;
72
73
  meter = null;
73
74
  checker = null;
74
- onBeforeSave = async (instance, options) => {
75
+ onBeforeSave = async (instance, { transaction }) => {
75
76
  const Model = instance.constructor;
76
77
  if (instance.enabled) {
77
78
  instance.set("current", true);
78
- } else if (!instance.current) {
79
- const count = await Model.count({
80
- where: {
81
- key: instance.key
82
- },
83
- transaction: options.transaction
84
- });
85
- if (!count) {
86
- instance.set("current", true);
87
- }
88
- }
89
- if (!instance.changed("enabled") || !instance.enabled) {
90
- return;
91
79
  }
92
80
  const previous = await Model.findOne({
93
81
  where: {
@@ -97,39 +85,40 @@ class PluginWorkflowServer extends import_server.Plugin {
97
85
  [import_database.Op.ne]: instance.id
98
86
  }
99
87
  },
100
- transaction: options.transaction
88
+ transaction
101
89
  });
102
- if (previous) {
90
+ if (!previous) {
91
+ instance.set("current", true);
92
+ }
93
+ if (instance.current && previous) {
103
94
  await previous.update(
104
95
  { enabled: false, current: null },
105
96
  {
106
- transaction: options.transaction,
97
+ transaction,
107
98
  hooks: false
108
99
  }
109
100
  );
110
- this.toggle(previous, false);
101
+ this.toggle(previous, false, { transaction });
111
102
  }
112
103
  };
113
- async onSync(message) {
104
+ async handleSyncMessage(message) {
114
105
  if (message.type === "statusChange") {
115
- const workflowId = Number.parseInt(message.workflowId, 10);
116
- const enabled = Number.parseInt(message.enabled, 10);
117
- if (enabled) {
118
- let workflow = this.enabledCache.get(workflowId);
106
+ if (message.enabled) {
107
+ let workflow = this.enabledCache.get(message.workflowId);
119
108
  if (workflow) {
120
109
  await workflow.reload();
121
110
  } else {
122
111
  workflow = await this.db.getRepository("workflows").findOne({
123
- filterByTk: workflowId
112
+ filterByTk: message.workflowId
124
113
  });
125
114
  }
126
115
  if (workflow) {
127
- this.toggle(workflow, true, true);
116
+ this.toggle(workflow, true, { silent: true });
128
117
  }
129
118
  } else {
130
- const workflow = this.enabledCache.get(workflowId);
119
+ const workflow = this.enabledCache.get(message.workflowId);
131
120
  if (workflow) {
132
- this.toggle(workflow, false, true);
121
+ this.toggle(workflow, false, { silent: true });
133
122
  }
134
123
  }
135
124
  }
@@ -200,6 +189,11 @@ class PluginWorkflowServer extends import_server.Plugin {
200
189
  this.registerInstruction(name, instruction);
201
190
  }
202
191
  }
192
+ async beforeLoad() {
193
+ this.db.registerRepositories({
194
+ WorkflowRepository: import_WorkflowRepository.default
195
+ });
196
+ }
203
197
  /**
204
198
  * @internal
205
199
  */
@@ -248,13 +242,19 @@ class PluginWorkflowServer extends import_server.Plugin {
248
242
  }
249
243
  });
250
244
  db.on("workflows.beforeSave", this.onBeforeSave);
251
- db.on("workflows.afterCreate", (model) => {
245
+ db.on("workflows.afterCreate", (model, { transaction }) => {
252
246
  if (model.enabled) {
253
- this.toggle(model);
247
+ this.toggle(model, true, { transaction });
254
248
  }
255
249
  });
256
- db.on("workflows.afterUpdate", (model) => this.toggle(model));
257
- db.on("workflows.beforeDestroy", (model) => this.toggle(model, false));
250
+ db.on(
251
+ "workflows.afterUpdate",
252
+ (model, { transaction }) => this.toggle(model, model.enabled, { transaction })
253
+ );
254
+ db.on(
255
+ "workflows.afterDestroy",
256
+ (model, { transaction }) => this.toggle(model, false, { transaction })
257
+ );
258
258
  this.app.on("afterStart", async () => {
259
259
  this.app.setMaintainingMessage("check for not started executions");
260
260
  this.ready = true;
@@ -263,16 +263,20 @@ class PluginWorkflowServer extends import_server.Plugin {
263
263
  filter: { enabled: true }
264
264
  });
265
265
  workflows.forEach((workflow) => {
266
- this.toggle(workflow);
266
+ this.toggle(workflow, true, { silent: true });
267
267
  });
268
268
  this.checker = setInterval(() => {
269
269
  this.dispatch();
270
270
  }, 3e5);
271
+ this.app.on("workflow:dispatch", () => {
272
+ this.app.logger.info("workflow:dispatch");
273
+ this.dispatch();
274
+ });
271
275
  this.dispatch();
272
276
  });
273
277
  this.app.on("beforeStop", async () => {
274
278
  for (const workflow of this.enabledCache.values()) {
275
- this.toggle(workflow, false);
279
+ this.toggle(workflow, false, { silent: true });
276
280
  }
277
281
  this.ready = false;
278
282
  if (this.events.length) {
@@ -286,7 +290,7 @@ class PluginWorkflowServer extends import_server.Plugin {
286
290
  }
287
291
  });
288
292
  }
289
- toggle(workflow, enable, silent = false) {
293
+ toggle(workflow, enable, { silent, transaction } = {}) {
290
294
  const type = workflow.get("type");
291
295
  const trigger = this.triggers.get(type);
292
296
  if (!trigger) {
@@ -306,11 +310,14 @@ class PluginWorkflowServer extends import_server.Plugin {
306
310
  this.enabledCache.delete(workflow.id);
307
311
  }
308
312
  if (!silent) {
309
- this.sync({
310
- type: "statusChange",
311
- workflowId: `${workflow.id}`,
312
- enabled: `${Number(next)}`
313
- });
313
+ this.sendSyncMessage(
314
+ {
315
+ type: "statusChange",
316
+ workflowId: workflow.id,
317
+ enabled: next
318
+ },
319
+ { transaction }
320
+ );
314
321
  }
315
322
  }
316
323
  trigger(workflow, context, options = {}) {
@@ -320,11 +327,15 @@ class PluginWorkflowServer extends import_server.Plugin {
320
327
  logger.debug(`ignored event data:`, context);
321
328
  return;
322
329
  }
330
+ if (!options.manually && !workflow.enabled) {
331
+ logger.warn(`workflow ${workflow.id} is not enabled, event will be ignored`);
332
+ return;
333
+ }
323
334
  if (context == null) {
324
335
  logger.warn(`workflow ${workflow.id} event data context is null, event will be ignored`);
325
336
  return;
326
337
  }
327
- if (this.isWorkflowSync(workflow)) {
338
+ if (options.manually || this.isWorkflowSync(workflow)) {
328
339
  return this.triggerSync(workflow, context, options);
329
340
  }
330
341
  const { transaction, ...rest } = options;
@@ -377,11 +388,13 @@ class PluginWorkflowServer extends import_server.Plugin {
377
388
  return new import_Processor.default(execution, { ...options, plugin: this });
378
389
  }
379
390
  async createExecution(workflow, context, options) {
380
- const { transaction = await this.db.sequelize.transaction(), deferred } = options;
391
+ const { deferred } = options;
392
+ const transaction = await this.useDataSourceTransaction("main", options.transaction, true);
393
+ const sameTransaction = options.transaction === transaction;
381
394
  const trigger = this.triggers.get(workflow.type);
382
395
  const valid = await trigger.validateEvent(workflow, context, { ...options, transaction });
383
396
  if (!valid) {
384
- if (!options.transaction) {
397
+ if (!sameTransaction) {
385
398
  await transaction.commit();
386
399
  }
387
400
  return null;
@@ -398,7 +411,7 @@ class PluginWorkflowServer extends import_server.Plugin {
398
411
  { transaction }
399
412
  );
400
413
  } catch (err) {
401
- if (!options.transaction) {
414
+ if (!sameTransaction) {
402
415
  await transaction.rollback();
403
416
  }
404
417
  throw err;
@@ -419,7 +432,7 @@ class PluginWorkflowServer extends import_server.Plugin {
419
432
  transaction
420
433
  }
421
434
  );
422
- if (!options.transaction) {
435
+ if (!sameTransaction) {
423
436
  await transaction.commit();
424
437
  }
425
438
  execution.workflow = workflow;
@@ -500,7 +513,8 @@ class PluginWorkflowServer extends import_server.Plugin {
500
513
  async process(execution, job, options = {}) {
501
514
  var _a, _b;
502
515
  if (execution.status === import_constants.EXECUTION_STATUS.QUEUEING) {
503
- await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction: options.transaction });
516
+ const transaction = await this.useDataSourceTransaction("main", options.transaction);
517
+ await execution.update({ status: import_constants.EXECUTION_STATUS.STARTED }, { transaction });
504
518
  }
505
519
  const logger = this.getLogger(execution.workflowId);
506
520
  const processor = this.createProcessor(execution, options);
@@ -509,13 +523,23 @@ class PluginWorkflowServer extends import_server.Plugin {
509
523
  await (job ? processor.resume(job) : processor.start());
510
524
  logger.info(`execution (${execution.id}) finished with status: ${execution.status}`, { execution });
511
525
  if (execution.status && ((_b = (_a = execution.workflow.options) == null ? void 0 : _a.deleteExecutionOnStatus) == null ? void 0 : _b.includes(execution.status))) {
512
- await execution.destroy();
526
+ await execution.destroy({ transaction: processor.mainTransaction });
513
527
  }
514
528
  } catch (err) {
515
529
  logger.error(`execution (${execution.id}) error: ${err.message}`, err);
516
530
  }
517
531
  return processor;
518
532
  }
533
+ async execute(workflow, context, options = {}) {
534
+ const trigger = this.triggers.get(workflow.type);
535
+ if (!trigger) {
536
+ throw new Error(`trigger type "${workflow.type}" of workflow ${workflow.id} is not registered`);
537
+ }
538
+ if (!trigger.execute) {
539
+ throw new Error(`"execute" method of trigger ${workflow.type} is not implemented`);
540
+ }
541
+ return trigger.execute(workflow, context, options);
542
+ }
519
543
  /**
520
544
  * @experimental
521
545
  * @param {string} dataSourceName
@@ -32,6 +32,10 @@ export default class Processor {
32
32
  * @experimental
33
33
  */
34
34
  transaction: Transaction;
35
+ /**
36
+ * @experimental
37
+ */
38
+ mainTransaction: Transaction;
35
39
  /**
36
40
  * @experimental
37
41
  */