@ldsg/workflow 0.2.12 → 0.3.1

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 (27) hide show
  1. package/dist/__tests__/unit/resource.js +118 -41
  2. package/dist/resource.d.ts.map +1 -1
  3. package/dist/resource.js +44 -14
  4. package/dist/types/node.d.ts +15 -9
  5. package/dist/types/node.d.ts.map +1 -1
  6. package/dist/utils/evaluate-variables/constants.d.ts +39 -0
  7. package/dist/utils/evaluate-variables/constants.d.ts.map +1 -0
  8. package/dist/utils/evaluate-variables/constants.js +65 -0
  9. package/dist/utils/evaluate-variables/index.d.ts +12 -0
  10. package/dist/utils/evaluate-variables/index.d.ts.map +1 -0
  11. package/dist/utils/evaluate-variables/index.js +17 -0
  12. package/dist/utils/evaluate-variables/utils/get-field-path-by-field-type-key.d.ts +2 -0
  13. package/dist/utils/evaluate-variables/utils/get-field-path-by-field-type-key.d.ts.map +1 -0
  14. package/dist/utils/evaluate-variables/utils/get-field-path-by-field-type-key.js +16 -0
  15. package/dist/utils/evaluate-variables/utils/resolve-json-schema.d.ts +22 -0
  16. package/dist/utils/evaluate-variables/utils/resolve-json-schema.d.ts.map +1 -0
  17. package/dist/utils/evaluate-variables/utils/resolve-json-schema.js +112 -0
  18. package/dist/utils/evaluate-variables.test.d.ts +2 -0
  19. package/dist/utils/evaluate-variables.test.d.ts.map +1 -0
  20. package/dist/utils/evaluate-variables.test.js +227 -0
  21. package/dist/utils/index.d.ts +0 -1
  22. package/dist/utils/index.d.ts.map +1 -1
  23. package/dist/utils/index.js +0 -1
  24. package/package.json +10 -5
  25. package/dist/utils/get-workflow-output-variables.d.ts +0 -10
  26. package/dist/utils/get-workflow-output-variables.d.ts.map +0 -1
  27. package/dist/utils/get-workflow-output-variables.js +0 -12
