@nocobase/plugin-workflow 0.17.0-alpha.7 → 0.18.0-alpha.8

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 (48) hide show
  1. package/dist/client/index.d.ts +8 -0
  2. package/dist/client/index.js +30 -30
  3. package/dist/client/nodes/calculation.d.ts +7 -2
  4. package/dist/client/nodes/index.d.ts +10 -5
  5. package/dist/client/triggers/collection.d.ts +0 -1
  6. package/dist/client/triggers/index.d.ts +2 -3
  7. package/dist/client/triggers/schedule/index.d.ts +0 -1
  8. package/dist/client/variable.d.ts +15 -14
  9. package/dist/externalVersion.js +17 -16
  10. package/dist/locale/en-US.json +1 -1
  11. package/dist/locale/es-ES.json +1 -1
  12. package/dist/locale/fr-FR.json +1 -1
  13. package/dist/locale/pt-BR.json +1 -1
  14. package/dist/locale/zh-CN.json +3 -1
  15. package/dist/node_modules/cron-parser/package.json +1 -1
  16. package/dist/node_modules/lru-cache/package.json +1 -1
  17. package/dist/server/Plugin.d.ts +10 -11
  18. package/dist/server/Plugin.js +105 -69
  19. package/dist/server/Processor.d.ts +9 -5
  20. package/dist/server/Processor.js +10 -35
  21. package/dist/server/actions/workflows.js +4 -4
  22. package/dist/server/collections/executions.js +0 -5
  23. package/dist/server/collections/workflows.js +0 -5
  24. package/dist/server/constants.d.ts +17 -22
  25. package/dist/server/constants.js +0 -7
  26. package/dist/server/instructions/CalculationInstruction.d.ts +4 -2
  27. package/dist/server/instructions/CalculationInstruction.js +2 -10
  28. package/dist/server/instructions/ConditionInstruction.d.ts +10 -2
  29. package/dist/server/instructions/ConditionInstruction.js +7 -0
  30. package/dist/server/instructions/CreateInstruction.d.ts +1 -1
  31. package/dist/server/instructions/CreateInstruction.js +4 -4
  32. package/dist/server/instructions/DestroyInstruction.d.ts +1 -1
  33. package/dist/server/instructions/DestroyInstruction.js +2 -2
  34. package/dist/server/instructions/QueryInstruction.d.ts +4 -1
  35. package/dist/server/instructions/QueryInstruction.js +2 -2
  36. package/dist/server/instructions/UpdateInstruction.d.ts +1 -1
  37. package/dist/server/instructions/UpdateInstruction.js +2 -2
  38. package/dist/server/instructions/index.d.ts +9 -6
  39. package/dist/server/instructions/index.js +2 -2
  40. package/dist/server/migrations/20230612021134-manual-collection-block.js +1 -0
  41. package/dist/server/triggers/CollectionTrigger.js +3 -3
  42. package/dist/server/triggers/ScheduleTrigger.d.ts +1 -1
  43. package/dist/server/triggers/ScheduleTrigger.js +14 -14
  44. package/dist/server/triggers/index.d.ts +2 -2
  45. package/dist/server/triggers/index.js +2 -2
  46. package/dist/server/types/Execution.d.ts +0 -2
  47. package/dist/server/types/Workflow.d.ts +0 -1
  48. package/package.json +6 -5
@@ -58,9 +58,14 @@ export default class extends Instruction {
58
58
  title: any;
59
59
  }, { types, fieldNames }: {
60
60
  types: any;
61
- fieldNames?: import("@nocobase/client").FieldNames;
61
+ fieldNames?: {
62
+ readonly label: "label";
63
+ readonly value: "value";
64
+ readonly children: "children";
65
+ };
62
66
  }): {
63
- [x: string]: any;
67
+ value: any;
68
+ label: any;
64
69
  };
65
70
  useInitializers(node: any): SchemaInitializerItemType;
