@nocobase/plugin-workflow 0.7.0-alpha.83 → 0.7.1-alpha.5
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/Plugin.d.ts +18 -0
- package/lib/Plugin.js +285 -0
- package/lib/Processor.d.ts +40 -0
- package/lib/Processor.js +440 -0
- package/lib/actions/workflows.d.ts +1 -2
- package/lib/actions/workflows.js +13 -87
- package/lib/calculators/index.d.ts +2 -2
- package/lib/calculators/index.js +4 -4
- package/lib/collections/executions.js +7 -15
- package/lib/collections/jobs.js +7 -26
- package/lib/collections/workflows.d.ts +1 -2
- package/lib/collections/workflows.js +67 -67
- package/lib/index.d.ts +4 -3
- package/lib/index.js +24 -10
- package/lib/instructions/calculation.d.ts +1 -1
- package/lib/instructions/calculation.js +4 -6
- package/lib/instructions/condition.d.ts +2 -2
- package/lib/instructions/condition.js +15 -19
- package/lib/instructions/create.d.ts +1 -1
- package/lib/instructions/create.js +8 -12
- package/lib/instructions/delay.d.ts +14 -0
- package/lib/instructions/delay.js +138 -0
- package/lib/instructions/destroy.d.ts +1 -1
- package/lib/instructions/destroy.js +8 -12
- package/lib/instructions/index.d.ts +11 -8
- package/lib/instructions/index.js +43 -13
- package/lib/instructions/parallel.d.ts +3 -3
- package/lib/instructions/parallel.js +15 -19
- package/lib/instructions/prompt.d.ts +2 -2
- package/lib/instructions/prompt.js +2 -2
- package/lib/instructions/query.d.ts +2 -1
- package/lib/instructions/query.js +9 -13
- package/lib/instructions/update.d.ts +2 -2
- package/lib/instructions/update.js +10 -14
- package/lib/models/Execution.d.ts +2 -33
- package/lib/models/Execution.js +2 -397
- package/lib/models/Workflow.d.ts +2 -2
- package/lib/models/Workflow.js +1 -81
- package/lib/triggers/collection.d.ts +2 -6
- package/lib/triggers/collection.js +62 -27
- package/lib/triggers/index.d.ts +11 -4
- package/lib/triggers/index.js +52 -5
- package/lib/triggers/schedule.d.ts +4 -7
- package/lib/triggers/schedule.js +205 -135
- package/package.json +8 -9
- package/lib/server.d.ts +0 -10
- package/lib/server.js +0 -124
package/lib/models/Execution.js
CHANGED
|
@@ -15,401 +15,6 @@ function _database() {
|
|
|
15
15
|
return data;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
const data = _interopRequireDefault(require("json-templates"));
|
|
18
|
+
class ExecutionModel extends _database().Model {}
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
return data;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
return data;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
var _constants = require("../constants");
|
|
29
|
-
|
|
30
|
-
var _instructions = _interopRequireDefault(require("../instructions"));
|
|
31
|
-
|
|
32
|
-
var _calculators = _interopRequireDefault(require("../calculators"));
|
|
33
|
-
|
|
34
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
|
-
|
|
36
|
-
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; } } }; }
|
|
37
|
-
|
|
38
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
39
|
-
|
|
40
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
41
|
-
|
|
42
|
-
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
43
|
-
|
|
44
|
-
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
45
|
-
|
|
46
|
-
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
47
|
-
|
|
48
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
49
|
-
|
|
50
|
-
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; }
|
|
51
|
-
|
|
52
|
-
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; }
|
|
53
|
-
|
|
54
|
-
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
55
|
-
|
|
56
|
-
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); } }
|
|
57
|
-
|
|
58
|
-
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); }); }; }
|
|
59
|
-
|
|
60
|
-
class ExecutionModel extends _database().Model {
|
|
61
|
-
constructor(...args) {
|
|
62
|
-
super(...args);
|
|
63
|
-
this.options = void 0;
|
|
64
|
-
this.tx = void 0;
|
|
65
|
-
this.nodes = [];
|
|
66
|
-
this.nodesMap = new Map();
|
|
67
|
-
this.jobsMap = new Map();
|
|
68
|
-
this.jobsMapByNodeId = {};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// make dual linked nodes list then cache
|
|
72
|
-
makeNodes(nodes = []) {
|
|
73
|
-
this.nodes = nodes;
|
|
74
|
-
nodes.forEach(node => {
|
|
75
|
-
this.nodesMap.set(node.id, node);
|
|
76
|
-
});
|
|
77
|
-
nodes.forEach(node => {
|
|
78
|
-
if (node.upstreamId) {
|
|
79
|
-
node.upstream = this.nodesMap.get(node.upstreamId);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (node.downstreamId) {
|
|
83
|
-
node.downstream = this.nodesMap.get(node.downstreamId);
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
makeJobs(jobs) {
|
|
89
|
-
jobs.forEach(job => {
|
|
90
|
-
this.jobsMap.set(job.id, job); // TODO: should consider cycle, and from previous job
|
|
91
|
-
|
|
92
|
-
this.jobsMapByNodeId[job.nodeId] = job.result;
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
getTransaction() {
|
|
97
|
-
var _this = this;
|
|
98
|
-
|
|
99
|
-
return _asyncToGenerator(function* () {
|
|
100
|
-
const sequelize = _this.constructor.database.sequelize;
|
|
101
|
-
|
|
102
|
-
if (!_this.useTransaction) {
|
|
103
|
-
return undefined;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const options = _this.options; // @ts-ignore
|
|
107
|
-
|
|
108
|
-
const transaction = options.transaction && !options.transaction.finished ? options.transaction : sequelize.transaction(); // @ts-ignore
|
|
109
|
-
|
|
110
|
-
if (_this.transaction !== transaction.id) {
|
|
111
|
-
// @ts-ignore
|
|
112
|
-
yield _this.update({
|
|
113
|
-
transaction: transaction.id
|
|
114
|
-
}, {
|
|
115
|
-
transaction
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
return transaction;
|
|
120
|
-
})();
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
prepare(options, commit = false) {
|
|
124
|
-
var _this2 = this;
|
|
125
|
-
|
|
126
|
-
return _asyncToGenerator(function* () {
|
|
127
|
-
_this2.options = options || {};
|
|
128
|
-
const transaction = yield _this2.getTransaction();
|
|
129
|
-
_this2.tx = transaction;
|
|
130
|
-
|
|
131
|
-
if (!_this2.workflow) {
|
|
132
|
-
_this2.workflow = yield _this2.getWorkflow({
|
|
133
|
-
transaction
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const nodes = yield _this2.workflow.getNodes({
|
|
138
|
-
transaction
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
_this2.makeNodes(nodes);
|
|
142
|
-
|
|
143
|
-
const jobs = yield _this2.getJobs({
|
|
144
|
-
order: [['id', 'ASC']],
|
|
145
|
-
transaction
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
_this2.makeJobs(jobs);
|
|
149
|
-
|
|
150
|
-
if (commit) {
|
|
151
|
-
yield _this2.commit();
|
|
152
|
-
}
|
|
153
|
-
})();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
start(options) {
|
|
157
|
-
var _this3 = this;
|
|
158
|
-
|
|
159
|
-
return _asyncToGenerator(function* () {
|
|
160
|
-
if (_this3.status !== _constants.EXECUTION_STATUS.STARTED) {
|
|
161
|
-
throw new Error(`execution was ended with status ${_this3.status}`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
yield _this3.prepare(options);
|
|
165
|
-
|
|
166
|
-
if (_this3.nodes.length) {
|
|
167
|
-
const head = _this3.nodes.find(item => !item.upstream);
|
|
168
|
-
|
|
169
|
-
yield _this3.run(head, {
|
|
170
|
-
result: _this3.context
|
|
171
|
-
});
|
|
172
|
-
} else {
|
|
173
|
-
yield _this3.exit(null);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
yield _this3.commit();
|
|
177
|
-
})();
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
resume(job, options) {
|
|
181
|
-
var _this4 = this;
|
|
182
|
-
|
|
183
|
-
return _asyncToGenerator(function* () {
|
|
184
|
-
if (_this4.status !== _constants.EXECUTION_STATUS.STARTED) {
|
|
185
|
-
throw new Error(`execution was ended with status ${_this4.status}`);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
yield _this4.prepare(options);
|
|
189
|
-
|
|
190
|
-
const node = _this4.nodesMap.get(job.nodeId);
|
|
191
|
-
|
|
192
|
-
yield _this4.recall(node, job);
|
|
193
|
-
yield _this4.commit();
|
|
194
|
-
})();
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
commit() {
|
|
198
|
-
var _this5 = this;
|
|
199
|
-
|
|
200
|
-
return _asyncToGenerator(function* () {
|
|
201
|
-
// @ts-ignore
|
|
202
|
-
if (_this5.tx && (!_this5.options.transaction || _this5.options.transaction.finished)) {
|
|
203
|
-
yield _this5.tx.commit();
|
|
204
|
-
}
|
|
205
|
-
})();
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
exec(instruction, node, prevJob) {
|
|
209
|
-
var _this6 = this;
|
|
210
|
-
|
|
211
|
-
return _asyncToGenerator(function* () {
|
|
212
|
-
let job;
|
|
213
|
-
|
|
214
|
-
try {
|
|
215
|
-
// call instruction to get result and status
|
|
216
|
-
job = yield instruction.call(node, prevJob, _this6);
|
|
217
|
-
|
|
218
|
-
if (!job) {
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
} catch (err) {
|
|
222
|
-
// for uncaught error, set to rejected
|
|
223
|
-
job = {
|
|
224
|
-
result: err instanceof Error ? {
|
|
225
|
-
message: err.message,
|
|
226
|
-
stack: process.env.NODE_ENV === 'production' ? [] : err.stack
|
|
227
|
-
} : err,
|
|
228
|
-
status: _constants.JOB_STATUS.REJECTED
|
|
229
|
-
}; // if previous job is from resuming
|
|
230
|
-
|
|
231
|
-
if (prevJob && prevJob.nodeId === node.id) {
|
|
232
|
-
prevJob.set(job);
|
|
233
|
-
job = prevJob;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
let savedJob; // TODO(optimize): many checking of resuming or new could be improved
|
|
238
|
-
// could be implemented separately in exec() / resume()
|
|
239
|
-
|
|
240
|
-
if (job instanceof _database().Model) {
|
|
241
|
-
savedJob = yield job.save({
|
|
242
|
-
transaction: _this6.tx
|
|
243
|
-
});
|
|
244
|
-
} else {
|
|
245
|
-
const upstreamId = prevJob instanceof _database().Model ? prevJob.get('id') : null;
|
|
246
|
-
savedJob = yield _this6.saveJob(_objectSpread({
|
|
247
|
-
nodeId: node.id,
|
|
248
|
-
upstreamId
|
|
249
|
-
}, job));
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (savedJob.status === _constants.JOB_STATUS.RESOLVED && node.downstream) {
|
|
253
|
-
// run next node
|
|
254
|
-
return _this6.run(node.downstream, savedJob);
|
|
255
|
-
} // all nodes in scope have been executed
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return _this6.end(node, savedJob);
|
|
259
|
-
})();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
run(node, input) {
|
|
263
|
-
var _this7 = this;
|
|
264
|
-
|
|
265
|
-
return _asyncToGenerator(function* () {
|
|
266
|
-
const _instructions$get = _instructions.default.get(node.type),
|
|
267
|
-
run = _instructions$get.run;
|
|
268
|
-
|
|
269
|
-
if (typeof run !== 'function') {
|
|
270
|
-
return Promise.reject(new Error('`run` should be implemented for customized execution of the node'));
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
return _this7.exec(run, node, input);
|
|
274
|
-
})();
|
|
275
|
-
} // parent node should take over the control
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
end(node, job) {
|
|
279
|
-
const parentNode = this.findBranchParentNode(node); // no parent, means on main flow
|
|
280
|
-
|
|
281
|
-
if (parentNode) {
|
|
282
|
-
return this.recall(parentNode, job);
|
|
283
|
-
} // really done for all nodes
|
|
284
|
-
// * should mark execution as done with last job status
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
return this.exit(job);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
recall(node, job) {
|
|
291
|
-
var _this8 = this;
|
|
292
|
-
|
|
293
|
-
return _asyncToGenerator(function* () {
|
|
294
|
-
const _instructions$get2 = _instructions.default.get(node.type),
|
|
295
|
-
resume = _instructions$get2.resume;
|
|
296
|
-
|
|
297
|
-
if (typeof resume !== 'function') {
|
|
298
|
-
return Promise.reject(new Error('`resume` should be implemented because the node made branch'));
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
return _this8.exec(resume, node, job);
|
|
302
|
-
})();
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
exit(job) {
|
|
306
|
-
var _this9 = this;
|
|
307
|
-
|
|
308
|
-
return _asyncToGenerator(function* () {
|
|
309
|
-
const status = job ? ExecutionModel.StatusMap[job.status] : _constants.EXECUTION_STATUS.RESOLVED;
|
|
310
|
-
yield _this9.update({
|
|
311
|
-
status
|
|
312
|
-
}, {
|
|
313
|
-
transaction: _this9.tx
|
|
314
|
-
});
|
|
315
|
-
return null;
|
|
316
|
-
})();
|
|
317
|
-
} // TODO(optimize)
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
saveJob(payload) {
|
|
321
|
-
var _this10 = this;
|
|
322
|
-
|
|
323
|
-
return _asyncToGenerator(function* () {
|
|
324
|
-
const database = _this10.constructor.database;
|
|
325
|
-
|
|
326
|
-
const _database$getCollecti = database.getCollection('jobs'),
|
|
327
|
-
model = _database$getCollecti.model;
|
|
328
|
-
|
|
329
|
-
const _yield$model$upsert = yield model.upsert(_objectSpread(_objectSpread({}, payload), {}, {
|
|
330
|
-
executionId: _this10.id
|
|
331
|
-
}), {
|
|
332
|
-
transaction: _this10.tx
|
|
333
|
-
}),
|
|
334
|
-
_yield$model$upsert2 = _slicedToArray(_yield$model$upsert, 1),
|
|
335
|
-
job = _yield$model$upsert2[0];
|
|
336
|
-
|
|
337
|
-
_this10.jobsMap.set(job.id, job);
|
|
338
|
-
|
|
339
|
-
_this10.jobsMapByNodeId[job.nodeId] = job.result;
|
|
340
|
-
return job;
|
|
341
|
-
})();
|
|
342
|
-
} // find the first node in current branch
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
findBranchStartNode(node) {
|
|
346
|
-
for (let n = node; n; n = n.upstream) {
|
|
347
|
-
if (n.branchIndex !== null) {
|
|
348
|
-
return n;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return null;
|
|
353
|
-
} // find the node start current branch
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
findBranchParentNode(node) {
|
|
357
|
-
for (let n = node; n; n = n.upstream) {
|
|
358
|
-
if (n.branchIndex !== null) {
|
|
359
|
-
return n.upstream;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
findBranchParentJob(job, node) {
|
|
367
|
-
for (let j = job; j; j = this.jobsMap.get(j.upstreamId)) {
|
|
368
|
-
if (j.nodeId === node.id) {
|
|
369
|
-
return j;
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
return null;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
getParsedValue(value, node) {
|
|
377
|
-
const injectedFns = {};
|
|
378
|
-
const scope = {
|
|
379
|
-
execution: this,
|
|
380
|
-
node
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
var _iterator = _createForOfIteratorHelper(_calculators.default.getEntities()),
|
|
384
|
-
_step;
|
|
385
|
-
|
|
386
|
-
try {
|
|
387
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
388
|
-
let _step$value = _slicedToArray(_step.value, 2),
|
|
389
|
-
name = _step$value[0],
|
|
390
|
-
fn = _step$value[1];
|
|
391
|
-
|
|
392
|
-
injectedFns[name] = fn.bind(scope);
|
|
393
|
-
}
|
|
394
|
-
} catch (err) {
|
|
395
|
-
_iterator.e(err);
|
|
396
|
-
} finally {
|
|
397
|
-
_iterator.f();
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
return (0, _jsonTemplates().default)(value)({
|
|
401
|
-
$context: this.context,
|
|
402
|
-
$jobsMapByNodeId: this.jobsMapByNodeId,
|
|
403
|
-
$fn: injectedFns
|
|
404
|
-
});
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
exports.default = ExecutionModel;
|
|
410
|
-
ExecutionModel.StatusMap = {
|
|
411
|
-
[_constants.JOB_STATUS.PENDING]: _constants.EXECUTION_STATUS.STARTED,
|
|
412
|
-
[_constants.JOB_STATUS.RESOLVED]: _constants.EXECUTION_STATUS.RESOLVED,
|
|
413
|
-
[_constants.JOB_STATUS.REJECTED]: _constants.EXECUTION_STATUS.REJECTED,
|
|
414
|
-
[_constants.JOB_STATUS.CANCELLED]: _constants.EXECUTION_STATUS.CANCELLED
|
|
415
|
-
};
|
|
20
|
+
exports.default = ExecutionModel;
|
package/lib/models/Workflow.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ import FlowNodeModel from './FlowNode';
|
|
|
5
5
|
export default class WorkflowModel extends Model {
|
|
6
6
|
static database: Database;
|
|
7
7
|
id: number;
|
|
8
|
+
key: string;
|
|
8
9
|
title: string;
|
|
9
10
|
enabled: boolean;
|
|
11
|
+
current: boolean;
|
|
10
12
|
description?: string;
|
|
11
13
|
type: string;
|
|
12
14
|
config: any;
|
|
@@ -21,6 +23,4 @@ export default class WorkflowModel extends Model {
|
|
|
21
23
|
countExecutions: HasManyCountAssociationsMixin;
|
|
22
24
|
getExecutions: HasManyGetAssociationsMixin<ExecutionModel>;
|
|
23
25
|
createExecution: HasManyCreateAssociationMixin<ExecutionModel>;
|
|
24
|
-
getTransaction(options: any): any;
|
|
25
|
-
trigger: (context: Object, options?: {}) => Promise<ExecutionModel>;
|
|
26
26
|
}
|
package/lib/models/Workflow.js
CHANGED
|
@@ -15,86 +15,6 @@ function _database() {
|
|
|
15
15
|
return data;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
22
|
-
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); }); }; }
|
|
23
|
-
|
|
24
|
-
class WorkflowModel extends _database().Model {
|
|
25
|
-
constructor(...args) {
|
|
26
|
-
var _this;
|
|
27
|
-
|
|
28
|
-
super(...args);
|
|
29
|
-
_this = this;
|
|
30
|
-
|
|
31
|
-
this.trigger = /*#__PURE__*/function () {
|
|
32
|
-
var _ref = _asyncToGenerator(function* (context, options = {}) {
|
|
33
|
-
// `null` means not to trigger
|
|
34
|
-
if (context === null) {
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const transaction = yield _this.getTransaction(options);
|
|
39
|
-
|
|
40
|
-
if (_this.useTransaction) {
|
|
41
|
-
const existed = yield _this.countExecutions({
|
|
42
|
-
where: {
|
|
43
|
-
transaction: transaction.id
|
|
44
|
-
},
|
|
45
|
-
transaction
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
if (existed) {
|
|
49
|
-
console.warn(`workflow ${_this.id} has already been triggered in same execution (${transaction.id}), and newly triggering will be skipped.`);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const execution = yield _this.createExecution({
|
|
55
|
-
context,
|
|
56
|
-
status: _constants.EXECUTION_STATUS.STARTED,
|
|
57
|
-
useTransaction: _this.useTransaction,
|
|
58
|
-
transaction: transaction.id
|
|
59
|
-
}, {
|
|
60
|
-
transaction
|
|
61
|
-
});
|
|
62
|
-
const executed = yield _this.countExecutions({
|
|
63
|
-
transaction
|
|
64
|
-
}); // NOTE: not to trigger afterUpdate hook here
|
|
65
|
-
|
|
66
|
-
yield _this.update({
|
|
67
|
-
executed
|
|
68
|
-
}, {
|
|
69
|
-
transaction,
|
|
70
|
-
hooks: false
|
|
71
|
-
});
|
|
72
|
-
execution.workflow = _this;
|
|
73
|
-
yield execution.start({
|
|
74
|
-
transaction
|
|
75
|
-
}); // @ts-ignore
|
|
76
|
-
|
|
77
|
-
if (transaction && (!options.transaction || options.transaction.finished)) {
|
|
78
|
-
yield transaction.commit();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return execution;
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
return function (_x) {
|
|
85
|
-
return _ref.apply(this, arguments);
|
|
86
|
-
};
|
|
87
|
-
}();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
getTransaction(options) {
|
|
91
|
-
if (!this.useTransaction) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return options.transaction && !options.transaction.finished ? options.transaction : this.constructor.database.sequelize.transaction();
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
}
|
|
18
|
+
class WorkflowModel extends _database().Model {}
|
|
99
19
|
|
|
100
20
|
exports.default = WorkflowModel;
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import { Trigger } from "
|
|
1
|
+
import { Trigger } from "..";
|
|
2
2
|
import WorkflowModel from "../models/Workflow";
|
|
3
3
|
export interface CollectionChangeTriggerConfig {
|
|
4
4
|
collection: string;
|
|
5
5
|
mode: number;
|
|
6
6
|
condition: any;
|
|
7
7
|
}
|
|
8
|
-
export default class CollectionTrigger
|
|
9
|
-
db: any;
|
|
8
|
+
export default class CollectionTrigger extends Trigger {
|
|
10
9
|
events: Map<any, any>;
|
|
11
|
-
constructor({ app }: {
|
|
12
|
-
app: any;
|
|
13
|
-
});
|
|
14
10
|
on(workflow: WorkflowModel): void;
|
|
15
11
|
off(workflow: WorkflowModel): void;
|
|
16
12
|
}
|
|
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
+
var _ = require("..");
|
|
9
|
+
|
|
8
10
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
9
11
|
|
|
10
12
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
@@ -19,6 +21,10 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
19
21
|
|
|
20
22
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
21
23
|
|
|
24
|
+
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); } }
|
|
25
|
+
|
|
26
|
+
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); }); }; }
|
|
27
|
+
|
|
22
28
|
const MODE_BITMAP = {
|
|
23
29
|
CREATE: 1,
|
|
24
30
|
UPDATE: 2,
|
|
@@ -34,39 +40,67 @@ function getHookId(workflow, type) {
|
|
|
34
40
|
} // async function, should return promise
|
|
35
41
|
|
|
36
42
|
|
|
37
|
-
function handler(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
changed = _this$config.changed; // NOTE: if no configured fields changed, do not trigger
|
|
41
|
-
|
|
42
|
-
if (changed && changed.length && changed.every(name => !data.changed(name))) {
|
|
43
|
-
return;
|
|
44
|
-
} // NOTE: if no configured condition match, do not trigger
|
|
45
|
-
|
|
43
|
+
function handler(_x, _x2, _x3) {
|
|
44
|
+
return _handler.apply(this, arguments);
|
|
45
|
+
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
function _handler() {
|
|
48
|
+
_handler = _asyncToGenerator(function* (workflow, data, options) {
|
|
49
|
+
var _condition$$and;
|
|
50
|
+
|
|
51
|
+
const _workflow$config3 = workflow.config,
|
|
52
|
+
collection = _workflow$config3.collection,
|
|
53
|
+
condition = _workflow$config3.condition,
|
|
54
|
+
changed = _workflow$config3.changed; // NOTE: if no configured fields changed, do not trigger
|
|
55
|
+
|
|
56
|
+
if (changed && changed.length && changed.every(name => !data.changed(name))) {// TODO: temp comment out
|
|
57
|
+
// return;
|
|
58
|
+
} // NOTE: if no configured condition match, do not trigger
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if (condition && ((_condition$$and = condition.$and) === null || _condition$$and === void 0 ? void 0 : _condition$$and.length)) {
|
|
62
|
+
// TODO: change to map filter format to calculation format
|
|
63
|
+
// const calculation = toCalculation(condition);
|
|
64
|
+
const _data$constructor$dat = data.constructor.database.getCollection(collection),
|
|
65
|
+
repository = _data$constructor$dat.repository,
|
|
66
|
+
model = _data$constructor$dat.model;
|
|
67
|
+
|
|
68
|
+
const transaction = options.transaction;
|
|
69
|
+
const count = yield repository.count({
|
|
70
|
+
filter: {
|
|
71
|
+
$and: [condition, {
|
|
72
|
+
[model.primaryKeyAttribute]: data[model.primaryKeyAttribute]
|
|
73
|
+
}]
|
|
74
|
+
},
|
|
75
|
+
transaction
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (!count) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
50
82
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
83
|
+
return this.plugin.trigger(workflow, {
|
|
84
|
+
data: data.get()
|
|
85
|
+
}, {
|
|
86
|
+
transaction: options.transaction
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
return _handler.apply(this, arguments);
|
|
54
90
|
}
|
|
55
91
|
|
|
56
|
-
class CollectionTrigger {
|
|
57
|
-
constructor({
|
|
58
|
-
|
|
59
|
-
}) {
|
|
60
|
-
this.db = void 0;
|
|
92
|
+
class CollectionTrigger extends _.Trigger {
|
|
93
|
+
constructor(...args) {
|
|
94
|
+
super(...args);
|
|
61
95
|
this.events = new Map();
|
|
62
|
-
this.db = app.db;
|
|
63
96
|
}
|
|
64
97
|
|
|
65
98
|
on(workflow) {
|
|
99
|
+
const db = this.plugin.app.db;
|
|
66
100
|
const _workflow$config = workflow.config,
|
|
67
101
|
collection = _workflow$config.collection,
|
|
68
102
|
mode = _workflow$config.mode;
|
|
69
|
-
const Collection =
|
|
103
|
+
const Collection = db.getCollection(collection);
|
|
70
104
|
|
|
71
105
|
if (!Collection) {
|
|
72
106
|
return;
|
|
@@ -86,15 +120,15 @@ class CollectionTrigger {
|
|
|
86
120
|
|
|
87
121
|
if (mode & key) {
|
|
88
122
|
if (!this.events.has(name)) {
|
|
89
|
-
const listener = handler.bind(workflow);
|
|
123
|
+
const listener = handler.bind(this, workflow);
|
|
90
124
|
this.events.set(name, listener);
|
|
91
|
-
|
|
125
|
+
db.on(event, listener);
|
|
92
126
|
}
|
|
93
127
|
} else {
|
|
94
128
|
const listener = this.events.get(name);
|
|
95
129
|
|
|
96
130
|
if (listener) {
|
|
97
|
-
|
|
131
|
+
db.off(event, listener);
|
|
98
132
|
this.events.delete(name);
|
|
99
133
|
}
|
|
100
134
|
}
|
|
@@ -107,10 +141,11 @@ class CollectionTrigger {
|
|
|
107
141
|
}
|
|
108
142
|
|
|
109
143
|
off(workflow) {
|
|
144
|
+
const db = this.plugin.app.db;
|
|
110
145
|
const _workflow$config2 = workflow.config,
|
|
111
146
|
collection = _workflow$config2.collection,
|
|
112
147
|
mode = _workflow$config2.mode;
|
|
113
|
-
const Collection =
|
|
148
|
+
const Collection = db.getCollection(collection);
|
|
114
149
|
|
|
115
150
|
if (!Collection) {
|
|
116
151
|
return;
|
|
@@ -132,7 +167,7 @@ class CollectionTrigger {
|
|
|
132
167
|
const listener = this.events.get(name);
|
|
133
168
|
|
|
134
169
|
if (listener) {
|
|
135
|
-
|
|
170
|
+
db.off(event, listener);
|
|
136
171
|
this.events.delete(name);
|
|
137
172
|
}
|
|
138
173
|
}
|
package/lib/triggers/index.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import Plugin from '..';
|
|
1
2
|
import WorkflowModel from '../models/Workflow';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
export declare abstract class Trigger {
|
|
4
|
+
readonly plugin: Plugin;
|
|
5
|
+
constructor(plugin: Plugin);
|
|
6
|
+
abstract on(workflow: WorkflowModel): void;
|
|
7
|
+
abstract off(workflow: WorkflowModel): void;
|
|
5
8
|
}
|
|
6
|
-
export default function (plugin: any
|
|
9
|
+
export default function <T extends Trigger>(plugin: any, more?: {
|
|
10
|
+
[key: string]: {
|
|
11
|
+
new (p: Plugin): T;
|
|
12
|
+
};
|
|
13
|
+
}): void;
|