@@ -1,53 +1,126 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const resource_1 = require("../../resource");
4
- const getWorkflowNodeExecute = (params) => {
5
- const { id } = params;
6
- const res = async (params) => {
4
+ const numberIdList = ["1", "2", "3", "4", "5"];
5
+ const nodeIdList = numberIdList.map((id) => `node-${id}`);
6
+ const nodes = nodeIdList.map((nodeId) => {
7
+ const workflowNodeExecute = async (params) => {
8
+ const { variables: workflowNodeInputVariables } = params;
9
+ const workflowNodeOutputVariables = workflowNodeInputVariables;
7
10
  const res = {
8
- variables: `hello, ${id}`,
11
+ variables: workflowNodeOutputVariables,
9
12
  };
10
13
  return res;
11
14
  };
12
- return res;
13
- };
14
- const nodeIdList = ["1", "2", "3", "4", "5"];
15
- const nodes = nodeIdList.map((id) => {
15
+ let input;
16
+ let output;
17
+ switch (nodeId) {
18
+ case "node-1": {
19
+ input = {
20
+ type: "object",
21
+ properties: {
22
+ hello: {
23
+ type: "string",
24
+ "x-expression": "hello",
25
+ },
26
+ },
27
+ };
28
+ output = {
29
+ type: "object",
30
+ properties: {
31
+ hello: {
32
+ type: "string",
33
+ "x-expression": "hello",
34
+ },
35
+ },
36
+ };
37
+ break;
38
+ }
39
+ case "node-5": {
40
+ input = {
41
+ type: "object",
42
+ properties: {
43
+ hello: {
44
+ type: "string",
45
+ "x-expression": `$."node-1".hello`,
46
+ },
47
+ },
48
+ };
49
+ output = {
50
+ type: "object",
51
+ properties: {
52
+ hello: {
53
+ type: "string",
54
+ "x-expression": "hello",
55
+ },
56
+ },
57
+ };
58
+ break;
59
+ }
60
+ default: {
61
+ input = {
62
+ type: "object",
63
+ properties: {
64
+ hello: {
65
+ type: "string",
66
+ default: "other",
67
+ },
68
+ },
69
+ };
70
+ output = {
71
+ type: "object",
72
+ properties: {
73
+ hello: {
74
+ type: "string",
75
+ default: "other",
76
+ },
77
+ },
78
+ };
79
+ break;
80
+ }
81
+ }
16
82
  const res = {
17
- id,
18
- execute: getWorkflowNodeExecute({ id }),
83
+ id: nodeId,
84
+ propertiesSchema: {
85
+ type: "object",
86
+ properties: {
87
+ input,
88
+ output,
89
+ },
90
+ },
91
+ execute: workflowNodeExecute,
19
92
  };
20
93
  return res;
21
94
  });
95
+ const workflowData = {
96
+ edges: [
97
+ {
98
+ sourceWorkflowNodeResourceId: "node-1",
99
+ targetWorkflowNodeResourceId: "node-2",
100
+ },
101
+ {
102
+ sourceWorkflowNodeResourceId: "node-2",
103
+ targetWorkflowNodeResourceId: "node-3",
104
+ },
105
+ {
106
+ sourceWorkflowNodeResourceId: "node-3",
107
+ targetWorkflowNodeResourceId: "node-4",
108
+ },
109
+ {
110
+ sourceWorkflowNodeResourceId: "node-4",
111
+ targetWorkflowNodeResourceId: "node-5",
112
+ },
113
+ ],
114
+ nodes,
115
+ };
116
+ const getWorkflowDataRes = {
117
+ workflowData,
118
+ };
22
119
  class TestWorkflowResource extends resource_1.WorkflowResource {
23
120
  constructor() {
24
121
  super(...arguments);
25
122
  this.getWorkflowData = () => {
26
- const workflowData = {
27
- edges: [
28
- {
29
- sourceWorkflowNodeResourceId: "1",
30
- targetWorkflowNodeResourceId: "2",
31
- },
32
- {
33
- sourceWorkflowNodeResourceId: "2",
34
- targetWorkflowNodeResourceId: "3",
35
- },
36
- {
37
- sourceWorkflowNodeResourceId: "3",
38
- targetWorkflowNodeResourceId: "4",
39
- },
40
- {
41
- sourceWorkflowNodeResourceId: "4",
42
- targetWorkflowNodeResourceId: "5",
43
- },
44
- ],
45
- nodes,
46
- };
47
- const res = {
48
- workflowData,
49
- };
50
- return res;
123
+ return getWorkflowDataRes;
51
124
  };
52
125
  }
53
126
  }
@@ -59,14 +132,18 @@ test("WorkflowResource execute", async () => {
59
132
  settings: {
60
133
  title: "",
61
134
  description: "",
62
- startWorkflowNodeResourceId: "1",
63
- endWorkflowNodeResourceId: "5",
135
+ startWorkflowNodeResourceId: "node-1",
136
+ endWorkflowNodeResourceId: "node-5",
64
137
  },
65
138
  });
139
+ const workflowInputVariables = {
140
+ hello: "world",
141
+ };
142
+ const workflowOutputVariables = {
143
+ hello: "world",
144
+ };
66
145
  const { variables } = await testWorkflowResource.execute({
67
- variables: {
68
- hello: "world",
69
- },
146
+ variables: workflowInputVariables,
70
147
  });
71
- expect(variables).toEqual("hello, 5");
148
+ expect(variables).toMatchObject(workflowOutputVariables);
72
149
  });
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAGL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAChB,gCAAgC,EAGjC,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,gCAAgC,CAAC;IAC9E,uBAAuB,EAAE,uBAAuB,CA4B9C;IAEF,uBAAuB,EAAE,uBAAuB,CAsB9C;IAEF,eAAe,EAAE,eAAe,CAiB9B;IAEF,OAAO,EAAE,eAAe,CA0DtB;IAEF,eAAe,EAAE,eAAe,CAY9B;CACH"}
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../src/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAGL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAEf,YAAY,EACZ,gBAAgB,EAChB,gCAAgC,EAGjC,MAAM,SAAS,CAAC;AAIjB,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,gBAAgB,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,CAAC;AAEvE,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,MAAM,kBAAkB,CAAC;AAEvD,qBAAa,gBAAiB,SAAQ,QAAQ,CAAC,gCAAgC,CAAC;IAC9E,uBAAuB,EAAE,uBAAuB,CA4B9C;IAEF,uBAAuB,EAAE,uBAAuB,CAsB9C;IAEF,eAAe,EAAE,eAAe,CAiB9B;IAEF,OAAO,EAAE,eAAe,CA8GtB;IAEF,eAAe,EAAE,eAAe,CAY9B;CACH"}
package/dist/resource.js CHANGED
@@ -7,6 +7,7 @@ exports.WorkflowResource = void 0;
7
7
  const resource_1 = require("@ldsg/resource");
8
8
  const lodash_1 = __importDefault(require("lodash"));
9
9
  const utils_1 = require("./utils");
10
+ const evaluate_variables_1 = require("./utils/evaluate-variables");
10
11
  class WorkflowResource extends resource_1.Resource {
11
12
  constructor() {
12
13
  super(...arguments);
@@ -71,22 +72,51 @@ class WorkflowResource extends resource_1.Resource {
71
72
  startNode,
72
73
  endNode,
73
74
  });
74
- for (const node of orderedNodeList) {
75
- const { id, execute } = node;
76
- const workflowVariablesRecord = Object.fromEntries(workflowVariablesMap);
77
- const executeRes = await execute({
78
- ...(id === startWorkflowNodeResourceId
79
- ? { workflowInputVariables }
80
- : {}),
81
- workflowVariablesRecord,
75
+ const orderedNodeListLength = orderedNodeList.length;
76
+ if (orderedNodeListLength < 2) {
77
+ throw new Error("invalid workflow nodes count");
78
+ }
79
+ let workflowOutputVariables;
80
+ for (let index = 0; index < orderedNodeListLength; index++) {
81
+ const node = orderedNodeList[index];
82
+ const { id, propertiesSchema, execute: nodeExecute } = node;
83
+ const workflowVariables = Object.fromEntries(workflowVariablesMap);
84
+ // 输入变量从工作流变量中使用表达式获取
85
+ const workflowNodePropertiesInputSchema = lodash_1.default.get(propertiesSchema, "properties.input");
86
+ const workflowNodePropertiesOutputSchema = lodash_1.default.get(propertiesSchema, "properties.output");
87
+ if (!lodash_1.default.isObject(workflowNodePropertiesInputSchema) ||
88
+ !lodash_1.default.isObject(workflowNodePropertiesOutputSchema)) {
89
+ throw new Error("invalid workflow node properties schema");
90
+ }
91
+ const { variables: workflowNodeInputVariables } = await (0, evaluate_variables_1.evaluateVariables)({
92
+ jsonSchema: workflowNodePropertiesInputSchema,
93
+ /**
94
+ * 对于开始节点,不忽略 input 表达式,但替换工作流内部变量为工作流输入变量。
95
+ */
96
+ variables: index === 0 ? workflowInputVariables : workflowVariables,
97
+ });
98
+ const { variables: workflowNodeOutputExpressionEvaluateInput } = await nodeExecute({
99
+ variables: workflowNodeInputVariables,
100
+ context: {
101
+ workflowResourceInstance: this,
102
+ },
82
103
  });
83
- const { variables } = executeRes;
84
- workflowVariablesMap.set(id, variables);
104
+ /**
105
+ * 输出变量从结果中使用表达式获取
106
+ * 对于结束节点,不忽略 output 表达式,但表达式固定为取返回变量。
107
+ */
108
+ const { variables: workflowNodeOutputVariables } = await (0, evaluate_variables_1.evaluateVariables)({
109
+ jsonSchema: workflowNodePropertiesOutputSchema,
110
+ variables: workflowNodeOutputExpressionEvaluateInput,
111
+ });
112
+ workflowVariablesMap.set(id, workflowNodeOutputVariables);
113
+ if (index === orderedNodeListLength - 1) {
114
+ workflowOutputVariables = workflowNodeOutputVariables;
115
+ }
85
116
  }
86
- const res = (0, utils_1.getWorkflowOutputVariables)({
87
- endNode,
88
- workflowVariablesMap,
89
- });
117
+ const res = {
118
+ variables: workflowOutputVariables,
119
+ };
90
120
  return res;
91
121
  };
92
122
  this.getWorkflowInfo = () => {
@@ -1,19 +1,20 @@
1
- import { WorkflowVariablesRecord } from "./variables";
1
+ import { JSONSchema7 } from "json-schema";
2
+ import { WorkflowResource } from "../resource";
2
3
  export type WorkflowNodeExecuterExecute = () => void | Promise<void>;
3
4
  export interface WorkflowNodeExecuteParams {
4
5
  /**
5
- * 工作流输入变量
6
- * 用作于工作流开始节点的输入变量
6
+ * (输入)变量
7
+ * 由工作流向工作流节点内输入
7
8
  */
8
- workflowInputVariables?: any;
9
- /**
10
- * 工作流变量记录
11
- */
12
- workflowVariablesRecord: WorkflowVariablesRecord;
9
+ variables: any;
10
+ context: {
11
+ workflowResourceInstance: WorkflowResource;
12
+ };
13
13
  }
14
14
  export interface WorkflowNodeExecuteRes {
15
15
  /**
16
- * 工作流节点输出变量
16
+ * (输出)变量
17
+ * 由工作流节点向工作流内输入
17
18
  */
18
19
  variables: any;
19
20
  }
@@ -27,6 +28,11 @@ export interface WorkflowNodeInfo {
27
28
  * ID
28
29
  */
29
30
  id: string;
31
+ /**
32
+ * Workflow Node Properties Schema
33
+ * 在运行时,可用于检验数据,默认不开启,仅开启调试模式时开启
34
+ */
35
+ propertiesSchema: JSONSchema7;
30
36
  /**
31
37
  * 工作流节点执行方法
32
38
  * 工作流节点执行时,实际运行的方法
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/types/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,MAAM,2BAA2B,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,GAAG,CAAC;IAE7B;;OAEG;IACH,uBAAuB,EAAE,uBAAuB,CAAC;CAClD;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,SAAS,EAAE,GAAG,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,yBAAyB,KAC9B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;OAGG;IACH,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/types/node.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,MAAM,2BAA2B,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAErE,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC;IAEf,OAAO,EAAE;QACP,wBAAwB,EAAE,gBAAgB,CAAC;KAC5C,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAChC,MAAM,EAAE,yBAAyB,KAC9B,OAAO,CAAC,sBAAsB,CAAC,CAAC;AAErC,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;OAGG;IACH,gBAAgB,EAAE,WAAW,CAAC;IAE9B;;;OAGG;IACH,OAAO,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,MAAM,mBAAmB,GAAG,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,39 @@
1
+ interface FieldValueRetrievalMethodHandleParams {
2
+ /**
3
+ * 取值方式的值
4
+ */
5
+ retrievalMethodValue: any;
6
+ /**
7
+ * 输入
8
+ * 表达式将使用此值进行计算
9
+ */
10
+ input: any;
11
+ /**
12
+ * 直接返回表达式作为数据
13
+ */
14
+ returnExpressionAsData?: boolean;
15
+ /**
16
+ * 对象项表达式
17
+ */
18
+ objectExpression?: string;
19
+ }
20
+ export interface FieldValueRetrievalMethodHandleRes {
21
+ const?: any;
22
+ data?: string;
23
+ default?: any;
24
+ expression?: string;
25
+ }
26
+ type FieldValueRetrievalMethodHandle = (params: FieldValueRetrievalMethodHandleParams) => Promise<FieldValueRetrievalMethodHandleRes> | FieldValueRetrievalMethodHandleRes;
27
+ /**
28
+ * 字段值获取方法
29
+ */
30
+ interface FieldValueRetrievalMethod {
31
+ name: string;
32
+ handle: FieldValueRetrievalMethodHandle;
33
+ }
34
+ /**
35
+ * 取值方式优先级应由高到低排序,取第一个有效值
36
+ */
37
+ export declare const FIELD_VALUE_RETRIEVAL_METHODS: FieldValueRetrievalMethod[];
38
+ export {};
39
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/utils/evaluate-variables/constants.ts"],"names":[],"mappings":"AAEA,UAAU,qCAAqC;IAC7C;;OAEG;IACH,oBAAoB,EAAE,GAAG,CAAC;IAE1B;;;OAGG;IACH,KAAK,EAAE,GAAG,CAAC;IAEX;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAG3B;AAED,MAAM,WAAW,kCAAkC;IACjD,KAAK,CAAC,EAAE,GAAG,CAAC;IAEZ,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,GAAG,CAAC;IAEd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,+BAA+B,GAAG,CACrC,MAAM,EAAE,qCAAqC,KAE3C,OAAO,CAAC,kCAAkC,CAAC,GAC3C,kCAAkC,CAAC;AAEvC;;GAEG;AACH,UAAU,yBAAyB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,+BAA+B,CAAC;CACzC;AAqCD;;GAEG;AACH,eAAO,MAAM,6BAA6B,EAAE,yBAAyB,EAmCpE,CAAC"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FIELD_VALUE_RETRIEVAL_METHODS = void 0;
7
+ const jsonata_1 = __importDefault(require("jsonata"));
8
+ const expressionHandle = async (params) => {
9
+ const { input, retrievalMethodValue, returnExpressionAsData, objectExpression,
10
+ // expressionMayContainObject
11
+ } = params;
12
+ /**
13
+ * 具有 objectArrayItemsExpression 的说明数据,不能返回表达式,只就返回数据。
14
+ */
15
+ if (returnExpressionAsData) {
16
+ return {
17
+ expression: retrievalMethodValue,
18
+ };
19
+ }
20
+ let jsonataStr = retrievalMethodValue;
21
+ if (objectExpression) {
22
+ jsonataStr = retrievalMethodValue.replace("{}", objectExpression);
23
+ }
24
+ const expression = (0, jsonata_1.default)(jsonataStr);
25
+ const data = await expression.evaluate(input);
26
+ const res = {
27
+ data,
28
+ };
29
+ return res;
30
+ };
31
+ /**
32
+ * 取值方式优先级应由高到低排序,取第一个有效值
33
+ */
34
+ exports.FIELD_VALUE_RETRIEVAL_METHODS = [
35
+ {
36
+ name: "const",
37
+ handle: (params) => {
38
+ const { retrievalMethodValue } = params;
39
+ const res = {
40
+ const: retrievalMethodValue,
41
+ data: retrievalMethodValue,
42
+ };
43
+ return res;
44
+ },
45
+ },
46
+ {
47
+ name: "x-expression-const",
48
+ handle: expressionHandle,
49
+ },
50
+ {
51
+ name: "x-expression",
52
+ handle: expressionHandle,
53
+ },
54
+ {
55
+ name: "default",
56
+ handle: (params) => {
57
+ const { retrievalMethodValue } = params;
58
+ const res = {
59
+ default: retrievalMethodValue,
60
+ data: retrievalMethodValue,
61
+ };
62
+ return res;
63
+ },
64
+ },
65
+ ];
@@ -0,0 +1,12 @@
1
+ import { JSONSchema7 } from "json-schema";
2
+ interface EvaluateVariablesParams {
3
+ jsonSchema: JSONSchema7;
4
+ variables: any;
5
+ }
6
+ interface EvaluateVariablesRes {
7
+ variables: any;
8
+ }
9
+ type EvaluateVariables = (params: EvaluateVariablesParams) => Promise<EvaluateVariablesRes>;
10
+ export declare const evaluateVariables: EvaluateVariables;
11
+ export {};
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/evaluate-variables/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,UAAU,uBAAuB;IAC/B,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,UAAU,oBAAoB;IAC5B,SAAS,EAAE,GAAG,CAAC;CAChB;AAED,KAAK,iBAAiB,GAAG,CACvB,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,iBAe/B,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluateVariables = void 0;
4
+ const resolve_json_schema_1 = require("./utils/resolve-json-schema");
5
+ const evaluateVariables = async (params) => {
6
+ const { jsonSchema, variables: paramsVariables } = params;
7
+ const resolveJsonSchemaRes = await (0, resolve_json_schema_1.resolveJsonSchema)({
8
+ jsonSchema,
9
+ input: paramsVariables,
10
+ });
11
+ const variables = JSON.parse(JSON.stringify(resolveJsonSchemaRes.data));
12
+ const res = {
13
+ variables,
14
+ };
15
+ return res;
16
+ };
17
+ exports.evaluateVariables = evaluateVariables;
@@ -0,0 +1,2 @@
1
+ export declare const getFieldPathByFieldTypeKey: (fieldTypeKey: string) => string;
2
+ //# sourceMappingURL=get-field-path-by-field-type-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-field-path-by-field-type-key.d.ts","sourceRoot":"","sources":["../../../../src/utils/evaluate-variables/utils/get-field-path-by-field-type-key.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,GAAI,cAAc,MAAM,KAAG,MAiBjE,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFieldPathByFieldTypeKey = void 0;
4
+ const getFieldPathByFieldTypeKey = (fieldTypeKey) => {
5
+ // 将字符串按点分割成数组
6
+ const splitRes = fieldTypeKey.split(".");
7
+ // 过滤数组:除了索引为复数且值为 properties ,其他所有元素均保留
8
+ const filterRes = splitRes.filter((value, index) => {
9
+ const res = !(value === "properties" && index % 2 === 0);
10
+ return res;
11
+ });
12
+ // 将过滤后的数组重新用点连接成字符串
13
+ const res = filterRes.join(".");
14
+ return res;
15
+ };
16
+ exports.getFieldPathByFieldTypeKey = getFieldPathByFieldTypeKey;
@@ -0,0 +1,22 @@
1
+ import { JSONSchema7 } from "json-schema";
2
+ interface ResolveJsonSchemaParams {
3
+ jsonSchema: JSONSchema7;
4
+ /**
5
+ * 输入
6
+ */
7
+ input: any;
8
+ /**
9
+ * 直接返回表达式作为数据
10
+ */
11
+ returnExpressionAsData?: boolean;
12
+ }
13
+ interface ResolveJsonSchemaRes {
14
+ const?: any;
15
+ data?: any;
16
+ default?: any;
17
+ expression?: any;
18
+ }
19
+ type ResolveJsonSchema = (params: ResolveJsonSchemaParams) => Promise<ResolveJsonSchemaRes>;
20
+ export declare const resolveJsonSchema: ResolveJsonSchema;
21
+ export {};
22
+ //# sourceMappingURL=resolve-json-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-json-schema.d.ts","sourceRoot":"","sources":["../../../../src/utils/evaluate-variables/utils/resolve-json-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAuB,MAAM,aAAa,CAAC;AAO/D,UAAU,uBAAuB;IAC/B,UAAU,EAAE,WAAW,CAAC;IAExB;;OAEG;IACH,KAAK,EAAE,GAAG,CAAC;IAEX;;OAEG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,UAAU,oBAAoB;IAC5B,KAAK,CAAC,EAAE,GAAG,CAAC;IAEZ,IAAI,CAAC,EAAE,GAAG,CAAC;IAEX,OAAO,CAAC,EAAE,GAAG,CAAC;IAEd,UAAU,CAAC,EAAE,GAAG,CAAC;CAClB;AAED,KAAK,iBAAiB,GAAG,CACvB,MAAM,EAAE,uBAAuB,KAC5B,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,iBAkK/B,CAAC"}
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveJsonSchema = void 0;
7
+ const lodash_1 = __importDefault(require("lodash"));
8
+ const constants_1 = require("../constants");
9
+ const resolveJsonSchema = async (params) => {
10
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
11
+ const { input, jsonSchema, returnExpressionAsData } = params;
12
+ const { type } = jsonSchema;
13
+ const res = {};
14
+ switch (type) {
15
+ case "object": {
16
+ const properties = lodash_1.default.get(jsonSchema, "properties");
17
+ const promises = lodash_1.default.keys(properties).map(async (propertyKey) => {
18
+ const propertyValue = lodash_1.default.get(properties, propertyKey);
19
+ if (!lodash_1.default.isObject(propertyValue)) {
20
+ return;
21
+ }
22
+ const resolveJsonSchemaRes = await (0, exports.resolveJsonSchema)({
23
+ jsonSchema: propertyValue,
24
+ input,
25
+ returnExpressionAsData,
26
+ });
27
+ lodash_1.default.set(res, `data.${propertyKey}`, resolveJsonSchemaRes.data);
28
+ lodash_1.default.set(res, `const.${propertyKey}`, resolveJsonSchemaRes.const);
29
+ lodash_1.default.set(res, `default.${propertyKey}`, resolveJsonSchemaRes.default);
30
+ lodash_1.default.set(res, `expression.${propertyKey}`, resolveJsonSchemaRes.expression);
31
+ });
32
+ await Promise.all(promises);
33
+ break;
34
+ }
35
+ case "array": {
36
+ const itemsType = (_a = jsonSchema.items) === null || _a === void 0 ? void 0 : _a.type;
37
+ let objectExpression;
38
+ if (itemsType === "object") {
39
+ const resolveJsonSchemaRes = await (0, exports.resolveJsonSchema)({
40
+ jsonSchema: jsonSchema.items,
41
+ input,
42
+ returnExpressionAsData: true,
43
+ });
44
+ const expressionSubstrings = [];
45
+ lodash_1.default.each(resolveJsonSchemaRes.expression, (value, key) => {
46
+ if (value) {
47
+ expressionSubstrings.push(`"${key}": ${value}`);
48
+ }
49
+ });
50
+ objectExpression = `{${expressionSubstrings.join(",")}}`;
51
+ }
52
+ const promises = constants_1.FIELD_VALUE_RETRIEVAL_METHODS.map(async (fieldValueRetrievalMethod) => {
53
+ const { name, handle } = fieldValueRetrievalMethod;
54
+ /**
55
+ * 字段的真实 path 是 key 去除类型
56
+ */
57
+ const value = lodash_1.default.get(jsonSchema, name);
58
+ let res;
59
+ if (!lodash_1.default.isNil(value)) {
60
+ res = await handle({
61
+ input,
62
+ retrievalMethodValue: value,
63
+ objectExpression,
64
+ returnExpressionAsData,
65
+ });
66
+ }
67
+ return res;
68
+ });
69
+ const fieldValues = await Promise.all(promises);
70
+ res.const = (_b = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.const))) === null || _b === void 0 ? void 0 : _b.const;
71
+ res.data = (_c = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.data))) === null || _c === void 0 ? void 0 : _c.data;
72
+ res.default = (_d = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.default))) === null || _d === void 0 ? void 0 : _d.default;
73
+ res.expression = (_e = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.expression))) === null || _e === void 0 ? void 0 : _e.expression;
74
+ break;
75
+ }
76
+ case "boolean":
77
+ case "integer":
78
+ case "number":
79
+ case "string": {
80
+ const promises = constants_1.FIELD_VALUE_RETRIEVAL_METHODS.map(async (fieldValueRetrievalMethod) => {
81
+ const { name, handle } = fieldValueRetrievalMethod;
82
+ /**
83
+ * 字段的真实 path 是 key 去除类型
84
+ */
85
+ const value = lodash_1.default.get(jsonSchema, name);
86
+ let res;
87
+ if (!lodash_1.default.isNil(value)) {
88
+ res = await handle({
89
+ input,
90
+ retrievalMethodValue: value,
91
+ returnExpressionAsData,
92
+ });
93
+ }
94
+ return res;
95
+ });
96
+ const fieldValues = await Promise.all(promises);
97
+ res.const = (_f = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.const))) === null || _f === void 0 ? void 0 : _f.const;
98
+ res.data = (_g = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.data))) === null || _g === void 0 ? void 0 : _g.data;
99
+ res.default = (_h = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.default))) === null || _h === void 0 ? void 0 : _h.default;
100
+ res.expression = (_j = fieldValues.find((value) => !lodash_1.default.isNil(value === null || value === void 0 ? void 0 : value.expression))) === null || _j === void 0 ? void 0 : _j.expression;
101
+ break;
102
+ }
103
+ case "null": {
104
+ break;
105
+ }
106
+ default: {
107
+ throw new Error("invalid field type");
108
+ }
109
+ }
110
+ return res;
111
+ };
112
+ exports.resolveJsonSchema = resolveJsonSchema;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=evaluate-variables.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate-variables.test.d.ts","sourceRoot":"","sources":["../../src/utils/evaluate-variables.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const evaluate_variables_1 = require("./evaluate-variables");
4
+ const input = {
5
+ Account: {
6
+ "Account Name": "Firefly",
7
+ Order: [
8
+ {
9
+ OrderID: "order103",
10
+ Product: [
11
+ {
12
+ "Product Name": "Bowler Hat",
13
+ ProductID: 858383,
14
+ SKU: "0406654608",
15
+ Description: {
16
+ Colour: "Purple",
17
+ Width: 300,
18
+ Height: 200,
19
+ Depth: 210,
20
+ Weight: 0.75,
21
+ },
22
+ Price: 34.45,
23
+ Quantity: 2,
24
+ },
25
+ {
26
+ "Product Name": "Trilby hat",
27
+ ProductID: 858236,
28
+ SKU: "0406634348",
29
+ Description: {
30
+ Colour: "Orange",
31
+ Width: 300,
32
+ Height: 200,
33
+ Depth: 210,
34
+ Weight: 0.6,
35
+ },
36
+ Price: 21.67,
37
+ Quantity: 1,
38
+ },
39
+ ],
40
+ },
41
+ {
42
+ OrderID: "order104",
43
+ Product: [
44
+ {
45
+ "Product Name": "Bowler Hat",
46
+ ProductID: 858383,
47
+ SKU: "040657863",
48
+ Description: {
49
+ Colour: "Purple",
50
+ Width: 300,
51
+ Height: 200,
52
+ Depth: 210,
53
+ Weight: 0.75,
54
+ },
55
+ Price: 34.45,
56
+ Quantity: 4,
57
+ },
58
+ {
59
+ ProductID: 345664,
60
+ SKU: "0406654603",
61
+ "Product Name": "Cloak",
62
+ Description: {
63
+ Colour: "Black",
64
+ Width: 30,
65
+ Height: 20,
66
+ Depth: 210,
67
+ Weight: 2,
68
+ },
69
+ Price: 107.99,
70
+ Quantity: 1,
71
+ },
72
+ ],
73
+ },
74
+ ],
75
+ },
76
+ };
77
+ const subJsonSchema = {
78
+ type: "object",
79
+ properties: {
80
+ CurrentAccount: {
81
+ type: "string",
82
+ /**
83
+ * 从默认值内取值
84
+ */
85
+ default: "Current Account",
86
+ const: "Current Account",
87
+ },
88
+ type: {
89
+ type: "string",
90
+ default: "order",
91
+ },
92
+ AccountName: {
93
+ type: "string",
94
+ /**
95
+ * 根据 jsonata 取值
96
+ */
97
+ // @ts-ignore
98
+ "x-expression": `Account."Account Name"`,
99
+ },
100
+ CurrentOrder: {
101
+ type: "string",
102
+ /**
103
+ * 根据 jsonata 取值
104
+ */
105
+ // @ts-ignore
106
+ "x-expression": `"Current Order"`,
107
+ },
108
+ OrderPrice: {
109
+ type: "number",
110
+ // @ts-ignore
111
+ "x-expression": "$sum(Account.Order.Product.(Price * Quantity))",
112
+ },
113
+ ProductIds: {
114
+ type: "array",
115
+ items: {
116
+ type: "number",
117
+ },
118
+ // @ts-ignore
119
+ "x-expression": "Account.Order.Product.ProductID",
120
+ },
121
+ ordersWithProductIds: {
122
+ type: "array",
123
+ title: "具有产品 ID 的订单列表",
124
+ items: {
125
+ type: "object",
126
+ properties: {
127
+ CurrentOrdersWithProductIdsTitle: {
128
+ type: "string",
129
+ /**
130
+ * 从默认值内取值
131
+ */
132
+ default: "CurrentOrdersWithProductIdsTitle",
133
+ const: "CurrentOrdersWithProductIdsTitle",
134
+ },
135
+ productIds: {
136
+ type: "array",
137
+ items: {
138
+ type: "number",
139
+ },
140
+ // @ts-ignore
141
+ "x-expression": "$v.Product.ProductID",
142
+ },
143
+ AccountName: {
144
+ type: "string",
145
+ /**
146
+ * 根据 jsonata 取值
147
+ */
148
+ // @ts-ignore
149
+ "x-expression": `Account."Account Name"`,
150
+ },
151
+ orderId: {
152
+ type: "string",
153
+ // @ts-ignore
154
+ "x-expression": "$v.OrderID",
155
+ },
156
+ },
157
+ },
158
+ // @ts-ignore
159
+ "x-expression": "$map($.Account.Order, function($v, $i, $a) {{}})",
160
+ },
161
+ },
162
+ };
163
+ const jsonSchema = {
164
+ type: "object",
165
+ properties: {
166
+ ...subJsonSchema.properties,
167
+ nestd: {
168
+ type: "object",
169
+ properties: {
170
+ ...subJsonSchema.properties,
171
+ nestd: {
172
+ type: "object",
173
+ properties: {
174
+ ...subJsonSchema.properties,
175
+ nestd: {
176
+ type: "object",
177
+ properties: {
178
+ ...subJsonSchema.properties,
179
+ },
180
+ },
181
+ },
182
+ },
183
+ },
184
+ },
185
+ },
186
+ };
187
+ test("evaluate variables", async () => {
188
+ const evaluateVariablesRes = await (0, evaluate_variables_1.evaluateVariables)({
189
+ jsonSchema,
190
+ variables: input,
191
+ });
192
+ const expectedObject = {
193
+ variables: {
194
+ CurrentAccount: "Current Account",
195
+ type: "order",
196
+ AccountName: "Firefly",
197
+ CurrentOrder: "Current Order",
198
+ OrderPrice: 336.36,
199
+ ProductIds: [858383, 858236, 858383, 345664],
200
+ nestd: {
201
+ CurrentAccount: "Current Account",
202
+ type: "order",
203
+ AccountName: "Firefly",
204
+ CurrentOrder: "Current Order",
205
+ OrderPrice: 336.36,
206
+ ProductIds: [858383, 858236, 858383, 345664],
207
+ nestd: {
208
+ CurrentAccount: "Current Account",
209
+ type: "order",
210
+ AccountName: "Firefly",
211
+ CurrentOrder: "Current Order",
212
+ OrderPrice: 336.36,
213
+ ProductIds: [858383, 858236, 858383, 345664],
214
+ nestd: {
215
+ CurrentAccount: "Current Account",
216
+ type: "order",
217
+ AccountName: "Firefly",
218
+ CurrentOrder: "Current Order",
219
+ OrderPrice: 336.36,
220
+ ProductIds: [858383, 858236, 858383, 345664],
221
+ },
222
+ },
223
+ },
224
+ },
225
+ };
226
+ expect(evaluateVariablesRes).toMatchObject(expectedObject);
227
+ });
@@ -1,3 +1,2 @@
1
- export * from "./get-workflow-output-variables";
2
1
  export * from "./get-ordered-node-list";