66
71
  }
@@ -1,7 +1,12 @@
1
1
  import { ISchema } from '@formily/react';
2
2
  import React from 'react';
3
3
  import { SchemaInitializerItemType } from '@nocobase/client';
4
- import { VariableOption, VariableOptions } from '../variable';
4
+ import { UseVariableOptions, VariableOption } from '../variable';
5
+ export type NodeAvailableContext = {
6
+ workflow: object;
7
+ upstream: object;
8
+ branchIndex: number;
9
+ };
5
10
  export declare abstract class Instruction {
6
11
  title: string;
7
12
  type: string;
@@ -23,14 +28,14 @@ export declare abstract class Instruction {
23
28
  [key: string]: any;
24
29
  };
25
30
  Component?(props: any): JSX.Element;
26
- useVariables?(node: any, options?: any): VariableOption;
27
- useScopeVariables?(node: any, options?: any): VariableOptions;
31
+ useVariables?(node: any, options?: UseVariableOptions): VariableOption;
32
+ useScopeVariables?(node: any, options?: any): VariableOption[];
28
33
  useInitializers?(node: any): SchemaInitializerItemType | null;
29
- isAvailable?(ctx: object): boolean;
34
+ isAvailable?(ctx: NodeAvailableContext): boolean;
30
35
  }
31
36
  export declare const NodeContext: React.Context<any>;
32
37
  export declare function useNodeContext(): any;
33
- export declare function useAvailableUpstreams(node: any): any[];
38
+ export declare function useAvailableUpstreams(node: any, filter?: any): any[];
34
39
  export declare function useUpstreamScopes(node: any): any[];
