@nocobase/plugin-workflow 0.9.2-alpha.4 → 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/FieldsSelect.js +2 -1
- 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 +35 -60
- package/lib/client/nodes/condition.d.ts +2 -6
- package/lib/client/nodes/condition.js +4 -3
- package/lib/client/nodes/create.d.ts +6 -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 +3 -2
- package/lib/client/nodes/destroy.js +1 -0
- package/lib/client/nodes/index.d.ts +5 -2
- package/lib/client/nodes/index.js +96 -105
- 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/WorkflowTodo.js +1 -8
- 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 +13 -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 +3 -2
- package/lib/client/nodes/update.js +1 -0
- package/lib/client/schemas/collection.d.ts +2 -2
- package/lib/client/schemas/collection.js +5 -5
- package/lib/client/style.d.ts +1 -0
- package/lib/client/style.js +40 -26
- package/lib/client/triggers/collection.d.ts +4 -11
- package/lib/client/triggers/collection.js +7 -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 +66 -35
- package/lib/server/Plugin.d.ts +5 -2
- package/lib/server/Plugin.js +2 -14
- package/lib/server/Processor.d.ts +3 -0
- package/lib/server/Processor.js +34 -8
- package/lib/server/actions/workflows.js +2 -2
- package/lib/server/collections/workflows.js +2 -1
- package/lib/server/functions/index.d.ts +7 -1
- package/lib/server/instructions/aggregate.d.ts +9 -0
- package/lib/server/instructions/aggregate.js +57 -0
- package/lib/server/instructions/calculation.js +6 -7
- 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 -14
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,11 +110,11 @@ 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;
|
|
84
|
-
return
|
|
117
|
+
return (_BaseTypeSets$type = BaseTypeSets[type]) === null || _BaseTypeSets$type === void 0 ? void 0 : _BaseTypeSets$type.has(field.interface);
|
|
85
118
|
}
|
|
86
119
|
if (inputType === 'object' && type.type === 'reference') {
|
|
87
120
|
if (isAssociationField(field)) {
|
|
@@ -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.d.ts
CHANGED
|
@@ -5,12 +5,13 @@ import ExecutionModel from './models/Execution';
|
|
|
5
5
|
import WorkflowModel from './models/Workflow';
|
|
6
6
|
import Processor from './Processor';
|
|
7
7
|
import { Trigger } from './triggers';
|
|
8
|
+
import { CustomFunction } from './functions';
|
|
8
9
|
import { Logger } from '@nocobase/logger';
|
|
9
10
|
declare type ID = number | string;
|
|
10
11
|
export default class WorkflowPlugin extends Plugin {
|
|
11
12
|
instructions: Registry<Instruction>;
|
|
12
13
|
triggers: Registry<Trigger>;
|
|
13
|
-
functions: Registry<
|
|
14
|
+
functions: Registry<CustomFunction>;
|
|
14
15
|
private executing;
|
|
15
16
|
private pending;
|
|
16
17
|
private events;
|
|
@@ -19,7 +20,9 @@ export default class WorkflowPlugin extends Plugin {
|
|
|
19
20
|
onBeforeSave: (instance: WorkflowModel, options: any) => Promise<void>;
|
|
20
21
|
load(): Promise<void>;
|
|
21
22
|
toggle(workflow: WorkflowModel, enable?: boolean): void;
|
|
22
|
-
trigger(workflow: WorkflowModel, context:
|
|
23
|
+
trigger(workflow: WorkflowModel, context: {
|
|
24
|
+
[key: string]: any;
|
|
25
|
+
}, options?: {
|
|
23
26
|
context?: any;
|
|
24
27
|
}): void;
|
|
25
28
|
private prepare;
|
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
|
@@ -18,15 +18,14 @@ function _evaluators() {
|
|
|
18
18
|
};
|
|
19
19
|
return data;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
22
|
-
const data =
|
|
23
|
-
|
|
21
|
+
function _utils() {
|
|
22
|
+
const data = require("@nocobase/utils");
|
|
23
|
+
_utils = function _utils() {
|
|
24
24
|
return data;
|
|
25
25
|
};
|
|
26
26
|
return data;
|
|
27
27
|
}
|
|
28
28
|
var _constants = require("./constants");
|
|
29
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
30
29
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e2) { throw _e2; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e3) { didErr = true; err = _e3; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
31
30
|
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; }
|
|
32
31
|
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; }
|
|
@@ -194,7 +193,7 @@ class Processor {
|
|
|
194
193
|
});
|
|
195
194
|
if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
|
|
196
195
|
// run next node
|
|
197
|
-
_this6.logger.debug(`run next node (${node.
|
|
196
|
+
_this6.logger.debug(`run next node (${node.downstreamId})`);
|
|
198
197
|
return _this6.run(node.downstream, savedJob);
|
|
199
198
|
}
|
|
200
199
|
// all nodes in scope have been executed
|
|
@@ -216,7 +215,7 @@ class Processor {
|
|
|
216
215
|
end(node, job) {
|
|
217
216
|
var _this8 = this;
|
|
218
217
|
return _asyncToGenerator(function* () {
|
|
219
|
-
_this8.logger.debug(`branch ended at node (${node.id})
|
|
218
|
+
_this8.logger.debug(`branch ended at node (${node.id})`);
|
|
220
219
|
const parentNode = _this8.findBranchParentNode(node);
|
|
221
220
|
// no parent, means on main flow
|
|
222
221
|
if (parentNode) {
|
|
@@ -315,6 +314,14 @@ class Processor {
|
|
|
315
314
|
}
|
|
316
315
|
return null;
|
|
317
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
|
+
}
|
|
318
325
|
findBranchParentJob(job, node) {
|
|
319
326
|
for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
|
|
320
327
|
if (j.nodeId === node.id) {
|
|
@@ -323,6 +330,15 @@ class Processor {
|
|
|
323
330
|
}
|
|
324
331
|
return null;
|
|
325
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
|
+
}
|
|
326
342
|
getScope(node) {
|
|
327
343
|
const systemFns = {};
|
|
328
344
|
const scope = {
|
|
@@ -343,14 +359,24 @@ class Processor {
|
|
|
343
359
|
} finally {
|
|
344
360
|
_iterator.f();
|
|
345
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
|
+
}
|
|
346
371
|
return {
|
|
347
372
|
$context: this.execution.context,
|
|
348
373
|
$jobsMapByNodeId: this.jobsMapByNodeId,
|
|
349
|
-
$system: systemFns
|
|
374
|
+
$system: systemFns,
|
|
375
|
+
$scopes
|
|
350
376
|
};
|
|
351
377
|
}
|
|
352
378
|
getParsedValue(value, node) {
|
|
353
|
-
const template = (0,
|
|
379
|
+
const template = (0, _utils().parse)(value);
|
|
354
380
|
const scope = this.getScope(node);
|
|
355
381
|
template.parameters.forEach(({
|
|
356
382
|
key
|
|
@@ -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: [{
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import Plugin from '..';
|
|
2
|
+
import ExecutionModel from '../models/Execution';
|
|
3
|
+
import FlowNodeModel from '../models/FlowNode';
|
|
4
|
+
export declare type CustomFunction = (this: {
|
|
5
|
+
execution: ExecutionModel;
|
|
6
|
+
node?: FlowNodeModel;
|
|
7
|
+
}) => any;
|
|
2
8
|
export default function ({ functions }: Plugin, more?: {
|
|
3
|
-
[key: string]:
|
|
9
|
+
[key: string]: CustomFunction;
|
|
4
10
|
}): void;
|
|
@@ -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;
|
|
@@ -11,15 +11,14 @@ function _evaluators() {
|
|
|
11
11
|
};
|
|
12
12
|
return data;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
15
|
-
const data =
|
|
16
|
-
|
|
14
|
+
function _utils() {
|
|
15
|
+
const data = require("@nocobase/utils");
|
|
16
|
+
_utils = function _utils() {
|
|
17
17
|
return data;
|
|
18
18
|
};
|
|
19
19
|
return data;
|
|
20
20
|
}
|
|
21
21
|
var _constants = require("../constants");
|
|
22
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
23
22
|
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); } }
|
|
24
23
|
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); }); }; }
|
|
25
24
|
var _default = {
|
|
@@ -33,13 +32,13 @@ var _default = {
|
|
|
33
32
|
engine = _node$config$engine === void 0 ? 'math.js' : _node$config$engine,
|
|
34
33
|
_node$config$expressi = _node$config.expression,
|
|
35
34
|
expression = _node$config$expressi === void 0 ? '' : _node$config$expressi;
|
|
36
|
-
let scope = processor.getScope();
|
|
35
|
+
let scope = processor.getScope(node);
|
|
37
36
|
if (dynamic) {
|
|
38
37
|
var _parse, _parse2, _node$config$scope;
|
|
39
|
-
const parsed = (_parse = (0,
|
|
38
|
+
const parsed = (_parse = (0, _utils().parse)(dynamic)(scope)) !== null && _parse !== void 0 ? _parse : {};
|
|
40
39
|
engine = parsed.engine;
|
|
41
40
|
expression = parsed.expression;
|
|
42
|
-
scope = (_parse2 = (0,
|
|
41
|
+
scope = (_parse2 = (0, _utils().parse)((_node$config$scope = node.config.scope) !== null && _node$config$scope !== void 0 ? _node$config$scope : '')(scope)) !== null && _parse2 !== void 0 ? _parse2 : {};
|
|
43
42
|
}
|
|
44
43
|
const evaluator = _evaluators().evaluators.get(engine);
|
|
45
44
|
try {
|
|
@@ -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;
|