@nocobase/plugin-workflow 0.18.0-alpha.1 → 0.18.0-alpha.9

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 (47) 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 +9 -8
  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 +11 -11
  18. package/dist/server/Plugin.js +56 -34
  19. package/dist/server/Processor.d.ts +9 -5
  20. package/dist/server/Processor.js +8 -33
  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/triggers/CollectionTrigger.js +3 -3
  41. package/dist/server/triggers/ScheduleTrigger.d.ts +1 -1
  42. package/dist/server/triggers/ScheduleTrigger.js +14 -14
  43. package/dist/server/triggers/index.d.ts +2 -2
  44. package/dist/server/triggers/index.js +2 -2
  45. package/dist/server/types/Execution.d.ts +0 -2
  46. package/dist/server/types/Workflow.d.ts +0 -1
  47. 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;
@@ -2,20 +2,21 @@ module.exports = {
2
2
  "react": "18.2.0",
3
3
  "antd": "5.12.2",
4
4
  "@ant-design/icons": "5.2.6",
5
- "@nocobase/client": "0.18.0-alpha.1",
5
+ "@nocobase/client": "0.18.0-alpha.9",
6
6
  "react-router-dom": "6.21.0",
7
- "@nocobase/utils": "0.18.0-alpha.1",
7
+ "@nocobase/utils": "0.18.0-alpha.9",
8
8
  "react-i18next": "11.18.6",
9
- "winston": "3.11.0",
10
- "@nocobase/database": "0.18.0-alpha.1",
11
- "@nocobase/server": "0.18.0-alpha.1",
12
- "@nocobase/logger": "0.18.0-alpha.1",
13
- "@nocobase/evaluators": "0.18.0-alpha.1",
9
+ "@nocobase/database": "0.18.0-alpha.9",
10
+ "@nocobase/server": "0.18.0-alpha.9",
11
+ "@nocobase/logger": "0.18.0-alpha.9",
12
+ "@nocobase/evaluators": "0.18.0-alpha.9",
14
13
  "@formily/react": "2.3.0",
15
14
  "@formily/core": "2.3.0",
16
15
  "lodash": "4.17.21",
17
16
  "@formily/antd-v5": "1.1.9",
18
- "@nocobase/actions": "0.18.0-alpha.1",
17
+ "@nocobase/actions": "0.18.0-alpha.9",
19
18
  "sequelize": "6.35.2",
19
+ "@nocobase/plugin-workflow-test": "0.18.0-alpha.9",
20
+ "@nocobase/test": "0.18.0-alpha.9",
20
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-21T12:51:37.067Z"}
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-01-03T02:11:26.806Z"}
@@ -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-21T12:51:36.734Z"}
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-01-03T02:11:26.452Z"}
@@ -3,31 +3,31 @@ 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;
15
15
  private executing;
16
16
  private pending;
17
17
  private events;
18
+ private eventsCount;
18
19
  private loggerCache;
20
+ private meter;
19
21
  getLogger(workflowId: ID): Logger;
20
22
  onBeforeSave: (instance: WorkflowModel, options: any) => Promise<void>;
21
- initTriggers<T extends Trigger>(more?: {
22
- [key: string]: T | {
23
- new (p: Plugin): T;
24
- };
23
+ registerTrigger<T extends Trigger>(type: string, trigger: T | {
24
+ new (p: Plugin): T;
25
25
  }): void;
26
- initInstructions<T extends Instruction>(more?: {
27
- [key: string]: T | {
28
- new (p: Plugin): T;
29
- };
26
+ registerInstruction(type: string, instruction: InstructionInterface | {
27
+ new (p: Plugin): InstructionInterface;
30
28
  }): void;
29
+ private initTriggers;
30
+ private initInstructions;
31
31
  load(): Promise<void>;
32
32
  toggle(workflow: WorkflowModel, enable?: boolean): void;
33
33
  trigger(workflow: WorkflowModel, context: object, options?: {
@@ -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");
@@ -57,7 +55,9 @@ class WorkflowPlugin extends import_server.Plugin {
57
55
  executing = null;
58
56
  pending = [];
59
57
  events = [];
58
+ eventsCount = 0;
60
59
  loggerCache;
60
+ meter = null;
61
61
  getLogger(workflowId) {
62
62
  const now = /* @__PURE__ */ new Date();
63
63
  const date = `${now.getFullYear()}-${`0${now.getMonth() + 1}`.slice(-2)}-${`0${now.getDate()}`.slice(-2)}`;
@@ -65,14 +65,10 @@ class WorkflowPlugin extends import_server.Plugin {
65
65
  if (this.loggerCache.has(key)) {
66
66
  return this.loggerCache.get(key);
67
67
  }
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
- ]
68
+ const logger = this.createLogger({
69
+ dirname: import_path.default.join("workflows", date),
70
+ filename: `${workflowId}.log`,
71
+ transports: [...process.env.NODE_ENV !== "production" ? ["console"] : ["file"]]
76
72
  });
77
73
  this.loggerCache.set(key, logger);
78
74
  return logger;
@@ -116,24 +112,40 @@ class WorkflowPlugin extends import_server.Plugin {
116
112
  this.toggle(previous, false);
117
113
  }
118
114
  };
115
+ registerTrigger(type, trigger) {
116
+ if (typeof trigger === "function") {
117
+ this.triggers.register(type, new trigger(this));
118
+ } else if (trigger) {
119
+ this.triggers.register(type, trigger);
120
+ } else {
121
+ throw new Error("invalid trigger type to register");
122
+ }
123
+ }
124
+ registerInstruction(type, instruction) {
125
+ if (typeof instruction === "function") {
126
+ this.instructions.register(type, new instruction(this));
127
+ } else if (instruction) {
128
+ this.instructions.register(type, instruction);
129
+ } else {
130
+ throw new Error("invalid instruction type to register");
131
+ }
132
+ }
119
133
  initTriggers(more = {}) {
120
- const { triggers } = this;
121
- triggers.register("collection", new import_CollectionTrigger.default(this));
122
- triggers.register("schedule", new import_ScheduleTrigger.default(this));
134
+ this.registerTrigger("collection", import_CollectionTrigger.default);
135
+ this.registerTrigger("schedule", import_ScheduleTrigger.default);
123
136
  for (const [name, trigger] of Object.entries(more)) {
124
- triggers.register(name, typeof trigger === "function" ? new trigger(this) : trigger);
137
+ this.registerTrigger(name, trigger);
125
138
  }
126
139
  }
127
140
  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));
141
+ this.registerInstruction("calculation", import_CalculationInstruction.default);
142
+ this.registerInstruction("condition", import_ConditionInstruction.default);
143
+ this.registerInstruction("create", import_CreateInstruction.default);
144
+ this.registerInstruction("destroy", import_DestroyInstruction.default);
145
+ this.registerInstruction("query", import_QueryInstruction.default);
146
+ this.registerInstruction("update", import_UpdateInstruction.default);
135
147
  for (const [name, instruction] of Object.entries({ ...more })) {
136
- instructions.register(name, typeof instruction === "function" ? new instruction(this) : instruction);
148
+ this.registerInstruction(name, instruction);
137
149
  }
138
150
  }
139
151
  async load() {
@@ -149,6 +161,11 @@ class WorkflowPlugin extends import_server.Plugin {
149
161
  logger.end();
150
162
  }
151
163
  });
164
+ this.meter = this.app.telemetry.metric.getMeter();
165
+ const counter = this.meter.createObservableGauge("workflow.events.counter");
166
+ counter.addCallback((result) => {
167
+ result.observe(this.eventsCount);
168
+ });
152
169
  this.app.acl.registerSnippet({
153
170
  name: `pm.${this.name}.workflows`,
154
171
  actions: [
@@ -164,7 +181,6 @@ class WorkflowPlugin extends import_server.Plugin {
164
181
  name: "ui.*",
165
182
  actions: ["workflows:list"]
166
183
  });
167
- this.app.acl.allow("users_jobs", ["list", "get", "submit"], "loggedIn");
168
184
  this.app.acl.allow("workflows", ["trigger"], "loggedIn");
169
185
  await db.import({
170
186
  directory: import_path.default.resolve(__dirname, "collections")
@@ -213,6 +229,10 @@ class WorkflowPlugin extends import_server.Plugin {
213
229
  toggle(workflow, enable) {
214
230
  const type = workflow.get("type");
215
231
  const trigger = this.triggers.get(type);
232
+ if (!trigger) {
233
+ this.getLogger(workflow.id).error(`trigger type ${workflow.type} of workflow ${workflow.id} is not implemented`);
234
+ return;
235
+ }
216
236
  if (typeof enable !== "undefined" ? enable : workflow.get("enabled")) {
217
237
  const prev = workflow.previous();
218
238
  if (prev.config) {
@@ -235,6 +255,7 @@ class WorkflowPlugin extends import_server.Plugin {
235
255
  return;
236
256
  }
237
257
  this.events.push([workflow, context, options]);
258
+ this.eventsCount = this.events.length;
238
259
  logger.info(`new event triggered, now events: ${this.events.length}`);
239
260
  logger.debug(`event data:`, {
240
261
  data: context
@@ -273,8 +294,8 @@ class WorkflowPlugin extends import_server.Plugin {
273
294
  return null;
274
295
  }
275
296
  }
276
- const execution = await this.db.sequelize.transaction(async (transaction) => {
277
- const execution2 = await workflow.createExecution(
297
+ return this.db.sequelize.transaction(async (transaction) => {
298
+ const execution = await workflow.createExecution(
278
299
  {
279
300
  context,
280
301
  key: workflow.key,
@@ -282,6 +303,7 @@ class WorkflowPlugin extends import_server.Plugin {
282
303
  },
283
304
  { transaction }
284
305
  );
306
+ this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
285
307
  await workflow.increment(["executed", "allExecuted"], { transaction });
286
308
  if (this.db.options.dialect !== "postgres") {
287
309
  await workflow.reload({ transaction });
@@ -297,17 +319,13 @@ class WorkflowPlugin extends import_server.Plugin {
297
319
  transaction
298
320
  }
299
321
  );
300
- execution2.workflow = workflow;
301
- return execution2;
322
+ execution.workflow = workflow;
323
+ return execution;
302
324
  });
303
- this.getLogger(workflow.id).info(`execution of workflow ${workflow.id} created as ${execution.id}`);
304
- if (!this.executing && !this.pending.length) {
305
- this.pending.push([execution]);
306
- }
307
- return execution;
308
325
  }
309
326
  prepare = async () => {
310
327
  const event = this.events.shift();
328
+ this.eventsCount = this.events.length;
311
329
  if (!event) {
312
330
  this.getLogger("dispatcher").warn(`events queue is empty, no need to prepare`);
313
331
  return;
@@ -315,7 +333,10 @@ class WorkflowPlugin extends import_server.Plugin {
315
333
  const logger = this.getLogger(event[0].id);
316
334
  logger.info(`preparing execution for event`);
317
335
  try {
318
- await this.createExecution(event);
336
+ const execution = await this.createExecution(event);
337
+ if (!this.executing && !this.pending.length) {
338
+ this.pending.push([execution]);
339
+ }
319
340
  } catch (err) {
320
341
  logger.error(`failed to create execution: ${err.message}`, err);
321
342
  }
@@ -343,6 +364,7 @@ class WorkflowPlugin extends import_server.Plugin {
343
364
  const execution = await this.db.getRepository("executions").findOne({
344
365
  filter: {
345
366
  status: import_constants.EXECUTION_STATUS.QUEUEING,
367
+ "workflow.enabled": true,
346
368
  "workflow.id": {
347
369
  [import_database.Op.not]: null
348
370
  }
@@ -350,7 +372,7 @@ class WorkflowPlugin extends import_server.Plugin {
350
372
  appends: ["workflow"],
351
373
  sort: "createdAt"
352
374
  });
353
- if (execution && execution.workflow.enabled) {
375
+ if (execution) {
354
376
  this.getLogger(execution.workflowId).info(`execution (${execution.id}) fetched from db`);
355
377
  next = [execution];
356
378
  }
@@ -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>;
@@ -41,7 +41,6 @@ class Processor {
41
41
  [import_constants.JOB_STATUS.RETRY_NEEDED]: import_constants.EXECUTION_STATUS.RETRY_NEEDED
42
42
  };
43
43
  logger;
44
- transaction;
45
44
  nodes = [];
46
45
  nodesMap = /* @__PURE__ */ new Map();
47
46
  jobsMap = /* @__PURE__ */ new Map();
@@ -68,26 +67,15 @@ class Processor {
68
67
  this.jobsMapByNodeKey[node.key] = job.result;
69
68
  });
70
69
  }
71
- async getTransaction() {
72
- var _a;
73
- if (!((_a = this.execution.workflow.options) == null ? void 0 : _a.useTransaction)) {
74
- return;
75
- }
76
- const { options } = this;
77
- return options.transaction && !options.transaction.finished ? options.transaction : await options.plugin.db.sequelize.transaction();
78
- }
79
70
  async prepare() {
80
71
  const { execution } = this;
81
72
  if (!execution.workflow) {
82
73
  execution.workflow = await execution.getWorkflow();
83
74
  }
84
- const transaction = await this.getTransaction();
85
- this.transaction = transaction;
86
75
  const nodes = await execution.workflow.getNodes();
87
76
  this.makeNodes(nodes);
88
77
  const jobs = await execution.getJobs({
89
- order: [["id", "ASC"]],
90
- transaction
78
+ order: [["id", "ASC"]]
91
79
  });
92
80
  this.makeJobs(jobs);
93
81
  }
@@ -113,11 +101,6 @@ class Processor {
113
101
  const node = this.nodesMap.get(job.nodeId);
114
102
  await this.recall(node, job);
115
103
  }
116
- async commit() {
117
- if (this.transaction && (!this.options.transaction || this.options.transaction.finished)) {
118
- await this.transaction.commit();
119
- }
120
- }
121
104
  async exec(instruction, node, prevJob) {
122
105
  let job;
123
106
  try {
@@ -188,10 +171,9 @@ class Processor {
188
171
  async exit(s) {
189
172
  if (typeof s === "number") {
190
173
  const status = this.constructor.StatusMap[s] ?? Math.sign(s);
191
- await this.execution.update({ status }, { transaction: this.transaction });
174
+ await this.execution.update({ status });
192
175
  }
193
176
  this.logger.info(`execution (${this.execution.id}) exiting with status ${this.execution.status}`);
194
- await this.commit();
195
177
  return null;
196
178
  }
197
179
  // TODO(optimize)
@@ -200,22 +182,15 @@ class Processor {
200
182
  const { model } = database.getCollection("jobs");
201
183
  let job;
202
184
  if (payload instanceof model) {
203
- job = await payload.save({ transaction: this.transaction });
185
+ job = await payload.save();
204
186
  } else if (payload.id) {
205
187
  job = await model.findByPk(payload.id);
206
- await job.update(payload, {
207
- transaction: this.transaction
208
- });
188
+ await job.update(payload);
209
189
  } else {
210
- job = await model.create(
211
- {
212
- ...payload,
213
- executionId: this.execution.id
214
- },
215
- {
216
- transaction: this.transaction
217
- }
218
- );
190
+ job = await model.create({
191
+ ...payload,
192
+ executionId: this.execution.id
193
+ });
219
194
  }
220
195
  this.jobsMap.set(job.id, job);
221
196
  const node = this.nodesMap.get(job.nodeId);