35
40
  export declare function Node({ data }: {
36
41
  data: any;
@@ -3,7 +3,6 @@ import { SchemaInitializerItemType, useCollectionDataSource } from '@nocobase/cl
3
3
  import { Trigger } from '.';
4
4
  export default class extends Trigger {
5
5
  title: string;
6
- type: string;
7
6
  description: string;
8
7
  fieldset: {
9
8
  collection: {
@@ -1,12 +1,11 @@
1
1
  import React from 'react';
2
2
  import { ISchema } from '@formily/react';
3
3
  import { SchemaInitializerItemType } from '@nocobase/client';
4
- import { VariableOptions } from '../variable';
4
+ import { UseVariableOptions, VariableOption } from '../variable';
5
5
  export declare abstract class Trigger {
6
6
  title: string;
7
- type: string;
8
7
  description?: string;
9
- useVariables?(config: any, options?: any): VariableOptions;
8
+ useVariables?(config: Record<string, any>, options?: UseVariableOptions): VariableOption[];
10
9
  fieldset: {
11
10
  [key: string]: ISchema;
12
11
  };
@@ -3,7 +3,6 @@ import { SchemaInitializerItemType, useCollectionDataSource } from '@nocobase/cl
3
3
  import { Trigger } from '..';
4
4
  export default class extends Trigger {
5
5
  title: string;
6
- type: string;
7
6
  description: string;
8
7
  fieldset: {
9
8
  config: {
@@ -3,18 +3,18 @@ export type VariableOption = {
3
3
  key?: string;
4
4
  value?: string;
5
5
  label?: string;
6
- children?: VariableOptions;
6
+ children?: VariableOption[] | null;
7
7
  [key: string]: any;
8
8
  };
9
- export type VariableOptions = VariableOption[] | null;
10
- export type VariableDataType = string | {
11
- type: string;
12
- options?: {
9
+ export type VariableDataType = 'boolean' | 'number' | 'string' | 'date' | {
10
+ type: 'reference';
11
+ options: {
12
+ collection: string;
13
+ multiple?: boolean;
13
14
  entity?: boolean;
14
- collection?: string;
15
15
  };
16
- } | ((field: any, appends?: string[]) => boolean);
17
- export type OptionsOfUseVariableOptions = {
16
+ } | ((field: any) => boolean);
17
+ export type UseVariableOptions = {
18
18
  types?: VariableDataType[];
19
19
  fieldNames?: {
20
20
  label?: string;
@@ -23,7 +23,6 @@ export type OptionsOfUseVariableOptions = {
23
23
  };
24
24
  appends?: string[] | null;
25
25
  depth?: number;
26
- current?: any;
27
26
  };
28
27
  export declare const defaultFieldNames: {
29
28
  readonly label: "label";
@@ -33,22 +32,24 @@ export declare const defaultFieldNames: {
33
32
  export declare const nodesOptions: {
34
33
  label: string;
35
34
  value: string;
36
- useOptions(options: OptionsOfUseVariableOptions): VariableOption[];
35
+ useOptions(options: UseVariableOptions): VariableOption[];
37
36
  };
38
37
  export declare const triggerOptions: {
39
38
  label: string;
40
39
  value: string;
41
- useOptions(options: OptionsOfUseVariableOptions): any;
40
+ useOptions(options: UseVariableOptions): any;
42
41
  };
43
42
  export declare const scopeOptions: {
44
43
  label: string;
45
44
  value: string;
46
- useOptions(options: OptionsOfUseVariableOptions): VariableOption[];
45
+ useOptions(options: UseVariableOptions & {
46
+ current: any;
47
+ }): VariableOption[];
47
48
  };
48
49
  export declare const systemOptions: {
49
50
  label: string;
50
51
  value: string;
51
- useOptions({ types, fieldNames }: OptionsOfUseVariableOptions): {
52
+ useOptions({ types, fieldNames }: UseVariableOptions): {
52
53
  [x: string]: string;
53
54
  key: string;
54
55
  }[];
@@ -59,7 +60,7 @@ export declare const BaseTypeSets: {
59
60
  string: Set<string>;
60
61
  date: Set<string>;
61
62
  };
62
- export declare function useWorkflowVariableOptions(options?: OptionsOfUseVariableOptions): {
63
+ export declare function useWorkflowVariableOptions(options?: UseVariableOptions): {
63
64
  [x: number]: any;
64
65
  key: any;
65
66
  disabled: boolean;
@@ -1,21 +1,22 @@
1
1
  module.exports = {
2
2
  "react": "18.2.0",
3
- "antd": "5.8.6",
4
- "@ant-design/icons": "5.1.4",
5
- "@nocobase/client": "0.17.0-alpha.7",
6
- "react-router-dom": "6.14.1",
7
- "@nocobase/utils": "0.17.0-alpha.7",
3
+ "antd": "5.12.2",
4
+ "@ant-design/icons": "5.2.6",
5
+ "@nocobase/client": "0.18.0-alpha.8",
6
+ "react-router-dom": "6.21.0",
7
+ "@nocobase/utils": "0.18.0-alpha.8",
8
8
  "react-i18next": "11.18.6",
9
- "winston": "3.9.0",
10
- "@nocobase/database": "0.17.0-alpha.7",
11
- "@nocobase/server": "0.17.0-alpha.7",
12
- "@nocobase/logger": "0.17.0-alpha.7",
13
- "@nocobase/evaluators": "0.17.0-alpha.7",
14
- "@formily/react": "2.2.27",
15
- "@formily/core": "2.2.27",
9
+ "@nocobase/database": "0.18.0-alpha.8",
10
+ "@nocobase/server": "0.18.0-alpha.8",
11
+ "@nocobase/logger": "0.18.0-alpha.8",
12
+ "@nocobase/evaluators": "0.18.0-alpha.8",
13
+ "@formily/react": "2.3.0",
14
+ "@formily/core": "2.3.0",
16
15
  "lodash": "4.17.21",
17
- "@formily/antd-v5": "1.1.7",
18
- "@nocobase/actions": "0.17.0-alpha.7",
19
- "sequelize": "6.32.1",
20
- "dayjs": "1.11.9"
16
+ "@formily/antd-v5": "1.1.9",
17
+ "@nocobase/actions": "0.18.0-alpha.8",
18
+ "sequelize": "6.35.2",
19
+ "@nocobase/plugin-workflow-test": "0.18.0-alpha.8",
20
+ "@nocobase/test": "0.18.0-alpha.8",
21
+ "dayjs": "1.11.10"
21
22
  };
@@ -58,7 +58,7 @@
58
58
  "Null": "Null",
59
59
  "Boolean": "Boolean",
60
60
  "String": "String",
61
- "Calculator": "Calculator",
61
+ "Operator": "Operator",
62
62
  "Arithmetic calculation": "Arithmetic calculation",
63
63
  "String operation": "String operation",
64
64
  "Executed at": "Executed at",
@@ -58,7 +58,7 @@
58
58
  "Null": "Null",
59
59
  "Boolean": "Booleano",
60
60
  "String": "Cadena",
61
- "Calculator": "Calculadora",
61
+ "Operator": "Calculadora",
62
62
  "Arithmetic calculation": "Cálculo aritmético",
63
63
  "String operation": "Operación de Cadena",
64
64
  "Executed at": "Ejecutado en",
@@ -58,7 +58,7 @@
58
58
  "Null": "Null",
59
59
  "Boolean": "Booléen",
60
60
  "String": "Chaîne de caractères",
61
- "Calculator": "Calculatrice",
61
+ "Operator": "Calculatrice",
62
62
  "Arithmetic calculation": "Calcul arithmétique",
63
63
  "String operation": "Opération sur les chaînes de caractères",
64
64
  "Executed at": "Exécuté à",
@@ -58,7 +58,7 @@
58
58
  "Null": "Nulo",
59
59
  "Boolean": "Booleano",
60
60
  "String": "String",
61
- "Calculator": "Calculadora",
61
+ "Operator": "Calculadora",
62
62
  "Arithmetic calculation": "Cálculo aritmético",
63
63
  "String operation": "Operação de string",
64
64
  "Executed at": "Executado em",
@@ -83,7 +83,9 @@
83
83
  "End": "结束",
84
84
  "Node result": "节点数据",
85
85
  "Variable key of node": "节点变量标识",
86
- "Calculator": "运算",
86
+ "Scope variables": "局域变量",
87
+
88
+ "Operator": "运算符",
87
89
  "Calculate an expression based on a calculation engine and obtain a value as the result. Variables in the upstream nodes can be used in the expression. The expression can be static or dynamic one from an expression collections.":
88
90
  "基于计算引擎对一个表达式进行计算,并获得一个值作为结果。表达式中可以使用上游节点里的变量。表达式可以是静态的,也可以是表达式表中的动态表达式。",
89
91
  "String operation": "字符串",
@@ -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-12-15T03:57:53.374Z"}
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-12-29T08:00:23.052Z"}
@@ -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-12-15T03:57:53.044Z"}
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-12-29T08:00:22.763Z"}
@@ -3,12 +3,12 @@ import { Registry } from '@nocobase/utils';
3
3
  import { Logger } from '@nocobase/logger';
4
4
  import Processor from './Processor';
5
5
  import { CustomFunction } from './functions';
6
- import type Trigger from './triggers';
7
- import type Instruction from './instructions';
6
+ import Trigger from './triggers';
7
+ import { InstructionInterface } from './instructions';
8
8
  import type { ExecutionModel, WorkflowModel } from './types';
9
9
  type ID = number | string;
10
10
  export default class WorkflowPlugin extends Plugin {
11
- instructions: Registry<Instruction>;
11
+ instructions: Registry<InstructionInterface>;
12
12
  triggers: Registry<Trigger>;
13
13
  functions: Registry<CustomFunction>;
14
14
  private ready;
@@ -18,16 +18,14 @@ export default class WorkflowPlugin extends Plugin {
18
18
  private loggerCache;
19
19
  getLogger(workflowId: ID): Logger;
20
20
  onBeforeSave: (instance: WorkflowModel, options: any) => Promise<void>;
21
- initTriggers<T extends Trigger>(more?: {
22
- [key: string]: T | {
23
- new (p: Plugin): T;
24
- };
21
+ registerTrigger<T extends Trigger>(type: string, trigger: T | {
22
+ new (p: Plugin): T;
25
23
  }): void;
26
- initInstructions<T extends Instruction>(more?: {
27
- [key: string]: T | {
28
- new (p: Plugin): T;
29
- };
24
+ registerInstruction(type: string, instruction: InstructionInterface | {
25
+ new (p: Plugin): InstructionInterface;
30
26
  }): void;
27
+ private initTriggers;
28
+ private initInstructions;
31
29
  load(): Promise<void>;
32
30
  toggle(workflow: WorkflowModel, enable?: boolean): void;
33
31
  trigger(workflow: WorkflowModel, context: object, options?: {
@@ -35,6 +33,7 @@ export default class WorkflowPlugin extends Plugin {
35
33
  }): void;
36
34
  resume(job: any): Promise<void>;
37
35
  createProcessor(execution: ExecutionModel, options?: {}): Processor;
36
+ private createExecution;
38
37
  private prepare;
39
38
  private dispatch;
40
39
  private process;
@@ -32,11 +32,9 @@ __export(Plugin_exports, {
32
32
  module.exports = __toCommonJS(Plugin_exports);
33
33
  var import_path = __toESM(require("path"));
34
34
  var import_lru_cache = __toESM(require("lru-cache"));
35
- var import_winston = __toESM(require("winston"));
36
35
  var import_database = require("@nocobase/database");
37
36
  var import_server = require("@nocobase/server");
38
37
  var import_utils = require("@nocobase/utils");
39
- var import_logger = require("@nocobase/logger");
40
38
  var import_Processor = __toESM(require("./Processor"));
41
39
  var import_actions = __toESM(require("./actions"));
42
40
  var import_constants = require("./constants");
@@ -65,14 +63,10 @@ class WorkflowPlugin extends import_server.Plugin {
65
63
  if (this.loggerCache.has(key)) {
66
64
  return this.loggerCache.get(key);
67
65
  }
68
- const logger = (0, import_logger.createLogger)({
69
- transports: [
70
- ...process.env.NODE_ENV !== "production" ? ["console"] : [],
71
- new import_winston.default.transports.File({
72
- filename: (0, import_logger.getLoggerFilePath)("workflows", date, `${workflowId}.log`),
73
- level: (0, import_logger.getLoggerLevel)()
74
- })
75
- ]
66
+ const logger = this.createLogger({
67
+ dirname: import_path.default.join("workflows", date),
68
+ filename: `${workflowId}.log`,
69
+ transports: [...process.env.NODE_ENV !== "production" ? ["console"] : ["file"]]
76
70
  });
77
71
  this.loggerCache.set(key, logger);
78
72
  return logger;
@@ -116,24 +110,40 @@ class WorkflowPlugin extends import_server.Plugin {
116
110
  this.toggle(previous, false);
117
111
  }
118
112
  };
113
+ registerTrigger(type, trigger) {
114
+ if (typeof trigger === "function") {
115
+ this.triggers.register(type, new trigger(this));
116
+ } else if (trigger) {
117
+ this.triggers.register(type, trigger);
118
+ } else {
119
+ throw new Error("invalid trigger type to register");
120
+ }
121
+ }
122
+ registerInstruction(type, instruction) {
123
+ if (typeof instruction === "function") {
124
+ this.instructions.register(type, new instruction(this));
125
+ } else if (instruction) {
126
+ this.instructions.register(type, instruction);
127
+ } else {
128
+ throw new Error("invalid instruction type to register");
129
+ }
130
+ }
119
131
  initTriggers(more = {}) {
120
- const { triggers } = this;
121
- triggers.register("collection", new import_CollectionTrigger.default(this));
122
- triggers.register("schedule", new import_ScheduleTrigger.default(this));
132
+ this.registerTrigger("collection", import_CollectionTrigger.default);
133
+ this.registerTrigger("schedule", import_ScheduleTrigger.default);
123
134
  for (const [name, trigger] of Object.entries(more)) {
124
- triggers.register(name, typeof trigger === "function" ? new trigger(this) : trigger);
135
+ this.registerTrigger(name, trigger);
125
136
  }
126
137
  }
127
138
  initInstructions(more = {}) {
128
- const { instructions } = this;
129
- instructions.register("calculation", new import_CalculationInstruction.default(this));
130
- instructions.register("condition", new import_ConditionInstruction.default(this));
131
- instructions.register("create", new import_CreateInstruction.default(this));
132
- instructions.register("destroy", new import_DestroyInstruction.default(this));
133
- instructions.register("query", new import_QueryInstruction.default(this));
134
- instructions.register("update", new import_UpdateInstruction.default(this));
139
+ this.registerInstruction("calculation", import_CalculationInstruction.default);
140
+ this.registerInstruction("condition", import_ConditionInstruction.default);
141
+ this.registerInstruction("create", import_CreateInstruction.default);
142
+ this.registerInstruction("destroy", import_DestroyInstruction.default);
143
+ this.registerInstruction("query", import_QueryInstruction.default);
144
+ this.registerInstruction("update", import_UpdateInstruction.default);
135
145
  for (const [name, instruction] of Object.entries({ ...more })) {
136
- instructions.register(name, typeof instruction === "function" ? new instruction(this) : instruction);
146
+ this.registerInstruction(name, instruction);
137
147
  }
138
148
  }
139
149
  async load() {
@@ -164,7 +174,6 @@ class WorkflowPlugin extends import_server.Plugin {
164
174
  name: "ui.*",
165
175
  actions: ["workflows:list"]
166
176
  });
167
- this.app.acl.allow("users_jobs", ["list", "get", "submit"], "loggedIn");
168
177
  this.app.acl.allow("workflows", ["trigger"], "loggedIn");
169
178
  await db.import({
170
179
  directory: import_path.default.resolve(__dirname, "collections")
@@ -202,7 +211,9 @@ class WorkflowPlugin extends import_server.Plugin {
202
211
  this.toggle(workflow, false);
203
212
  });
204
213
  this.ready = false;
205
- await this.prepare();
214
+ if (this.events.length) {
215
+ await this.prepare();
216
+ }
206
217
  if (this.executing) {
207
218
  await this.executing;
208
219
  }
@@ -211,6 +222,10 @@ class WorkflowPlugin extends import_server.Plugin {
211
222
  toggle(workflow, enable) {
212
223
  const type = workflow.get("type");
213
224
  const trigger = this.triggers.get(type);
225
+ if (!trigger) {
226
+ this.getLogger(workflow.id).error(`trigger type ${workflow.type} of workflow ${workflow.id} is not implemented`);
227
+ return;
228
+ }
214
229
  if (typeof enable !== "undefined" ? enable : workflow.get("enabled")) {
215
230
  const prev = workflow.previous();
216
231
  if (prev.config) {
@@ -222,12 +237,19 @@ class WorkflowPlugin extends import_server.Plugin {
222
237
  }
223
238
  }
224
239
  trigger(workflow, context, options = {}) {
225
- if (!this.ready || context == null) {
240
+ const logger = this.getLogger(workflow.id);
241
+ if (!this.ready) {
242
+ logger.warn(`app is not ready, event of workflow ${workflow.id} will be ignored`);
243
+ logger.debug(`ignored event data:`, { data: context });
244
+ return;
245
+ }
246
+ if (context == null) {
247
+ logger.warn(`workflow ${workflow.id} event data context is null, event will be ignored`);
226
248
  return;
227
249
  }
228
250
  this.events.push([workflow, context, options]);
229
- this.getLogger(workflow.id).info(`new event triggered, now events: ${this.events.length}`);
230
- this.getLogger(workflow.id).debug(`event data:`, {
251
+ logger.info(`new event triggered, now events: ${this.events.length}`);
252
+ logger.debug(`event data:`, {
231
253
  data: context
232
254
  });
233
255
  if (this.events.length > 1) {
@@ -239,20 +261,18 @@ class WorkflowPlugin extends import_server.Plugin {
239
261
  if (!job.execution) {
240
262
  job.execution = await job.getExecution();
241
263
  }
264
+ this.getLogger(job.execution.workflowId).info(
265
+ `execution (${job.execution.id}) resuming from job (${job.id}) added to pending list`
266
+ );
242
267
  this.pending.push([job.execution, job]);
243
268
  this.dispatch();
244
269
  }
245
270
  createProcessor(execution, options = {}) {
246
271
  return new import_Processor.default(execution, { ...options, plugin: this });
247
272
  }
248
- prepare = async () => {
273
+ async createExecution(event) {
249
274
  var _a;
250
- const [event] = this.events;
251
- if (!event) {
252
- return;
253
- }
254
275
  const [workflow, context, options] = event;
255
- let valid = true;
256
276
  if ((_a = options.context) == null ? void 0 : _a.executionId) {
257
277
  const existed = await workflow.countExecutions({
258
278
  where: {
@@ -263,45 +283,55 @@ class WorkflowPlugin extends import_server.Plugin {
263
283
  this.getLogger(workflow.id).warn(
264
284
  `workflow ${workflow.id} has already been triggered in same execution (${options.context.executionId}), and newly triggering will be skipped.`
265
285
  );
266
- valid = false;
286
+ return null;
267
287
  }
268
288
  }
269
- if (valid) {
270
- const execution = await this.db.sequelize.transaction(async (transaction) => {
271
- const execution2 = await workflow.createExecution(
272
- {
273
- context,
274
- key: workflow.key,
275
- status: import_constants.EXECUTION_STATUS.QUEUEING
289
+ const execution = await this.db.sequelize.transaction(async (transaction) => {
290
+ const execution2 = await workflow.createExecution(
291
+ {
292
+ context,
293
+ key: workflow.key,
294
+ status: import_constants.EXECUTION_STATUS.QUEUEING
295
+ },
296
+ { transaction }
297
+ );
298
+ await workflow.increment(["executed", "allExecuted"], { transaction });
299
+ if (this.db.options.dialect !== "postgres") {
300
+ await workflow.reload({ transaction });
301
+ }
302
+ await workflow.constructor.update(
303
+ {
304
+ allExecuted: workflow.allExecuted
305
+ },
306
+ {
307
+ where: {
308
+ key: workflow.key
276
309
  },
277
- { transaction }
278
- );
279
- await workflow.increment(["executed", "allExecuted"], { transaction });
280
- if (this.db.options.dialect !== "postgres") {
281
- await workflow.reload({ transaction });
310
+ transaction
282
311
  }
283
- await workflow.constructor.update(
284
- {
285
- allExecuted: workflow.allExecuted
286
- },
287
- {
288
- where: {
289
- key: workflow.key
290
- },
291
- transaction
292
- }
293
- );
294
- execution2.workflow = workflow;
295
- return execution2;
296
- });
297
- this.getLogger(workflow.id).debug(`execution of workflow ${workflow.id} created as ${execution.id}`, {
298
- data: execution.context
299
- });
300
- if (!this.executing && !this.pending.length) {
301
- this.pending.push([execution]);
302
- }
312
+ );
313
+ execution2.workflow = workflow;
314
+ return execution2;
315
+ });
316
+ this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
317
+ if (!this.executing && !this.pending.length) {
318
+ this.pending.push([execution]);
319
+ }
320
+ return execution;
321
+ }
322
+ prepare = async () => {
323
+ const event = this.events.shift();
324
+ if (!event) {
325
+ this.getLogger("dispatcher").warn(`events queue is empty, no need to prepare`);
326
+ return;
327
+ }
328
+ const logger = this.getLogger(event[0].id);
329
+ logger.info(`preparing execution for event`);
330
+ try {
331
+ await this.createExecution(event);
332
+ } catch (err) {
333
+ logger.error(`failed to create execution: ${err.message}`, err);
303
334
  }
304
- this.events.shift();
305
335
  if (this.events.length) {
306
336
  await this.prepare();
307
337
  } else {
@@ -309,7 +339,12 @@ class WorkflowPlugin extends import_server.Plugin {
309
339
  }
310
340
  };
311
341
  dispatch() {
312
- if (!this.ready || this.executing) {
342
+ if (!this.ready) {
343
+ this.getLogger("dispatcher").warn(`app is not ready, new dispatching will be ignored`);
344
+ return;
345
+ }
346
+ if (this.executing) {
347
+ this.getLogger("dispatcher").warn(`workflow executing is not finished, new dispatching will be ignored`);
313
348
  return;
314
349
  }
315
350
  this.executing = (async () => {
@@ -321,6 +356,7 @@ class WorkflowPlugin extends import_server.Plugin {
321
356
  const execution = await this.db.getRepository("executions").findOne({
322
357
  filter: {
323
358
  status: import_constants.EXECUTION_STATUS.QUEUEING,
359
+ "workflow.enabled": true,
324
360
  "workflow.id": {
325
361
  [import_database.Op.not]: null
326
362
  }
@@ -328,7 +364,7 @@ class WorkflowPlugin extends import_server.Plugin {
328
364
  appends: ["workflow"],
329
365
  sort: "createdAt"
330
366
  });
331
- if (execution && execution.workflow.enabled) {
367
+ if (execution) {
332
368
  this.getLogger(execution.workflowId).info(`execution (${execution.id}) fetched from db`);
333
369
  next = [execution];
334
370
  }
@@ -1,4 +1,4 @@
1
- import { Transaction, Transactionable } from '@nocobase/database';
1
+ import { Transactionable } from '@nocobase/database';
2
2
  import { Logger } from '@nocobase/logger';
3
3
  import type Plugin from './Plugin';
4
4
  import type { ExecutionModel, FlowNodeModel, JobModel } from './types';
@@ -9,10 +9,16 @@ export default class Processor {
9
9
  execution: ExecutionModel;
10
10
  options: ProcessorOptions;
11
11
  static StatusMap: {
12
- [x: number]: number;
12
+ 0: 0;
13
+ 1: 1;
14
+ [-1]: -1;
15
+ [-2]: -2;
16
+ [-3]: -3;
17
+ [-4]: -4;
18
+ [-5]: -5;
19
+ [-6]: -6;
13
20
  };
14
21
  logger: Logger;
15
- transaction?: Transaction;
16
22
  nodes: FlowNodeModel[];
17
23
  nodesMap: Map<number, FlowNodeModel>;
18
24
  jobsMap: Map<number, JobModel>;
@@ -22,11 +28,9 @@ export default class Processor {
22
28
  constructor(execution: ExecutionModel, options: ProcessorOptions);
23
29
  private makeNodes;
24
30
  private makeJobs;
25
- private getTransaction;
26
31
  prepare(): Promise<void>;
27
32
  start(): Promise<void>;
28
33
  resume(job: JobModel): Promise<void>;
29
- private commit;
30
34
  private exec;
31
35
  run(node: any, input?: any): any;
32
36
  end(node: any, job: JobModel): Promise<any>;