3
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
@@ -14,5 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./get-workflow-output-variables"), exports);
18
17
  __exportStar(require("./get-ordered-node-list"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ldsg/workflow",
3
- "version": "0.2.12",
3
+ "version": "0.3.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "files": [
@@ -14,14 +14,19 @@
14
14
  "access": "public"
15
15
  },
16
16
  "dependencies": {
17
+ "flat": "^5.0.2",
18
+ "json-schema": "0.4.0",
19
+ "json-schema-default": "^1.0.2",
17
20
  "lodash": "^4.17.21",
18
- "@ldsg/handler": "0.2.12",
19
- "@ldsg/resource": "0.2.12",
20
- "@ldsg/resource-definition": "0.2.12"
21
+ "@ldsg/handler": "0.3.1",
22
+ "@ldsg/resource-definition": "0.3.1",
23
+ "@ldsg/resource": "0.3.1"
21
24
  },
22
25
  "devDependencies": {
26
+ "@types/flat": "^5.0.5",
27
+ "@types/json-schema": "^7.0.15",
23
28
  "@types/lodash": "^4.14.202",
24
- "@ldsg/types": "0.2.12"
29
+ "@ldsg/types": "0.3.1"
25
30
  },
26
31
  "scripts": {
27
32
  "build": "tsc --project tsconfig.build.json",
@@ -1,10 +0,0 @@
1
- import { WorkflowExecuteRes, WorkflowNodeInfo, WorkflowVariablesMap } from "../types";
2
- export interface GetWorkflowOutputVariablesParams {
3
- endNode: WorkflowNodeInfo;
4
- workflowVariablesMap: WorkflowVariablesMap;
5
- }
6
- export interface GetWorkflowOutputVariablesRes extends WorkflowExecuteRes {
7
- }
8
- export type GetWorkflowOutputVariables = (params: GetWorkflowOutputVariablesParams) => GetWorkflowOutputVariablesRes;
9
- export declare const getWorkflowOutputVariables: GetWorkflowOutputVariables;
10
- //# sourceMappingURL=get-workflow-output-variables.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"get-workflow-output-variables.d.ts","sourceRoot":"","sources":["../../src/utils/get-workflow-output-variables.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,gBAAgB,CAAC;IAC1B,oBAAoB,EAAE,oBAAoB,CAAC;CAC5C;AAED,MAAM,WAAW,6BAA8B,SAAQ,kBAAkB;CAAG;AAE5E,MAAM,MAAM,0BAA0B,GAAG,CACvC,MAAM,EAAE,gCAAgC,KACrC,6BAA6B,CAAC;AAEnC,eAAO,MAAM,0BAA0B,EAAE,0BAYxC,CAAC"}
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getWorkflowOutputVariables = void 0;
4
- const getWorkflowOutputVariables = (params) => {
5
- const { endNode, workflowVariablesMap } = params;
6
- const variables = workflowVariablesMap.get(endNode.id);
7
- const res = {
8
- variables,
9
- };
10
- return res;
11
- };
12
- exports.getWorkflowOutputVariables = getWorkflowOutputVariables;