@nocobase/plugin-workflow 0.9.3-alpha.1 → 0.9.4-alpha.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.
- package/lib/client/CanvasContent.d.ts +4 -0
- package/lib/client/CanvasContent.js +49 -0
- package/lib/client/ExecutionCanvas.js +110 -44
- package/lib/client/WorkflowCanvas.js +35 -18
- package/lib/client/components/CollectionFieldset.js +2 -2
- package/lib/client/components/NodeDescription.d.ts +2 -0
- package/lib/client/components/NodeDescription.js +59 -0
- package/lib/client/components/ValueBlock.d.ts +5 -0
- package/lib/client/components/ValueBlock.js +110 -0
- package/lib/client/index.d.ts +1 -0
- package/lib/client/index.js +12 -0
- package/lib/client/locale/es-ES.d.ts +130 -0
- package/lib/client/locale/es-ES.js +136 -0
- package/lib/client/locale/zh-CN.d.ts +35 -6
- package/lib/client/locale/zh-CN.js +35 -6
- package/lib/client/nodes/aggregate.d.ts +186 -0
- package/lib/client/nodes/aggregate.js +349 -0
- package/lib/client/nodes/calculation.d.ts +2 -1
- package/lib/client/nodes/calculation.js +28 -53
- package/lib/client/nodes/condition.d.ts +2 -6
- package/lib/client/nodes/condition.js +4 -3
- package/lib/client/nodes/create.d.ts +5 -3
- package/lib/client/nodes/create.js +16 -7
- package/lib/client/nodes/delay.d.ts +1 -0
- package/lib/client/nodes/delay.js +1 -0
- package/lib/client/nodes/destroy.d.ts +2 -2
- package/lib/client/nodes/destroy.js +1 -0
- package/lib/client/nodes/index.d.ts +5 -2
- package/lib/client/nodes/index.js +95 -97
- package/lib/client/nodes/loop.d.ts +29 -0
- package/lib/client/nodes/loop.js +165 -0
- package/lib/client/nodes/manual/AssigneesSelect.js +8 -6
- package/lib/client/nodes/manual/index.d.ts +6 -1
- package/lib/client/nodes/manual/index.js +6 -1
- package/lib/client/nodes/parallel.d.ts +1 -0
- package/lib/client/nodes/parallel.js +2 -1
- package/lib/client/nodes/query.d.ts +12 -3
- package/lib/client/nodes/query.js +24 -17
- package/lib/client/nodes/request.d.ts +1 -0
- package/lib/client/nodes/request.js +1 -0
- package/lib/client/nodes/update.d.ts +2 -2
- package/lib/client/nodes/update.js +1 -0
- package/lib/client/schemas/collection.d.ts +1 -2
- package/lib/client/schemas/collection.js +5 -6
- package/lib/client/style.d.ts +1 -0
- package/lib/client/style.js +40 -26
- package/lib/client/triggers/collection.d.ts +2 -11
- package/lib/client/triggers/collection.js +6 -7
- package/lib/client/triggers/index.d.ts +1 -1
- package/lib/client/triggers/index.js +5 -3
- package/lib/client/triggers/schedule/index.d.ts +3 -1
- package/lib/client/triggers/schedule/index.js +6 -4
- package/lib/client/variable.d.ts +27 -1
- package/lib/client/variable.js +65 -34
- package/lib/server/Plugin.js +2 -14
- package/lib/server/Processor.d.ts +3 -0
- package/lib/server/Processor.js +30 -3
- package/lib/server/actions/workflows.js +2 -2
- package/lib/server/collections/workflows.js +2 -1
- package/lib/server/instructions/aggregate.d.ts +9 -0
- package/lib/server/instructions/aggregate.js +57 -0
- package/lib/server/instructions/calculation.js +1 -1
- package/lib/server/instructions/condition.js +1 -1
- package/lib/server/instructions/create.js +1 -1
- package/lib/server/instructions/destroy.js +1 -1
- package/lib/server/instructions/index.d.ts +1 -0
- package/lib/server/instructions/index.js +1 -1
- package/lib/server/instructions/loop.d.ts +16 -0
- package/lib/server/instructions/loop.js +107 -0
- package/lib/server/instructions/parallel.js +17 -10
- package/lib/server/instructions/query.js +1 -4
- package/lib/server/instructions/request.js +1 -1
- package/lib/server/instructions/update.js +1 -1
- package/package.json +13 -13
|
@@ -126,7 +126,7 @@ function TriggerExecution() {
|
|
|
126
126
|
'x-component-props': {
|
|
127
127
|
title: _react().default.createElement(_icons().InfoOutlined, null),
|
|
128
128
|
shape: 'circle',
|
|
129
|
-
className: 'workflow-node-job-button',
|
|
129
|
+
className: (0, _css().cx)(_style.nodeJobButtonClass, 'workflow-node-job-button'),
|
|
130
130
|
type: 'primary'
|
|
131
131
|
},
|
|
132
132
|
properties: {
|
|
@@ -187,8 +187,10 @@ const TriggerConfig = () => {
|
|
|
187
187
|
editingConfig = _useState4[0],
|
|
188
188
|
setEditingConfig = _useState4[1];
|
|
189
189
|
(0, _react().useEffect)(() => {
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
if (workflow) {
|
|
191
|
+
var _workflow$title;
|
|
192
|
+
setEditingTitle((_workflow$title = workflow.title) !== null && _workflow$title !== void 0 ? _workflow$title : typeTitle);
|
|
193
|
+
}
|
|
192
194
|
}, [workflow]);
|
|
193
195
|
if (!workflow || !workflow.type) {
|
|
194
196
|
return null;
|
|
@@ -37,7 +37,9 @@ declare const _default: {
|
|
|
37
37
|
ScheduleConfig: () => JSX.Element;
|
|
38
38
|
FieldsSelect: import("react").MemoExoticComponent<import("react").FunctionComponent<Pick<any, string | number | symbol>>>;
|
|
39
39
|
};
|
|
40
|
-
|
|
40
|
+
useVariables(config: any, { types }: {
|
|
41
|
+
types: any;
|
|
42
|
+
}): any[];
|
|
41
43
|
useInitializers(config: any): SchemaInitializerItemOptions | null;
|
|
42
44
|
initializers: {
|
|
43
45
|
CollectionFieldInitializers: typeof CollectionFieldInitializers;
|
|
@@ -51,7 +51,9 @@ var _default = {
|
|
|
51
51
|
ScheduleConfig: _ScheduleConfig.ScheduleConfig,
|
|
52
52
|
FieldsSelect: _FieldsSelect.FieldsSelect
|
|
53
53
|
},
|
|
54
|
-
|
|
54
|
+
useVariables(config, {
|
|
55
|
+
types
|
|
56
|
+
}) {
|
|
55
57
|
const _useWorkflowTranslati = (0, _locale.useWorkflowTranslation)(),
|
|
56
58
|
t = _useWorkflowTranslati.t;
|
|
57
59
|
const options = [];
|
|
@@ -62,10 +64,10 @@ var _default = {
|
|
|
62
64
|
label: t('Trigger time')
|
|
63
65
|
});
|
|
64
66
|
}
|
|
67
|
+
const fieldOptions = (0, _variable.useCollectionFieldOptions)({
|
|
68
|
+
collection: config.collection
|
|
69
|
+
});
|
|
65
70
|
if (config.mode === _constants.SCHEDULE_MODE.COLLECTION_FIELD) {
|
|
66
|
-
const fieldOptions = (0, _variable.useCollectionFieldOptions)({
|
|
67
|
-
collection: config.collection
|
|
68
|
-
});
|
|
69
71
|
if (fieldOptions.length) {
|
|
70
72
|
options.push({
|
|
71
73
|
key: 'data',
|
package/lib/client/variable.d.ts
CHANGED
|
@@ -5,6 +5,32 @@ export declare type VariableOption = {
|
|
|
5
5
|
children?: VariableOptions;
|
|
6
6
|
};
|
|
7
7
|
export declare type VariableOptions = VariableOption[] | null;
|
|
8
|
+
export declare const nodesOptions: {
|
|
9
|
+
label: string;
|
|
10
|
+
value: string;
|
|
11
|
+
useOptions(options: any): VariableOption[];
|
|
12
|
+
};
|
|
13
|
+
export declare const triggerOptions: {
|
|
14
|
+
label: string;
|
|
15
|
+
value: string;
|
|
16
|
+
useOptions(options: any): VariableOption[];
|
|
17
|
+
};
|
|
18
|
+
export declare const scopeOptions: {
|
|
19
|
+
label: string;
|
|
20
|
+
value: string;
|
|
21
|
+
useOptions(options: any): VariableOption[];
|
|
22
|
+
};
|
|
23
|
+
export declare const systemOptions: {
|
|
24
|
+
label: string;
|
|
25
|
+
value: string;
|
|
26
|
+
useOptions({ types }: {
|
|
27
|
+
types: any;
|
|
28
|
+
}): {
|
|
29
|
+
key: string;
|
|
30
|
+
value: string;
|
|
31
|
+
label: string;
|
|
32
|
+
}[];
|
|
33
|
+
};
|
|
8
34
|
export declare const BaseTypeSets: {
|
|
9
35
|
boolean: Set<string>;
|
|
10
36
|
number: Set<string>;
|
|
@@ -12,7 +38,7 @@ export declare const BaseTypeSets: {
|
|
|
12
38
|
date: Set<string>;
|
|
13
39
|
};
|
|
14
40
|
export declare function filterTypedFields(fields: any, types: any, depth?: number): any;
|
|
15
|
-
export declare function useWorkflowVariableOptions(
|
|
41
|
+
export declare function useWorkflowVariableOptions(options?: {}): {
|
|
16
42
|
label: any;
|
|
17
43
|
value: any;
|
|
18
44
|
key: any;
|
package/lib/client/variable.js
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.BaseTypeSets = void 0;
|
|
7
7
|
exports.filterTypedFields = filterTypedFields;
|
|
8
|
+
exports.triggerOptions = exports.systemOptions = exports.scopeOptions = exports.nodesOptions = void 0;
|
|
8
9
|
exports.useCollectionFieldOptions = useCollectionFieldOptions;
|
|
9
10
|
exports.useWorkflowVariableOptions = useWorkflowVariableOptions;
|
|
10
11
|
function _client() {
|
|
@@ -23,20 +24,20 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
23
24
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
24
25
|
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
25
26
|
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
26
|
-
const
|
|
27
|
-
|
|
27
|
+
const nodesOptions = {
|
|
28
|
+
label: `{{t("Node result", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
28
29
|
value: '$jobsMapByNodeId',
|
|
29
|
-
options
|
|
30
|
+
useOptions(options) {
|
|
30
31
|
const current = (0, _nodes.useNodeContext)();
|
|
31
32
|
const upstreams = (0, _nodes.useAvailableUpstreams)(current);
|
|
32
|
-
const
|
|
33
|
+
const result = [];
|
|
33
34
|
upstreams.forEach(node => {
|
|
34
|
-
var _instruction$
|
|
35
|
+
var _instruction$useVaria;
|
|
35
36
|
const instruction = _nodes.instructions.get(node.type);
|
|
36
|
-
const subOptions = (_instruction$
|
|
37
|
+
const subOptions = (_instruction$useVaria = instruction.useVariables) === null || _instruction$useVaria === void 0 ? void 0 : _instruction$useVaria.call(instruction, node, options);
|
|
37
38
|
if (subOptions) {
|
|
38
39
|
var _node$title;
|
|
39
|
-
|
|
40
|
+
result.push({
|
|
40
41
|
key: node.id.toString(),
|
|
41
42
|
value: node.id.toString(),
|
|
42
43
|
label: (_node$title = node.title) !== null && _node$title !== void 0 ? _node$title : `#${node.id}`,
|
|
@@ -44,29 +45,61 @@ const VariableTypes = [{
|
|
|
44
45
|
});
|
|
45
46
|
}
|
|
46
47
|
});
|
|
47
|
-
return
|
|
48
|
+
return result;
|
|
48
49
|
}
|
|
49
|
-
}
|
|
50
|
-
|
|
50
|
+
};
|
|
51
|
+
exports.nodesOptions = nodesOptions;
|
|
52
|
+
const triggerOptions = {
|
|
53
|
+
label: `{{t("Trigger variables", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
51
54
|
value: '$context',
|
|
52
|
-
options
|
|
53
|
-
var _trigger$
|
|
55
|
+
useOptions(options) {
|
|
56
|
+
var _trigger$useVariables, _trigger$useVariables2;
|
|
54
57
|
const _useFlowContext = (0, _FlowContext.useFlowContext)(),
|
|
55
58
|
workflow = _useFlowContext.workflow;
|
|
56
59
|
const trigger = _triggers.triggers.get(workflow.type);
|
|
57
|
-
return (_trigger$
|
|
60
|
+
return (_trigger$useVariables = trigger === null || trigger === void 0 ? void 0 : (_trigger$useVariables2 = trigger.useVariables) === null || _trigger$useVariables2 === void 0 ? void 0 : _trigger$useVariables2.call(trigger, workflow.config, options)) !== null && _trigger$useVariables !== void 0 ? _trigger$useVariables : null;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
exports.triggerOptions = triggerOptions;
|
|
64
|
+
const scopeOptions = {
|
|
65
|
+
label: `{{t("Scope variables", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
66
|
+
value: '$scopes',
|
|
67
|
+
useOptions(options) {
|
|
68
|
+
const current = (0, _nodes.useNodeContext)();
|
|
69
|
+
const scopes = (0, _nodes.useUpstreamScopes)(current);
|
|
70
|
+
const result = [];
|
|
71
|
+
scopes.forEach(node => {
|
|
72
|
+
var _instruction$useScope;
|
|
73
|
+
const instruction = _nodes.instructions.get(node.type);
|
|
74
|
+
const subOptions = (_instruction$useScope = instruction.useScopeVariables) === null || _instruction$useScope === void 0 ? void 0 : _instruction$useScope.call(instruction, node, options);
|
|
75
|
+
if (subOptions) {
|
|
76
|
+
var _node$title2;
|
|
77
|
+
result.push({
|
|
78
|
+
key: node.id.toString(),
|
|
79
|
+
value: node.id.toString(),
|
|
80
|
+
label: (_node$title2 = node.title) !== null && _node$title2 !== void 0 ? _node$title2 : `#${node.id}`,
|
|
81
|
+
children: subOptions
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return result;
|
|
58
86
|
}
|
|
59
|
-
}
|
|
60
|
-
|
|
87
|
+
};
|
|
88
|
+
exports.scopeOptions = scopeOptions;
|
|
89
|
+
const systemOptions = {
|
|
90
|
+
label: `{{t("System variables", { ns: "${_locale.NAMESPACE}" })}}`,
|
|
61
91
|
value: '$system',
|
|
62
|
-
|
|
92
|
+
useOptions({
|
|
93
|
+
types
|
|
94
|
+
}) {
|
|
63
95
|
return [...(!types || types.includes('date') ? [{
|
|
64
96
|
key: 'now',
|
|
65
97
|
value: 'now',
|
|
66
98
|
label: `{{t("System time")}}`
|
|
67
99
|
}] : [])];
|
|
68
100
|
}
|
|
69
|
-
}
|
|
101
|
+
};
|
|
102
|
+
exports.systemOptions = systemOptions;
|
|
70
103
|
const BaseTypeSets = {
|
|
71
104
|
boolean: new Set(['checkbox']),
|
|
72
105
|
number: new Set(['number', 'percent']),
|
|
@@ -77,7 +110,7 @@ const BaseTypeSets = {
|
|
|
77
110
|
// { type: 'reference', options: { collection: 'attachments', multiple: false } }
|
|
78
111
|
// { type: 'reference', options: { collection: 'myExpressions', entity: false } }
|
|
79
112
|
exports.BaseTypeSets = BaseTypeSets;
|
|
80
|
-
function matchFieldType(field, type) {
|
|
113
|
+
function matchFieldType(field, type, depth) {
|
|
81
114
|
const inputType = typeof type;
|
|
82
115
|
if (inputType === 'string') {
|
|
83
116
|
var _BaseTypeSets$type;
|
|
@@ -95,7 +128,7 @@ function matchFieldType(field, type) {
|
|
|
95
128
|
}
|
|
96
129
|
}
|
|
97
130
|
if (inputType === 'function') {
|
|
98
|
-
return type(field);
|
|
131
|
+
return type(field, depth);
|
|
99
132
|
}
|
|
100
133
|
return false;
|
|
101
134
|
}
|
|
@@ -110,32 +143,28 @@ function filterTypedFields(fields, types, depth = 1) {
|
|
|
110
143
|
if (isAssociationField(field) && depth && filterTypedFields(useNormalizedFields(field.target), types, depth - 1).length) {
|
|
111
144
|
return true;
|
|
112
145
|
}
|
|
113
|
-
return types.some(type => matchFieldType(field, type));
|
|
146
|
+
return types.some(type => matchFieldType(field, type, depth));
|
|
114
147
|
});
|
|
115
148
|
}
|
|
116
|
-
function useWorkflowVariableOptions(
|
|
149
|
+
function useWorkflowVariableOptions(options = {}) {
|
|
117
150
|
const compile = (0, _client().useCompile)();
|
|
118
|
-
const
|
|
119
|
-
const opts = typeof item.
|
|
151
|
+
const result = [scopeOptions, nodesOptions, triggerOptions, systemOptions].map(item => {
|
|
152
|
+
const opts = typeof item.useOptions === 'function' ? item.useOptions(options).filter(Boolean) : null;
|
|
120
153
|
return {
|
|
121
|
-
label: compile(item.
|
|
154
|
+
label: compile(item.label),
|
|
122
155
|
value: item.value,
|
|
123
156
|
key: item.value,
|
|
124
157
|
children: compile(opts),
|
|
125
158
|
disabled: opts && !opts.length
|
|
126
159
|
};
|
|
127
160
|
});
|
|
128
|
-
return
|
|
161
|
+
return result;
|
|
129
162
|
}
|
|
130
163
|
function useNormalizedFields(collectionName) {
|
|
131
164
|
const compile = (0, _client().useCompile)();
|
|
132
165
|
const _useCollectionManager = (0, _client().useCollectionManager)(),
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
if (!collection) {
|
|
136
|
-
return [];
|
|
137
|
-
}
|
|
138
|
-
const fields = collection.fields;
|
|
166
|
+
getCollectionFields = _useCollectionManager.getCollectionFields;
|
|
167
|
+
const fields = getCollectionFields(collectionName);
|
|
139
168
|
const foreignKeyFields = [];
|
|
140
169
|
const otherFields = [];
|
|
141
170
|
fields.forEach(field => {
|
|
@@ -189,8 +218,9 @@ function useCollectionFieldOptions(options) {
|
|
|
189
218
|
_options$depth = options.depth,
|
|
190
219
|
depth = _options$depth === void 0 ? 1 : _options$depth;
|
|
191
220
|
const compile = (0, _client().useCompile)();
|
|
192
|
-
const normalizedFields =
|
|
193
|
-
const
|
|
221
|
+
const normalizedFields = useNormalizedFields(collection);
|
|
222
|
+
const computedFields = fields !== null && fields !== void 0 ? fields : normalizedFields;
|
|
223
|
+
const result = filterTypedFields(computedFields, types, depth).filter(field => !isAssociationField(field) || depth).map(field => {
|
|
194
224
|
var _field$uiSchema5;
|
|
195
225
|
const label = compile(((_field$uiSchema5 = field.uiSchema) === null || _field$uiSchema5 === void 0 ? void 0 : _field$uiSchema5.title) || field.name);
|
|
196
226
|
return {
|
|
@@ -201,7 +231,8 @@ function useCollectionFieldOptions(options) {
|
|
|
201
231
|
collection: field.target,
|
|
202
232
|
types,
|
|
203
233
|
depth: depth - 1
|
|
204
|
-
}) : null
|
|
234
|
+
}) : null,
|
|
235
|
+
field
|
|
205
236
|
};
|
|
206
237
|
});
|
|
207
238
|
return result;
|
package/lib/server/Plugin.js
CHANGED
|
@@ -169,25 +169,13 @@ class WorkflowPlugin extends _server().Plugin {
|
|
|
169
169
|
transaction
|
|
170
170
|
});
|
|
171
171
|
// NOTE: not to trigger afterUpdate hook here
|
|
172
|
-
yield workflow.
|
|
173
|
-
executed
|
|
174
|
-
}, {
|
|
175
|
-
transaction,
|
|
176
|
-
hooks: false
|
|
177
|
-
});
|
|
178
|
-
const allExecuted = yield execution.constructor.count({
|
|
179
|
-
where: {
|
|
180
|
-
key: workflow.key
|
|
181
|
-
},
|
|
172
|
+
yield workflow.increment('executed', {
|
|
182
173
|
transaction
|
|
183
174
|
});
|
|
184
|
-
yield workflow.constructor.
|
|
185
|
-
allExecuted
|
|
186
|
-
}, {
|
|
175
|
+
yield workflow.constructor.increment('allExecuted', {
|
|
187
176
|
where: {
|
|
188
177
|
key: workflow.key
|
|
189
178
|
},
|
|
190
|
-
individualHooks: true,
|
|
191
179
|
transaction
|
|
192
180
|
});
|
|
193
181
|
execution.workflow = workflow;
|
|
@@ -38,13 +38,16 @@ export default class Processor {
|
|
|
38
38
|
getBranches(node: FlowNodeModel): FlowNodeModel[];
|
|
39
39
|
findBranchStartNode(node: FlowNodeModel, parent?: FlowNodeModel): FlowNodeModel | null;
|
|
40
40
|
findBranchParentNode(node: FlowNodeModel): FlowNodeModel | null;
|
|
41
|
+
findBranchEndNode(node: FlowNodeModel): FlowNodeModel | null;
|
|
41
42
|
findBranchParentJob(job: JobModel, node: FlowNodeModel): JobModel | null;
|
|
43
|
+
findBranchLastJob(node: FlowNodeModel): JobModel | null;
|
|
42
44
|
getScope(node?: any): {
|
|
43
45
|
$context: any;
|
|
44
46
|
$jobsMapByNodeId: {
|
|
45
47
|
[key: number]: any;
|
|
46
48
|
};
|
|
47
49
|
$system: {};
|
|
50
|
+
$scopes: {};
|
|
48
51
|
};
|
|
49
52
|
getParsedValue(value: any, node?: any): any;
|
|
50
53
|
}
|
package/lib/server/Processor.js
CHANGED
|
@@ -193,7 +193,7 @@ class Processor {
|
|
|
193
193
|
});
|
|
194
194
|
if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
|
|
195
195
|
// run next node
|
|
196
|
-
_this6.logger.debug(`run next node (${node.
|
|
196
|
+
_this6.logger.debug(`run next node (${node.downstreamId})`);
|
|
197
197
|
return _this6.run(node.downstream, savedJob);
|
|
198
198
|
}
|
|
199
199
|
// all nodes in scope have been executed
|
|
@@ -215,7 +215,7 @@ class Processor {
|
|
|
215
215
|
end(node, job) {
|
|
216
216
|
var _this8 = this;
|
|
217
217
|
return _asyncToGenerator(function* () {
|
|
218
|
-
_this8.logger.debug(`branch ended at node (${node.id})
|
|
218
|
+
_this8.logger.debug(`branch ended at node (${node.id})`);
|
|
219
219
|
const parentNode = _this8.findBranchParentNode(node);
|
|
220
220
|
// no parent, means on main flow
|
|
221
221
|
if (parentNode) {
|
|
@@ -314,6 +314,14 @@ class Processor {
|
|
|
314
314
|
}
|
|
315
315
|
return null;
|
|
316
316
|
}
|
|
317
|
+
findBranchEndNode(node) {
|
|
318
|
+
for (let n = node; n; n = n.downstream) {
|
|
319
|
+
if (!n.downstream) {
|
|
320
|
+
return n;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return null;
|
|
324
|
+
}
|
|
317
325
|
findBranchParentJob(job, node) {
|
|
318
326
|
for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
|
|
319
327
|
if (j.nodeId === node.id) {
|
|
@@ -322,6 +330,15 @@ class Processor {
|
|
|
322
330
|
}
|
|
323
331
|
return null;
|
|
324
332
|
}
|
|
333
|
+
findBranchLastJob(node) {
|
|
334
|
+
for (let n = this.findBranchEndNode(node); n && n !== node.upstream; n = n.upstream) {
|
|
335
|
+
const jobs = Array.from(this.jobsMap.values()).filter(item => item.nodeId === n.id).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
336
|
+
if (jobs.length) {
|
|
337
|
+
return jobs[jobs.length - 1];
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
325
342
|
getScope(node) {
|
|
326
343
|
const systemFns = {};
|
|
327
344
|
const scope = {
|
|
@@ -342,10 +359,20 @@ class Processor {
|
|
|
342
359
|
} finally {
|
|
343
360
|
_iterator.f();
|
|
344
361
|
}
|
|
362
|
+
const $scopes = {};
|
|
363
|
+
if (node) {
|
|
364
|
+
for (let n = this.findBranchParentNode(node); n; n = this.findBranchParentNode(n)) {
|
|
365
|
+
const instruction = this.options.plugin.instructions.get(n.type);
|
|
366
|
+
if (typeof instruction.getScope === 'function') {
|
|
367
|
+
$scopes[n.id] = instruction.getScope(n, this.jobsMapByNodeId[n.id], this);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
345
371
|
return {
|
|
346
372
|
$context: this.execution.context,
|
|
347
373
|
$jobsMapByNodeId: this.jobsMapByNodeId,
|
|
348
|
-
$system: systemFns
|
|
374
|
+
$system: systemFns,
|
|
375
|
+
$scopes
|
|
349
376
|
};
|
|
350
377
|
}
|
|
351
378
|
getParsedValue(value, node) {
|
|
@@ -132,12 +132,12 @@ function migrateConfig(config, oldToNew) {
|
|
|
132
132
|
case 'array':
|
|
133
133
|
return value.map(item => migrate(item));
|
|
134
134
|
case 'string':
|
|
135
|
-
return value.replace(/(
|
|
135
|
+
return value.replace(/({{\$jobsMapByNodeId|{{\$scopes)\.([\w-]+)/g, (_, jobVar, oldNodeId) => {
|
|
136
136
|
const newNode = oldToNew.get(Number.parseInt(oldNodeId, 10));
|
|
137
137
|
if (!newNode) {
|
|
138
138
|
throw new Error('node configurated for result is not existed');
|
|
139
139
|
}
|
|
140
|
-
return
|
|
140
|
+
return `${jobVar}.${newNode.id}`;
|
|
141
141
|
});
|
|
142
142
|
default:
|
|
143
143
|
return value;
|
|
@@ -64,7 +64,8 @@ function _default() {
|
|
|
64
64
|
foreignKey: 'key',
|
|
65
65
|
sourceKey: 'key',
|
|
66
66
|
// NOTE: no constraints needed here because tricky self-referencing
|
|
67
|
-
constraints: false
|
|
67
|
+
constraints: false,
|
|
68
|
+
onDelete: 'NO ACTION'
|
|
68
69
|
}],
|
|
69
70
|
// NOTE: use unique index for avoiding deadlock in mysql when setCurrent
|
|
70
71
|
indexes: [{
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _sequelize() {
|
|
8
|
+
const data = require("sequelize");
|
|
9
|
+
_sequelize = function _sequelize() {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
var _constants = require("../constants");
|
|
15
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
16
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
19
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
21
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
22
|
+
const aggregators = {
|
|
23
|
+
count: 'count',
|
|
24
|
+
sum: 'sum',
|
|
25
|
+
avg: 'avg',
|
|
26
|
+
min: 'min',
|
|
27
|
+
max: 'max'
|
|
28
|
+
};
|
|
29
|
+
var _default = {
|
|
30
|
+
run(node, input, processor) {
|
|
31
|
+
return _asyncToGenerator(function* () {
|
|
32
|
+
const _node$config = node.config,
|
|
33
|
+
aggregator = _node$config.aggregator,
|
|
34
|
+
associated = _node$config.associated,
|
|
35
|
+
collection = _node$config.collection,
|
|
36
|
+
_node$config$associat = _node$config.association,
|
|
37
|
+
association = _node$config$associat === void 0 ? {} : _node$config$associat,
|
|
38
|
+
_node$config$params = _node$config.params,
|
|
39
|
+
params = _node$config$params === void 0 ? {} : _node$config$params;
|
|
40
|
+
const options = processor.getParsedValue(params);
|
|
41
|
+
const database = node.constructor.database;
|
|
42
|
+
const repo = associated ? database.getRepository(`${association === null || association === void 0 ? void 0 : association.associatedCollection}.${association.name}`, processor.getParsedValue(association === null || association === void 0 ? void 0 : association.associatedKey)) : database.getRepository(collection);
|
|
43
|
+
if (!options.dataType && aggregator === 'avg') {
|
|
44
|
+
options.dataType = _sequelize().DataTypes.DOUBLE;
|
|
45
|
+
}
|
|
46
|
+
const result = yield repo.aggregate(_objectSpread(_objectSpread({}, options), {}, {
|
|
47
|
+
method: aggregators[aggregator],
|
|
48
|
+
transaction: processor.transaction
|
|
49
|
+
}));
|
|
50
|
+
return {
|
|
51
|
+
result: options.dataType === _sequelize().DataTypes.DOUBLE ? Number(result) : result,
|
|
52
|
+
status: _constants.JOB_STATUS.RESOLVED
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
exports.default = _default;
|
|
@@ -32,7 +32,7 @@ var _default = {
|
|
|
32
32
|
engine = _node$config$engine === void 0 ? 'math.js' : _node$config$engine,
|
|
33
33
|
_node$config$expressi = _node$config.expression,
|
|
34
34
|
expression = _node$config$expressi === void 0 ? '' : _node$config$expressi;
|
|
35
|
-
let scope = processor.getScope();
|
|
35
|
+
let scope = processor.getScope(node);
|
|
36
36
|
if (dynamic) {
|
|
37
37
|
var _parse, _parse2, _node$config$scope;
|
|
38
38
|
const parsed = (_parse = (0, _utils().parse)(dynamic)(scope)) !== null && _parse !== void 0 ? _parse : {};
|
|
@@ -108,7 +108,7 @@ var _default = {
|
|
|
108
108
|
const evaluator = _evaluators().evaluators.get(engine);
|
|
109
109
|
let result = true;
|
|
110
110
|
try {
|
|
111
|
-
result = evaluator ? evaluator(expression, processor.getScope()) : logicCalculate(processor.getParsedValue(calculation));
|
|
111
|
+
result = evaluator ? evaluator(expression, processor.getScope()) : logicCalculate(processor.getParsedValue(calculation, node));
|
|
112
112
|
} catch (e) {
|
|
113
113
|
return {
|
|
114
114
|
result: e.toString(),
|
|
@@ -28,7 +28,7 @@ var _default = {
|
|
|
28
28
|
const _node$constructor$dat = node.constructor.database.getCollection(collection),
|
|
29
29
|
repository = _node$constructor$dat.repository,
|
|
30
30
|
model = _node$constructor$dat.model;
|
|
31
|
-
const options = processor.getParsedValue(params);
|
|
31
|
+
const options = processor.getParsedValue(params, node);
|
|
32
32
|
const result = yield repository.create(_objectSpread(_objectSpread({}, options), {}, {
|
|
33
33
|
context: {
|
|
34
34
|
executionId: processor.execution.id
|
|
@@ -20,7 +20,7 @@ var _default = {
|
|
|
20
20
|
_node$config$params = _node$config.params,
|
|
21
21
|
params = _node$config$params === void 0 ? {} : _node$config$params;
|
|
22
22
|
const repo = node.constructor.database.getRepository(collection);
|
|
23
|
-
const options = processor.getParsedValue(params);
|
|
23
|
+
const options = processor.getParsedValue(params, node);
|
|
24
24
|
const result = yield repo.destroy(_objectSpread(_objectSpread({}, options), {}, {
|
|
25
25
|
context: {
|
|
26
26
|
executionId: processor.execution.id
|
|
@@ -11,6 +11,7 @@ export declare type Runner = (node: FlowNodeModel, input: any, processor: Proces
|
|
|
11
11
|
export interface Instruction {
|
|
12
12
|
run: Runner;
|
|
13
13
|
resume?: Runner;
|
|
14
|
+
getScope?: (node: FlowNodeModel, job: any, processor: Processor) => any;
|
|
14
15
|
}
|
|
15
16
|
declare type InstructionConstructor<T> = {
|
|
16
17
|
new (p: Plugin): T;
|
|
@@ -32,7 +32,7 @@ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typ
|
|
|
32
32
|
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
33
33
|
function _default(plugin, more = {}) {
|
|
34
34
|
const instructions = plugin.instructions;
|
|
35
|
-
const natives = ['calculation', 'condition', 'parallel', 'delay', 'manual', 'query', 'create', 'update', 'destroy', 'request'].reduce((result, key) => Object.assign(result, {
|
|
35
|
+
const natives = ['calculation', 'condition', 'parallel', 'loop', 'delay', 'manual', 'query', 'create', 'update', 'destroy', 'aggregate', 'request'].reduce((result, key) => Object.assign(result, {
|
|
36
36
|
[key]: (0, _utils().requireModule)(_path().default.isAbsolute(key) ? key : _path().default.join(__dirname, key))
|
|
37
37
|
}), {});
|
|
38
38
|
for (var _i = 0, _Object$entries = Object.entries(_objectSpread(_objectSpread({}, more), natives)); _i < _Object$entries.length; _i++) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import FlowNodeModel from '../models/FlowNode';
|
|
2
|
+
import JobModel from '../models/Job';
|
|
3
|
+
import Processor from '../Processor';
|
|
4
|
+
declare const _default: {
|
|
5
|
+
run(node: FlowNodeModel, prevJob: JobModel, processor: Processor): Promise<{
|
|
6
|
+
status: number;
|
|
7
|
+
result: number;
|
|
8
|
+
}>;
|
|
9
|
+
resume(node: FlowNodeModel, branchJob: any, processor: Processor): Promise<JobModel>;
|
|
10
|
+
getScope(node: any, index: any, processor: any): {
|
|
11
|
+
item: any;
|
|
12
|
+
index: any;
|
|
13
|
+
length: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export default _default;
|